node-red-contrib-web-worldmap 2.25.0 → 2.27.1
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 +3 -0
- package/README.md +6 -0
- package/package.json +1 -1
- package/worldmap/index.html +2 -2
- package/worldmap/index3d.html +216 -214
- package/worldmap/leaflet/leaflet.mousecoordinate.css +7 -0
- package/worldmap/leaflet/leaflet.mousecoordinate.js +639 -0
- package/worldmap/worldmap.js +15 -25
- package/worldmap.html +6 -0
- package/worldmap.js +13 -0
- package/worldmap/leaflet/3dstyle.json +0 -11296
- package/worldmap/leaflet/Leaflet.Coordinates.css +0 -1
- package/worldmap/leaflet/Leaflet.Coordinates.js +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
### Change Log for Node-RED Worldmap
|
|
2
2
|
|
|
3
|
+
- v2.27.1 - Reload existing markers for late joiners
|
|
4
|
+
- v2.26.1 - Add QTH/Maidenhead option also
|
|
5
|
+
- v2.26.0 - Add UTM and MGRS to coordinate display options.
|
|
3
6
|
- v2.25.0 - Add bounds command to set overall map bounds.
|
|
4
7
|
- v2.24.3 - Fix geojson incorrect fill.
|
|
5
8
|
- v2.24.2 - Changes to drawing colours to be more visible.
|
package/README.md
CHANGED
|
@@ -11,6 +11,9 @@ map web page for plotting "things" on.
|
|
|
11
11
|
|
|
12
12
|
### Updates
|
|
13
13
|
|
|
14
|
+
- v2.27.1 - Reload existing markers for late joiners
|
|
15
|
+
- v2.26.1 - Add QTH/Maidenhead option also
|
|
16
|
+
- v2.26.0 - Add UTM and MGRS to coordinate display options.
|
|
14
17
|
- v2.25.0 - Add bounds command to set overall map bounds.
|
|
15
18
|
- v2.24.3 - Fix geojson incorrect fill.
|
|
16
19
|
- v2.24.2 - Changes to drawing colours to be more visible.
|
|
@@ -140,6 +143,8 @@ following the great circle between the two co-ordinates is plotted.
|
|
|
140
143
|
|
|
141
144
|
msg.payload = {name:"GC1", color:"#ff00ff", greatcircle:[ [51.464,0], [25.76,-80.18] ] }
|
|
142
145
|
|
|
146
|
+
Shapes can also have a **popup** property containing html, but you MUST also set a property `clickable:true` in order to allow it to be seen.
|
|
147
|
+
|
|
143
148
|
There are extra optional properties you can specify - see Options below.
|
|
144
149
|
|
|
145
150
|
|
|
@@ -254,6 +259,7 @@ Areas, Rectangles, Lines, Circles and Ellipses can also specify more optional pr
|
|
|
254
259
|
|
|
255
260
|
Other properties can be found in the leaflet documentation.
|
|
256
261
|
|
|
262
|
+
Shapes can also have a **popup** property containing html, but you MUST also set a property `clickable:true` in order to allow it to be seen.
|
|
257
263
|
|
|
258
264
|
### Drawing
|
|
259
265
|
|
package/package.json
CHANGED
package/worldmap/index.html
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
<link rel="stylesheet" type="text/css" href="leaflet/Leaflet.Dialog.css">
|
|
39
39
|
<link rel="stylesheet" type="text/css" href="leaflet/Control.MiniMap.min.css">
|
|
40
40
|
<link rel="stylesheet" type="text/css" href="leaflet/leaflet-velocity.min.css">
|
|
41
|
-
<link rel="stylesheet" type="text/css" href="leaflet/
|
|
41
|
+
<link rel="stylesheet" type="text/css" href="leaflet/leaflet.mousecoordinate.css">
|
|
42
42
|
<link rel="stylesheet" type="text/css" href="leaflet/dialog-polyfill.css"/>
|
|
43
43
|
<link rel="stylesheet" type="text/css" href="css/worldmap.css"/>
|
|
44
44
|
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
<script src="leaflet/leaflet-side-by-side.js"></script>
|
|
69
69
|
<script src="leaflet/OSMBuildings-Leaflet.js"></script>
|
|
70
70
|
<script src="leaflet/leaflet-omnivore.min.js"></script>
|
|
71
|
-
<script src="leaflet/
|
|
71
|
+
<script src="leaflet/leaflet.mousecoordinate.js"></script>
|
|
72
72
|
<script src="leaflet/leaflet.latlng-graticule.js"></script>
|
|
73
73
|
<script src="leaflet/VectorTileLayer.umd.min.js"></script>
|
|
74
74
|
<script src="leaflet/Semicircle.js"></script>
|
package/worldmap/index3d.html
CHANGED
|
@@ -18,237 +18,239 @@
|
|
|
18
18
|
<script>
|
|
19
19
|
|
|
20
20
|
// TO MAKE THE MAP APPEAR YOU MUST ADD YOUR ACCESS TOKEN FROM https://account.mapbox.com
|
|
21
|
+
// This needs to be set as an environment variable MAPBOXGL_TOKEN available to the Node-RED session on your server
|
|
21
22
|
mapboxgl.accessToken = '';
|
|
22
|
-
//mapboxgl.accessToken = 'pk.eyJ1IjoiZGNlZWpheSIsImEiOiJjaml1aDR6ejQwMml0M3dtdGFlbmEyZHVpIn0.3aD-974hxir335vuLjHOSg';
|
|
23
|
-
mapboxgl.accessToken = 'pk.eyJ1Ijoib3NtYnVpbGRpbmdzIiwiYSI6IjNldU0tNDAifQ.c5EU_3V8b87xO24tuWil0w';
|
|
24
|
-
// if (process.env.MAPBOXGL_TOKEN) {
|
|
25
|
-
// mapboxgl.accessToken = process.env.MAPBOXGL_TOKEN
|
|
26
|
-
// }
|
|
27
|
-
|
|
28
|
-
if (mapboxgl.accessToken === "") {
|
|
29
|
-
alert("To make the map apperar you must add your Access Token from https://account.mapbox.com")
|
|
30
|
-
}
|
|
31
23
|
|
|
24
|
+
var people = {};
|
|
32
25
|
var mbstyle = 'mapbox://styles/mapbox/streets-v10';
|
|
33
26
|
// var mbstyle = 'mapbox://styles/mapbox/light-v10';
|
|
34
|
-
// var mbstyle = 'https://data.osmbuildings.org/0.2/anonymous/style.json';
|
|
35
|
-
|
|
36
|
-
var map = new mapboxgl.Map({
|
|
37
|
-
container: 'map',
|
|
38
|
-
style: mbstyle,
|
|
39
|
-
center: [-1.3971, 51.0259],
|
|
40
|
-
zoom: 16,
|
|
41
|
-
pitch: 40,
|
|
42
|
-
bearing: 20,
|
|
43
|
-
attributionControl: true
|
|
44
|
-
});
|
|
45
27
|
|
|
46
|
-
|
|
28
|
+
fetch('/-worldmap3d-key')
|
|
29
|
+
.then(response => response.json())
|
|
30
|
+
.then(data => {
|
|
31
|
+
mapboxgl.accessToken = data.key;
|
|
32
|
+
if (mapboxgl.accessToken === "") {
|
|
33
|
+
alert("To make the map appear you must add your Access Token from https://account.mapbox.com by setting the MAPBOXGL_TOKEN environment variable on your server.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
47
36
|
|
|
48
|
-
map.
|
|
37
|
+
var map = new mapboxgl.Map({
|
|
38
|
+
container: 'map',
|
|
39
|
+
style: mbstyle,
|
|
40
|
+
center: [-1.3971, 51.0259],
|
|
41
|
+
zoom: 16,
|
|
42
|
+
pitch: 40,
|
|
43
|
+
bearing: 20,
|
|
44
|
+
attributionControl: true
|
|
45
|
+
});
|
|
49
46
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/// Add the base 3D buildings layer
|
|
60
|
-
map.addLayer({
|
|
61
|
-
'id': '3d-buildings',
|
|
62
|
-
'source': 'composite',
|
|
63
|
-
'source-layer': 'building',
|
|
64
|
-
'filter': ['==', 'extrude', 'true'],
|
|
65
|
-
'type': 'fill-extrusion',
|
|
66
|
-
'minzoom': 15,
|
|
67
|
-
'paint': {
|
|
68
|
-
'fill-extrusion-color': '#ddd',
|
|
69
|
-
'fill-extrusion-height': [
|
|
70
|
-
"interpolate", ["linear"], ["zoom"],
|
|
71
|
-
15, 0, 15.05, ["get", "height"]
|
|
72
|
-
],
|
|
73
|
-
'fill-extrusion-base': [
|
|
74
|
-
"interpolate", ["linear"], ["zoom"],
|
|
75
|
-
15, 0, 15.05, ["get", "min_height"]
|
|
76
|
-
],
|
|
77
|
-
'fill-extrusion-opacity': .4
|
|
78
|
-
}
|
|
79
|
-
}, firstSymbolId);
|
|
80
|
-
|
|
81
|
-
// ---- Connect to the Node-RED Events Websocket --------------------
|
|
82
|
-
|
|
83
|
-
var connect = function() {
|
|
84
|
-
ws = new SockJS(location.pathname.split("index")[0] + 'socket');
|
|
85
|
-
ws.onopen = function() {
|
|
86
|
-
console.log("CONNECTED");
|
|
87
|
-
// if (!inIframe) {
|
|
88
|
-
// document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
|
|
89
|
-
// }
|
|
90
|
-
ws.send(JSON.stringify({action:"connected"}));
|
|
91
|
-
};
|
|
92
|
-
ws.onclose = function() {
|
|
93
|
-
console.log("DISCONNECTED");
|
|
94
|
-
// if (!inIframe) {
|
|
95
|
-
// document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
|
|
96
|
-
// }
|
|
97
|
-
setTimeout(function() { connect(); }, 2500);
|
|
98
|
-
};
|
|
99
|
-
ws.onmessage = function(e) {
|
|
100
|
-
var data = JSON.parse(e.data);
|
|
101
|
-
//console.log("GOT",data);
|
|
102
|
-
if (Array.isArray(data)) {
|
|
103
|
-
//console.log("ARRAY");
|
|
104
|
-
for (var prop in data) {
|
|
105
|
-
if (data[prop].command) { doCommand(data[prop].command); delete data[prop].command; }
|
|
106
|
-
if (data[prop].hasOwnProperty("name")) { setMarker(data[prop]); }
|
|
107
|
-
else { console.log("SKIP A",data[prop]); }
|
|
47
|
+
map.on('load', function() {
|
|
48
|
+
var layers = map.getStyle().layers;
|
|
49
|
+
var firstSymbolId;
|
|
50
|
+
for (var i = 0; i < layers.length; i++) {
|
|
51
|
+
if (layers[i].type === 'symbol') {
|
|
52
|
+
firstSymbolId = layers[i].id;
|
|
53
|
+
break;
|
|
108
54
|
}
|
|
109
55
|
}
|
|
110
|
-
else {
|
|
111
|
-
if (data.command) { doCommand(data.command); delete data.command; }
|
|
112
|
-
if (data.hasOwnProperty("name")) { setMarker(data); }
|
|
113
|
-
else { console.log("SKIP",data); }
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
console.log("CONNECT TO",location.pathname + 'socket');
|
|
118
|
-
connect();
|
|
119
|
-
|
|
120
|
-
var doCommand = function(c) {
|
|
121
|
-
console.log("CMD",c);
|
|
122
|
-
// Add our own overlay geojson layer if necessary
|
|
123
|
-
if (c.hasOwnProperty("map") && c.map.hasOwnProperty("geojson") && c.map.hasOwnProperty("overlay")) {
|
|
124
|
-
addGeo(c.map.overlay,c.map.geojson);
|
|
125
|
-
}
|
|
126
|
-
var clat,clon;
|
|
127
|
-
if (c.hasOwnProperty("lat")) { clat = c.lat; }
|
|
128
|
-
if (c.hasOwnProperty("lon")) { clon = c.lon; }
|
|
129
|
-
if (clat && clon) { map.setCenter([clon,clat]); }
|
|
130
|
-
if (c.hasOwnProperty("zoom")) { map.setZoom(c.zoom); }
|
|
131
|
-
if (c.hasOwnProperty("pitch")) { map.setPitch(c.pitch); }
|
|
132
|
-
if (c.hasOwnProperty("bearing")) { map.setBearing(c.bearing); }
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
var addGeo = function(o,g) {
|
|
136
|
-
map.addLayer({
|
|
137
|
-
'id': o,
|
|
138
|
-
'type': 'fill-extrusion',
|
|
139
|
-
'source': {
|
|
140
|
-
'type': 'geojson',
|
|
141
|
-
'data': g
|
|
142
|
-
},
|
|
143
|
-
'paint': {
|
|
144
|
-
// https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions
|
|
145
|
-
'fill-extrusion-color': ['get', 'color'],
|
|
146
|
-
'fill-extrusion-height': ['get', 'height'],
|
|
147
|
-
'fill-extrusion-base': ['get', 'base_height'],
|
|
148
|
-
'fill-extrusion-opacity': 0.5
|
|
149
|
-
}
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
56
|
|
|
153
|
-
|
|
154
|
-
if (d.hasOwnProperty("area")) { return; } // ignore areas for now.
|
|
155
|
-
console.log("DATA",d);
|
|
156
|
-
if (people.hasOwnProperty(d.name)) {
|
|
157
|
-
map.getSource(d.name).setData(getPoints(d)); // Just update existing marker
|
|
158
|
-
}
|
|
159
|
-
else { // it's a new thing
|
|
160
|
-
people[d.name] = d;
|
|
57
|
+
/// Add the base 3D buildings layer
|
|
161
58
|
map.addLayer({
|
|
162
|
-
'id':
|
|
59
|
+
'id': '3d-buildings',
|
|
60
|
+
'source': 'composite',
|
|
61
|
+
'source-layer': 'building',
|
|
62
|
+
'filter': ['==', 'extrude', 'true'],
|
|
163
63
|
'type': 'fill-extrusion',
|
|
164
|
-
'
|
|
165
|
-
'type': 'geojson',
|
|
166
|
-
'data': getPoints(d)
|
|
167
|
-
},
|
|
64
|
+
'minzoom': 15,
|
|
168
65
|
'paint': {
|
|
169
|
-
|
|
170
|
-
'fill-extrusion-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
66
|
+
'fill-extrusion-color': '#ddd',
|
|
67
|
+
'fill-extrusion-height': [
|
|
68
|
+
"interpolate", ["linear"], ["zoom"],
|
|
69
|
+
15, 0, 15.05, ["get", "height"]
|
|
70
|
+
],
|
|
71
|
+
'fill-extrusion-base': [
|
|
72
|
+
"interpolate", ["linear"], ["zoom"],
|
|
73
|
+
15, 0, 15.05, ["get", "min_height"]
|
|
74
|
+
],
|
|
75
|
+
'fill-extrusion-opacity': .4
|
|
174
76
|
}
|
|
175
|
-
},firstSymbolId);
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
if (p.hasOwnProperty("hdg") && !isNaN(p.hdg)) {
|
|
213
|
-
sin = Math.sin((90 - p.hdg) * Math.PI / 180);
|
|
214
|
-
cos = Math.cos((90 - p.hdg) * Math.PI / 180);
|
|
215
|
-
}
|
|
216
|
-
var dx = 1 * cos - 1 * sin;
|
|
217
|
-
var dy = 1 * sin + 1 * cos;
|
|
218
|
-
var d = {
|
|
219
|
-
"type": "Feature",
|
|
220
|
-
"properties": {
|
|
221
|
-
"name": p.name,
|
|
222
|
-
"type": t,
|
|
223
|
-
"color": p.iconColor || "#910000",
|
|
224
|
-
"height": base + tall,
|
|
225
|
-
"base_height": base
|
|
226
|
-
},
|
|
227
|
-
"geometry": {
|
|
228
|
-
"type": "Polygon",
|
|
229
|
-
"coordinates": [
|
|
230
|
-
[
|
|
231
|
-
[ p.lon + (fac * dx ) / Math.cos( Math.PI / 180 * p.lat ), p.lat + (fac * dy) ],
|
|
232
|
-
[ p.lon - (fac * dy ) / Math.cos( Math.PI / 180 * p.lat ), p.lat + (fac * dx) ],
|
|
233
|
-
[ p.lon - (fac * dx ) / Math.cos( Math.PI / 180 * p.lat ), p.lat - (fac * dy) ],
|
|
234
|
-
[ p.lon + (fac * dy ) / Math.cos( Math.PI / 180 * p.lat ), p.lat - (fac * dx) ],
|
|
235
|
-
[ p.lon + (fac * dx ) / Math.cos( Math.PI / 180 * p.lat ), p.lat + (fac * dy) ],
|
|
236
|
-
]
|
|
237
|
-
]
|
|
77
|
+
}, firstSymbolId);
|
|
78
|
+
|
|
79
|
+
// ---- Connect to the Node-RED Events Websocket --------------------
|
|
80
|
+
|
|
81
|
+
var connect = function() {
|
|
82
|
+
ws = new SockJS(location.pathname.split("index")[0] + 'socket');
|
|
83
|
+
ws.onopen = function() {
|
|
84
|
+
console.log("CONNECTED");
|
|
85
|
+
// if (!inIframe) {
|
|
86
|
+
// document.getElementById("foot").innerHTML = "<font color='#494'>"+ibmfoot+"</font>";
|
|
87
|
+
// }
|
|
88
|
+
ws.send(JSON.stringify({action:"connected"}));
|
|
89
|
+
};
|
|
90
|
+
ws.onclose = function() {
|
|
91
|
+
console.log("DISCONNECTED");
|
|
92
|
+
// if (!inIframe) {
|
|
93
|
+
// document.getElementById("foot").innerHTML = "<font color='#900'>"+ibmfoot+"</font>";
|
|
94
|
+
// }
|
|
95
|
+
setTimeout(function() { connect(); }, 2500);
|
|
96
|
+
};
|
|
97
|
+
ws.onmessage = function(e) {
|
|
98
|
+
var data = JSON.parse(e.data);
|
|
99
|
+
//console.log("GOT",data);
|
|
100
|
+
if (Array.isArray(data)) {
|
|
101
|
+
//console.log("ARRAY");
|
|
102
|
+
for (var prop in data) {
|
|
103
|
+
if (data[prop].command) { doCommand(data[prop].command); delete data[prop].command; }
|
|
104
|
+
if (data[prop].hasOwnProperty("name")) { setMarker(data[prop]); }
|
|
105
|
+
else { console.log("SKIP A",data[prop]); }
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
if (data.command) { doCommand(data.command); delete data.command; }
|
|
110
|
+
if (data.hasOwnProperty("name")) { setMarker(data); }
|
|
111
|
+
else { console.log("SKIP",data); }
|
|
112
|
+
}
|
|
113
|
+
};
|
|
238
114
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
115
|
+
console.log("CONNECT TO",location.pathname + 'socket');
|
|
116
|
+
connect();
|
|
117
|
+
|
|
118
|
+
var doCommand = function(c) {
|
|
119
|
+
console.log("CMD",c);
|
|
120
|
+
// Add our own overlay geojson layer if necessary
|
|
121
|
+
if (c.hasOwnProperty("map") && c.map.hasOwnProperty("geojson") && c.map.hasOwnProperty("overlay")) {
|
|
122
|
+
addGeo(c.map.overlay,c.map.geojson);
|
|
123
|
+
}
|
|
124
|
+
var clat,clon;
|
|
125
|
+
if (c.hasOwnProperty("lat")) { clat = c.lat; }
|
|
126
|
+
if (c.hasOwnProperty("lon")) { clon = c.lon; }
|
|
127
|
+
if (clat && clon) { map.setCenter([clon,clat]); }
|
|
128
|
+
if (c.hasOwnProperty("zoom")) { map.setZoom(c.zoom); }
|
|
129
|
+
if (c.hasOwnProperty("pitch")) { map.setPitch(c.pitch); }
|
|
130
|
+
if (c.hasOwnProperty("bearing")) { map.setBearing(c.bearing); }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
var addGeo = function(o,g) {
|
|
134
|
+
map.addLayer({
|
|
135
|
+
'id': o,
|
|
136
|
+
'type': 'fill-extrusion',
|
|
137
|
+
'source': {
|
|
138
|
+
'type': 'geojson',
|
|
139
|
+
'data': g
|
|
140
|
+
},
|
|
141
|
+
'paint': {
|
|
142
|
+
// https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions
|
|
143
|
+
'fill-extrusion-color': ['get', 'color'],
|
|
144
|
+
'fill-extrusion-height': ['get', 'height'],
|
|
145
|
+
'fill-extrusion-base': ['get', 'base_height'],
|
|
146
|
+
'fill-extrusion-opacity': 0.5
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
var setMarker = function(d) {
|
|
152
|
+
if (d.hasOwnProperty("area")) { return; } // ignore areas for now.
|
|
153
|
+
console.log("DATA",d);
|
|
154
|
+
if (people.hasOwnProperty(d.name)) {
|
|
155
|
+
map.getSource(d.name).setData(getPoints(d)); // Just update existing marker
|
|
156
|
+
}
|
|
157
|
+
else { // it's a new thing
|
|
158
|
+
people[d.name] = d;
|
|
159
|
+
map.addLayer({
|
|
160
|
+
'id': d.name,
|
|
161
|
+
'type': 'fill-extrusion',
|
|
162
|
+
'source': {
|
|
163
|
+
'type': 'geojson',
|
|
164
|
+
'data': getPoints(d)
|
|
165
|
+
},
|
|
166
|
+
'paint': {
|
|
167
|
+
// https://www.mapbox.com/mapbox-gl-js/style-spec/#expressions
|
|
168
|
+
'fill-extrusion-color': ['get', 'color'],
|
|
169
|
+
'fill-extrusion-height': ['get', 'height'],
|
|
170
|
+
'fill-extrusion-base': ['get', 'base_height'],
|
|
171
|
+
'fill-extrusion-opacity': 1
|
|
172
|
+
}
|
|
173
|
+
},firstSymbolId);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
var lookupColor = function(s) {
|
|
178
|
+
var c = s.charAt(1);
|
|
179
|
+
if (c === "F") { return "#79DFFF"; }
|
|
180
|
+
if (c === "N") { return "#A4FFA3"; }
|
|
181
|
+
if (c === "U") { return "#FFFF78"; }
|
|
182
|
+
if (c === "H") { return "#FF7779"; }
|
|
183
|
+
if (c === "S") { return "#FF7779"; }
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// create the points for the marker and return the geojson
|
|
187
|
+
var getPoints = function(p) {
|
|
188
|
+
var fac = 0.000007; // basic size for bock icon in degrees....
|
|
189
|
+
var thing = "";
|
|
190
|
+
if (p.hasOwnProperty("icon")) {
|
|
191
|
+
if (p.icon.indexOf("male") !== -1) { thing = "person"; }
|
|
192
|
+
}
|
|
193
|
+
p.SDIC = p.SIDC || p.sidc;
|
|
194
|
+
if (p.hasOwnProperty("SIDC")) {
|
|
195
|
+
if (p.SIDC.indexOf("SFGPU") !== -1) { thing = "person"; }
|
|
196
|
+
if (p.SIDC.indexOf("SFGPUC") !== -1) { thing = "block"; }
|
|
197
|
+
if (p.SIDC.indexOf("GPEV") !== -1) { thing = "block"; }
|
|
198
|
+
p.iconColor = lookupColor(p.SIDC);
|
|
199
|
+
}
|
|
200
|
+
var t = p.type || thing;
|
|
201
|
+
var base = p.height || 0;
|
|
202
|
+
if (t === "person") { tall = 3; } // person slightly tall and thin
|
|
203
|
+
else if (t === "bar") { base = 0; tall = p.height; } // bar from ground to height
|
|
204
|
+
else if (t === "block") { fac = fac * 4; tall = 5; } // block large and cube
|
|
205
|
+
else { tall = 2; fac = fac * 2; } // else small cube
|
|
206
|
+
//console.log({p},{t},{fac},{base},{tall});
|
|
207
|
+
var sin = 1;
|
|
208
|
+
var cos = 0;
|
|
209
|
+
p.hdg = Number(p.hdg || p.heading);
|
|
210
|
+
if (p.hasOwnProperty("hdg") && !isNaN(p.hdg)) {
|
|
211
|
+
sin = Math.sin((90 - p.hdg) * Math.PI / 180);
|
|
212
|
+
cos = Math.cos((90 - p.hdg) * Math.PI / 180);
|
|
213
|
+
}
|
|
214
|
+
var dx = 1 * cos - 1 * sin;
|
|
215
|
+
var dy = 1 * sin + 1 * cos;
|
|
216
|
+
var d = {
|
|
217
|
+
"type": "Feature",
|
|
218
|
+
"properties": {
|
|
219
|
+
"name": p.name,
|
|
220
|
+
"type": t,
|
|
221
|
+
"color": p.iconColor || "#910000",
|
|
222
|
+
"height": base + tall,
|
|
223
|
+
"base_height": base
|
|
224
|
+
},
|
|
225
|
+
"geometry": {
|
|
226
|
+
"type": "Polygon",
|
|
227
|
+
"coordinates": [
|
|
228
|
+
[
|
|
229
|
+
[ p.lon + (fac * dx ) / Math.cos( Math.PI / 180 * p.lat ), p.lat + (fac * dy) ],
|
|
230
|
+
[ p.lon - (fac * dy ) / Math.cos( Math.PI / 180 * p.lat ), p.lat + (fac * dx) ],
|
|
231
|
+
[ p.lon - (fac * dx ) / Math.cos( Math.PI / 180 * p.lat ), p.lat - (fac * dy) ],
|
|
232
|
+
[ p.lon + (fac * dy ) / Math.cos( Math.PI / 180 * p.lat ), p.lat - (fac * dx) ],
|
|
233
|
+
[ p.lon + (fac * dx ) / Math.cos( Math.PI / 180 * p.lat ), p.lat + (fac * dy) ],
|
|
234
|
+
]
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
return d;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
document.addEventListener ("keydown", function (ev) {
|
|
242
|
+
if (ev.ctrlKey && ev.altKey && ev.code === "Digit3") {
|
|
243
|
+
ws.close();
|
|
244
|
+
//window.onbeforeunload = null;
|
|
245
|
+
window.location.href = "index.html";
|
|
246
|
+
}
|
|
247
|
+
});
|
|
250
248
|
|
|
251
249
|
});
|
|
250
|
+
|
|
251
|
+
})
|
|
252
|
+
.catch(error => { console.log("Unable to fetch MAPBOXGL_TOKEN.",error)} );
|
|
253
|
+
|
|
252
254
|
</script>
|
|
253
255
|
</body>
|
|
254
256
|
</html>
|