GUI -- Further work on MapService and GeoDataService. Still WIP.
Change-Id: I92e826cc15cc1a07238cc4b4eac20583260a3c84
diff --git a/web/gui/src/main/webapp/app/fw/svg/geodata.js b/web/gui/src/main/webapp/app/fw/svg/geodata.js
index 244507a..4d3c4a2 100644
--- a/web/gui/src/main/webapp/app/fw/svg/geodata.js
+++ b/web/gui/src/main/webapp/app/fw/svg/geodata.js
@@ -21,18 +21,36 @@
*/
/*
- The GeoData Service caches GeoJSON map data, and provides supporting
- projections for mapping into SVG layers.
+ The GeoData Service facilitates the fetching and caching of TopoJSON data
+ from the server, as well as providing a way of creating a path generator
+ for that data, to be used to render the map in an SVG layer.
- A GeoMap object can be fetched by ID. IDs that start with an asterisk
+ A TopoData object can be fetched by ID. IDs that start with an asterisk
identify maps bundled with the GUI. IDs that do not start with an
- asterisk are assumed to be URLs to externally provided data (exact
- format to be decided).
+ asterisk are assumed to be URLs to externally provided data.
- e.g. var geomap = GeoDataService.fetchGeoMap('*continental-us');
+ var topodata = GeoDataService.fetchTopoData('*continental-us');
- Note that, since the GeoMap instance is cached / shared, it should
- contain no state.
+ The path generator can then be created for that data-set:
+
+ var gen = GeoDataService.createPathGenerator(topodata, opts);
+
+ opts is an optional argument that allows the override of default settings:
+ {
+ objectTag: 'states',
+ projection: d3.geo.mercator(),
+ logicalSize: 1000,
+ mapFillScale: .95
+ };
+
+ The returned object (gen) comprises transformed data (TopoJSON -> GeoJSON),
+ the D3 path generator function, and the settings used ...
+
+ {
+ geodata: { ... },
+ pathgen: function (...) { ... },
+ settings: { ... }
+ }
*/
(function () {
@@ -66,9 +84,9 @@
// returns a promise decorated with:
// .meta -- id, url, and whether the data was cached
- // .mapdata -- geojson data (on response from server)
+ // .topodata -- TopoJSON data (on response from server)
- function fetchGeoMap(id) {
+ function fetchTopoData(id) {
if (!fs.isS(id)) {
return null;
}
@@ -88,10 +106,10 @@
promise.then(function (response) {
// success
- promise.mapdata = response.data;
+ promise.topodata = response.data;
}, function (response) {
// error
- $log.warn('Failed to retrieve map data: ' + url,
+ $log.warn('Failed to retrieve map TopoJSON data: ' + url,
response.status, response.data);
});
@@ -104,15 +122,32 @@
return promise;
}
- // TODO: clean up implementation of projection...
- function setProjForView(path, topoData) {
- var dim = 1000;
+ var defaultGenSettings = {
+ objectTag: 'states',
+ projection: d3.geo.mercator(),
+ logicalSize: 1000,
+ mapFillScale: .95
+ };
+
+ // converts given TopoJSON-format data into corresponding GeoJSON
+ // data, and creates a path generator for that data.
+ function createPathGenerator(topoData, opts) {
+ var settings = $.extend({}, defaultGenSettings, opts),
+ topoObject = topoData.objects[settings.objectTag],
+ geoData = topojson.feature(topoData, topoObject),
+ proj = settings.projection,
+ dim = settings.logicalSize,
+ mfs = settings.mapFillScale,
+ path = d3.geo.path().projection(proj);
+
+ // adjust projection scale and translation to fill the view
+ // with the map
// start with unit scale, no translation..
- geoMapProj.scale(1).translate([0, 0]);
+ proj.scale(1).translate([0, 0]);
// figure out dimensions of map data..
- var b = path.bounds(topoData),
+ var b = path.bounds(geoData),
x1 = b[0][0],
y1 = b[0][1],
x2 = b[1][0],
@@ -123,17 +158,24 @@
y = (y1 + y2) / 2;
// size map to 95% of minimum dimension to fill space..
- var s = .95 / Math.min(dx / dim, dy / dim);
- var t = [dim / 2 - s * x, dim / 2 - s * y];
+ var s = mfs / Math.min(dx / dim, dy / dim),
+ t = [dim / 2 - s * x, dim / 2 - s * y];
// set new scale, translation on the projection..
- geoMapProj.scale(s).translate(t);
- }
+ proj.scale(s).translate(t);
+ // return the results
+ return {
+ geodata: geoData,
+ pathgen: path,
+ settings: settings
+ };
+ }
return {
clearCache: clearCache,
- fetchGeoMap: fetchGeoMap
+ fetchTopoData: fetchTopoData,
+ createPathGenerator: createPathGenerator
};
}]);
}());
\ No newline at end of file