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 @@
function getUrl(id) {
if (id[0] === '*') {
return bundledUrlPrefix + id.slice(1) + '.json';
return bundledUrlPrefix + id.slice(1) + '.topojson';
}
return id + '.json';
return id + '.topojson';
}
angular.module('onosSvg')
.factory('GeoDataService', ['$log', '$http', 'FnService',
function (_$log_, _$http_, _fs_) {
$log = _$log_;
$http = _$http_;
fs = _fs_;
// start afresh...
function clearCache() {
......@@ -138,6 +132,17 @@
mfs = settings.mapFillScale,
path = d3.geo.path().projection(proj);
rescaleProjection(proj, mfs, dim, path, geoData);
// return the results
return {
geodata: geoData,
pathgen: path,
settings: settings
};
}
function rescaleProjection(proj, mfs, dim, path, geoData) {
// adjust projection scale and translation to fill the view
// with the map
......@@ -161,19 +166,21 @@
// set new scale, translation on the projection..
proj.scale(s).translate(t);
// return the results
return {
geodata: geoData,
pathgen: path,
settings: settings
};
}
angular.module('onosSvg')
.factory('GeoDataService', ['$log', '$http', 'FnService',
function (_$log_, _$http_, _fs_) {
$log = _$log_;
$http = _$http_;
fs = _fs_;
return {
clearCache: clearCache,
fetchTopoData: fetchTopoData,
createPathGenerator: createPathGenerator
createPathGenerator: createPathGenerator,
rescaleProjection: rescaleProjection
};
}]);
}());
\ No newline at end of file
......
......@@ -37,6 +37,11 @@
// injected references
var $log, $q, fs, gds;
// NOTE: This method assumes the datafile has exactly the map data
// that you want to load; for example id="*continental_us"
// mapping to ~/data/map/continental_us.topojson contains
// exactly the paths for the continental US.
function loadMapInto(mapLayer, id, opts) {
var promise = gds.fetchTopoData(id),
deferredProjection = $q.defer();
......@@ -60,6 +65,52 @@
return deferredProjection.promise;
}
// ---
// NOTE: This method uses the countries.topojson data file, and then
// filters the results based on the supplied options.
// Usage:
// promise = loadMapRegionInto(svgGroup, {
// countryFilter: function (country) {
// return country.properties.continent === 'South America';
// }
// });
function loadMapRegionInto(mapLayer, filterOpts) {
var promise = gds.fetchTopoData("*countries"),
deferredProjection = $q.defer();
if (!promise) {
$log.warn('Failed to load countries TopoJSON data');
return false;
}
promise.then(function () {
var width = 1000,
height = 1000,
proj = d3.geo.mercator().translate([width/2, height/2]),
pathGen = d3.geo.path().projection(proj),
data = promise.topodata,
features = topojson.feature(data, data.objects.countries).features,
country = features.filter(filterOpts.countryFilter),
countryFeature = {
type: 'FeatureCollection',
features: country
},
path = d3.geo.path().projection(proj);
gds.rescaleProjection(proj, 0.95, 1000, path, countryFeature);
deferredProjection.resolve(proj);
mapLayer.selectAll('path.country')
.data([countryFeature])
.enter()
.append('path').classed('country', true)
.attr('d', pathGen);
});
return deferredProjection.promise;
}
angular.module('onosSvg')
.factory('MapService', ['$log', '$q', 'FnService', 'GeoDataService',
......@@ -70,6 +121,7 @@
gds = _gds_;
return {
loadMapRegionInto: loadMapRegionInto,
loadMapInto: loadMapInto
};
}]);
......
......@@ -65,7 +65,7 @@
}
.light #ov-topo svg #topo-map {
stroke: #eee;
stroke: #ddd;
}
.dark #ov-topo svg #topo-map {
stroke: #444;
......
......@@ -276,10 +276,57 @@
sus.visible(noDevsLayer, b);
}
function setUpMap() {
var countryFilters = {
world: function (c) {
return c.properties.continent !== 'Antarctica';
},
// NOTE: for "usa" we are using our hand-crafted topojson file
s_america: function (c) {
return c.properties.continent === 'South America';
},
japan: function (c) {
return c.properties.geounit === 'Japan';
},
europe: function (c) {
return c.properties.continent === 'Europe';
},
italy: function (c) {
return c.properties.geounit === 'Italy';
},
uk: function (c) {
// technically, Ireland is not part of the United Kingdom,
// but the map looks weird without it showing.
return c.properties.adm0_a3 === 'GBR' ||
c.properties.adm0_a3 === 'IRL';
}
};
function setUpMap($loc) {
var s1 = $loc.search().mapid,
s2 = ps.getPrefs('topo_mapid'),
mapId = s1 || (s2 && s2.id) || 'world',
promise,
cfilter,
opts;
mapG = zoomLayer.append('g').attr('id', 'topo-map');
// returns a promise for the projection...
return ms.loadMapInto(mapG, '*continental_us');
if (mapId === 'usa') {
promise = ms.loadMapInto(mapG, '*continental_us');
} else {
ps.setPrefs('topo_mapid', {id:mapId});
cfilter = countryFilters[mapId] || countryFilters.world;
opts = { countryFilter: cfilter };
promise = ms.loadMapRegionInto(mapG, opts);
}
return promise;
}
function opacifyMap(b) {
......@@ -405,7 +452,7 @@
setUpDefs();
setUpZoom();
setUpNoDevs();
setUpMap().then(
setUpMap($loc).then(
function (proj) {
var z = ps.getPrefs('topo_zoom') || {tx:0, ty:0, sc:1};
zoomer.panZoom([z.tx, z.ty], z.sc);
......@@ -416,6 +463,7 @@
flash.enable(false);
toggleMap(prefsState.bg);
flash.enable(true);
// TODO: move tes.start() to here ????
}
);
setUpSprites($loc, tspr);
......
This diff could not be displayed because it is too large.