Simon Hunt
Committed by Brian O'Connor

GUI -- Topo View - Added ability to define different background maps of world regions.

Change-Id: I937106c1c7c9e045230fce88dc7e5a5849b5cb3f
...@@ -63,17 +63,11 @@ ...@@ -63,17 +63,11 @@
63 63
64 function getUrl(id) { 64 function getUrl(id) {
65 if (id[0] === '*') { 65 if (id[0] === '*') {
66 - return bundledUrlPrefix + id.slice(1) + '.json'; 66 + return bundledUrlPrefix + id.slice(1) + '.topojson';
67 } 67 }
68 - return id + '.json'; 68 + return id + '.topojson';
69 } 69 }
70 70
71 - angular.module('onosSvg')
72 - .factory('GeoDataService', ['$log', '$http', 'FnService',
73 - function (_$log_, _$http_, _fs_) {
74 - $log = _$log_;
75 - $http = _$http_;
76 - fs = _fs_;
77 71
78 // start afresh... 72 // start afresh...
79 function clearCache() { 73 function clearCache() {
...@@ -138,6 +132,17 @@ ...@@ -138,6 +132,17 @@
138 mfs = settings.mapFillScale, 132 mfs = settings.mapFillScale,
139 path = d3.geo.path().projection(proj); 133 path = d3.geo.path().projection(proj);
140 134
135 + rescaleProjection(proj, mfs, dim, path, geoData);
136 +
137 + // return the results
138 + return {
139 + geodata: geoData,
140 + pathgen: path,
141 + settings: settings
142 + };
143 + }
144 +
145 + function rescaleProjection(proj, mfs, dim, path, geoData) {
141 // adjust projection scale and translation to fill the view 146 // adjust projection scale and translation to fill the view
142 // with the map 147 // with the map
143 148
...@@ -161,19 +166,21 @@ ...@@ -161,19 +166,21 @@
161 166
162 // set new scale, translation on the projection.. 167 // set new scale, translation on the projection..
163 proj.scale(s).translate(t); 168 proj.scale(s).translate(t);
164 -
165 - // return the results
166 - return {
167 - geodata: geoData,
168 - pathgen: path,
169 - settings: settings
170 - };
171 } 169 }
172 170
171 + angular.module('onosSvg')
172 + .factory('GeoDataService', ['$log', '$http', 'FnService',
173 + function (_$log_, _$http_, _fs_) {
174 + $log = _$log_;
175 + $http = _$http_;
176 + fs = _fs_;
177 +
178 +
173 return { 179 return {
174 clearCache: clearCache, 180 clearCache: clearCache,
175 fetchTopoData: fetchTopoData, 181 fetchTopoData: fetchTopoData,
176 - createPathGenerator: createPathGenerator 182 + createPathGenerator: createPathGenerator,
183 + rescaleProjection: rescaleProjection
177 }; 184 };
178 }]); 185 }]);
179 }()); 186 }());
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -37,6 +37,11 @@ ...@@ -37,6 +37,11 @@
37 // injected references 37 // injected references
38 var $log, $q, fs, gds; 38 var $log, $q, fs, gds;
39 39
40 + // NOTE: This method assumes the datafile has exactly the map data
41 + // that you want to load; for example id="*continental_us"
42 + // mapping to ~/data/map/continental_us.topojson contains
43 + // exactly the paths for the continental US.
44 +
40 function loadMapInto(mapLayer, id, opts) { 45 function loadMapInto(mapLayer, id, opts) {
41 var promise = gds.fetchTopoData(id), 46 var promise = gds.fetchTopoData(id),
42 deferredProjection = $q.defer(); 47 deferredProjection = $q.defer();
...@@ -60,6 +65,52 @@ ...@@ -60,6 +65,52 @@
60 return deferredProjection.promise; 65 return deferredProjection.promise;
61 } 66 }
62 67
68 + // ---
69 +
70 + // NOTE: This method uses the countries.topojson data file, and then
71 + // filters the results based on the supplied options.
72 + // Usage:
73 + // promise = loadMapRegionInto(svgGroup, {
74 + // countryFilter: function (country) {
75 + // return country.properties.continent === 'South America';
76 + // }
77 + // });
78 +
79 + function loadMapRegionInto(mapLayer, filterOpts) {
80 + var promise = gds.fetchTopoData("*countries"),
81 + deferredProjection = $q.defer();
82 +
83 + if (!promise) {
84 + $log.warn('Failed to load countries TopoJSON data');
85 + return false;
86 + }
87 +
88 + promise.then(function () {
89 + var width = 1000,
90 + height = 1000,
91 + proj = d3.geo.mercator().translate([width/2, height/2]),
92 + pathGen = d3.geo.path().projection(proj),
93 + data = promise.topodata,
94 + features = topojson.feature(data, data.objects.countries).features,
95 + country = features.filter(filterOpts.countryFilter),
96 + countryFeature = {
97 + type: 'FeatureCollection',
98 + features: country
99 + },
100 + path = d3.geo.path().projection(proj);
101 +
102 + gds.rescaleProjection(proj, 0.95, 1000, path, countryFeature);
103 +
104 + deferredProjection.resolve(proj);
105 +
106 + mapLayer.selectAll('path.country')
107 + .data([countryFeature])
108 + .enter()
109 + .append('path').classed('country', true)
110 + .attr('d', pathGen);
111 + });
112 + return deferredProjection.promise;
113 + }
63 114
64 angular.module('onosSvg') 115 angular.module('onosSvg')
65 .factory('MapService', ['$log', '$q', 'FnService', 'GeoDataService', 116 .factory('MapService', ['$log', '$q', 'FnService', 'GeoDataService',
...@@ -70,6 +121,7 @@ ...@@ -70,6 +121,7 @@
70 gds = _gds_; 121 gds = _gds_;
71 122
72 return { 123 return {
124 + loadMapRegionInto: loadMapRegionInto,
73 loadMapInto: loadMapInto 125 loadMapInto: loadMapInto
74 }; 126 };
75 }]); 127 }]);
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
65 } 65 }
66 66
67 .light #ov-topo svg #topo-map { 67 .light #ov-topo svg #topo-map {
68 - stroke: #eee; 68 + stroke: #ddd;
69 } 69 }
70 .dark #ov-topo svg #topo-map { 70 .dark #ov-topo svg #topo-map {
71 stroke: #444; 71 stroke: #444;
......
...@@ -276,10 +276,57 @@ ...@@ -276,10 +276,57 @@
276 sus.visible(noDevsLayer, b); 276 sus.visible(noDevsLayer, b);
277 } 277 }
278 278
279 - function setUpMap() { 279 +
280 + var countryFilters = {
281 + world: function (c) {
282 + return c.properties.continent !== 'Antarctica';
283 + },
284 +
285 + // NOTE: for "usa" we are using our hand-crafted topojson file
286 +
287 + s_america: function (c) {
288 + return c.properties.continent === 'South America';
289 + },
290 +
291 + japan: function (c) {
292 + return c.properties.geounit === 'Japan';
293 + },
294 +
295 + europe: function (c) {
296 + return c.properties.continent === 'Europe';
297 + },
298 +
299 + italy: function (c) {
300 + return c.properties.geounit === 'Italy';
301 + },
302 +
303 + uk: function (c) {
304 + // technically, Ireland is not part of the United Kingdom,
305 + // but the map looks weird without it showing.
306 + return c.properties.adm0_a3 === 'GBR' ||
307 + c.properties.adm0_a3 === 'IRL';
308 + }
309 + };
310 +
311 +
312 + function setUpMap($loc) {
313 + var s1 = $loc.search().mapid,
314 + s2 = ps.getPrefs('topo_mapid'),
315 + mapId = s1 || (s2 && s2.id) || 'world',
316 + promise,
317 + cfilter,
318 + opts;
319 +
280 mapG = zoomLayer.append('g').attr('id', 'topo-map'); 320 mapG = zoomLayer.append('g').attr('id', 'topo-map');
281 - // returns a promise for the projection... 321 + if (mapId === 'usa') {
282 - return ms.loadMapInto(mapG, '*continental_us'); 322 + promise = ms.loadMapInto(mapG, '*continental_us');
323 + } else {
324 + ps.setPrefs('topo_mapid', {id:mapId});
325 + cfilter = countryFilters[mapId] || countryFilters.world;
326 + opts = { countryFilter: cfilter };
327 + promise = ms.loadMapRegionInto(mapG, opts);
328 + }
329 + return promise;
283 } 330 }
284 331
285 function opacifyMap(b) { 332 function opacifyMap(b) {
...@@ -405,7 +452,7 @@ ...@@ -405,7 +452,7 @@
405 setUpDefs(); 452 setUpDefs();
406 setUpZoom(); 453 setUpZoom();
407 setUpNoDevs(); 454 setUpNoDevs();
408 - setUpMap().then( 455 + setUpMap($loc).then(
409 function (proj) { 456 function (proj) {
410 var z = ps.getPrefs('topo_zoom') || {tx:0, ty:0, sc:1}; 457 var z = ps.getPrefs('topo_zoom') || {tx:0, ty:0, sc:1};
411 zoomer.panZoom([z.tx, z.ty], z.sc); 458 zoomer.panZoom([z.tx, z.ty], z.sc);
...@@ -416,6 +463,7 @@ ...@@ -416,6 +463,7 @@
416 flash.enable(false); 463 flash.enable(false);
417 toggleMap(prefsState.bg); 464 toggleMap(prefsState.bg);
418 flash.enable(true); 465 flash.enable(true);
466 + // TODO: move tes.start() to here ????
419 } 467 }
420 ); 468 );
421 setUpSprites($loc, tspr); 469 setUpSprites($loc, tspr);
......
This diff could not be displayed because it is too large.