GUI -- Further work on MapService and GeoDataService. Still WIP.

Change-Id: I92e826cc15cc1a07238cc4b4eac20583260a3c84
diff --git a/web/gui/src/main/webapp/app/fw/svg/map.js b/web/gui/src/main/webapp/app/fw/svg/map.js
index d57e65d..366204c 100644
--- a/web/gui/src/main/webapp/app/fw/svg/map.js
+++ b/web/gui/src/main/webapp/app/fw/svg/map.js
@@ -27,126 +27,40 @@
     e.g.  var ok = MapService.loadMapInto(svgLayer, '*continental-us');
 
     The Map Service makes use of the GeoDataService to load the required data
-    from the server.
+    from the server and to create the appropriate geographical projection.
+
 */
 
 (function () {
     'use strict';
 
     // injected references
-    var $log, $http, fs;
-
-    // internal state
-    var mapCache = d3.map(),
-        bundledUrlPrefix = '../data/map/';
-
-    function getUrl(id) {
-        if (id[0] === '*') {
-            return bundledUrlPrefix + id.slice(1) + '.json';
-        }
-        return id + '.json';
-    }
+    var $log, fs, gds;
 
     angular.module('onosSvg')
-        .factory('MapService', ['$log', '$http', 'FnService',
-        function (_$log_, _$http_, _fs_) {
+        .factory('MapService', ['$log', 'FnService', 'GeoDataService',
+        function (_$log_, _fs_, _gds_) {
             $log = _$log_;
-            $http = _$http_;
             fs = _fs_;
-
-
-            function fetchGeoMap(id) {
-                if (!fs.isS(id)) {
-                    return null;
-                }
-                var url = getUrl(id),
-                    promise = mapCache.get(id);
-
-                if (!promise) {
-                    // need to fetch the data, build the object,
-                    // cache it, and return it.
-                    promise = $http.get(url);
-
-                    promise.meta = {
-                        id: id,
-                        url: url,
-                        wasCached: false
-                    };
-
-                    promise.then(function (response) {
-                            // success
-                            promise.mapdata = response.data;
-                        }, function (response) {
-                            // error
-                            $log.warn('Failed to retrieve map data: ' + url,
-                                response.status, response.data);
-                        });
-
-                    mapCache.set(id, promise);
-
-                } else {
-                    promise.meta.wasCached = true;
-                }
-
-                return promise;
-            }
-
-            var geoMapProj;
-
-            function setProjForView(path, topoData) {
-                var dim = 1000;
-
-                // start with unit scale, no translation..
-                geoMapProj.scale(1).translate([0, 0]);
-
-                // figure out dimensions of map data..
-                var b = path.bounds(topoData),
-                    x1 = b[0][0],
-                    y1 = b[0][1],
-                    x2 = b[1][0],
-                    y2 = b[1][1],
-                    dx = x2 - x1,
-                    dy = y2 - y1,
-                    x = (x1 + x2) / 2,
-                    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];
-
-                // set new scale, translation on the projection..
-                geoMapProj.scale(s).translate(t);
-            }
-
+            gds = _gds_;
 
             function loadMapInto(mapLayer, id) {
-                var mapObject = fetchGeoMap(id);
-                if (!mapObject) {
+                var promise = gds.fetchTopoData(id);
+                if (!promise) {
                     $log.warn('Failed to load map: ' + id);
-                    return null;
+                    return false;
                 }
 
-                var mapdata = mapObject.mapdata,
-                    topoData, path;
-
-                mapObject.then(function () {
-                    // extracts the topojson data into geocoordinate-based geometry
-                    topoData = topojson.feature(mapdata, mapdata.objects.states);
-
-                    // see: http://bl.ocks.org/mbostock/4707858
-                    geoMapProj = d3.geo.mercator();
-                    path = d3.geo.path().projection(geoMapProj);
-
-                    setProjForView(path, topoData);
+                promise.then(function () {
+                    var gen = gds.createPathGenerator(promise.topodata);
 
                     mapLayer.selectAll('path')
-                        .data(topoData.features)
+                        .data(gen.geodata.features)
                         .enter()
                         .append('path')
-                        .attr('d', path);
+                        .attr('d', gen.pathgen);
                 });
-                // TODO: review whether we should just return true (not the map object)
-                return mapObject;
+                return true;
             }
 
             return {