Committed by
Brian O'Connor
GUI -- Topo View - Added ability to define different background maps of world regions.
Change-Id: I937106c1c7c9e045230fce88dc7e5a5849b5cb3f
Showing
6 changed files
with
128 additions
and
21 deletions
... | @@ -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 | }]); | ... | ... |
... | @@ -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.
-
Please register or login to post a comment