blob: aadb6935d4c221b4e8a5d02f5dcc017f8a4fb41b [file] [log] [blame]
Simon Hunt7ac7be92015-01-06 10:47:56 -08001/*
2 * Copyright 2015 Open Networking Laboratory
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 ONOS GUI -- SVG -- Map Service
Simon Hunt7ac7be92015-01-06 10:47:56 -080019 */
Simon Huntf044d8a2015-01-07 17:53:04 -080020
21/*
Simon Huntf8173382015-01-13 14:12:09 -080022 The Map Service provides a simple API for loading geographical maps into
23 an SVG layer. For example, as a background to the Topology View.
Simon Huntf044d8a2015-01-07 17:53:04 -080024
Simon Huntac4c6f72015-02-03 19:50:53 -080025 e.g. var promise = MapService.loadMapInto(svgLayer, '*continental-us');
Simon Huntf044d8a2015-01-07 17:53:04 -080026
Simon Huntf8173382015-01-13 14:12:09 -080027 The Map Service makes use of the GeoDataService to load the required data
Simon Hunta7b6a6b2015-01-13 19:53:09 -080028 from the server and to create the appropriate geographical projection.
29
Simon Huntac4c6f72015-02-03 19:50:53 -080030 A promise is returned to the caller, which is resolved with the
31 map projection once created.
Simon Huntf8173382015-01-13 14:12:09 -080032*/
Simon Huntf044d8a2015-01-07 17:53:04 -080033
Simon Hunt7ac7be92015-01-06 10:47:56 -080034(function () {
35 'use strict';
36
Simon Huntf044d8a2015-01-07 17:53:04 -080037 // injected references
Simon Huntac4c6f72015-02-03 19:50:53 -080038 var $log, $q, fs, gds;
39
Simon Hunt2362b072015-06-11 20:08:22 -070040 // 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
Simon Huntac4c6f72015-02-03 19:50:53 -080045 function loadMapInto(mapLayer, id, opts) {
46 var promise = gds.fetchTopoData(id),
47 deferredProjection = $q.defer();
48
49 if (!promise) {
50 $log.warn('Failed to load map: ' + id);
51 return false;
52 }
53
54 promise.then(function () {
55 var gen = gds.createPathGenerator(promise.topodata, opts);
56
57 deferredProjection.resolve(gen.settings.projection);
58
Simon Hunta34fcb52016-02-25 16:27:32 -080059 mapLayer.selectAll('path')
Simon Huntac4c6f72015-02-03 19:50:53 -080060 .data(gen.geodata.features)
61 .enter()
62 .append('path')
63 .attr('d', gen.pathgen);
Simon Huntfacad992016-02-25 09:58:33 -080064
Simon Hunta34fcb52016-02-25 16:27:32 -080065 reshade(opts.shading);
Simon Huntac4c6f72015-02-03 19:50:53 -080066 });
67 return deferredProjection.promise;
68 }
69
Simon Hunt2362b072015-06-11 20:08:22 -070070 // ---
71
72 // NOTE: This method uses the countries.topojson data file, and then
73 // filters the results based on the supplied options.
74 // Usage:
75 // promise = loadMapRegionInto(svgGroup, {
76 // countryFilter: function (country) {
77 // return country.properties.continent === 'South America';
78 // }
79 // });
80
Simon Hunta34fcb52016-02-25 16:27:32 -080081 function loadMapRegionInto(mapLayer, opts) {
Simon Hunt2362b072015-06-11 20:08:22 -070082 var promise = gds.fetchTopoData("*countries"),
83 deferredProjection = $q.defer();
84
85 if (!promise) {
86 $log.warn('Failed to load countries TopoJSON data');
87 return false;
88 }
89
90 promise.then(function () {
91 var width = 1000,
92 height = 1000,
93 proj = d3.geo.mercator().translate([width/2, height/2]),
94 pathGen = d3.geo.path().projection(proj),
95 data = promise.topodata,
96 features = topojson.feature(data, data.objects.countries).features,
Simon Hunta34fcb52016-02-25 16:27:32 -080097 country = features.filter(opts.countryFilter),
Simon Hunt2362b072015-06-11 20:08:22 -070098 countryFeature = {
99 type: 'FeatureCollection',
100 features: country
101 },
102 path = d3.geo.path().projection(proj);
103
Simon Hunta34fcb52016-02-25 16:27:32 -0800104 gds.rescaleProjection(proj, 0.95, 1000, path, countryFeature, opts.adjustScale);
Simon Hunt2362b072015-06-11 20:08:22 -0700105
106 deferredProjection.resolve(proj);
107
108 mapLayer.selectAll('path.country')
109 .data([countryFeature])
110 .enter()
111 .append('path').classed('country', true)
112 .attr('d', pathGen);
Simon Hunta34fcb52016-02-25 16:27:32 -0800113
114 reshade(opts.shading);
Simon Hunt2362b072015-06-11 20:08:22 -0700115 });
116 return deferredProjection.promise;
117 }
Simon Hunt7ac7be92015-01-06 10:47:56 -0800118
Simon Hunta34fcb52016-02-25 16:27:32 -0800119 function reshade(sh) {
120 var p = sh && sh.palette,
Thomas Vachuska26be4f32016-03-31 01:10:27 -0700121 paths, stroke, fill, bg,
122 svg = d3.select('#ov-topo').select('svg');
Simon Hunta34fcb52016-02-25 16:27:32 -0800123 if (sh) {
124 stroke = p.outline;
125 fill = sh.flip ? p.sea : p.land;
126 bg = sh.flip ? p.land : p.sea;
127
Simon Hunta34fcb52016-02-25 16:27:32 -0800128 paths = d3.select('#topo-map').selectAll('path');
Simon Hunta34fcb52016-02-25 16:27:32 -0800129 svg.style('background-color', bg);
130 paths.attr({
131 stroke: stroke,
132 fill: fill
133 });
Thomas Vachuska26be4f32016-03-31 01:10:27 -0700134 } else {
135 svg.style('background-color', null);
Simon Hunta34fcb52016-02-25 16:27:32 -0800136 }
137 }
138
Simon Hunt7ac7be92015-01-06 10:47:56 -0800139 angular.module('onosSvg')
Simon Huntac4c6f72015-02-03 19:50:53 -0800140 .factory('MapService', ['$log', '$q', 'FnService', 'GeoDataService',
141 function (_$log_, _$q_, _fs_, _gds_) {
Simon Hunt7ac7be92015-01-06 10:47:56 -0800142 $log = _$log_;
Simon Huntac4c6f72015-02-03 19:50:53 -0800143 $q = _$q_;
Simon Huntf044d8a2015-01-07 17:53:04 -0800144 fs = _fs_;
Simon Hunta7b6a6b2015-01-13 19:53:09 -0800145 gds = _gds_;
Simon Hunt404e54c2015-01-09 11:58:49 -0800146
Simon Hunt7ac7be92015-01-06 10:47:56 -0800147 return {
Simon Hunt2362b072015-06-11 20:08:22 -0700148 loadMapRegionInto: loadMapRegionInto,
Simon Hunta34fcb52016-02-25 16:27:32 -0800149 loadMapInto: loadMapInto,
150 reshade: reshade
Simon Hunt7ac7be92015-01-06 10:47:56 -0800151 };
152 }]);
153
154}());