ONOS-2470: Implement "Reset Node Locations" function in topology view.
- also cleaned up some Long/Lat code.
- Note also that metadata from client is structured so 'lng/lat' properties
(from repositioned node) are wrapped in 'equivLoc' object.
Change-Id: I5afc53d26ef56fc0932f8650e8f7df79b36c3947
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
index 49d5155..b700a54 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
@@ -357,18 +357,24 @@
return;
}
- String slat = annotations.value(AnnotationKeys.LATITUDE);
String slng = annotations.value(AnnotationKeys.LONGITUDE);
+ String slat = annotations.value(AnnotationKeys.LATITUDE);
+ boolean haveLng = slng != null && !slng.isEmpty();
+ boolean haveLat = slat != null && !slat.isEmpty();
try {
- if (slat != null && slng != null && !slat.isEmpty() && !slng.isEmpty()) {
- double lat = Double.parseDouble(slat);
+ if (haveLng && haveLat) {
double lng = Double.parseDouble(slng);
+ double lat = Double.parseDouble(slat);
ObjectNode loc = objectNode()
- .put("type", "latlng").put("lat", lat).put("lng", lng);
+ .put("type", "lnglat")
+ .put("lng", lng)
+ .put("lat", lat);
payload.set("location", loc);
+ } else {
+ log.trace("missing Lng/Lat: lng={}, lat={}", slng, slat);
}
} catch (NumberFormatException e) {
- log.warn("Invalid geo data latitude={}; longiture={}", slat, slng);
+ log.warn("Invalid geo data: longitude={}, latitude={}", slng, slat);
}
}
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.js b/web/gui/src/main/webapp/app/view/topo/topo.js
index ace9a0e..dbd5e0c 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.js
+++ b/web/gui/src/main/webapp/app/view/topo/topo.js
@@ -55,7 +55,7 @@
B: [toggleMap, 'Toggle background map'],
S: [toggleSprites, 'Toggle sprite layer'],
- //X: [toggleNodeLock, 'Lock / unlock node positions'],
+ X: [tfs.resetAllLocations, 'Reset node locations'],
Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'],
N: [fltr.clickAction, 'Cycle node layers'],
L: [tfs.cycleDeviceLabels, 'Cycle device labels'],
diff --git a/web/gui/src/main/webapp/app/view/topo/topoForce.js b/web/gui/src/main/webapp/app/view/topo/topoForce.js
index 21137af..8508f85 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoForce.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoForce.js
@@ -455,10 +455,17 @@
ll;
// if we are not clearing the position data (unpinning),
- // attach the x, y, longitude, latitude...
+ // attach the x, y, (and equivalent longitude, latitude)...
if (!clearPos) {
ll = tms.lngLatFromCoord([d.x, d.y]);
- metaUi = {x: d.x, y: d.y, lng: ll[0], lat: ll[1]};
+ metaUi = {
+ x: d.x,
+ y: d.y,
+ equivLoc: {
+ lng: ll[0],
+ lat: ll[1]
+ }
+ };
}
d.metaUi = metaUi;
wss.sendEvent('updateMeta', {
@@ -580,6 +587,13 @@
$timeout(updateLinks, 2000);
}
+ function resetAllLocations() {
+ tms.resetAllLocations();
+ updateNodes();
+ tick(); // force nodes to be redrawn in their new locations
+ flash.flash('Reset Node Locations');
+ }
+
// ==========================================
function updateNodes() {
@@ -1169,6 +1183,7 @@
showMastership: showMastership,
showBadLinks: showBadLinks,
+ resetAllLocations: resetAllLocations,
addDevice: addDevice,
updateDevice: updateDevice,
removeDevice: removeDevice,
diff --git a/web/gui/src/main/webapp/app/view/topo/topoModel.js b/web/gui/src/main/webapp/app/view/topo/topoModel.js
index a21fc93..418285c 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoModel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoModel.js
@@ -62,7 +62,13 @@
y = meta && meta.y,
xy;
- // If we have [x,y] already, use that...
+ // if the device contains explicit LONG/LAT data, use that to position
+ if (setLongLat(node)) {
+ // indicate we want to update cached meta data...
+ return true;
+ }
+
+ // else if we have [x,y] cached in meta data, use that...
if (x && y) {
node.fixed = true;
node.px = node.x = x;
@@ -70,17 +76,6 @@
return;
}
- var location = node.location,
- coord;
-
- if (location && location.type === 'latlng') {
- coord = coordFromLngLat(location);
- node.fixed = true;
- node.px = node.x = coord[0];
- node.py = node.y = coord[1];
- return true;
- }
-
// if this is a node update (not a node add).. skip randomizer
if (forUpdate) {
return;
@@ -116,6 +111,25 @@
angular.extend(node, xy);
}
+ function setLongLat(node) {
+ var loc = node.location,
+ coord;
+
+ if (loc && loc.type === 'lnglat') {
+ coord = coordFromLngLat(loc);
+ node.fixed = true;
+ node.px = node.x = coord[0];
+ node.py = node.y = coord[1];
+ return true;
+ }
+ }
+
+ function resetAllLocations() {
+ nodes.forEach(function (d) {
+ setLongLat(d);
+ });
+ }
+
function mkSvgCls(dh, t, on) {
var ndh = 'node ' + dh,
ndht = t ? ndh + ' ' + t : ndh;
@@ -428,6 +442,7 @@
destroyModel: destroyModel,
positionNode: positionNode,
+ resetAllLocations: resetAllLocations,
createDeviceNode: createDeviceNode,
createHostNode: createHostNode,
createHostLink: createHostLink,
diff --git a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
index c62e52b..deb49a5 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoToolbar.js
@@ -51,6 +51,7 @@
B: { id: 'bkgrnd-tog', gid: 'map', isel: false },
S: { id: 'sprite-tog', gid: 'cloud', isel: false },
+ // TODO: add reset-node-locations button to toolbar
//X: { id: 'nodelock-tog', gid: 'lock', isel: false },
Z: { id: 'oblique-tog', gid: 'oblique', isel: false },
N: { id: 'filters-btn', gid: 'filters' },
diff --git a/web/gui/src/main/webapp/tests/app/view/topo/topoModel-spec.js b/web/gui/src/main/webapp/tests/app/view/topo/topoModel-spec.js
index 725bd47..99511fa 100644
--- a/web/gui/src/main/webapp/tests/app/view/topo/topoModel-spec.js
+++ b/web/gui/src/main/webapp/tests/app/view/topo/topoModel-spec.js
@@ -232,7 +232,7 @@
it('should position a node by translating lng/lat', function () {
var node = {
location: {
- type: 'latlng',
+ type: 'lnglat',
lng: 2008,
lat: 3009
}
@@ -319,7 +319,7 @@
type: 'yowser',
online: true,
location: {
- type: 'latlng',
+ type: 'lnglat',
lng: 2048,
lat: 3096
}
diff --git a/web/gui/src/test/_karma/ev/simple/ev_16_removeDevice_03.json b/web/gui/src/test/_karma/ev/simple/ev_16_removeDevice_03.json
index 9df9d61..396db5c 100644
--- a/web/gui/src/test/_karma/ev/simple/ev_16_removeDevice_03.json
+++ b/web/gui/src/test/_karma/ev/simple/ev_16_removeDevice_03.json
@@ -5,7 +5,7 @@
"type": "switch",
"online": false,
"location": {
- "type": "latlng",
+ "type": "lnglat",
"lat": 40.7127,
"lng": -74.0059
},
diff --git a/web/gui/src/test/_karma/ev/simple/ev_17_removeDevice_08.json b/web/gui/src/test/_karma/ev/simple/ev_17_removeDevice_08.json
index 15e711d..b6093ee 100644
--- a/web/gui/src/test/_karma/ev/simple/ev_17_removeDevice_08.json
+++ b/web/gui/src/test/_karma/ev/simple/ev_17_removeDevice_08.json
@@ -6,7 +6,7 @@
"online": false,
"master": "myInstA",
"location": {
- "type": "latlng",
+ "type": "lnglat",
"lat": 37.7833,
"lng": -122.4167
},
diff --git a/web/gui/src/test/_karma/ev/simple/ev_3_addDevice_08.json b/web/gui/src/test/_karma/ev/simple/ev_3_addDevice_08.json
index 9c16f2b..6f4137d 100644
--- a/web/gui/src/test/_karma/ev/simple/ev_3_addDevice_08.json
+++ b/web/gui/src/test/_karma/ev/simple/ev_3_addDevice_08.json
@@ -6,7 +6,7 @@
"online": false,
"master": "myInstA",
"location": {
- "type": "latlng",
+ "type": "lnglat",
"lat": 37.7833,
"lng": -122.4167
},
diff --git a/web/gui/src/test/_karma/ev/simple/ev_4_addDevice_03.json b/web/gui/src/test/_karma/ev/simple/ev_4_addDevice_03.json
index 0b8f044..fb5027c 100644
--- a/web/gui/src/test/_karma/ev/simple/ev_4_addDevice_03.json
+++ b/web/gui/src/test/_karma/ev/simple/ev_4_addDevice_03.json
@@ -6,7 +6,7 @@
"online": false,
"master": "myInstB",
"location": {
- "type": "latlng",
+ "type": "lnglat",
"lat": 40.7127,
"lng": -74.0059
},