Added different location support to map
Ylian Saint-Hilaire committed
Sep 25, 2017 at 15:28 UTC
0b86ecefa5356995799fda790700ac32086f3c6a
9 files changed
+175
-49
mesherrors.txt
+57
@@ -50,3 +50,60 @@ TypeError: socket.getPeerCertificate is not a function
50
at TCP.onconnection (net.js:1452:8)
51
52
53
+-------- 9/25/2017, 1:57:36 PM --------
54
+
55
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:1589
56
+ if ((node.userloc) && (node.userloc.length != 2)) return;
57
+ ^
58
+
59
+ReferenceError: node is not defined
60
+ at WebSocket.<anonymous> (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:1589:34)
61
+ at emitTwo (events.js:106:13)
62
+ at WebSocket.emit (events.js:191:7)
63
+ at Receiver.ontext (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\WebSocket.js:841:10)
64
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:536:18
65
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\Receiver.js:368:7
66
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\ws\lib\PerMessageDeflate.js:249:5
67
+ at afterWrite (_stream_writable.js:360:3)
68
+ at onwrite (_stream_writable.js:351:7)
69
+ at WritableState.onwrite (_stream_writable.js:89:5)
70
+
71
+
72
+-------- 9/25/2017, 2:01:16 PM --------
73
+
74
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:1616
75
+ command.userloc.push((Math.floor((new Date(iploc.date)) / 1000)));
76
+ ^
77
+
78
+ReferenceError: iploc is not defined
79
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:1616:88
80
+ at newArguments.(anonymous function) (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\executor.js:29:17)
81
+ at Cursor.execFn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:484:12)
82
+ at callback (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:126:19)
83
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:193:12
84
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:329:14
85
+ at Object.async.eachSeries (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:130:20)
86
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:323:11
87
+ at fn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:582:34)
88
+ at Immediate._onImmediate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:498:34)
89
+
90
+
91
+-------- 9/25/2017, 2:02:08 PM --------
92
+
93
+C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:1617
94
+ node.userloc = command.join(',');
95
+ ^
96
+
97
+TypeError: command.join is not a function
98
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\webserver.js:1617:68
99
+ at newArguments.(anonymous function) (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\executor.js:29:17)
100
+ at Cursor.execFn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:484:12)
101
+ at callback (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:126:19)
102
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\cursor.js:193:12
103
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:329:14
104
+ at Object.async.eachSeries (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:130:20)
105
+ at C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\nedb\lib\datastore.js:323:11
106
+ at fn (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:582:34)
107
+ at Immediate._onImmediate (C:\Users\Default.DESKTOP-M9I88C9\Desktop\AmtWebApp\meshcentral\node_modules\async\lib\async.js:498:34)
108
+
109
+
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.0.8-d",
3
+ "version": "0.0.8-e",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
public/images/mapmarker-gps.png
Binary files /dev/null and b/public/images/mapmarker-gps.png differ
public/images/mapmarker-ip.png
Binary files /dev/null and b/public/images/mapmarker-ip.png differ
public/images/mapmarker-user.png
Binary files /dev/null and b/public/images/mapmarker-user.png differ
public/images/mapmarker-wifi.png
Binary files /dev/null and b/public/images/mapmarker-wifi.png differ
public/styles/ol3-contextmenu.min.css
new
+7
@@ -0,0 +1,7 @@
1
+/*!
2
+ * ol3-contextmenu - v2.5.0
3
+ * Custom Context Menu for Openlayers
4
+ * https://github.com/jonataswalker/ol3-contextmenu
5
+ * Built: Fri Feb 24 2017 15:11:23 GMT-0300 (BRT)
6
+ */
7
+.ol-ctx-menu-container{position:absolute;padding:8px;background:#fff;color:#222;font-size:13px;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,.2);box-sizing:border-box}.ol-ctx-menu-container a,.ol-ctx-menu-container div,.ol-ctx-menu-container img,.ol-ctx-menu-container li,.ol-ctx-menu-container span,.ol-ctx-menu-container ul{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}.ol-ctx-menu-container a img{border:none}.ol-ctx-menu-container *,.ol-ctx-menu-container :after,.ol-ctx-menu-container :before{box-sizing:inherit}.ol-ctx-menu-container.ol-ctx-menu-hidden{opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container ul{list-style:none}.ol-ctx-menu-container li{position:relative;line-height:20px;padding:2px 5px}.ol-ctx-menu-container li:not(.ol-ctx-menu-separator):hover{cursor:pointer;background-color:#333;color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-submenu .ol-ctx-menu-container{border:1px solid #eee;padding:8px;top:0;opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover .ol-ctx-menu-container{opacity:1;visibility:visible;-webkit-transition-delay:0s;transition-delay:0s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:after{position:absolute;top:7px;right:10px;content:"";display:inline-block;width:.6em;height:.6em;border-right:.3em solid #222;border-top:.3em solid #222;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover:after{border-color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-separator{padding:0}.ol-ctx-menu-container li.ol-ctx-menu-separator hr{border:0;height:1px;background-image:-webkit-linear-gradient(right,transparent,rgba(0,0,0,.75),transparent);background-image:linear-gradient(270deg,transparent,rgba(0,0,0,.75),transparent)}.ol-ctx-menu-icon{text-indent:20px;background-size:20px auto;background-repeat:no-repeat;background-position:0}.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABaUlEQVQ4T72U7VHCQBCGn90GtAMuNGCswFiBWIFQgWMFxg6wArECsQKhArEBiB1Qwa1zgQn5IAYcxv13k71n3919L8KJQ07M47+BzgG9TRfZ/JBuWhS6BJFHRJICYrZGZIz3z5Ct2+B7gG6I6kt+wewdkQVwjtkAkR5mC8yu26A1oItR/cTsOweQBdgutD8G7jGm2PJ2n8oqUKIpIjd4HxTM8gvaT/F+AlmWnyWaIXKF95eNguFzTYFhNsdWu9kFgFlaFMANUH3D8wDLoLgSTSD2il8NCe2ZXQBxWDGwxmyUzzOMBZ7wy7Qb2K0wQfXjMOBuhlFpZtNty5sFaTQBuTusZdymeqs1SpYKcO9HkE3KbTd9WFijMHJQ5hBNEAYNq5Qd0dhyke0GiE4QzjqfW23mHT8Hl4DG4Lce3FPE7AtbBSdsbNqpoJLgYkRnNeUV+xwJDHTnUEkxHGbhBXUs5TjJjew/KPy94g+NRaIVRYmMXwAAAABJRU5ErkJggg==")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABc0lEQVQ4T71U21ECQRDsJgGdvQDECMQIxAjECMQILCPwzAAjECIQI0AiEDPQAPaWCBhrcKHuCUcV5f7dY3v6tUscefHIePhfwBBCF8CZqRCReRs1tQxDCH1VfQLQz4EsSY4AvIjIsgm8AhhCGKrqa9zwrqoLAKckB5HtguR1E2gBMITQU9VPAD8GICIGtl3e+xHJBwBT59xtHcsCYJZlUwA3kcGHbfDep51OZywi3/acZZm9vyJ5WR5o38uACmDunNt6ZwAkUxFZDwghDFT1jeSjiJinhVUBVNVJkiTDKO8CQA+AsbNQ7s1Ps0VVn5MkSfcCtmBoDZi1Bdx4eJ7zbBolrwPy3o9J3rWSHPs3A1BbjVKlYBaIyDgvu9LDXDU2RTZmXVW1oKyLxRD+OrkOrJLy5mVM0iaftDhuhVbsvBzMglzKUNW6IV/OOWtCM8MmVvEkmbwt83LaB19fdgOtVquUZJeknaDdobTwbOcvBzPcN/AXH1DFFWP7u9oAAAAASUVORK5CYII=")}.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABU0lEQVQ4T72U7VECMRRFz3sNaAdkacC1AtcKxApcKnCsQOwAK3CtQKxAqEBsANYOqCDPyTIC+8WCw5jfybn33dxEOPGSE/P4b6BzQG89RT47ZJoWhy5B5BGRZAMxWyEyxvtnyFdt8AagS1F9KQ6YvSMyB84xGyDSw2yO2XUbtAJ0MaqfmH0XAPIA2y7tj4F7jAm2uG1yWQZKNEHkBu+Dg2njWBJNEbnC+8uaIFRuWfuG2QxbbrOrUd0A1Tc8D7AIjkur7DAAsVf8MiWMZ3ZR2m02LPIMscATfjHqBnY7TFD9OAy4zTCCPG/MUKMM5O6wkXFr9dZq7FQqqHk/hDzbFa73cFONTZFDdRyiCcKg5rrSiLaXkiI6RjjrfG6VzDs+B5eAxuDXeYpmNRGzL2wZ/wof+du4GNFpBVqqz5HA4MM5VEYYDrOs+1I6Q9u/4Q8O9wN/AGgWjBVqQjjgAAAAAElFTkSuQmCC")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABYklEQVQ4T72U4VHCQBCF36tA91KAWIFYgViBWIFYgWMFYgdYgVCBWAFSgdiBFpAsFWSdxcDkQoBkhnF/ZjbfvX377ogjF4/Mw/8CVbUD4MynEJF5k2lqFapqz8yeAPRKkCXJEYAXEVnugm8BVXVgZq/FD+9mtgBwSrJfqF2QvN4FjYCq2jWzTwA/DhARh20qTdMRyQcA0xDCbZ3KCJhl2RTATaHgo+6HLMv8+xXJy+qB3l8FGoB5CKHsXcRV1b6ZvZF8FBH3NKotoJlNkiQZFONdlLtJ3rufbouZPSdJMjwIbKDQEzBrClx7eC4i33Uepmk6JnnXaOQifzMAtdGoRApugYiMI1uqKkrRWAfZo9MxM1+UZzFewl8mN4nYdVM83L7BkwbXLUrF3sfBLQDQBbDy08x8vOohXyEE71lVq9emuEk+3gZa3XYroCvwFyjP8yHJDsnxwaU08GxvS2uFhw78BbzWrxXgMbsHAAAAAElFTkSuQmCC")}
\ No newline at end of file
views/default.handlebars
+97
-47
@@ -8,6 +8,7 @@
8
<meta name="format-detection" content="telephone=no" />
9
<link type="text/css" href="styles/style.css" media="screen" rel="stylesheet" title="CSS" />
10
<link type="text/css" href="styles/ol.css" media="screen" rel="stylesheet" title="CSS" />
11
+ <link type="text/css" href="styles/ol3-contextmenu.min.css" media="screen" rel="stylesheet" title="CSS" />
12
<script type="text/javascript" src="scripts/common-0.0.1.js"></script>
13
<script type="text/javascript" src="scripts/meshcentral.js"></script>
14
<script type="text/javascript" src="scripts/amt-0.2.0.js"></script>
@@ -21,6 +22,7 @@
22
<script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
23
<script type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script>
24
<script type="text/javascript" src="scripts/ol.js"></script>
25
+ <script type="text/javascript" src="scripts/ol3-contextmenu.js"></script>
26
<title>MeshCentral</title>
27
</head>
28
@@ -1003,6 +1005,9 @@
1005
node.desc = message.event.node.desc;
1006
node.publicip = message.event.node.publicip;
1007
node.iploc = message.event.node.iploc;
1008
+ node.wifiloc = message.event.node.wifiloc;
1009
+ node.gpsloc = message.event.node.gpsloc;
1010
+ node.userloc = message.event.node.userloc;
1011
if (message.event.node.agent != undefined) {
1012
if (node.agent == undefined) node.agent = {};
1013
if (message.event.node.agent.ver != undefined) { node.agent.ver = message.event.node.agent.ver; }
@@ -1027,6 +1032,8 @@
1032
drawNotifications();
1033
refreshDevice(node._id);
1034
updateMapMarkers();
1035
+
1036
+ if ((currentNode == node) && (xxdialogMode != null) && (xxdialogTag == '@xxmap')) { p10showNodeLocationDialog(); }
1037
}
1038
break;
1039
}
@@ -1673,16 +1680,15 @@
1680
var boundingBox = null;
1681
for (var i in nodes) {
1682
var loc = map_parseNodeLoc(nodes[i]);
1676
- if (loc) { // Draw markers for devices with locations
1683
+ var feature = xxmap.markersSource.getFeatureById(nodes[i]._id); // Remove if present
1684
+ if ((loc != null) && ((nodes[i].meshid == selectedMesh) || (selectedMesh == undefined))) { // Draw markers for devices with locations
1685
lat = loc[0];
1686
lon = loc[1];
1687
+ var type = loc[2];
1688
if (boundingBox == null) { boundingBox = [ lat, lon, lat, lon, 0 ]; } else { if (lat < boundingBox[0]) { boundingBox[0] = lat; } if (lon < boundingBox[1]) { boundingBox[1] = lon; } if (lat > boundingBox[2]) { boundingBox[2] = lat; } if (lon > boundingBox[3]) { boundingBox[3] = lon; } }
1680
- var feature = xxmap.markersSource.getFeatureById(nodes[i]._id);
1681
- if (nodes[i].meshid == selectedMesh || selectedMesh == undefined) {
1682
- if (feature == null || feature == undefined) { addFeature(nodes[i]); boundingBox[4] = 1; } else { updateFeature(nodes[i], feature); } // Update Feature
1683
- } else {
1684
- if (feature) { xxmap.markersSource.removeFeature(feature); } // Remove if it does not belong to that mesh
1685
- }
1689
+ if (feature == null) { addFeature(nodes[i]); boundingBox[4] = 1; } else { updateFeature(nodes[i], feature); feature.setStyle(markerStyle(nodes[i], loc[2])); } // Update Feature
1690
+ } else {
1691
+ if (feature) { xxmap.markersSource.removeFeature(feature); }
1692
}
1693
}
1694
return boundingBox;
@@ -1692,10 +1698,15 @@
1698
var map_cm_popup = new ol.Overlay({ element: Q('xmap-info-window'), positioning: 'bottom-center', stopEvent: false });
1699
1700
// Edit Marker item
1695
- var map_cm_editMarker = { text: "Modify Node location", callback: function (obj) { modifyMarkerloc(obj.data); } };
1701
+ var map_cm_editMarker = { text: "Modify node location", callback: function (obj) { modifyMarkerloc(obj.data); } };
1702
+
1703
+ // Clear Marker item
1704
+ var map_cm_clearMarker = { text: "Remove node location", callback: function (obj) {
1705
+ meshserver.Send({ action: 'changedevice', nodeid: obj.data.a, userloc: [] }); // Clear the user position marker
1706
+ }};
1707
1708
// Save Marker item
1698
- var map_cm_saveMarker = { text: "Save Node location", callback: function (obj) { saveMarkerloc(obj.data); } };
1709
+ var map_cm_saveMarker = { text: "Save node location", callback: function (obj) { saveMarkerloc(obj.data); } };
1710
1711
// Build a context menu for a feature
1712
var map_cm_nodemenu_items = [
@@ -1724,9 +1735,14 @@
1735
1736
// Get the lat/lon from a node
1737
function map_parseNodeLoc(node) {
1727
- if (!node.iploc) return;
1728
- var loc = node.iploc.split(',');
1729
- return [parseFloat(loc[0]) + (stringToIntHash(node._id.substring(0, 20)) / 100000000000), parseFloat(loc[1]) + (stringToIntHash(node._id.substring(20)) / 100000000000)]
1738
+ var loc = null, t = 0;
1739
+ if (node.iploc) { loc = node.iploc; t = 1; }
1740
+ if (node.wifiloc) { loc = node.wifiloc; t = 2; }
1741
+ if (node.gpsloc) { loc = node.gpsloc; t = 3; }
1742
+ if (node.userloc) { loc = node.userloc; t = 4; }
1743
+ if ((loc == null) || (typeof loc != 'string')) return;
1744
+ loc = loc.split(',');
1745
+ return [ parseFloat(loc[0]) + (stringToIntHash(node._id.substring(0, 20)) / 100000000000), parseFloat(loc[1]) + (stringToIntHash(node._id.substring(20)) / 100000000000), t ]
1746
}
1747
1748
// Load the entire map
@@ -1792,7 +1808,6 @@
1808
}
1809
});
1810
1795
- /*
1811
// Initialize context menu for openlayers
1812
contextmenu = new ContextMenu({
1813
width: 160,
@@ -1805,20 +1820,18 @@
1820
var feature = xxmap.map.forEachFeatureAtPixel(evt.pixel, function(ft, l){ return ft; });
1821
xxmap.contextmenu.clear(); //Clear the context menu
1822
if (feature) {
1808
- var featId=feature.getId();
1809
- if (featId) { // Node feature will have an id
1810
- addContextMenuItems(feature);
1811
- }
1823
+ var featId = feature.getId();
1824
+ if (featId) { addContextMenuItems(feature); } // Node feature will have an id
1825
else { // If the feature is a pointer, Get its corresponding Node feature
1813
- var nodeFeature= getCorrespondingFeature(feature); //return the node feature associated to pointer.
1826
+ var nodeFeature = getCorrespondingFeature(feature); //return the node feature associated to pointer.
1827
if (nodeFeature) { addContextMenuItems(nodeFeature); }
1828
else{ xxmap.contextmenu.extend(contextmenu_items); }
1829
}
1830
}
1831
else { xxmap.contextmenu.extend(contextmenu_items); }
1832
});
1833
+ if (xxmap.contextmenu == null) { xxmap.contextmenu = contextmenu; }
1834
xxmap.map.addControl(xxmap.contextmenu);
1821
- */
1835
//addMeshOptions(); // Adds Mesh names to mesh dropdown
1836
} catch (e) {
1837
QV('viewselectmapoption', false);
@@ -1827,24 +1840,24 @@
1840
}
1841
1842
// Add feature on to Map for a Node
1830
- function addFeature(node, lat, lon){
1843
+ function addFeature(node, lat, lon) {
1844
var existingfeature = getModifiedFeature(node._id); // Check if Corresponding feature was Modified ( Modifed feature are in active interactions list)
1845
if (existingfeature) { xxmap.markersSource.addFeature(existingfeature); } // Add that existing feature
1846
else { // Add new feature for this node
1847
if (!lat && !lon) { var loc = map_parseNodeLoc(node); lat = loc[0]; lon = loc[1]; }
1835
- var feature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326','EPSG:3857')), name: node.name, status: node.conn, lat: lat, lon: lon });
1836
- feature.setId(node._id); // Set id for the device as nodeid
1837
- feature.setStyle(markerStyle(node));
1838
- xxmap.markersSource.addFeature(feature); // Add the feature to Marker Source
1848
+ if ((lat < 90) && (lat > -90) && (lon < 180) && (lon > -180)) { // Check valid lat/lon
1849
+ var feature = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.transform([lon, lat], 'EPSG:4326','EPSG:3857')), name: node.name, status: node.conn, lat: lat, lon: lon });
1850
+ feature.setId(node._id); // Set id for the device as nodeid
1851
+ feature.setStyle(markerStyle(node));
1852
+ xxmap.markersSource.addFeature(feature); // Add the feature to Marker Source
1853
+ }
1854
}
1855
}
1856
1857
// Removing any feature from map
1858
function removeFeature(node) {
1844
- if (node.iploc) {
1845
- var feature = xxmap.markersSource.getFeatureById(node._id);
1846
- if (feature) { xxmap.markersSource.removeFeature(feature); }
1847
- }
1859
+ var feature = xxmap.markersSource.getFeatureById(node._id);
1860
+ if (feature) { xxmap.markersSource.removeFeature(feature); }
1861
}
1862
1863
// Update feature
@@ -1870,6 +1883,7 @@
1883
function modifyMarkerloc(ft){
1884
var featid = ft.getId();
1885
if (featid) {
1886
+ ft.setStyle(markerStyle(getNodeFromId(ft.a), 4)); // Switch to a user marker
1887
if ( !getActiveInteractions(ft)) {
1888
var dragInteration = new ol.interaction.Modify({
1889
features: new ol.Collection([ft]),
@@ -1891,16 +1905,25 @@
1905
removeInteraction(featid);
1906
var coord = ft.getGeometry().getCoordinates();
1907
var v = ol.proj.transform(coord, 'EPSG:3857', 'EPSG:4326');
1894
- meshserver.Send({ action: 'changelocation', nodeid: featid, value: v }); // Send them to server to save changes
1908
+ var vx = [ v[1], v[0] ]; // Flip the coordinates around, lat/long
1909
+ meshserver.Send({ action: 'changedevice', nodeid: featid, userloc: vx }); // Send them to server to save changes
1910
}
1911
}
1912
}
1913
1914
// Style the Markers
1900
- function markerStyle(node) {
1915
+ function markerStyle(node, type) {
1916
+ if (type == null) {
1917
+ type = 0;
1918
+ if (node.iploc) { type = 1; }
1919
+ if (node.wifiloc) { type = 2; }
1920
+ if (node.gpsloc) { type = 3; }
1921
+ if (node.userloc) { type = 4; }
1922
+ }
1923
+ var types = ['', '-ip','-wifi','-gps','-user'];
1924
var color = connStateColor(node);
1925
var style = new ol.style.Style({
1903
- image: new ol.style.Icon({ color: color, anchor: [0.5, 1], src: 'images/mapmarker.png' })
1926
+ image: new ol.style.Icon({ color: color, anchor: [0.5, 1], src: 'images/mapmarker' + types[type] + '.png' })
1927
//stroke: new ol.style.Stroke({ color: '#000', width: 20 })
1928
//text: new ol.style.Text({ text: 'bob!', textAlign: 'right', offsetX: -10, fill: new ol.style.Fill({ color: '#000' }), stroke: new ol.style.Stroke({ color: '#fff', width: 2 }) })
1929
});
@@ -1935,6 +1958,11 @@
1958
} else {
1959
map_cm_editMarker.data = feature;
1960
xxmap.contextmenu.push(map_cm_editMarker);
1961
+ var node = getNodeFromId(feature.a);
1962
+ if (node.userloc) {
1963
+ map_cm_clearMarker.data = feature;
1964
+ xxmap.contextmenu.push(map_cm_clearMarker);
1965
+ }
1966
}
1967
map_cm_nodemenu_items.forEach(function (item){
1968
if (item.text == 'Zoom-in to extent' || item.text == 'Zoom-out to extent') { item.data = feature; }
@@ -2047,6 +2075,7 @@
2075
if (node) {
2076
var feature = markersSource.getFeatureById(i);
2077
var v = ol.proj.transform(coords, 'EPSG:3857', 'EPSG:4326');
2078
+ var vx = [ v[1], v[0] ]; // Flip the coordinates around, lat/long
2079
if (button == 2) {
2080
if (feature) {
2081
feature.getGeometry().setCoordinates(coords);
@@ -2054,10 +2083,10 @@
2083
if (activeInteraction) {
2084
saveMarkerloc(feature);
2085
} else { // If this feature is not modified, then send updated coords to server.
2057
- meshserver.Send({ action: 'changelocation', nodeid: node._id, value: v }); // Send them to server to save changes
2086
+ meshserver.Send({ action: 'changedevice', nodeid: node._id, value: vx }); // Send them to server to save changes
2087
}
2088
} else {
2060
- meshserver.Send({ action: 'changelocation', nodeid: node._id, value: v }); // This Node is not yet added to maps.
2089
+ meshserver.Send({ action: 'changedevice', nodeid: node._id, value: vx }); // This Node is not yet added to maps.
2090
}
2091
}
2092
else if (button == 1) {
@@ -2065,11 +2094,11 @@
2094
feature.getGeometry().setCoordinates(coords);
2095
modifyMarkerloc(feature);
2096
} else {
2068
- if (!node.iploc) {
2097
+ //if (map_parseNodeLoc(node.iploc) != null) {
2098
addFeature(node, v[0], v[1]);
2099
var newFeature = markersSource.getFeatureById(node._id);
2100
modifyMarkerloc(newFeature);
2072
- }
2101
+ //}
2102
}
2103
}
2104
}
@@ -2438,7 +2467,7 @@
2467
if ((meshrights & 4) != 0) x += '<a style=cursor:pointer onclick=p10showDeleteNodeDialog("' + node._id + '")>Delete Device</a>';
2468
x += '</div><div style=font-size:x-small>';
2469
if (mesh.mtype == 2) x += '<a style=cursor:pointer onclick=p10showNodeNetInfoDialog("' + node._id + '")>Interfaces</a> ';
2441
- if ((node.iploc) && (xxmap != null)) x += '<a style=cursor:pointer onclick=p10showNodeLocationDialog("' + node._id + '")>Location</a> ';
2470
+ if (xxmap != null) x += '<a style=cursor:pointer onclick=p10showNodeLocationDialog("' + node._id + '")>Location</a> ';
2471
x += '</div><br>'
2472
2473
QH('p10html3', x);
@@ -2650,26 +2679,47 @@
2679
// Show current location
2680
var d2map = null;
2681
function p10showNodeLocationDialog() {
2653
- if (xxdialogMode) return;
2654
- var loc = currentNode.iploc.split(',');
2655
- var lat = parseFloat(loc[0]);
2656
- var lng = parseFloat(loc[1]);
2657
- //var x = '<div><a href="https://www.google.com/maps/preview/@' + lat + ',' + lng + ',12z" target=_blank>Open in Google maps</a></div>';
2658
- var x = '<div id=d2map style=width:100%;height:300px></div>';
2659
- setDialogMode(2, "Device Location", 1, null, x);
2682
+ if ((xxdialogMode != null) && (xxdialogTag == '@xxmap')) { setDialogMode(0); } else { if (xxdialogMode) return; }
2683
+ var markers = [], types = ['iploc', 'wifiloc', 'gpsloc', 'userloc'], boundingBox = null;
2684
+
2685
+ for (var loctype in types) {
2686
+ if (currentNode[types[loctype]] != null) {
2687
+ var loc = currentNode[types[loctype]].split(','), lat = parseFloat(loc[0]), lon = parseFloat(loc[1]);
2688
+ if ((lat < 90) && (lat > -90) && (lon < 180) && (lon > -180)) { // Check valid lat/lon
2689
+ var deviceMark = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon, lat])) });
2690
+ deviceMark.setStyle(markerStyle(currentNode, parseInt(loctype) + 1));
2691
+ markers.push(deviceMark);
2692
+
2693
+ if (boundingBox == null) { boundingBox = [ lat, lon, lat, lon, 0 ]; } else { if (lat < boundingBox[0]) { boundingBox[0] = lat; } if (lon < boundingBox[1]) { boundingBox[1] = lon; } if (lat > boundingBox[2]) { boundingBox[2] = lat; } if (lon > boundingBox[3]) { boundingBox[3] = lon; } }
2694
+ }
2695
+ }
2696
+ }
2697
2698
// Setup the device mark layer
2662
- var deviceMark = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lng, lat])) });
2663
- deviceMark.setStyle(markerStyle(currentNode));
2664
- var vectorSource = new ol.source.Vector({ features: [deviceMark] });
2699
+ var vectorSource = new ol.source.Vector({ features: markers });
2700
var vectorLayer = new ol.layer.Vector({ source: vectorSource });
2701
2702
+ //var x = '<div><a href="https://www.google.com/maps/preview/@' + lat + ',' + lng + ',12z" target=_blank>Open in Google maps</a></div>';
2703
+ var x = '<div id=d2map style=width:100%;height:300px></div>';
2704
+ setDialogMode(2, "Device Location", 1, null, x, '@xxmap');
2705
+
2706
+ var clng = 0, clat = 0, zoom = 8;
2707
+ if (boundingBox != null) {
2708
+ var clat = (boundingBox[0] + boundingBox[2]) / 2;
2709
+ var clng = (boundingBox[1] + boundingBox[3]) / 2;
2710
+ var cscale = Math.max(Math.abs(boundingBox[0] - boundingBox[2]), Math.abs(boundingBox[1] - boundingBox[3]));
2711
+ var i = 360, zoom = -2;
2712
+ while (i > cscale) { zoom++; i = i / 2; }
2713
+ }
2714
+
2715
+ if (markers.length == 1) { zoom = 8; }
2716
+
2717
// Setup the map
2718
d2map = new ol.Map({
2719
target: 'd2map',
2720
interactions: ol.interaction.defaults({dragPan:false, mouseWheelZoom:false}),
2721
layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer ],
2672
- view: new ol.View({ center: ol.proj.fromLonLat([lng, lat]), zoom: 8 })
2722
+ view: new ol.View({ center: ol.proj.fromLonLat([clng, clat]), zoom: zoom })
2723
});
2724
}
2725
webserver.js
+13
-1
@@ -1586,7 +1586,8 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1586
{
1587
// Argument validation
1588
if ((command.nodeid == null) || (typeof command.nodeid != 'string') || (command.nodeid.split('/').length != 3) || (command.nodeid.split('/')[1] != domain.id)) return; // Invalid domain, operation only valid for current domain
1589
-
1589
+ if ((command.userloc) && (command.userloc.length != 2) && (command.userloc.length != 0)) return;
1590
+
1591
// Change the device
1592
obj.db.Get(command.nodeid, function (err, nodes) {
1593
if (nodes.length != 1) return;
@@ -1606,6 +1607,17 @@ module.exports.CreateWebServer = function (parent, db, args, secret, certificate
1607
if (command.icon && (command.icon != node.icon)) { change = 1; node.icon = command.icon; changes.push('icon'); }
1608
if (command.name && (command.name != node.name)) { change = 1; node.name = command.name; changes.push('name'); }
1609
if (command.host && (command.host != node.host)) { change = 1; node.host = command.host; changes.push('host'); }
1610
+ if (command.userloc && ((node.userloc == null) || (command.userloc[0] != node.userloc[0]) || (command.userloc[1] != node.userloc[1]))) {
1611
+ change = 1;
1612
+ if ((command.userloc.length == 0) && (node.userloc)) {
1613
+ delete node.userloc;
1614
+ changes.push('location removed');
1615
+ } else {
1616
+ command.userloc.push((Math.floor((new Date()) / 1000)));
1617
+ node.userloc = command.userloc.join(',');
1618
+ changes.push('location');
1619
+ }
1620
+ }
1621
if (command.desc != null && (command.desc != node.desc)) { change = 1; node.desc = command.desc; changes.push('description'); }
1622
if (command.intelamt != null) {
1623
if ((command.intelamt.user != null) && (command.intelamt.pass != undefined) && ((command.intelamt.user != node.intelamt.user) || (command.intelamt.pass != node.intelamt.pass))) { change = 1; node.intelamt.user = command.intelamt.user; node.intelamt.pass = command.intelamt.pass; changes.push('Intel AMT credentials'); }