GUI -- Split MapService into GeoDataService and MapService. WIP.
Change-Id: Ibfe5b35ecdfaaf39b9d48abd29d0a44327dec130
diff --git a/web/gui/src/main/webapp/app/fw/svg/geodata.js b/web/gui/src/main/webapp/app/fw/svg/geodata.js
new file mode 100644
index 0000000..244507a
--- /dev/null
+++ b/web/gui/src/main/webapp/app/fw/svg/geodata.js
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ ONOS GUI -- SVG -- GeoData Service
+
+ @author Simon Hunt
+ */
+
+/*
+ The GeoData Service caches GeoJSON map data, and provides supporting
+ projections for mapping into SVG layers.
+
+ A GeoMap 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).
+
+ e.g. var geomap = GeoDataService.fetchGeoMap('*continental-us');
+
+ Note that, since the GeoMap instance is cached / shared, it should
+ contain no state.
+ */
+
+(function () {
+ 'use strict';
+
+ // injected references
+ var $log, $http, fs;
+
+ // internal state
+ var cache = d3.map(),
+ bundledUrlPrefix = '../data/map/';
+
+ function getUrl(id) {
+ if (id[0] === '*') {
+ return bundledUrlPrefix + id.slice(1) + '.json';
+ }
+ return id + '.json';
+ }
+
+ angular.module('onosSvg')
+ .factory('GeoDataService', ['$log', '$http', 'FnService',
+ function (_$log_, _$http_, _fs_) {
+ $log = _$log_;
+ $http = _$http_;
+ fs = _fs_;
+
+ // start afresh...
+ function clearCache() {
+ cache = d3.map();
+ }
+
+ // returns a promise decorated with:
+ // .meta -- id, url, and whether the data was cached
+ // .mapdata -- geojson data (on response from server)
+
+ function fetchGeoMap(id) {
+ if (!fs.isS(id)) {
+ return null;
+ }
+ var url = getUrl(id),
+ promise = cache.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);
+ });
+
+ cache.set(id, promise);
+
+ } else {
+ promise.meta.wasCached = true;
+ }
+
+ return promise;
+ }
+
+ // TODO: clean up implementation of projection...
+ 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);
+ }
+
+
+ return {
+ clearCache: clearCache,
+ fetchGeoMap: fetchGeoMap
+ };
+ }]);
+}());
\ No newline at end of file
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 7a6b981..d57e65d 100644
--- a/web/gui/src/main/webapp/app/fw/svg/map.js
+++ b/web/gui/src/main/webapp/app/fw/svg/map.js
@@ -21,22 +21,14 @@
*/
/*
- The Map Service caches GeoJSON maps, which can be loaded into the map
- layer of the Topology View.
+ The Map Service provides a simple API for loading geographical maps into
+ an SVG layer. For example, as a background to the Topology View.
- A GeoMap 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).
+ e.g. var ok = MapService.loadMapInto(svgLayer, '*continental-us');
- e.g. var geomap = MapService.fetchGeoMap('*continental-us');
-
- The GeoMap object encapsulates topology data (features), and the
- D3 projection object.
-
- Note that, since the GeoMap instance is cached / shared, it should
- contain no state.
- */
+ The Map Service makes use of the GeoDataService to load the required data
+ from the server.
+*/
(function () {
'use strict';
diff --git a/web/gui/src/main/webapp/app/index.html b/web/gui/src/main/webapp/app/index.html
index d261b3f..5fa0364 100644
--- a/web/gui/src/main/webapp/app/index.html
+++ b/web/gui/src/main/webapp/app/index.html
@@ -44,6 +44,7 @@
<script src="fw/svg/svg.js"></script>
<script src="fw/svg/glyph.js"></script>
<script src="fw/svg/icon.js"></script>
+ <script src="fw/svg/geodata.js"></script>
<script src="fw/svg/map.js"></script>
<script src="fw/svg/zoom.js"></script>