Committed by
Gerrit Code Review
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
Showing
10 changed files
with
63 additions
and
26 deletions
| ... | @@ -357,18 +357,24 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { | ... | @@ -357,18 +357,24 @@ public abstract class TopologyViewMessageHandlerBase extends UiMessageHandler { |
| 357 | return; | 357 | return; |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | - String slat = annotations.value(AnnotationKeys.LATITUDE); | ||
| 361 | String slng = annotations.value(AnnotationKeys.LONGITUDE); | 360 | String slng = annotations.value(AnnotationKeys.LONGITUDE); |
| 361 | + String slat = annotations.value(AnnotationKeys.LATITUDE); | ||
| 362 | + boolean haveLng = slng != null && !slng.isEmpty(); | ||
| 363 | + boolean haveLat = slat != null && !slat.isEmpty(); | ||
| 362 | try { | 364 | try { |
| 363 | - if (slat != null && slng != null && !slat.isEmpty() && !slng.isEmpty()) { | 365 | + if (haveLng && haveLat) { |
| 364 | - double lat = Double.parseDouble(slat); | ||
| 365 | double lng = Double.parseDouble(slng); | 366 | double lng = Double.parseDouble(slng); |
| 367 | + double lat = Double.parseDouble(slat); | ||
| 366 | ObjectNode loc = objectNode() | 368 | ObjectNode loc = objectNode() |
| 367 | - .put("type", "latlng").put("lat", lat).put("lng", lng); | 369 | + .put("type", "lnglat") |
| 370 | + .put("lng", lng) | ||
| 371 | + .put("lat", lat); | ||
| 368 | payload.set("location", loc); | 372 | payload.set("location", loc); |
| 373 | + } else { | ||
| 374 | + log.trace("missing Lng/Lat: lng={}, lat={}", slng, slat); | ||
| 369 | } | 375 | } |
| 370 | } catch (NumberFormatException e) { | 376 | } catch (NumberFormatException e) { |
| 371 | - log.warn("Invalid geo data latitude={}; longiture={}", slat, slng); | 377 | + log.warn("Invalid geo data: longitude={}, latitude={}", slng, slat); |
| 372 | } | 378 | } |
| 373 | } | 379 | } |
| 374 | 380 | ... | ... |
| ... | @@ -55,7 +55,7 @@ | ... | @@ -55,7 +55,7 @@ |
| 55 | B: [toggleMap, 'Toggle background map'], | 55 | B: [toggleMap, 'Toggle background map'], |
| 56 | S: [toggleSprites, 'Toggle sprite layer'], | 56 | S: [toggleSprites, 'Toggle sprite layer'], |
| 57 | 57 | ||
| 58 | - //X: [toggleNodeLock, 'Lock / unlock node positions'], | 58 | + X: [tfs.resetAllLocations, 'Reset node locations'], |
| 59 | Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'], | 59 | Z: [tos.toggleOblique, 'Toggle oblique view (Experimental)'], |
| 60 | N: [fltr.clickAction, 'Cycle node layers'], | 60 | N: [fltr.clickAction, 'Cycle node layers'], |
| 61 | L: [tfs.cycleDeviceLabels, 'Cycle device labels'], | 61 | L: [tfs.cycleDeviceLabels, 'Cycle device labels'], | ... | ... |
| ... | @@ -455,10 +455,17 @@ | ... | @@ -455,10 +455,17 @@ |
| 455 | ll; | 455 | ll; |
| 456 | 456 | ||
| 457 | // if we are not clearing the position data (unpinning), | 457 | // if we are not clearing the position data (unpinning), |
| 458 | - // attach the x, y, longitude, latitude... | 458 | + // attach the x, y, (and equivalent longitude, latitude)... |
| 459 | if (!clearPos) { | 459 | if (!clearPos) { |
| 460 | ll = tms.lngLatFromCoord([d.x, d.y]); | 460 | ll = tms.lngLatFromCoord([d.x, d.y]); |
| 461 | - metaUi = {x: d.x, y: d.y, lng: ll[0], lat: ll[1]}; | 461 | + metaUi = { |
| 462 | + x: d.x, | ||
| 463 | + y: d.y, | ||
| 464 | + equivLoc: { | ||
| 465 | + lng: ll[0], | ||
| 466 | + lat: ll[1] | ||
| 467 | + } | ||
| 468 | + }; | ||
| 462 | } | 469 | } |
| 463 | d.metaUi = metaUi; | 470 | d.metaUi = metaUi; |
| 464 | wss.sendEvent('updateMeta', { | 471 | wss.sendEvent('updateMeta', { |
| ... | @@ -580,6 +587,13 @@ | ... | @@ -580,6 +587,13 @@ |
| 580 | $timeout(updateLinks, 2000); | 587 | $timeout(updateLinks, 2000); |
| 581 | } | 588 | } |
| 582 | 589 | ||
| 590 | + function resetAllLocations() { | ||
| 591 | + tms.resetAllLocations(); | ||
| 592 | + updateNodes(); | ||
| 593 | + tick(); // force nodes to be redrawn in their new locations | ||
| 594 | + flash.flash('Reset Node Locations'); | ||
| 595 | + } | ||
| 596 | + | ||
| 583 | // ========================================== | 597 | // ========================================== |
| 584 | 598 | ||
| 585 | function updateNodes() { | 599 | function updateNodes() { |
| ... | @@ -1169,6 +1183,7 @@ | ... | @@ -1169,6 +1183,7 @@ |
| 1169 | showMastership: showMastership, | 1183 | showMastership: showMastership, |
| 1170 | showBadLinks: showBadLinks, | 1184 | showBadLinks: showBadLinks, |
| 1171 | 1185 | ||
| 1186 | + resetAllLocations: resetAllLocations, | ||
| 1172 | addDevice: addDevice, | 1187 | addDevice: addDevice, |
| 1173 | updateDevice: updateDevice, | 1188 | updateDevice: updateDevice, |
| 1174 | removeDevice: removeDevice, | 1189 | removeDevice: removeDevice, | ... | ... |
| ... | @@ -62,7 +62,13 @@ | ... | @@ -62,7 +62,13 @@ |
| 62 | y = meta && meta.y, | 62 | y = meta && meta.y, |
| 63 | xy; | 63 | xy; |
| 64 | 64 | ||
| 65 | - // If we have [x,y] already, use that... | 65 | + // if the device contains explicit LONG/LAT data, use that to position |
| 66 | + if (setLongLat(node)) { | ||
| 67 | + // indicate we want to update cached meta data... | ||
| 68 | + return true; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + // else if we have [x,y] cached in meta data, use that... | ||
| 66 | if (x && y) { | 72 | if (x && y) { |
| 67 | node.fixed = true; | 73 | node.fixed = true; |
| 68 | node.px = node.x = x; | 74 | node.px = node.x = x; |
| ... | @@ -70,17 +76,6 @@ | ... | @@ -70,17 +76,6 @@ |
| 70 | return; | 76 | return; |
| 71 | } | 77 | } |
| 72 | 78 | ||
| 73 | - var location = node.location, | ||
| 74 | - coord; | ||
| 75 | - | ||
| 76 | - if (location && location.type === 'latlng') { | ||
| 77 | - coord = coordFromLngLat(location); | ||
| 78 | - node.fixed = true; | ||
| 79 | - node.px = node.x = coord[0]; | ||
| 80 | - node.py = node.y = coord[1]; | ||
| 81 | - return true; | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | // if this is a node update (not a node add).. skip randomizer | 79 | // if this is a node update (not a node add).. skip randomizer |
| 85 | if (forUpdate) { | 80 | if (forUpdate) { |
| 86 | return; | 81 | return; |
| ... | @@ -116,6 +111,25 @@ | ... | @@ -116,6 +111,25 @@ |
| 116 | angular.extend(node, xy); | 111 | angular.extend(node, xy); |
| 117 | } | 112 | } |
| 118 | 113 | ||
| 114 | + function setLongLat(node) { | ||
| 115 | + var loc = node.location, | ||
| 116 | + coord; | ||
| 117 | + | ||
| 118 | + if (loc && loc.type === 'lnglat') { | ||
| 119 | + coord = coordFromLngLat(loc); | ||
| 120 | + node.fixed = true; | ||
| 121 | + node.px = node.x = coord[0]; | ||
| 122 | + node.py = node.y = coord[1]; | ||
| 123 | + return true; | ||
| 124 | + } | ||
| 125 | + } | ||
| 126 | + | ||
| 127 | + function resetAllLocations() { | ||
| 128 | + nodes.forEach(function (d) { | ||
| 129 | + setLongLat(d); | ||
| 130 | + }); | ||
| 131 | + } | ||
| 132 | + | ||
| 119 | function mkSvgCls(dh, t, on) { | 133 | function mkSvgCls(dh, t, on) { |
| 120 | var ndh = 'node ' + dh, | 134 | var ndh = 'node ' + dh, |
| 121 | ndht = t ? ndh + ' ' + t : ndh; | 135 | ndht = t ? ndh + ' ' + t : ndh; |
| ... | @@ -428,6 +442,7 @@ | ... | @@ -428,6 +442,7 @@ |
| 428 | destroyModel: destroyModel, | 442 | destroyModel: destroyModel, |
| 429 | 443 | ||
| 430 | positionNode: positionNode, | 444 | positionNode: positionNode, |
| 445 | + resetAllLocations: resetAllLocations, | ||
| 431 | createDeviceNode: createDeviceNode, | 446 | createDeviceNode: createDeviceNode, |
| 432 | createHostNode: createHostNode, | 447 | createHostNode: createHostNode, |
| 433 | createHostLink: createHostLink, | 448 | createHostLink: createHostLink, | ... | ... |
| ... | @@ -51,6 +51,7 @@ | ... | @@ -51,6 +51,7 @@ |
| 51 | B: { id: 'bkgrnd-tog', gid: 'map', isel: false }, | 51 | B: { id: 'bkgrnd-tog', gid: 'map', isel: false }, |
| 52 | S: { id: 'sprite-tog', gid: 'cloud', isel: false }, | 52 | S: { id: 'sprite-tog', gid: 'cloud', isel: false }, |
| 53 | 53 | ||
| 54 | + // TODO: add reset-node-locations button to toolbar | ||
| 54 | //X: { id: 'nodelock-tog', gid: 'lock', isel: false }, | 55 | //X: { id: 'nodelock-tog', gid: 'lock', isel: false }, |
| 55 | Z: { id: 'oblique-tog', gid: 'oblique', isel: false }, | 56 | Z: { id: 'oblique-tog', gid: 'oblique', isel: false }, |
| 56 | N: { id: 'filters-btn', gid: 'filters' }, | 57 | N: { id: 'filters-btn', gid: 'filters' }, | ... | ... |
| ... | @@ -232,7 +232,7 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -232,7 +232,7 @@ describe('factory: view/topo/topoModel.js', function() { |
| 232 | it('should position a node by translating lng/lat', function () { | 232 | it('should position a node by translating lng/lat', function () { |
| 233 | var node = { | 233 | var node = { |
| 234 | location: { | 234 | location: { |
| 235 | - type: 'latlng', | 235 | + type: 'lnglat', |
| 236 | lng: 2008, | 236 | lng: 2008, |
| 237 | lat: 3009 | 237 | lat: 3009 |
| 238 | } | 238 | } |
| ... | @@ -319,7 +319,7 @@ describe('factory: view/topo/topoModel.js', function() { | ... | @@ -319,7 +319,7 @@ describe('factory: view/topo/topoModel.js', function() { |
| 319 | type: 'yowser', | 319 | type: 'yowser', |
| 320 | online: true, | 320 | online: true, |
| 321 | location: { | 321 | location: { |
| 322 | - type: 'latlng', | 322 | + type: 'lnglat', |
| 323 | lng: 2048, | 323 | lng: 2048, |
| 324 | lat: 3096 | 324 | lat: 3096 |
| 325 | } | 325 | } | ... | ... |
-
Please register or login to post a comment