node-red-contrib-web-worldmap 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -1
- package/README.md +75 -45
- package/examples/ESRI featurelayer overlay.json +1 -0
- package/package.json +1 -1
- package/worldmap/index.html +1 -0
- package/worldmap/leaflet/esri-leaflet.js +12 -0
- package/worldmap/worldmap.js +319 -184
- package/worldmap.html +2 -1
- package/worldmap.js +32 -2
package/worldmap/worldmap.js
CHANGED
|
@@ -16,9 +16,9 @@ var buttons = {};
|
|
|
16
16
|
var marksIndex = 0;
|
|
17
17
|
var menuOpen = false;
|
|
18
18
|
var clusterAt = 0;
|
|
19
|
-
var maxage = 900; // default max age of icons on map in seconds - cleared after
|
|
19
|
+
var maxage = 900; // default max age of icons on map in seconds - cleared after 15 mins
|
|
20
20
|
var baselayername = "OSM grey"; // Default base layer OSM but uniform grey
|
|
21
|
-
var pagefoot = " © DCJ 2023"
|
|
21
|
+
var pagefoot = " © DCJ 2023";
|
|
22
22
|
var inIframe = false;
|
|
23
23
|
var showUserMenu = true;
|
|
24
24
|
var showLayerMenu = true;
|
|
@@ -28,10 +28,12 @@ var heat;
|
|
|
28
28
|
var minimap;
|
|
29
29
|
var sidebyside;
|
|
30
30
|
var layercontrol;
|
|
31
|
-
|
|
31
|
+
var colorControl;
|
|
32
|
+
var drawCount = 0;
|
|
32
33
|
var drawingColour = "#910000";
|
|
34
|
+
var drawcontextmenu = "";
|
|
33
35
|
var sendDrawing;
|
|
34
|
-
var
|
|
36
|
+
var rmenudata = {};
|
|
35
37
|
var sendRoute;
|
|
36
38
|
var oldBounds = {ne:{lat:0, lng:0}, sw:{lat:0, lng:0}};
|
|
37
39
|
var edgeLayer = new L.layerGroup();
|
|
@@ -54,7 +56,32 @@ var iconSz = {
|
|
|
54
56
|
"Command": 44
|
|
55
57
|
};
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
var filesAdded = '';
|
|
60
|
+
|
|
61
|
+
var loadStatic = function(fileName) {
|
|
62
|
+
if (filesAdded.indexOf(fileName) !== -1) { return; }
|
|
63
|
+
var head = document.getElementsByTagName('head')[0]
|
|
64
|
+
if (fileName.indexOf('js') !== -1) {
|
|
65
|
+
var script = document.createElement('script');
|
|
66
|
+
script.src = fileName;
|
|
67
|
+
script.type = 'text/javascript';
|
|
68
|
+
console.log("Loading: ",fileName);
|
|
69
|
+
head.append(script);
|
|
70
|
+
filesAdded += ' ' + fileName;
|
|
71
|
+
}
|
|
72
|
+
else if (fileName.indexOf('css') !== -1) {
|
|
73
|
+
var style = document.createElement('link');
|
|
74
|
+
style.href = fileName;
|
|
75
|
+
style.type = 'text/css';
|
|
76
|
+
style.rel = 'stylesheet';
|
|
77
|
+
console.log("Loading: ",fileName);
|
|
78
|
+
head.append(style);;
|
|
79
|
+
filesAdded += ' ' + fileName;
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
console.log("Unsupported file type: ",fileName);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
58
85
|
|
|
59
86
|
// Create the socket
|
|
60
87
|
var connect = function() {
|
|
@@ -81,17 +108,15 @@ var connect = function() {
|
|
|
81
108
|
if (data.hasOwnProperty("type") && data.hasOwnProperty("data") && data.type === "Buffer") { data = data.data.toString(); }
|
|
82
109
|
handleData(data);
|
|
83
110
|
}
|
|
84
|
-
catch (e) { if (data) { console.log("BAD DATA",data); console.log(e) } }
|
|
111
|
+
catch (e) { if (data) { console.log("BAD DATA",data); console.log(e); } }
|
|
85
112
|
// console.log("DATA",typeof data,data);
|
|
86
113
|
};
|
|
87
|
-
}
|
|
114
|
+
};
|
|
88
115
|
console.log("CONNECT TO",location.pathname + 'socket');
|
|
89
116
|
|
|
90
117
|
var handleData = function(data) {
|
|
91
118
|
if (Array.isArray(data)) {
|
|
92
119
|
//console.log("ARRAY");
|
|
93
|
-
// map.closePopup();
|
|
94
|
-
// var bnds= L.latLngBounds([0,0]);
|
|
95
120
|
for (var prop in data) {
|
|
96
121
|
if (data[prop].command) { doCommand(data[prop].command); delete data[prop].command; }
|
|
97
122
|
if (data[prop].hasOwnProperty("name")) {
|
|
@@ -102,11 +127,11 @@ var handleData = function(data) {
|
|
|
102
127
|
data = {command:{map:{overlay:"KML", kml:data[prop].payload}}};
|
|
103
128
|
doCommand(data.command); return;
|
|
104
129
|
}
|
|
105
|
-
else { console.log("SKIP
|
|
130
|
+
else { console.log("SKIP array item",data[prop]); }
|
|
106
131
|
}
|
|
107
|
-
// map.fitBounds(bnds.pad(0.25));
|
|
108
132
|
}
|
|
109
133
|
else {
|
|
134
|
+
// Handle some raw string data overlays
|
|
110
135
|
if (typeof data === "string" && data.indexOf("<?xml") == 0) {
|
|
111
136
|
if (data.indexOf("<nvg") != -1) {
|
|
112
137
|
data = {command:{map:{overlay:"NVG", nvg:data}}};
|
|
@@ -118,6 +143,8 @@ var handleData = function(data) {
|
|
|
118
143
|
data = {command:{map:{overlay:"GPX", gpx:data}}};
|
|
119
144
|
}
|
|
120
145
|
}
|
|
146
|
+
|
|
147
|
+
// handle any commands in the data
|
|
121
148
|
if (data.command) { doCommand(data.command); delete data.command; }
|
|
122
149
|
|
|
123
150
|
// handle raw geojson type msg
|
|
@@ -131,7 +158,7 @@ var handleData = function(data) {
|
|
|
131
158
|
else if (data.hasOwnProperty("event") && data.event.hasOwnProperty("point")) {
|
|
132
159
|
doTAKjson(data.event);
|
|
133
160
|
}
|
|
134
|
-
// handle TAK json (from multicast Protobuf)
|
|
161
|
+
// handle TAK json (from multicast Protobuf via tak-ingest node)
|
|
135
162
|
else if (data.hasOwnProperty("cotEvent") && data.cotEvent.hasOwnProperty("lat") && data.cotEvent.hasOwnProperty("lon")) {
|
|
136
163
|
doTAKMCjson(data.cotEvent);
|
|
137
164
|
}
|
|
@@ -147,7 +174,7 @@ var handleData = function(data) {
|
|
|
147
174
|
}
|
|
148
175
|
}
|
|
149
176
|
|
|
150
|
-
window.onunload = function() { if (ws) ws.close(); }
|
|
177
|
+
window.onunload = function() { if (ws) { ws.close(); } }
|
|
151
178
|
|
|
152
179
|
var customTopoLayer = L.geoJson(null, {clickable:false, style: {color:"blue", weight:2, fillColor:"#cf6", fillOpacity:0.04}});
|
|
153
180
|
layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,customTopoLayer);
|
|
@@ -181,23 +208,16 @@ if (inIframe === true) {
|
|
|
181
208
|
startzoom = window.localStorage.getItem("lastzoom");
|
|
182
209
|
}
|
|
183
210
|
}
|
|
184
|
-
// if ( window.localStorage.hasOwnProperty("clusterat") ) {
|
|
185
|
-
// clusterAt = window.localStorage.getItem("clusterat");
|
|
186
|
-
// document.getElementById("setclus").value = clusterAt;
|
|
187
|
-
// }
|
|
188
|
-
// if ( window.localStorage.hasOwnProperty("maxage") ) {
|
|
189
|
-
// maxage = window.localStorage.getItem("maxage");
|
|
190
|
-
// document.getElementById("maxage").value = maxage;
|
|
191
|
-
// }
|
|
192
211
|
|
|
193
212
|
// Create the Initial Map object.
|
|
194
213
|
map = new L.map('map',{
|
|
195
214
|
zoomSnap: 0.1,
|
|
196
215
|
rotate: true,
|
|
197
|
-
rotateControl:
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
216
|
+
rotateControl: false,
|
|
217
|
+
// rotateControl: {
|
|
218
|
+
// closeOnZeroBearing: true,
|
|
219
|
+
// position: 'topleft'
|
|
220
|
+
// },
|
|
201
221
|
bearing: 0}).setView(startpos, startzoom);
|
|
202
222
|
map.whenReady(function() {
|
|
203
223
|
connect();
|
|
@@ -343,7 +363,7 @@ if (inIframe) {
|
|
|
343
363
|
document.getElementById("menu").style.borderRadius="6px";
|
|
344
364
|
}
|
|
345
365
|
else {
|
|
346
|
-
console.log("NOT in an iframe");
|
|
366
|
+
//console.log("NOT in an iframe");
|
|
347
367
|
if (!showUserMenu) { document.getElementById("bars").style.display="none"; }
|
|
348
368
|
|
|
349
369
|
// Add the fullscreen button
|
|
@@ -418,17 +438,17 @@ var Lgrid = L.latlngGraticule({
|
|
|
418
438
|
// Copyright (c) 2013 Måns Beckman, All rights reserved.
|
|
419
439
|
var edgeAware = function() {
|
|
420
440
|
if (!edgeEnabled) { return; }
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
441
|
+
map.removeLayer(edgeLayer)
|
|
442
|
+
edgeLayer = new L.layerGroup();
|
|
443
|
+
var mapBounds = map.getBounds();
|
|
444
|
+
var mapBoundsCenter = mapBounds.getCenter();
|
|
425
445
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
446
|
+
pSW = map.options.crs.latLngToPoint(mapBounds.getSouthWest(), map.getZoom());
|
|
447
|
+
pNE = map.options.crs.latLngToPoint(mapBounds.getNorthEast(), map.getZoom());
|
|
448
|
+
pCenter = map.options.crs.latLngToPoint(mapBoundsCenter, map.getZoom());
|
|
429
449
|
|
|
430
|
-
|
|
431
|
-
|
|
450
|
+
var viewBounds = L.latLngBounds(map.options.crs.pointToLatLng(L.point(pSW.x - (pCenter.x - pSW.x ), pSW.y - (pCenter.y - pSW.y )), map.getZoom()) , map.options.crs.pointToLatLng(L.point(pNE.x + (pNE.x - pCenter.x) , pNE.y + (pNE.y - pCenter.y) ), map.getZoom()) );
|
|
451
|
+
for (var id in markers) {
|
|
432
452
|
if (allData[id] && allData[id].hasOwnProperty("SIDC")) {
|
|
433
453
|
markerLatLng = markers[id].getLatLng();
|
|
434
454
|
if ( viewBounds.contains(markerLatLng) && !mapBounds.contains(markerLatLng) ) {
|
|
@@ -471,15 +491,15 @@ var edgeAware = function() {
|
|
|
471
491
|
edgeLayer.addLayer(L.marker([lat,lng],{icon:myicon}))
|
|
472
492
|
}
|
|
473
493
|
}
|
|
474
|
-
|
|
475
|
-
|
|
494
|
+
}
|
|
495
|
+
edgeLayer.addTo(map)
|
|
476
496
|
}
|
|
477
|
-
// end of
|
|
497
|
+
// end of edgeAware function
|
|
478
498
|
|
|
479
499
|
var panit = false;
|
|
480
500
|
function doPanit(v) {
|
|
481
501
|
if (v !== undefined) { panit = v; }
|
|
482
|
-
console.log("Panit set :",panit);
|
|
502
|
+
// console.log("Panit set :",panit);
|
|
483
503
|
}
|
|
484
504
|
|
|
485
505
|
var heatAll = false;
|
|
@@ -489,24 +509,23 @@ function doHeatAll(v) {
|
|
|
489
509
|
}
|
|
490
510
|
|
|
491
511
|
var lockit = false;
|
|
492
|
-
var
|
|
512
|
+
var mbnds = new L.LatLngBounds([[-120,-360],[120,360]]);
|
|
493
513
|
function doLock(v) {
|
|
494
514
|
if (v !== undefined) { lockit = v; }
|
|
495
515
|
if (lockit === false) {
|
|
496
|
-
|
|
516
|
+
mbnds = new L.LatLngBounds([[-120,-360],[120,360]]);
|
|
497
517
|
map.dragging.enable();
|
|
498
518
|
}
|
|
499
519
|
else {
|
|
500
|
-
|
|
520
|
+
mbnds = map.getBounds();
|
|
501
521
|
map.dragging.disable();
|
|
502
522
|
window.localStorage.setItem("lastpos",JSON.stringify(map.getCenter()));
|
|
503
523
|
window.localStorage.setItem("lastzoom", map.getZoom());
|
|
504
524
|
window.localStorage.setItem("lastlayer", baselayername);
|
|
505
|
-
//window.localStorage.setItem("clusterat", clusterAt);
|
|
506
525
|
window.localStorage.setItem("maxage", maxage);
|
|
507
526
|
console.log("Saved :",JSON.stringify(map.getCenter()),map.getZoom(),baselayername);
|
|
508
527
|
}
|
|
509
|
-
map.setMaxBounds(
|
|
528
|
+
map.setMaxBounds(mbnds);
|
|
510
529
|
//console.log("Map bounds lock :",lockit);
|
|
511
530
|
}
|
|
512
531
|
|
|
@@ -581,7 +600,7 @@ function doSearch() {
|
|
|
581
600
|
marks = [];
|
|
582
601
|
marksIndex = 0;
|
|
583
602
|
for (var key in markers) {
|
|
584
|
-
if ( (~(key.toLowerCase()).indexOf(value.toLowerCase())) && (
|
|
603
|
+
if ( (~(key.toLowerCase()).indexOf(value.toLowerCase())) && (mbnds.contains(markers[key].getLatLng()))) {
|
|
585
604
|
marks.push(markers[key]);
|
|
586
605
|
}
|
|
587
606
|
if (markers[key].icon === value) {
|
|
@@ -616,7 +635,8 @@ function doSearch() {
|
|
|
616
635
|
else {
|
|
617
636
|
if (lockit) {
|
|
618
637
|
document.getElementById('searchResult').innerHTML = " <font color='#ff0'>Found "+marks.length+" results within bounds.</font>";
|
|
619
|
-
}
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
620
640
|
document.getElementById('searchResult').innerHTML = " <font color='#ff0'>Found "+marks.length+" results.</font>";
|
|
621
641
|
}
|
|
622
642
|
}
|
|
@@ -639,7 +659,7 @@ function clearSearch() {
|
|
|
639
659
|
marks = [];
|
|
640
660
|
marksIndex = 0;
|
|
641
661
|
for (var key in markers) {
|
|
642
|
-
if ( (~(key.toLowerCase()).indexOf(value.toLowerCase())) && (
|
|
662
|
+
if ( (~(key.toLowerCase()).indexOf(value.toLowerCase())) && (mbnds.contains(markers[key].getLatLng()))) {
|
|
643
663
|
marks.push(markers[key]);
|
|
644
664
|
}
|
|
645
665
|
}
|
|
@@ -665,7 +685,8 @@ function toggleMenu() {
|
|
|
665
685
|
menuOpen = !menuOpen;
|
|
666
686
|
if (menuOpen) {
|
|
667
687
|
document.getElementById("menu").style.display = 'block';
|
|
668
|
-
}
|
|
688
|
+
}
|
|
689
|
+
else {
|
|
669
690
|
document.getElementById("menu").style.display = 'none';
|
|
670
691
|
dialogue.close();
|
|
671
692
|
}
|
|
@@ -814,7 +835,7 @@ var addThing = function() {
|
|
|
814
835
|
//popped = false;
|
|
815
836
|
var bits = thing.split(",");
|
|
816
837
|
var icon = (bits[1] || "circle").trim();
|
|
817
|
-
var lay = (bits[2] || "
|
|
838
|
+
var lay = (bits[2] || "unknown").trim(); // TODO: Do we want _drawing here or unknown ?
|
|
818
839
|
var colo = (bits[3] ?? "#910000").trim();
|
|
819
840
|
colo = colorKeywordToRGB(colo);
|
|
820
841
|
var hdg = parseFloat(bits[4] || 0);
|
|
@@ -836,28 +857,30 @@ var addThing = function() {
|
|
|
836
857
|
map.addLayer(layers[lay]);
|
|
837
858
|
}
|
|
838
859
|
|
|
860
|
+
var form = {};
|
|
861
|
+
var addToForm = function(n,v) { form[n] = v; }
|
|
839
862
|
var feedback = function(n,v,a,c) {
|
|
840
|
-
if (v === "
|
|
863
|
+
if (v === "_form") { v = form; }
|
|
841
864
|
if (markers[n]) {
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
865
|
+
console.log("FB1",n,v,a,c)
|
|
866
|
+
allData[n].action = a || "feedback";
|
|
867
|
+
if (v !== undefined) { allData[n][a||"value"] = v; }
|
|
868
|
+
ws.send(JSON.stringify(allData[n]));
|
|
869
|
+
setMarker(allData[n]);
|
|
870
|
+
}
|
|
871
|
+
else if (polygons[n]) {
|
|
872
|
+
console.log("FB2",n,v,a)
|
|
873
|
+
sendDrawing(n,v,a)
|
|
848
874
|
}
|
|
849
875
|
else {
|
|
850
876
|
if (n === undefined) { n = "map"; }
|
|
877
|
+
console.log("FB3",n,v,a,c)
|
|
878
|
+
rmenudata = v;
|
|
851
879
|
ws.send(JSON.stringify({action:a||"feedback", name:n, value:v, lat:rclk.lat, lon:rclk.lng}));
|
|
852
880
|
}
|
|
853
881
|
if (c === true) { map.closePopup(); }
|
|
854
882
|
}
|
|
855
883
|
|
|
856
|
-
var form = {};
|
|
857
|
-
var addToForm = function(n,v) {
|
|
858
|
-
form[n] = v;
|
|
859
|
-
}
|
|
860
|
-
|
|
861
884
|
// map.on('click', function(e) {
|
|
862
885
|
// ws.send(JSON.stringify({action:"click", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5)}));
|
|
863
886
|
// });
|
|
@@ -882,6 +905,12 @@ map.on('contextmenu', function(e) {
|
|
|
882
905
|
if ((hiderightclick !== true) && (addmenu.length > 0)) {
|
|
883
906
|
rclk = e.latlng;
|
|
884
907
|
form = {};
|
|
908
|
+
var ramen = ""+addmenu;
|
|
909
|
+
for (const item in rmenudata) {
|
|
910
|
+
ramen = ramen.replace(new RegExp("\\${"+item+"}","g"),rmenudata[item]);
|
|
911
|
+
}
|
|
912
|
+
ramen = ramen.replace(/\${.*?}/g,'')
|
|
913
|
+
rightmenuMap.setContent(ramen);
|
|
885
914
|
rightmenuMap.setLatLng(e.latlng);
|
|
886
915
|
map.openPopup(rightmenuMap);
|
|
887
916
|
setTimeout( function() {
|
|
@@ -893,7 +922,6 @@ map.on('contextmenu', function(e) {
|
|
|
893
922
|
}
|
|
894
923
|
});
|
|
895
924
|
|
|
896
|
-
|
|
897
925
|
// Layer control based on select box rather than radio buttons.
|
|
898
926
|
//var layercontrol = L.control.selectLayers(basemaps, overlays).addTo(map);
|
|
899
927
|
layercontrol = L.control.layers(basemaps, overlays);
|
|
@@ -1086,7 +1114,6 @@ var addOverlays = function(overlist) {
|
|
|
1086
1114
|
|
|
1087
1115
|
layers["_drawing"] = new L.FeatureGroup();
|
|
1088
1116
|
overlays["drawing"] = layers["_drawing"];
|
|
1089
|
-
var drawCount = 0;
|
|
1090
1117
|
map.pm.addControls({
|
|
1091
1118
|
position: 'topleft',
|
|
1092
1119
|
drawMarker: false,
|
|
@@ -1102,19 +1129,27 @@ var addOverlays = function(overlist) {
|
|
|
1102
1129
|
color: drawingColour,
|
|
1103
1130
|
fillColor: drawingColour,
|
|
1104
1131
|
fillOpacity: 0.4
|
|
1105
|
-
|
|
1132
|
+
});
|
|
1106
1133
|
}
|
|
1107
1134
|
|
|
1108
1135
|
var shape;
|
|
1109
1136
|
map.on("pm:create", (e) => {
|
|
1110
|
-
var name = e.shape + drawCount;
|
|
1111
1137
|
drawCount = drawCount + 1;
|
|
1138
|
+
var name = e.shape + drawCount;
|
|
1112
1139
|
|
|
1113
1140
|
e.layer.on('contextmenu', function(e) {
|
|
1114
1141
|
L.DomEvent.stopPropagation(e);
|
|
1142
|
+
var name = e.target.name;
|
|
1115
1143
|
var rmen = L.popup({offset:[0,-12]}).setLatLng(e.latlng);
|
|
1116
|
-
|
|
1117
|
-
|
|
1144
|
+
var d = drawcontextmenu || "<input type='text' value='${name}' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\"${name}\");'>Edit points</button><button onclick='editPoly(\"${name}\",\"drag\");'>Drag</button><button onclick='editPoly(\"${name}\",\"rot\");'>Rotate</button><button onclick='delMarker(\"${name}\",true);'>Delete</button><button onclick='sendDrawing();'>OK</button>";
|
|
1145
|
+
d = d.replace(/\${name}/g,name);
|
|
1146
|
+
if (e.target.value) {
|
|
1147
|
+
for (const item in e.target.value) {
|
|
1148
|
+
d = d.replace(new RegExp("\\${"+item+"}","g"),e.target.value[item]);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
rmen.setContent(d);
|
|
1152
|
+
setImmediate(function() { map.openPopup(rmen) });
|
|
1118
1153
|
});
|
|
1119
1154
|
e.layer.bindPopup(name);
|
|
1120
1155
|
|
|
@@ -1127,7 +1162,7 @@ var addOverlays = function(overlist) {
|
|
|
1127
1162
|
else {
|
|
1128
1163
|
cent = e.layer.getBounds().getCenter();
|
|
1129
1164
|
}
|
|
1130
|
-
var m = {action:"draw", name:name, type:e.shape, layer:"_drawing", options:e.layer.options, radius:e.layer._mRadius, lat:la, lon:lo};
|
|
1165
|
+
var m = {action:"draw", name:name, type:e.shape, layer:"_drawing", options:e.layer.options, radius:e.layer._mRadius, lat:la, lon:lo, drawCount:drawCount};
|
|
1131
1166
|
if (e.layer.hasOwnProperty("_latlngs")) {
|
|
1132
1167
|
if (e.layer.options.fill === false) { m.line = e.layer._latlngs; }
|
|
1133
1168
|
else { m.area = e.layer._latlngs[0]; }
|
|
@@ -1139,21 +1174,24 @@ var addOverlays = function(overlist) {
|
|
|
1139
1174
|
polygons[name].name = name;
|
|
1140
1175
|
layers["_drawing"].addLayer(shape.layer);
|
|
1141
1176
|
|
|
1142
|
-
var rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<input type='text' autofocus value='"+name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+name+"\");'>Edit points</button><button onclick='editPoly(\""+name+"\",\"drag\");'>Drag</button><button onclick='editPoly(\""+name+"\",\"rot\");'>Rotate</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
|
|
1177
|
+
var rightmenuMarker = L.popup({offset:[0,-12]}).setContent(drawcontextmenu.replace(/\${name}/g,name).replace(/\${.*?}/g,'') || "<input type='text' autofocus value='"+name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+name+"\");'>Edit points</button><button onclick='editPoly(\""+name+"\",\"drag\");'>Drag</button><button onclick='editPoly(\""+name+"\",\"rot\");'>Rotate</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
|
|
1143
1178
|
if (e.layer.options.fill === false && navigator.onLine) {
|
|
1144
|
-
rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<input type='text' autofocus value='"+name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+name+"\");'>Edit points</button><button onclick='editPoly(\""+name+"\",\"drag\");'>Drag</button><button onclick='editPoly(\""+name+"\",\"rot\");'>Rotate</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendRoute(\""+name+"\");'>Route</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
|
|
1179
|
+
rightmenuMarker = L.popup({offset:[0,-12]}).setContent(drawcontextmenu.replace(/\${name}/g,name).replace(/\${.*?}/g,'') || "<input type='text' autofocus value='"+name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+name+"\");'>Edit points</button><button onclick='editPoly(\""+name+"\",\"drag\");'>Drag</button><button onclick='editPoly(\""+name+"\",\"rot\");'>Rotate</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendRoute(\""+name+"\");'>Route</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
|
|
1145
1180
|
}
|
|
1146
1181
|
rightmenuMarker.setLatLng(cent);
|
|
1147
1182
|
setTimeout(function() {map.openPopup(rightmenuMarker)},25);
|
|
1148
1183
|
});
|
|
1149
1184
|
|
|
1150
|
-
sendDrawing = function(n) {
|
|
1151
|
-
var thing = document.getElementById('dinput')
|
|
1185
|
+
sendDrawing = function(n,v,a) {
|
|
1186
|
+
var thing = document.getElementById('dinput')?.value || n;
|
|
1152
1187
|
map.closePopup();
|
|
1153
1188
|
shape.m.name = thing;
|
|
1154
1189
|
shape.layer.bindPopup(thing);
|
|
1155
1190
|
delMarker(n,true);
|
|
1156
|
-
|
|
1191
|
+
if (v) {
|
|
1192
|
+
shape.layer.value = v;
|
|
1193
|
+
shape.m.value = v;
|
|
1194
|
+
}
|
|
1157
1195
|
polygons[thing] = shape.layer;
|
|
1158
1196
|
polygons[thing].lay = "_drawing";
|
|
1159
1197
|
polygons[thing].name = thing;
|
|
@@ -1224,7 +1262,8 @@ var addOverlays = function(overlist) {
|
|
|
1224
1262
|
numbers.push(current);
|
|
1225
1263
|
current = 0;
|
|
1226
1264
|
shift = 0;
|
|
1227
|
-
}
|
|
1265
|
+
}
|
|
1266
|
+
else {
|
|
1228
1267
|
shift += 5;
|
|
1229
1268
|
}
|
|
1230
1269
|
}
|
|
@@ -1250,6 +1289,8 @@ var addOverlays = function(overlist) {
|
|
|
1250
1289
|
sendDrawing(n);
|
|
1251
1290
|
});
|
|
1252
1291
|
}
|
|
1292
|
+
|
|
1293
|
+
changeDrawColour("#4040F0"); // Set default drawing color to blue on start
|
|
1253
1294
|
}
|
|
1254
1295
|
|
|
1255
1296
|
// Add the countries (world-110m) for offline use
|
|
@@ -1346,10 +1387,11 @@ var addOverlays = function(overlist) {
|
|
|
1346
1387
|
if (!inIframe) { layercontrol.addTo(map); }
|
|
1347
1388
|
else { showLayerMenu = false;}
|
|
1348
1389
|
|
|
1390
|
+
// Add optional mouse co-ordinates display
|
|
1349
1391
|
var coords = L.control.mouseCoordinate({position:"bottomleft"});
|
|
1350
1392
|
|
|
1351
1393
|
// Add an optional legend
|
|
1352
|
-
var legend = L.control({
|
|
1394
|
+
var legend = L.control({position:"bottomleft"});
|
|
1353
1395
|
|
|
1354
1396
|
// Add the dialog box for messages
|
|
1355
1397
|
// var dialogue = L.control.dialog({initOpen:false, size:[600,400], anchor:[50,150]}).addTo(map);
|
|
@@ -1382,9 +1424,11 @@ helpText += 'The default is that only visible layers add to the heatmap.</p>';
|
|
|
1382
1424
|
// Delete a marker or shape (and notify websocket)
|
|
1383
1425
|
var delMarker = function(dname,note) {
|
|
1384
1426
|
if (note) { map.closePopup(); }
|
|
1427
|
+
var pol = false;
|
|
1385
1428
|
if (typeof polygons[dname] != "undefined") {
|
|
1386
1429
|
layers[polygons[dname].lay].removeLayer(polygons[dname]);
|
|
1387
1430
|
delete polygons[dname];
|
|
1431
|
+
pol = true;
|
|
1388
1432
|
}
|
|
1389
1433
|
if (typeof polygons[dname+"_"] != "undefined") {
|
|
1390
1434
|
layers[polygons[dname+"_"].lay].removeLayer(polygons[dname+"_"]);
|
|
@@ -1400,7 +1444,10 @@ var delMarker = function(dname,note) {
|
|
|
1400
1444
|
delete markers[dname];
|
|
1401
1445
|
}
|
|
1402
1446
|
delete allData[dname];
|
|
1403
|
-
if (note) {
|
|
1447
|
+
if (note) {
|
|
1448
|
+
if (pol === true) { ws.send(JSON.stringify({action:"drawdelete", name:dname, deleted:true})); }
|
|
1449
|
+
else { ws.send(JSON.stringify({action:"delete", name:dname, deleted:true})); }
|
|
1450
|
+
}
|
|
1404
1451
|
}
|
|
1405
1452
|
|
|
1406
1453
|
var editPoly = function(pname,fun) {
|
|
@@ -1419,6 +1466,7 @@ var editPoly = function(pname,fun) {
|
|
|
1419
1466
|
lo = e.target._latlng.lng;
|
|
1420
1467
|
}
|
|
1421
1468
|
var m = {action:"draw", name:pname, layer:polygons[pname].lay, options:e.target.options, radius:e.target._mRadius, lat:la, lon:lo};
|
|
1469
|
+
if (e.target.value) { m.value = e.target.value; }
|
|
1422
1470
|
if (e.target.hasOwnProperty("_latlngs")) {
|
|
1423
1471
|
if (e.target.options.fill === false) { m.line = e.target._latlngs; }
|
|
1424
1472
|
else { m.area = e.target._latlngs[0]; }
|
|
@@ -1427,7 +1475,6 @@ var editPoly = function(pname,fun) {
|
|
|
1427
1475
|
})
|
|
1428
1476
|
}
|
|
1429
1477
|
|
|
1430
|
-
|
|
1431
1478
|
var rangerings = function(latlng, options) {
|
|
1432
1479
|
options = L.extend({
|
|
1433
1480
|
ranges: [250,500,750,1000],
|
|
@@ -1448,7 +1495,7 @@ var rangerings = function(latlng, options) {
|
|
|
1448
1495
|
return rings;
|
|
1449
1496
|
}
|
|
1450
1497
|
|
|
1451
|
-
// the MAIN add
|
|
1498
|
+
// the MAIN add marker or shape to map function
|
|
1452
1499
|
function setMarker(data) {
|
|
1453
1500
|
var rightmenu = function(m) {
|
|
1454
1501
|
m.on('click', function(e) {
|
|
@@ -1465,9 +1512,13 @@ function setMarker(data) {
|
|
|
1465
1512
|
rightcontext = "<button onclick='editPoly(\""+data.name+"\");'>Edit</button><button onclick='delMarker(\""+data.name+"\",true);'>Delete</button>";
|
|
1466
1513
|
}
|
|
1467
1514
|
if ((data.contextmenu !== undefined) && (typeof data.contextmenu === "string")) {
|
|
1468
|
-
rightcontext = data.contextmenu.replace(/\$name/g,
|
|
1515
|
+
rightcontext = data.contextmenu.replace(/\${name}/g,data.name);
|
|
1469
1516
|
delete data.contextmenu;
|
|
1470
1517
|
}
|
|
1518
|
+
for (const item in allData[data.name].value) {
|
|
1519
|
+
rightcontext = rightcontext.replace(new RegExp("\\${"+item+"}","g"),allData[data.name].value[item]);
|
|
1520
|
+
}
|
|
1521
|
+
rightcontext = rightcontext.replace(/\${.*?}/g,'')
|
|
1471
1522
|
if (rightcontext.length > 0) {
|
|
1472
1523
|
var rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<b>"+data.name+"</b><br/>"+rightcontext);
|
|
1473
1524
|
if (hiderightclick !== true) {
|
|
@@ -1496,15 +1547,15 @@ function setMarker(data) {
|
|
|
1496
1547
|
|
|
1497
1548
|
var ll;
|
|
1498
1549
|
var lli = null;
|
|
1499
|
-
var opt = {};
|
|
1500
|
-
opt.color = data.color ?? data.lineColor ?? "#910000";
|
|
1501
|
-
opt.fillColor = data.fillColor ?? "#910000";
|
|
1502
|
-
opt.stroke = (data.hasOwnProperty("stroke")) ? data.stroke : true;
|
|
1503
|
-
opt.weight = data.weight;
|
|
1504
|
-
opt.opacity = data.opacity;
|
|
1505
|
-
opt.fillOpacity = data.fillOpacity;
|
|
1550
|
+
var opt = data.options || {};
|
|
1551
|
+
opt.color = opt.color ?? data.color ?? data.lineColor ?? "#910000";
|
|
1552
|
+
opt.fillColor = opt.fillColor ?? data.fillColor ?? "#910000";
|
|
1553
|
+
opt.stroke = opt.stroke ?? (data.hasOwnProperty("stroke")) ? data.stroke : true;
|
|
1554
|
+
opt.weight = opt.weight ?? data.weight;
|
|
1555
|
+
opt.opacity = opt.opacity ?? data.opacity;
|
|
1556
|
+
opt.fillOpacity = opt.fillOpacity ?? data.fillOpacity;
|
|
1506
1557
|
opt.clickable = (data.hasOwnProperty("clickable")) ? data.clickable : false;
|
|
1507
|
-
opt.fill = (data.hasOwnProperty("fill")) ? data.fill : true;
|
|
1558
|
+
opt.fill = opt.fill ?? (data.hasOwnProperty("fill")) ? data.fill : true;
|
|
1508
1559
|
if (data.hasOwnProperty("dashArray")) { opt.dashArray = data.dashArray; }
|
|
1509
1560
|
if (opt.fillOpacity === undefined) { opt.fillOpacity = 0.2; }
|
|
1510
1561
|
if (opt.opacity === undefined) { opt.opacity = 1; }
|
|
@@ -1571,29 +1622,23 @@ function setMarker(data) {
|
|
|
1571
1622
|
|
|
1572
1623
|
if (typeof polygons[data.name] != "undefined") { layers[lay].removeLayer(polygons[data.name]); }
|
|
1573
1624
|
|
|
1625
|
+
if (data.hasOwnProperty("drawCount")) { drawCount = data.drawCount; }
|
|
1626
|
+
// Draw lines
|
|
1574
1627
|
if (data.hasOwnProperty("line") && Array.isArray(data.line)) {
|
|
1575
1628
|
delete opt.fill;
|
|
1576
1629
|
if (!data.hasOwnProperty("weight")) { opt.weight = 3; } //Standard settings different for lines
|
|
1577
1630
|
if (!data.hasOwnProperty("opacity")) { opt.opacity = 0.8; }
|
|
1578
1631
|
var polyln = L.polyline(data.line, opt);
|
|
1579
1632
|
polygons[data.name] = rightmenu(polyln);
|
|
1580
|
-
if (data.hasOwnProperty("fly") && data.fly === true) {
|
|
1581
|
-
map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1582
|
-
} else if (data.hasOwnProperty("fit") && data.fit === true) {
|
|
1583
|
-
map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1584
|
-
}
|
|
1585
1633
|
}
|
|
1634
|
+
// Draw Areas
|
|
1586
1635
|
else if (data.hasOwnProperty("area") && Array.isArray(data.area)) {
|
|
1587
1636
|
var polyarea;
|
|
1588
1637
|
if (data.area.length === 2) { polyarea = L.rectangle(data.area, opt); }
|
|
1589
1638
|
else { polyarea = L.polygon(data.area, opt); }
|
|
1590
1639
|
polygons[data.name] = rightmenu(polyarea);
|
|
1591
|
-
if (data.hasOwnProperty("fly") && data.fly === true) {
|
|
1592
|
-
map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1593
|
-
} else if (data.hasOwnProperty("fit") && data.fit === true) {
|
|
1594
|
-
map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1595
|
-
}
|
|
1596
1640
|
}
|
|
1641
|
+
// Draw Great circles
|
|
1597
1642
|
if (data.hasOwnProperty("greatcircle") && Array.isArray(data.greatcircle) && data.greatcircle.length === 2) {
|
|
1598
1643
|
delete opt.fill;
|
|
1599
1644
|
opt.vertices = opt.vertices || 20;
|
|
@@ -1601,25 +1646,20 @@ function setMarker(data) {
|
|
|
1601
1646
|
if (!data.hasOwnProperty("opacity")) { opt.opacity = 0.8; }
|
|
1602
1647
|
var greatc = L.Polyline.Arc(data.greatcircle[0], data.greatcircle[1], opt);
|
|
1603
1648
|
var aml = new L.Wrapped.Polyline(greatc._latlngs, opt);
|
|
1604
|
-
|
|
1605
1649
|
polygons[data.name] = rightmenu(aml);
|
|
1606
|
-
if (data.hasOwnProperty("fly") && data.fly === true) {
|
|
1607
|
-
map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1608
|
-
} else if (data.hasOwnProperty("fit") && data.fit === true) {
|
|
1609
|
-
map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1610
|
-
}
|
|
1611
1650
|
}
|
|
1651
|
+
// Draw error ellipses
|
|
1612
1652
|
else if (data.hasOwnProperty("sdlat") && data.hasOwnProperty("sdlon")) {
|
|
1613
1653
|
if (!data.hasOwnProperty("iconColor")) { opt.color = "blue"; } //different standard Color Settings
|
|
1614
1654
|
if (!data.hasOwnProperty("fillColor")) { opt.fillColor = "blue"; }
|
|
1615
1655
|
var ellipse = L.ellipse(new L.LatLng((data.lat*1), (data.lon*1)), [200000*data.sdlon*Math.cos(data.lat*Math.PI/180), 200000*data.sdlat], 0, opt);
|
|
1616
1656
|
polygons[data.name] = rightmenu(ellipse);
|
|
1617
1657
|
}
|
|
1658
|
+
// Draw circles and ellipses
|
|
1618
1659
|
else if (data.hasOwnProperty("radius")) {
|
|
1619
1660
|
if (data.hasOwnProperty("lat") && data.hasOwnProperty("lon")) {
|
|
1620
1661
|
var polycirc;
|
|
1621
1662
|
if (Array.isArray(data.radius)) {
|
|
1622
|
-
//polycirc = L.ellipse(new L.LatLng((data.lat*1), (data.lon*1)), [data.radius[0]*Math.cos(data.lat*Math.PI/180), data.radius[1]], data.tilt || 0, opt);
|
|
1623
1663
|
polycirc = L.ellipse(new L.LatLng((data.lat*1), (data.lon*1)), [data.radius[0], data.radius[1]], data.tilt || 0, opt);
|
|
1624
1664
|
}
|
|
1625
1665
|
else {
|
|
@@ -1632,26 +1672,41 @@ function setMarker(data) {
|
|
|
1632
1672
|
}
|
|
1633
1673
|
}
|
|
1634
1674
|
}
|
|
1675
|
+
// Draw arcs (and range rings)
|
|
1635
1676
|
else if (data.hasOwnProperty("arc")) {
|
|
1636
1677
|
if (data.hasOwnProperty("lat") && data.hasOwnProperty("lon")) {
|
|
1637
1678
|
polygons[data.name] = rangerings(new L.LatLng((data.lat*1), (data.lon*1)), data.arc);
|
|
1638
1679
|
}
|
|
1639
1680
|
}
|
|
1681
|
+
// Draw a geojson "shape"
|
|
1640
1682
|
else if (data.hasOwnProperty("geojson")) {
|
|
1641
1683
|
doGeojson(data.name,data.geojson,(data.layer || "unknown"),opt);
|
|
1642
1684
|
}
|
|
1643
1685
|
|
|
1686
|
+
// If we created a shape then apply some generic things to it
|
|
1644
1687
|
if (polygons[data.name] !== undefined) {
|
|
1688
|
+
// Set the layer
|
|
1645
1689
|
polygons[data.name].lay = lay;
|
|
1690
|
+
// if clickable then add popup
|
|
1646
1691
|
if (opt.clickable === true) {
|
|
1647
1692
|
var words = "<b>"+data.name+"</b>";
|
|
1648
1693
|
if (data.popup) { words = words + "<br/>" + data.popup; }
|
|
1649
|
-
polygons[data.name].bindPopup(words, {autoClose:false, closeButton:true, closeOnClick:
|
|
1694
|
+
polygons[data.name].bindPopup(words, {autoClose:false, closeButton:true, closeOnClick:true, minWidth:200});
|
|
1650
1695
|
}
|
|
1651
|
-
//
|
|
1696
|
+
// add a tooltip (if supplied)
|
|
1697
|
+
if (data.hasOwnProperty("tooltip")) { polygons[data.name].bindTooltip(data.tooltip); }
|
|
1698
|
+
// add to the layers
|
|
1652
1699
|
layers[lay].addLayer(polygons[data.name]);
|
|
1700
|
+
// fly or fit to the bounds if required
|
|
1701
|
+
if (data.hasOwnProperty("fly") && data.fly === true) {
|
|
1702
|
+
map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1703
|
+
}
|
|
1704
|
+
else if (data.hasOwnProperty("fit") && data.fit === true) {
|
|
1705
|
+
map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
|
|
1706
|
+
}
|
|
1653
1707
|
}
|
|
1654
1708
|
|
|
1709
|
+
// Now handle the markers
|
|
1655
1710
|
if (typeof data.coordinates == "object") { ll = new L.LatLng(data.coordinates[1],data.coordinates[0]); }
|
|
1656
1711
|
else if (data.hasOwnProperty("position") && data.position.hasOwnProperty("lat") && data.position.hasOwnProperty("lon")) {
|
|
1657
1712
|
data.lat = data.position.lat*1;
|
|
@@ -1691,7 +1746,7 @@ function setMarker(data) {
|
|
|
1691
1746
|
if (data.draggable === true) { drag = true; }
|
|
1692
1747
|
|
|
1693
1748
|
if (data.hasOwnProperty("icon")) {
|
|
1694
|
-
var dir = parseFloat(data.hdg ?? data.heading ?? data.bearing ?? "0");
|
|
1749
|
+
var dir = parseFloat(data.track ?? data.hdg ?? data.heading ?? data.bearing ?? "0") + map.getBearing();
|
|
1695
1750
|
if (data.icon === "ship") {
|
|
1696
1751
|
marker = L.boatMarker(ll, {
|
|
1697
1752
|
title: data.name,
|
|
@@ -1792,6 +1847,17 @@ function setMarker(data) {
|
|
|
1792
1847
|
});
|
|
1793
1848
|
marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
|
|
1794
1849
|
}
|
|
1850
|
+
else if (data.icon === "sensor") {
|
|
1851
|
+
data.iconColor = data.iconColor || "#F39C12";
|
|
1852
|
+
icon = '<svg viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg"><path fill="'+data.iconColor+'" d="M 478.281 5.437 L 367.741 118.227 L 367.741 84.075 C 367.741 38.352 344.315 1.298 315.417 1.298 L 53.768 1.298 C 24.87 1.298 1.434 38.352 1.434 84.075 L 1.434 415.183 C 1.434 460.893 24.87 497.959 53.768 497.959 L 315.417 497.959 C 344.315 497.959 367.741 460.893 367.741 415.183 L 367.741 381.031 L 478.281 493.808 C 490.714 504.155 498.566 486.571 498.566 476.224 L 498.566 21.993 C 498.566 11.646 491.37 -6.979 478.281 5.437 Z M 341.573 415.183 C 341.573 438.044 329.86 456.571 315.417 456.571 L 53.768 456.571 C 39.314 456.571 27.612 438.044 27.612 415.183 L 27.612 84.075 C 27.612 61.226 39.314 42.687 53.768 42.687 L 315.417 42.687 C 329.86 42.687 341.573 61.226 341.573 84.075 L 341.573 415.183 Z M 472.398 438.975 L 367.741 332.406 L 367.741 166.853 L 472.398 60.27 L 472.398 438.975 Z" style="transform-origin: 250.000025px 249.628505px;" transform="matrix(0, -1, 1, 0, -0.000013709068, 0.000009864569)"/></svg>';
|
|
1853
|
+
var svgcam = "data:image/svg+xml;base64," + btoa(icon);
|
|
1854
|
+
myMarker = L.divIcon({
|
|
1855
|
+
className:"camicon",
|
|
1856
|
+
iconAnchor: [12, 12],
|
|
1857
|
+
html:'<img src="'+svgcam+'" style="width:24px; height:24px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
|
|
1858
|
+
});
|
|
1859
|
+
marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
|
|
1860
|
+
}
|
|
1795
1861
|
else if (data.icon === "arrow") {
|
|
1796
1862
|
data.iconColor = data.iconColor || "black";
|
|
1797
1863
|
icon = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="32px" viewBox="0 0 32 32">';
|
|
@@ -1897,7 +1963,7 @@ function setMarker(data) {
|
|
|
1897
1963
|
else if (data.icon === "earthquake") {
|
|
1898
1964
|
marker = L.marker(ll, { icon: L.divIcon({ className: 'circle e', iconSize: [data.mag*5, data.mag*5] }), title: data.name, draggable:drag });
|
|
1899
1965
|
}
|
|
1900
|
-
else if (data.icon.match(/^:.*:$/g)) {
|
|
1966
|
+
else if (data.icon.match(/^:.*:$/g)) { // emoji icon :smile:
|
|
1901
1967
|
var em = emojify(data.icon);
|
|
1902
1968
|
var col = data.iconColor ?? "#910000";
|
|
1903
1969
|
myMarker = L.divIcon({
|
|
@@ -1908,7 +1974,7 @@ function setMarker(data) {
|
|
|
1908
1974
|
marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
|
|
1909
1975
|
labelOffset = [12,-4];
|
|
1910
1976
|
}
|
|
1911
|
-
else if (data.icon.match(/^https?:.*$|^\//)) {
|
|
1977
|
+
else if (data.icon.match(/^https?:.*$|^\//)) { // web url icon https://...
|
|
1912
1978
|
var sz = data.iconSize ?? 32;
|
|
1913
1979
|
myMarker = L.icon({
|
|
1914
1980
|
iconUrl: data.icon,
|
|
@@ -1920,7 +1986,7 @@ function setMarker(data) {
|
|
|
1920
1986
|
labelOffset = [sz/2-4,-4];
|
|
1921
1987
|
delete data.iconSize;
|
|
1922
1988
|
}
|
|
1923
|
-
else if (data.icon.substr(0,3) === "fa-") {
|
|
1989
|
+
else if (data.icon.substr(0,3) === "fa-") { // fa icon
|
|
1924
1990
|
var col = data.iconColor ?? "#910000";
|
|
1925
1991
|
var imod = "";
|
|
1926
1992
|
if (data.icon.indexOf(" ") === -1) { imod = "fa-2x "; }
|
|
@@ -1934,7 +2000,7 @@ function setMarker(data) {
|
|
|
1934
2000
|
marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
|
|
1935
2001
|
labelOffset = [8,-8];
|
|
1936
2002
|
}
|
|
1937
|
-
else if (data.icon.substr(0,3) === "wi-") {
|
|
2003
|
+
else if (data.icon.substr(0,3) === "wi-") { // weather icon
|
|
1938
2004
|
var col = data.iconColor ?? "#910000";
|
|
1939
2005
|
var imod = "";
|
|
1940
2006
|
if (data.icon.indexOf(" ") === -1) { imod = "wi-2x "; }
|
|
@@ -1949,7 +2015,7 @@ function setMarker(data) {
|
|
|
1949
2015
|
labelOffset = [16,-16];
|
|
1950
2016
|
}
|
|
1951
2017
|
else {
|
|
1952
|
-
myMarker = L.VectorMarkers.icon({
|
|
2018
|
+
myMarker = L.VectorMarkers.icon({ // default - fa-icon in a marker shape
|
|
1953
2019
|
icon: data.icon ?? "circle",
|
|
1954
2020
|
markerColor: (data.iconColor ?? "#910000"),
|
|
1955
2021
|
prefix: 'fa',
|
|
@@ -1959,7 +2025,7 @@ function setMarker(data) {
|
|
|
1959
2025
|
labelOffset = [6,-6];
|
|
1960
2026
|
}
|
|
1961
2027
|
}
|
|
1962
|
-
else if (data.hasOwnProperty("SIDC")) {
|
|
2028
|
+
else if (data.hasOwnProperty("SIDC")) { // NATO mil2525 icons
|
|
1963
2029
|
// "SIDC":"SFGPU------E***","name":"1.C2 komp","fullname":"1.C2 komp/FTS/INSS"
|
|
1964
2030
|
myMarker = new ms.Symbol( data.SIDC.toUpperCase(), { uniqueDesignation:unescape(encodeURIComponent(data.name)) });
|
|
1965
2031
|
// Now that we have a symbol we can ask for the echelon and set the symbol size
|
|
@@ -1988,7 +2054,7 @@ function setMarker(data) {
|
|
|
1988
2054
|
marker = L.marker(ll, { title:data.name, icon:myicon, draggable:drag });
|
|
1989
2055
|
edgeAware();
|
|
1990
2056
|
}
|
|
1991
|
-
else {
|
|
2057
|
+
else { // Otherwise just a generic map marker pin
|
|
1992
2058
|
myMarker = L.VectorMarkers.icon({
|
|
1993
2059
|
icon: "circle",
|
|
1994
2060
|
markerColor: (data.iconColor ?? "#910000"),
|
|
@@ -2033,7 +2099,8 @@ function setMarker(data) {
|
|
|
2033
2099
|
}
|
|
2034
2100
|
|
|
2035
2101
|
// tidy up altitude
|
|
2036
|
-
if (data.hasOwnProperty("alt")) {
|
|
2102
|
+
if (data.hasOwnProperty("alt")||data.hasOwnProperty("altitude")) {
|
|
2103
|
+
data.alt = data.alt ?? data.altitude;
|
|
2037
2104
|
var reft = new RegExp('feet|ft','i');
|
|
2038
2105
|
var refm = new RegExp('metres|m','i');
|
|
2039
2106
|
if ( reft.test(""+data.alt) ) {
|
|
@@ -2047,8 +2114,8 @@ function setMarker(data) {
|
|
|
2047
2114
|
}
|
|
2048
2115
|
}
|
|
2049
2116
|
|
|
2050
|
-
// remove
|
|
2051
|
-
if (data.hasOwnProperty("
|
|
2117
|
+
// remove items from list of properties, then add all others to popup
|
|
2118
|
+
if (data.hasOwnProperty("options")) { delete data.options; }
|
|
2052
2119
|
if (data.hasOwnProperty("icon")) { delete data.icon; }
|
|
2053
2120
|
if (data.hasOwnProperty("iconColor")) { delete data.iconColor; }
|
|
2054
2121
|
if (data.hasOwnProperty("photourl")) {
|
|
@@ -2076,13 +2143,14 @@ function setMarker(data) {
|
|
|
2076
2143
|
if (!Array.isArray(data.weblink) || !data.weblink.length) {
|
|
2077
2144
|
if (typeof data.weblink === "string") {
|
|
2078
2145
|
words += "<b><a href='"+ data.weblink + "' target='_new'>more information...</a></b><br/>";
|
|
2079
|
-
}
|
|
2146
|
+
}
|
|
2147
|
+
else {
|
|
2080
2148
|
var tgt = data.weblink.target || "_new";
|
|
2081
2149
|
words += "<b><a href='"+ data.weblink.url + "' target='"+ tgt + "'>" + data.weblink.name + "</a></b><br/>";
|
|
2082
2150
|
}
|
|
2083
2151
|
}
|
|
2084
2152
|
else {
|
|
2085
|
-
data.weblink.forEach(function(weblink){
|
|
2153
|
+
data.weblink.forEach(function(weblink) {
|
|
2086
2154
|
if (typeof weblink === "string") {
|
|
2087
2155
|
words += "<b><a href='"+ weblink + "' target='_new'>more information...</a></b><br/>";
|
|
2088
2156
|
}
|
|
@@ -2124,10 +2192,11 @@ function setMarker(data) {
|
|
|
2124
2192
|
}
|
|
2125
2193
|
}
|
|
2126
2194
|
|
|
2195
|
+
// Add right click contextmenu
|
|
2127
2196
|
marker = rightmenu(marker);
|
|
2128
2197
|
|
|
2129
|
-
//
|
|
2130
|
-
var llc = data.lineColor
|
|
2198
|
+
// Delete more already handled properties
|
|
2199
|
+
var llc = data.lineColor ?? data.color;
|
|
2131
2200
|
delete data.lat;
|
|
2132
2201
|
delete data.lon;
|
|
2133
2202
|
if (data.arc) { delete data.arc; }
|
|
@@ -2143,15 +2212,17 @@ function setMarker(data) {
|
|
|
2143
2212
|
if (data.hasOwnProperty("fillColor")) { delete data.fillColor; }
|
|
2144
2213
|
if (data.hasOwnProperty("radius")) { delete data.radius; }
|
|
2145
2214
|
if (data.hasOwnProperty("greatcircle")) { delete data.greatcircle; }
|
|
2215
|
+
|
|
2216
|
+
// then any remaining properties to the info box
|
|
2146
2217
|
if (data.popup) { words = data.popup; }
|
|
2147
2218
|
else {
|
|
2148
2219
|
words += '<table>';
|
|
2149
2220
|
for (var i in data) {
|
|
2150
2221
|
if ((i != "name") && (i != "length") && (i != "clickable")) {
|
|
2151
2222
|
if (typeof data[i] === "object") {
|
|
2152
|
-
//
|
|
2153
2223
|
words += '<tr><td>'+ i +'</td><td>' + JSON.stringify(data[i]) + '</td></tr>';
|
|
2154
|
-
}
|
|
2224
|
+
}
|
|
2225
|
+
else {
|
|
2155
2226
|
// words += i +" : "+data[i]+"<br/>";
|
|
2156
2227
|
words += '<tr><td>'+ i +'</td><td>' + data[i] + '</td></tr>';
|
|
2157
2228
|
}
|
|
@@ -2160,9 +2231,9 @@ function setMarker(data) {
|
|
|
2160
2231
|
words += '<tr><td>lat, lon</td><td>'+ marker.getLatLng().toString().replace('LatLng(','').replace(')','') + '</td></tr>';
|
|
2161
2232
|
words += '</table>';
|
|
2162
2233
|
}
|
|
2163
|
-
words = "<b>"+data.name+"</b><br/>" + words; //"<button style=\"border-radius:4px; float:right; background-color:lightgrey;\" onclick='popped=false;popmark.closePopup();'>X</button><br/>" + words;
|
|
2234
|
+
words = "<b>"+data.name+"</b><br/>" + words.replace(/\${name}/g,data.name); //"<button style=\"border-radius:4px; float:right; background-color:lightgrey;\" onclick='popped=false;popmark.closePopup();'>X</button><br/>" + words;
|
|
2164
2235
|
var wopt = {autoClose:false, closeButton:true, closeOnClick:false, minWidth:200};
|
|
2165
|
-
if (words.indexOf('<video ') >=0 || words.indexOf('<img ') >=0 ) { wopt.maxWidth="640"; }
|
|
2236
|
+
if (words.indexOf('<video ') >=0 || words.indexOf('<img ') >=0 ) { wopt.maxWidth="640"; } // make popup wider if it has an image or video
|
|
2166
2237
|
if (!data.hasOwnProperty("clickable") && data.clickable != false) {
|
|
2167
2238
|
marker.bindPopup(words, wopt);
|
|
2168
2239
|
marker._popup.dname = data.name;
|
|
@@ -2180,11 +2251,15 @@ function setMarker(data) {
|
|
|
2180
2251
|
}
|
|
2181
2252
|
markers[data.name] = marker;
|
|
2182
2253
|
layers[lay].addLayer(marker);
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
else if (data.
|
|
2187
|
-
else if (data.
|
|
2254
|
+
|
|
2255
|
+
// var track;
|
|
2256
|
+
// if (data.track !== undefined) { track = data.track; }
|
|
2257
|
+
// else if (data.hdg !== undefined) { track = data.hdg; }
|
|
2258
|
+
// else if (data.heading !== undefined) { track = data.heading; }
|
|
2259
|
+
// else if (data.bearing !== undefined) { track = data.bearing; }
|
|
2260
|
+
|
|
2261
|
+
// Now add any leader lines
|
|
2262
|
+
var track = data.track ?? data.hdg ?? data.heading ?? data.bearing;
|
|
2188
2263
|
if (track != undefined) { // if there is a heading
|
|
2189
2264
|
if (data.speed != null && data.length === undefined) { // and a speed - lets convert to a leader length
|
|
2190
2265
|
data.length = parseFloat(data.speed || "0") * 60;
|
|
@@ -2217,7 +2292,8 @@ function setMarker(data) {
|
|
|
2217
2292
|
var x3 = x + Math.cos((90-angle-data.accuracy)/180*Math.PI)*lengthAsDegrees/Math.cos(y/180*Math.PI);
|
|
2218
2293
|
var ll3 = new L.LatLng(y3,x3);
|
|
2219
2294
|
polygon = L.polygon([ ll1, ll2, ll3 ], {weight:2, color:llc||'#900', fillOpacity:0.06, clickable:false});
|
|
2220
|
-
}
|
|
2295
|
+
}
|
|
2296
|
+
else {
|
|
2221
2297
|
var ya = y + Math.sin((90-angle)/180*Math.PI)*lengthAsDegrees;
|
|
2222
2298
|
var xa = x + Math.cos((90-angle)/180*Math.PI)*lengthAsDegrees/Math.cos(y/180*Math.PI);
|
|
2223
2299
|
var lla = new L.LatLng(ya,xa);
|
|
@@ -2246,7 +2322,7 @@ function setMarker(data) {
|
|
|
2246
2322
|
|
|
2247
2323
|
// handle any incoming COMMANDS to control the map remotely
|
|
2248
2324
|
function doCommand(cmd) {
|
|
2249
|
-
//
|
|
2325
|
+
//console.log("COMMAND",cmd);
|
|
2250
2326
|
if (cmd.init && cmd.hasOwnProperty("maplist")) {
|
|
2251
2327
|
//basemaps = {};
|
|
2252
2328
|
addBaseMaps(cmd.maplist,cmd.layer);
|
|
@@ -2275,10 +2351,6 @@ function doCommand(cmd) {
|
|
|
2275
2351
|
else { panit = false; }
|
|
2276
2352
|
document.getElementById("panit").checked = panit;
|
|
2277
2353
|
}
|
|
2278
|
-
if (cmd.hasOwnProperty("hiderightclick")) {
|
|
2279
|
-
if (cmd.hiderightclick == "true" || cmd.hiderightclick == true) { hiderightclick = true; }
|
|
2280
|
-
else { hiderightclick = false; }
|
|
2281
|
-
}
|
|
2282
2354
|
if (cmd.hasOwnProperty("showmenu")) {
|
|
2283
2355
|
if ((cmd.showmenu === "hide") && (showUserMenu === true)) {
|
|
2284
2356
|
showUserMenu = false;
|
|
@@ -2371,10 +2443,18 @@ function doCommand(cmd) {
|
|
|
2371
2443
|
if (trackMeButton !== undefined) { trackMeButton.state('track-on'); }
|
|
2372
2444
|
}
|
|
2373
2445
|
}
|
|
2446
|
+
if (cmd.hasOwnProperty("hiderightclick")) {
|
|
2447
|
+
if (cmd.hiderightclick == "true" || cmd.hiderightclick == true) { hiderightclick = true; }
|
|
2448
|
+
else { hiderightclick = false; }
|
|
2449
|
+
}
|
|
2374
2450
|
if (cmd.hasOwnProperty("contextmenu")) {
|
|
2375
2451
|
if (typeof cmd.contextmenu === "string") {
|
|
2376
2452
|
addmenu = cmd.contextmenu;
|
|
2377
|
-
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
if (cmd.hasOwnProperty("drawcontextmenu")) {
|
|
2456
|
+
if (typeof cmd.drawcontextmenu === "string") {
|
|
2457
|
+
drawcontextmenu = cmd.drawcontextmenu;
|
|
2378
2458
|
}
|
|
2379
2459
|
}
|
|
2380
2460
|
if (cmd.hasOwnProperty("allowFileDrop")) {
|
|
@@ -2467,57 +2547,69 @@ function doCommand(cmd) {
|
|
|
2467
2547
|
}
|
|
2468
2548
|
}
|
|
2469
2549
|
// Add a new geojson overlay layer
|
|
2470
|
-
if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("geojson")
|
|
2550
|
+
if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("geojson")) {
|
|
2471
2551
|
if (overlays.hasOwnProperty(cmd.map.overlay)) {
|
|
2472
2552
|
map.removeLayer(overlays[cmd.map.overlay]);
|
|
2473
2553
|
existsalready = true;
|
|
2474
2554
|
}
|
|
2475
|
-
|
|
2476
|
-
var
|
|
2477
|
-
if (
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2555
|
+
try {
|
|
2556
|
+
var opt = cmd.map.opt || {};
|
|
2557
|
+
if (opt.hasOwnProperty("style")) { opt.style = new Function('return ' + opt.style)(); }
|
|
2558
|
+
else {
|
|
2559
|
+
opt.style = function(feature) {
|
|
2560
|
+
var st = { stroke:true, weight:2, fill:true };
|
|
2561
|
+
if (feature.hasOwnProperty("properties")) {
|
|
2562
|
+
st.color = feature.properties.color||feature.properties.roofColor||"black";
|
|
2563
|
+
if (feature.properties.hasOwnProperty("color")) { delete feature.properties.color; }
|
|
2564
|
+
if (feature.properties.hasOwnProperty("roofColor")) { delete feature.properties.roofColor; }
|
|
2565
|
+
}
|
|
2566
|
+
if (feature.hasOwnProperty("properties") && feature.properties.hasOwnProperty('style')) {
|
|
2567
|
+
if (feature.properties.style.hasOwnProperty('stroke')) {
|
|
2568
|
+
st.color = feature.properties.style.stroke;
|
|
2569
|
+
}
|
|
2570
|
+
if (feature.properties.style.hasOwnProperty('stroke-width')) {
|
|
2571
|
+
st.weight = feature.properties.style["stroke-width"];
|
|
2572
|
+
}
|
|
2573
|
+
if (feature.properties.style.hasOwnProperty('stroke-opacity')) {
|
|
2574
|
+
st.opacity = feature.properties.style["stroke-opacity"];
|
|
2575
|
+
}
|
|
2576
|
+
if (feature.properties.style.hasOwnProperty('fill')) {
|
|
2577
|
+
if (feature.properties.style.fill == "none") { st.fill = false; }
|
|
2578
|
+
else { st.fillColor = feature.properties.style.fill; }
|
|
2579
|
+
}
|
|
2580
|
+
if (feature.properties.style.hasOwnProperty('fill-opacity')) {
|
|
2581
|
+
st.fillOpacity = feature.properties.style["fill-opacity"];
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
delete feature.properties.style;
|
|
2585
|
+
return st;
|
|
2586
|
+
};
|
|
2481
2587
|
}
|
|
2482
|
-
if (
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
else { st.fillColor = feature.properties.style.fill; }
|
|
2495
|
-
}
|
|
2496
|
-
if (feature.properties.style.hasOwnProperty('fill-opacity')) {
|
|
2497
|
-
st.fillOpacity = feature.properties.style["fill-opacity"];
|
|
2588
|
+
if (opt.hasOwnProperty("pointToLayer")) { opt.pointToLayer = new Function('return ' + opt.pointToLayer)(); }
|
|
2589
|
+
if (opt.hasOwnProperty("filter")) { opt.filter = new Function('return ' + opt.filter)(); }
|
|
2590
|
+
if (opt.hasOwnProperty("onEachFeature")) { opt.onEachFeature = new Function('return ' + opt.onEachFeature)(); }
|
|
2591
|
+
else {
|
|
2592
|
+
opt.onEachFeature = function (f,l) {
|
|
2593
|
+
var pw = '<pre>'+JSON.stringify(f.properties,null,' ').replace(/[\{\}"]/g,'')+'</pre>';
|
|
2594
|
+
if (pw.length > 11) { l.bindPopup(pw); }
|
|
2595
|
+
if (cmd.map.hasOwnProperty("clickable") && cmd.map.clickable === true) {
|
|
2596
|
+
l.on('click', function (e) {
|
|
2597
|
+
ws.send(JSON.stringify({action:"clickgeo",name:cmd.map.overlay,type:f.type,properties:f.properties,geometry:f.geometry}));
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2498
2600
|
}
|
|
2499
2601
|
}
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
opt.onEachFeature = function (f,l) {
|
|
2504
|
-
var pw = '<pre>'+JSON.stringify(f.properties,null,' ').replace(/[\{\}"]/g,'')+'</pre>';
|
|
2505
|
-
if (pw.length > 11) { l.bindPopup(pw); }
|
|
2506
|
-
if (cmd.map.hasOwnProperty("clickable") && cmd.map.clickable === true) {
|
|
2507
|
-
l.on('click', function (e) {
|
|
2508
|
-
ws.send(JSON.stringify({action:"clickgeo",name:cmd.map.overlay,type:f.type,properties:f.properties,geometry:f.geometry}));
|
|
2509
|
-
});
|
|
2602
|
+
overlays[cmd.map.overlay] = L.geoJson(cmd.map.geojson,opt);
|
|
2603
|
+
if (!existsalready) {
|
|
2604
|
+
layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
|
|
2510
2605
|
}
|
|
2606
|
+
if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
|
|
2607
|
+
map.addLayer(overlays[cmd.map.overlay]);
|
|
2608
|
+
}
|
|
2609
|
+
if (cmd.map.hasOwnProperty("fly") && (cmd.map.fly === true)) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
|
|
2610
|
+
else if (cmd.map.hasOwnProperty("fit") && (cmd.map.fit === true)) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
|
|
2511
2611
|
}
|
|
2512
|
-
|
|
2513
|
-
if (!existsalready) {
|
|
2514
|
-
layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
|
|
2515
|
-
}
|
|
2516
|
-
if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
|
|
2517
|
-
map.addLayer(overlays[cmd.map.overlay]);
|
|
2518
|
-
}
|
|
2519
|
-
if (cmd.map.hasOwnProperty("fly") && (cmd.map.fly === true)) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
|
|
2520
|
-
else if (cmd.map.hasOwnProperty("fit") && (cmd.map.fit === true)) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
|
|
2612
|
+
catch(e) { console.log(e); }
|
|
2521
2613
|
}
|
|
2522
2614
|
// Add a new NVG XML overlay layer
|
|
2523
2615
|
if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("nvg") ) {
|
|
@@ -2660,6 +2752,29 @@ function doCommand(cmd) {
|
|
|
2660
2752
|
if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); }
|
|
2661
2753
|
else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); }
|
|
2662
2754
|
}
|
|
2755
|
+
// Add a new ESRI feature layer
|
|
2756
|
+
if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("esri") ) {
|
|
2757
|
+
try {
|
|
2758
|
+
if (overlays.hasOwnProperty(cmd.map.overlay)) {
|
|
2759
|
+
overlays[cmd.map.overlay].removeFrom(map);
|
|
2760
|
+
existsalready = true;
|
|
2761
|
+
}
|
|
2762
|
+
var opt = {};
|
|
2763
|
+
if (cmd.map.hasOwnProperty("opt")) { opt = cmd.map.opt; }
|
|
2764
|
+
if (opt.hasOwnProperty("style")) { opt.style = new Function('return ' + opt.style)(); }
|
|
2765
|
+
if (opt.hasOwnProperty("pointToLayer")) { opt.pointToLayer = new Function('return ' + opt.pointToLayer)(); }
|
|
2766
|
+
if (opt.hasOwnProperty("onEachFeature")) { opt.onEachFeature = new Function('return ' + opt.onEachFeature)(); }
|
|
2767
|
+
opt.url = cmd.map.esri;
|
|
2768
|
+
overlays[cmd.map.overlay] = L.esri.featureLayer(opt);
|
|
2769
|
+
if (!existsalready) {
|
|
2770
|
+
layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay);
|
|
2771
|
+
}
|
|
2772
|
+
if (!cmd.map.hasOwnProperty("visible") || (cmd.map.visible != false)) {
|
|
2773
|
+
overlays[cmd.map.overlay].addTo(map);
|
|
2774
|
+
}
|
|
2775
|
+
// NOTE can't fit or fly to bounds as they keep reloading
|
|
2776
|
+
} catch(e) { console.log(e); }
|
|
2777
|
+
}
|
|
2663
2778
|
// Add a new TOPOJSON overlay layer
|
|
2664
2779
|
if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("topojson") ) {
|
|
2665
2780
|
if (overlays.hasOwnProperty(cmd.map.overlay)) {
|
|
@@ -2805,7 +2920,7 @@ function doCommand(cmd) {
|
|
|
2805
2920
|
}
|
|
2806
2921
|
}
|
|
2807
2922
|
}
|
|
2808
|
-
// Lock the pan so map can be moved
|
|
2923
|
+
// Lock the pan so map can't be moved
|
|
2809
2924
|
if (cmd.hasOwnProperty("panlock")) {
|
|
2810
2925
|
if (cmd.panlock == "true" || cmd.panlock == true) { lockit = true; }
|
|
2811
2926
|
else { lockit = false; doLock(false); }
|
|
@@ -2821,8 +2936,14 @@ function doCommand(cmd) {
|
|
|
2821
2936
|
map.setView([clat,clon],czoom);
|
|
2822
2937
|
|
|
2823
2938
|
// Set rotation of map
|
|
2824
|
-
if (cmd.hasOwnProperty("rotation") && !isNaN(cmd.rotation)) {
|
|
2825
|
-
|
|
2939
|
+
if (cmd.hasOwnProperty("rotation") && !isNaN(cmd.rotation)) {
|
|
2940
|
+
map.setBearing(-cmd.rotation);
|
|
2941
|
+
for (const item in allData) {
|
|
2942
|
+
if (allData[item].hasOwnProperty("hdg") || allData[item].hasOwnProperty("heading") || allData[item].hasOwnProperty("bearing") || allData[item].hasOwnProperty("track")) {
|
|
2943
|
+
setMarker(allData[item]);
|
|
2944
|
+
}
|
|
2945
|
+
}
|
|
2946
|
+
}
|
|
2826
2947
|
if (cmd.hasOwnProperty("cluster")) {
|
|
2827
2948
|
clusterAt = cmd.cluster;
|
|
2828
2949
|
document.getElementById("setclus").value = cmd.cluster;
|
|
@@ -2859,15 +2980,29 @@ function doCommand(cmd) {
|
|
|
2859
2980
|
if (cmd.bounds.length === 2 && cmd.bounds[0].length === 2 && cmd.bounds[1].length === 2) {
|
|
2860
2981
|
if (cmd.hasOwnProperty("fly") && cmd.fly === true) {
|
|
2861
2982
|
map.flyToBounds(cmd.bounds);
|
|
2862
|
-
}
|
|
2983
|
+
}
|
|
2984
|
+
else {
|
|
2863
2985
|
map.fitBounds(cmd.bounds);
|
|
2864
2986
|
}
|
|
2865
2987
|
}
|
|
2866
2988
|
}
|
|
2989
|
+
if (cmd.hasOwnProperty("loadStatic")) {
|
|
2990
|
+
console.log("load Static files",JSON.stringify(cmd.loadStatic.fileNames));
|
|
2991
|
+
cmd.loadStatic.fileNames.forEach(fileName => loadStatic(fileName));
|
|
2992
|
+
}
|
|
2993
|
+
if (cmd.hasOwnProperty("customCmd")) {
|
|
2994
|
+
console.log("custom Command",JSON.stringify(cmd.customCmd));
|
|
2995
|
+
try {
|
|
2996
|
+
eval(cmd.customCmd);
|
|
2997
|
+
}
|
|
2998
|
+
catch (e) {
|
|
2999
|
+
console.log("ERR - custom command: ", JSON.stringify(cmd.customCmd));
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
2867
3002
|
}
|
|
2868
3003
|
|
|
2869
3004
|
// handle any incoming GEOJSON directly - may style badly
|
|
2870
|
-
function doGeojson(n,g,l,o) {
|
|
3005
|
+
function doGeojson(n,g,l,o) { // name, geojson, layer, options
|
|
2871
3006
|
var lay = l ?? g.name ?? "unknown";
|
|
2872
3007
|
// if (!basemaps[lay]) {
|
|
2873
3008
|
var opt = { style: function(feature) {
|