node-red-contrib-web-worldmap 2.28.1 → 2.29.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 CHANGED
@@ -1,16 +1,24 @@
1
1
  ### Change Log for Node-RED Worldmap
2
2
 
3
+ - v2.29.0 - Change locate to be a toggle and add command (trackme) to set style
4
+
5
+ - v2.28.3 - Let button declaration be an array
3
6
  - v2.28.1 - Fix layer command bug for non-core layers. Issue #195
4
7
  - v2.28.0 - Better Handling of sidc icons in geojson
8
+
5
9
  - v2.27.3 - Try to handle greatcircles crossing antimeridian
6
10
  - v2.27.1 - Reload existing markers for late joiners
11
+
7
12
  - v2.26.1 - Add QTH/Maidenhead option also
8
13
  - v2.26.0 - Add UTM and MGRS to coordinate display options.
14
+
9
15
  - v2.25.0 - Add bounds command to set overall map bounds.
16
+
10
17
  - v2.24.3 - Fix geojson incorrect fill.
11
18
  - v2.24.2 - Changes to drawing colours to be more visible.
12
19
  - v2.24.1 - Fix ellipse accuracy.
13
20
  - v2.24.0 - Add greatcircle option, fix non default httpRoot. Issue #193
21
+
14
22
  - v2.23.5 - Fix addtoheatmap. Issue #192
15
23
  - v2.23.4 - Fix opacity of area borders
16
24
  - v2.23.3 - Fix initial load of maps
package/README.md CHANGED
@@ -11,6 +11,8 @@ map web page for plotting "things" on.
11
11
 
12
12
  ### Updates
13
13
 
14
+ - v2.29.0 - Change locate to be a toggle and add command (trackme) to set style. Issue #202
15
+ - v2.28.3 - Let button declaration be an array
14
16
  - v2.28.1 - Fix layer command bug for non-core layers. Issue #195
15
17
  - v2.28.0 - Better Handling of sidc icons in geojson
16
18
  - v2.27.3 - Try to handle greatcircles crossing antimeridian
@@ -28,9 +30,6 @@ map web page for plotting "things" on.
28
30
  - v2.23.2 - Add convex-hull example
29
31
  - v2.23.1 - Fix saving of custom map layer
30
32
  - v2.23.0 - Give logo an id so it can be overridden by toplogo command. PR #188.
31
- - v2.22.3 - Don't show empty popup for geojson object. Issue #186. Add wobble to null island.
32
- - v2.22.2 - Be more tolerant of speed string types
33
- - v2.22.0 - Separate out layer events in worldmap in
34
33
 
35
34
  - see [CHANGELOG](https://github.com/dceejay/RedMap/blob/master/CHANGELOG.md) for full list of changes.
36
35
 
@@ -420,10 +419,11 @@ Optional properties include
420
419
  - **hiderightclick** - disables the right click that allows adding or deleting points on the map - `{"command":{"hiderightclick":true}}`
421
420
  - **coords** - turns on and off a display of the current mouse co-ordinates. Values can be "deg", "dms", or "none" (default). - `{"command":{"coords":"deg"}}`
422
421
  - **button** - if supplied with a `name` and `icon` property - adds a button to provide user input - sends
423
- a msg `{"action":"button", "name":"the_button_name"}` to the worldmap in node. If supplied with a `name` property only, it will remove the button. Optional `position` property can be 'bottomright', 'bottomleft', 'topleft' or 'topright' (default).
422
+ a msg `{"action":"button", "name":"the_button_name"}` to the worldmap in node. If supplied with a `name` property only, it will remove the button. Optional `position` property can be 'bottomright', 'bottomleft', 'topleft' or 'topright' (default). button can also be an array of button objects.
424
423
  - **contextmenu** - html string to define the right click menu when not on a marker. Defaults to the simple add marker input. Empty string `""` disables this right click.
425
424
  - **toptitle** - Words to replace title in title bar (if not in iframe)
426
425
  - **toplogo** - URL to logo image for top tile bar (if not in iframe) - ideally 60px by 24px.
426
+ - **trackme** - Turns on/off the browser self locating. Boolean false = off, true = cyan circle showing accuracy error, or an object like `{"command":{"trackme":{"name":"Dave","icon":"car","iconColor":"blue","layer":"mytrack","accuracy":false}}}`. Usual marker options can be applied.
427
427
 
428
428
  #### To switch layer, move map and zoom
429
429
 
@@ -445,6 +445,8 @@ to remove
445
445
 
446
446
  msg.payload.command = { "button": { "name":"My Fancy Button" } };
447
447
 
448
+ Multiple buttons can declared by using an array of button objects.
449
+
448
450
  #### To add a custom popup or contextmenu
449
451
 
450
452
  You can customise a marker's popup, or context menu (right click), by setting the
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "node-red-contrib-web-worldmap",
3
- "version": "2.28.1",
3
+ "version": "2.29.0",
4
4
  "description": "A Node-RED node to provide a web page of a world map for plotting things on.",
5
5
  "dependencies": {
6
6
  "@turf/bezier-spline": "~6.5.0",
7
7
  "cgi": "0.3.1",
8
8
  "compression": "^1.7.4",
9
- "express": "^4.17.2",
9
+ "express": "^4.18.1",
10
10
  "sockjs": "~0.3.24"
11
11
  },
12
12
  "bundledDependencies": [
@@ -257,16 +257,27 @@ var menuButton = L.easyButton({states:[{icon:'fa-bars fa-lg', onClick:function()
257
257
  var fullscreenButton = L.control.fullscreen();
258
258
  var rulerButton = L.control.ruler({position:"topleft"});
259
259
 
260
+ var followMode = { accuracy:true };
261
+ var followState = false;
262
+ var trackMeButton;
263
+ var errRing;
264
+
260
265
  function onLocationFound(e) {
261
- var radius = e.accuracy;
262
- //L.marker(e.latlng).addTo(map).bindPopup("You are within " + radius + " meters from this point").openPopup();
263
- L.circle(e.latlng, radius, {color:"cyan", weight:4, opacity:0.8, fill:false, clickable:false}).addTo(map);
264
- if (e.hasOwnProperty("heading")) {
265
- var lengthAsDegrees = e.speed * 60 / 110540;
266
- var ya = e.latlng.lat + Math.sin((90-e.heading)/180*Math.PI)*lengthAsDegrees*Math.cos(e.latlng.lng/180*Math.PI);
267
- var xa = e.latlng.lng + Math.cos((90-e.heading)/180*Math.PI)*lengthAsDegrees;
268
- var lla = new L.LatLng(ya,xa);
269
- L.polygon([ e.latlng, lla ], {color:"cyan", weight:3, opacity:0.5, clickable:false}).addTo(map);
266
+ if (followState === true) { map.panTo(e.latlng); }
267
+ if (followMode.icon) {
268
+ var self = {name:followMode.name || "self", lat:e.latlng.lat, lon:e.latlng.lng, hdg:e.heading, speed:(e.speed*3.6 || undefined), layer:followMode.layer, icon:followMode.icon, iconColor:followMode.iconColor || "#910000" };
269
+ setMarker(self);
270
+ }
271
+ if (followMode.accuracy) {
272
+ errRing = L.circle(e.latlng, e.accuracy, {color:followMode.color || "cyan", weight:3, opacity:0.6, fill:false, clickable:false});
273
+ errRing.addTo(map);
274
+ // if (e.hasOwnProperty("heading")) {
275
+ // var lengthAsDegrees = e.speed * 60 / 110540;
276
+ // var ya = e.latlng.lat + Math.sin((90-e.heading)/180*Math.PI)*lengthAsDegrees*Math.cos(e.latlng.lng/180*Math.PI);
277
+ // var xa = e.latlng.lng + Math.cos((90-e.heading)/180*Math.PI)*lengthAsDegrees;
278
+ // var lla = new L.LatLng(ya,xa);
279
+ // L.polygon([ e.latlng, lla ], {color:"cyan", weight:3, opacity:0.5, clickable:false}).addTo(map);
280
+ // }
270
281
  }
271
282
  ws.send(JSON.stringify({action:"point", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5), point:"self", hdg:e.heading, speed:(e.speed*3.6 || undefined)}));
272
283
  }
@@ -295,13 +306,36 @@ else {
295
306
  // Add the fullscreen button
296
307
  fullscreenButton.addTo(map);
297
308
 
298
- // Add the locate my position button
299
- L.easyButton( 'fa-crosshairs fa-lg', function() {
300
- map.locate({setView:true, maxZoom:16});
301
- }, "Locate me").addTo(map);
309
+ trackMeButton = L.easyButton({
310
+ states: [{
311
+ stateName: 'track-on',
312
+ icon: 'fa-window-close-o fa-lg',
313
+ title: 'Disable tracking',
314
+ onClick: function(btn, map) {
315
+ btn.state('track-off');
316
+ followState = false;
317
+ if (errRing) { errRing.removeFrom(map); }
318
+ delMarker(followMode.name || "self")
319
+ map.stopLocate();
320
+ }
321
+ }, {
322
+ stateName: 'track-off',
323
+ icon: 'fa-crosshairs fa-lg',
324
+ title: 'Enable tracking',
325
+ onClick: function(btn, map) {
326
+ btn.state('track-on');
327
+ followState = true;
328
+ map.locate({setView:false, watch:followState, enableHighAccuracy:true});
329
+ }
330
+ }]
331
+ });
332
+ trackMeButton.state('track-off');
333
+ trackMeButton.addTo(map);
302
334
 
303
- map.on('locationfound', onLocationFound);
304
- map.on('locationerror', onLocationError);
335
+ // Add the locate my position button
336
+ // L.easyButton( 'fa-crosshairs fa-lg', function() {
337
+ // map.locate({setView:true, maxZoom:16});
338
+ // }, "Locate me").addTo(map);
305
339
 
306
340
  // Add the measure/ruler button
307
341
  rulerButton.addTo(map);
@@ -644,6 +678,8 @@ map.on('moveend', function() {
644
678
  var b = map.getBounds();
645
679
  ws.send(JSON.stringify({action:"bounds", south:b._southWest.lat, west:b._southWest.lng, north:b._northEast.lat, east:b._northEast.lng, zoom:map.getZoom() }));
646
680
  });
681
+ map.on('locationfound', onLocationFound);
682
+ map.on('locationerror', onLocationError);
647
683
 
648
684
  //map.on('contextmenu', function(e) {
649
685
  // ws.send(JSON.stringify({action:"rightclick", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5)}));
@@ -743,7 +779,7 @@ var addBaseMaps = function(maplist,first) {
743
779
  // console.log("MAPS",first,maplist)
744
780
  var layerlookup = { OSMG:"OSM grey", OSMC:"OSM", OSMH:"OSM Humanitarian", EsriC:"Esri", EsriS:"Esri Satellite",
745
781
  EsriR:"Esri Relief", EsriT:"Esri Topography", EsriO:"Esri Ocean", EsriDG:"Esri Dark Grey", NatGeo: "National Geographic",
746
- UKOS:"UK OS OpenData", OS45:"UK OS 1919-1947", OS00:"UK OS 1900", OpTop:"Open Topo Map",
782
+ UKOS:"UK OS OpenData", OpTop:"Open Topo Map",
747
783
  HB:"Hike Bike OSM", ST:"Stamen Topography", SW:"Stamen Watercolor", AN:"AutoNavi (Chinese)"
748
784
  }
749
785
 
@@ -866,25 +902,6 @@ var addBaseMaps = function(maplist,first) {
866
902
  });
867
903
  }
868
904
 
869
- if (maplist.indexOf("OS45")!==-1) {
870
- basemaps[layerlookup["OS45"]] = L.tileLayer( 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
871
- attribution: 'Historical Maps Layer, from <a href="https://maps.nls.uk/projects/api/">NLS Maps</a>',
872
- bounds: [[49.6, -12], [61.7, 3]],
873
- minZoom:1, maxZoom:18,
874
- subdomains: '0123'
875
- });
876
- }
877
-
878
- if (maplist.indexOf("OS00")!==-1) {
879
- //var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/NLS_API/{z}/{x}/{y}.jpg', {
880
- basemaps[layerlookup["OS00"]] = L.tileLayer('https://nls-{s}.tileserver.com/fpsUZbzrfb5d/{z}/{x}/{y}.jpg', {
881
- attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
882
- bounds: [[49.6, -12], [61.7, 3]],
883
- minZoom:1, maxNativeZoom:19, maxZoom:20,
884
- subdomains: '0123'
885
- });
886
- }
887
-
888
905
  // Nice terrain based maps by Stamen Design
889
906
  if (maplist.indexOf("ST")!==-1) {
890
907
  var terrainUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg";
@@ -2166,18 +2183,37 @@ function doCommand(cmd) {
2166
2183
  }
2167
2184
  }
2168
2185
  if (cmd.hasOwnProperty("button")) {
2169
- if (cmd.button.icon) {
2170
- if (!buttons[cmd.button.name]) {
2171
- buttons[cmd.button.name] = L.easyButton( cmd.button.icon, function() {
2172
- ws.send(JSON.stringify({action:"button",name:cmd.button.name}));
2173
- }, cmd.button.name, { position:cmd.button.position||'topright' }).addTo(map);
2186
+ if (!Array.isArray(cmd.button)) { cmd.button = [cmd.button]; }
2187
+ cmd.button.forEach(function(b) {
2188
+ if (b.icon) {
2189
+ if (!buttons[b.name]) {
2190
+ buttons[b.name] = L.easyButton( b.icon, function() {
2191
+ ws.send(JSON.stringify({action:"button", name:b.name}));
2192
+ }, b.name, { position:b.position||'topright' }).addTo(map);
2193
+ }
2174
2194
  }
2195
+ else {
2196
+ if (buttons[b.name]) {
2197
+ buttons[b.name].removeFrom(map);
2198
+ delete buttons[b.name];
2199
+ }
2200
+ }
2201
+ })
2202
+ }
2203
+ if (cmd.hasOwnProperty("trackme")) {
2204
+ if (cmd.trackme === false) {
2205
+ followState = false;
2206
+ map.stopLocate();
2207
+ if (errRing) { errRing.removeFrom(map); }
2208
+ delMarker(followMode.name || "self")
2209
+ if (trackMeButton !== undefined) { trackMeButton.state('track-off'); }
2175
2210
  }
2176
2211
  else {
2177
- if (buttons[cmd.button.name]) {
2178
- buttons[cmd.button.name].removeFrom(map);
2179
- delete buttons[cmd.button.name];
2180
- }
2212
+ followState = true;
2213
+ if (cmd.trackme === true) { followMode = { accuracy:true }; }
2214
+ else { followMode = cmd.trackme; }
2215
+ map.locate({setView:false, watch:followState, enableHighAccuracy:true});
2216
+ if (trackMeButton !== undefined) { trackMeButton.state('track-on'); }
2181
2217
  }
2182
2218
  }
2183
2219
  if (cmd.hasOwnProperty("contextmenu")) {
package/worldmap.html CHANGED
@@ -318,8 +318,6 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
318
318
  { value: "EsriDG", label: "ESRI Dark Grey" },
319
319
  { value: "NatGeo", label: "National Geographic" },
320
320
  { value: "UKOS", label: "UK OS Opendata" },
321
- { value: "OS45", label: "UK OS 1919-47" },
322
- { value: "OS00", label: "UK OS 1900" },
323
321
  { value: "OpTop", label: "Open Topo Map" },
324
322
  { value: "HB", label: "Hike Bike OSM" },
325
323
  { value: "AN", label: "Autonavi (Chinese)" },