node-red-contrib-web-worldmap 4.7.0 → 4.8.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 CHANGED
@@ -1,5 +1,8 @@
1
1
  ### Change Log for Node-RED Worldmap
2
2
 
3
+ - v4.8.1 - Slight tidy of some of the geojson handling
4
+ - v4.8.0 - Merged PR for feedback functionality cleanup and example. PR #271 and #272
5
+ - v4.7.0 - Update pmtiles library, fix feedback function inconsistency. Issue #270
3
6
  - v4.6.5 - Let geojson allow for generic overrides with .icon and .layer.
4
7
  - v4.6.4 - Fix deletion of layers logic to actually fully remove points.
5
8
  - v4.6.3 - Fix sending of layer events when not wanted. Issue #262
package/README.md CHANGED
@@ -13,6 +13,9 @@ Feel free to [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%
13
13
 
14
14
  ### Updates
15
15
 
16
+ - v4.8.1 - Slight tidy of some of the geojson handling
17
+ - v4.8.0 - Merged PR for feedback functionality cleanup and example. PR #271 and #272
18
+ - v4.7.0 - Update pmtiles library, fix feedback function inconsistency. Issue #270
16
19
  - v4.6.5 - Let geojson allow for generic overrides with .icon and .layer.
17
20
  - v4.6.4 - Fix deletion of layers logic to actually fully remove points.
18
21
  - v4.6.3 - Fix sending of layer events when not wanted. Issue #262
@@ -395,7 +398,7 @@ Optional properties for **msg.payload.command** include
395
398
  - **panit** - auto pan to the latest marker updated. - `{"command":{"panit":true}}`
396
399
  - **zoomlock** - locks the zoom control to the current value and removes zoom control - `{"command":{"zoomlock":true}}`
397
400
  - **hiderightclick** - disables the right click that allows adding or deleting points on the map - `{"command":{"hiderightclick":true}}`
398
- - **coords** - turns on and off a display of the current mouse co-ordinates. Values can be "deg", "dms", or "none" (default). - `{"command":{"coords":"deg"}}`
401
+ - **coords** - turns on and off a display of the current mouse co-ordinates. Values can be "deg", "dms", "utm", "mgrs", "qth" or "none" (default). - `{"command":{"coords":"deg"}}` , `{"command":{"coords":"deg,dms,utm"}}`
399
402
  - **showruler** - turns on and off a display of the ruler control. Values can be "true" or "false". - `{"command": {"ruler": {"showruler": true}}}`
400
403
  - **button** - if supplied with a `name` and `icon` property - adds a button to provide user input - sends
401
404
  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.
@@ -0,0 +1,129 @@
1
+ [
2
+ {
3
+ "id": "46f4b9ae1c66c1ba",
4
+ "type": "tab",
5
+ "label": "Flow 4",
6
+ "disabled": false,
7
+ "info": "",
8
+ "env": []
9
+ },
10
+ {
11
+ "id": "c643e022.1816c",
12
+ "type": "worldmap",
13
+ "z": "46f4b9ae1c66c1ba",
14
+ "name": "",
15
+ "lat": "30",
16
+ "lon": "0",
17
+ "zoom": "3",
18
+ "layer": "OSMG",
19
+ "cluster": "",
20
+ "maxage": "",
21
+ "usermenu": "show",
22
+ "layers": "show",
23
+ "panit": "false",
24
+ "panlock": "false",
25
+ "zoomlock": "false",
26
+ "hiderightclick": "false",
27
+ "coords": "deg",
28
+ "showgrid": "false",
29
+ "showruler": "false",
30
+ "allowFileDrop": "false",
31
+ "path": "worldmap",
32
+ "overlist": "DR,CO,RA,DN",
33
+ "maplist": "OSMG,OSMH,EsriS",
34
+ "mapname": "",
35
+ "mapurl": "",
36
+ "mapopt": "",
37
+ "mapwms": false,
38
+ "x": 1000,
39
+ "y": 480,
40
+ "wires": []
41
+ },
42
+ {
43
+ "id": "4966f5218c3fe1df",
44
+ "type": "inject",
45
+ "z": "46f4b9ae1c66c1ba",
46
+ "name": "",
47
+ "repeat": "",
48
+ "crontab": "",
49
+ "once": false,
50
+ "topic": "",
51
+ "payload": "",
52
+ "payloadType": "none",
53
+ "x": 530,
54
+ "y": 480,
55
+ "wires": [
56
+ [
57
+ "87dff974113c8c54"
58
+ ]
59
+ ]
60
+ },
61
+ {
62
+ "id": "87dff974113c8c54",
63
+ "type": "function",
64
+ "z": "46f4b9ae1c66c1ba",
65
+ "name": "add new rectangle",
66
+ "func": "\nmsg.payload = {\"command\":{\"bounds\":[[49.83682820280039,-4.019763692204326],[51.4723362586149,1.1741268015945219]]}};\nnode.send(msg);\nmsg.payload = {\"command\":{\"zoom\":9.7}};\nnode.send(msg);\n\n\nvar popup = \"<button name=\\\"B1name\\\" onclick='feedback(\\\"${name}\\\",\\\"${name} sends {x} Hellow\\\",\\\"myAction\\\",true);'>Hellow1 from ${name}</button>\";\npopup += \"<button name=\\\"B2name\\\" onclick='feedback(this.name,\\\"${name} sends {x} Hellow\\\",\\\"myAction\\\",true);'>Hellow2 from ${name}</button>\";\n\nvar points = [ { \"lat\": 50.66, \"lng\": -1.59 }, { \"lat\": 50.60, \"lng\": -1.47 } ] ;\nmsg.payload = {\n popup: popup.replace(/\\{x\\}/,\"popup\"),\n contextmenu: popup.replace(/\\{x\\}/, \"context\"),\n name: \"myShape\",\n area: points,\n clickable:true,\n };\nnode.send(msg);\n\nmsg.payload = {\n popup: popup,\n contextmenu: popup,\n name: \"myMarker\",\n lat: 50.40,\n lon: -1.0,\n weight: 1,\n};\nnode.send(msg);\nreturn msg;",
67
+ "outputs": 1,
68
+ "timeout": "",
69
+ "noerr": 0,
70
+ "initialize": "",
71
+ "finalize": "",
72
+ "libs": [],
73
+ "x": 770,
74
+ "y": 480,
75
+ "wires": [
76
+ [
77
+ "c643e022.1816c",
78
+ "34ad8daae96efd3e"
79
+ ]
80
+ ]
81
+ },
82
+ {
83
+ "id": "32d7cc4d4db67f66",
84
+ "type": "worldmap in",
85
+ "z": "46f4b9ae1c66c1ba",
86
+ "name": "",
87
+ "path": "/worldmap",
88
+ "events": "connect,disconnect,point,layer,bounds,files,draw,other",
89
+ "x": 500,
90
+ "y": 540,
91
+ "wires": [
92
+ [
93
+ "32a2b83008623990"
94
+ ]
95
+ ]
96
+ },
97
+ {
98
+ "id": "32a2b83008623990",
99
+ "type": "debug",
100
+ "z": "46f4b9ae1c66c1ba",
101
+ "name": "debug 14",
102
+ "active": true,
103
+ "tosidebar": true,
104
+ "console": false,
105
+ "tostatus": false,
106
+ "complete": "false",
107
+ "statusVal": "",
108
+ "statusType": "auto",
109
+ "x": 680,
110
+ "y": 540,
111
+ "wires": []
112
+ },
113
+ {
114
+ "id": "34ad8daae96efd3e",
115
+ "type": "debug",
116
+ "z": "46f4b9ae1c66c1ba",
117
+ "name": "debug 15",
118
+ "active": true,
119
+ "tosidebar": true,
120
+ "console": false,
121
+ "tostatus": false,
122
+ "complete": "false",
123
+ "statusVal": "",
124
+ "statusType": "auto",
125
+ "x": 980,
126
+ "y": 400,
127
+ "wires": []
128
+ }
129
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-web-worldmap",
3
- "version": "4.7.0",
3
+ "version": "4.8.1",
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",
@@ -865,6 +865,10 @@ var addThing = function() {
865
865
  var form = {};
866
866
  var addToForm = function(n,v) { form[n] = v; }
867
867
  var feedback = function(n,v,a,c) {
868
+ /*
869
+ // suggest to reove all the special handling for simplification, no reason to send information
870
+ // about entities that the backend generaed, the need is only to get recognizable actions from the frontend
871
+ //
868
872
  if (v === "_form") { v = form; }
869
873
  if (markers[n]) {
870
874
  console.log("FB1",n,v,a,c)
@@ -875,8 +879,10 @@ var feedback = function(n,v,a,c) {
875
879
  setMarker(allData[n]);
876
880
  }
877
881
  else if (polygons[n]) {
878
- console.log("FB2",n,v,a)
879
- sendDrawing(n,v,a)
882
+ console.log("FB2", n, v, a);
883
+ const polyData = { "name": n, "action": a || "feedback", "value": v || null };
884
+ //sendDrawing(n,v,a)
885
+ ws.send(JSON.stringify(polyData));
880
886
  }
881
887
  else {
882
888
  if (n === undefined) { n = "map"; }
@@ -884,6 +890,10 @@ var feedback = function(n,v,a,c) {
884
890
  rmenudata = v;
885
891
  ws.send(JSON.stringify({action:a||"feedback", name:n, value:v, lat:rclk.lat, lon:rclk.lng}));
886
892
  }
893
+ */
894
+
895
+ const dataToSend = { "name": n, "action": a || "feedback", "value": v || null };
896
+ ws.send(JSON.stringify(dataToSend));
887
897
  if (c === true) { map.closePopup(); }
888
898
  }
889
899
 
@@ -1188,7 +1198,7 @@ var addOverlays = function(overlist) {
1188
1198
  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>");
1189
1199
  }
1190
1200
  rightmenuMarker.setLatLng(cent);
1191
- setTimeout(function() {map.openPopup(rightmenuMarker)},25);
1201
+ setTimeout(function() {map.openPopup(rightmenuMarker).replace(/\${name}/g,name)},25);
1192
1202
  });
1193
1203
 
1194
1204
  sendDrawing = function(n,v,a) {
@@ -1510,7 +1520,8 @@ function setMarker(data) {
1510
1520
  m.on('click', function(e) {
1511
1521
  var fb = allData[data["name"]];
1512
1522
  fb.action = "click";
1513
- ws.send(JSON.stringify(fb));
1523
+ if (fb.sendOnClick ?? true)
1524
+ ws.send(JSON.stringify(fb));
1514
1525
  });
1515
1526
  // customise right click context menu
1516
1527
  var rightcontext = "";
@@ -1529,7 +1540,7 @@ function setMarker(data) {
1529
1540
  rightcontext = rightcontext.replace(new RegExp("\\${"+item+"}","g"),allData[data["name"]].value[item]);
1530
1541
  }
1531
1542
  }
1532
- rightcontext = rightcontext.replace(/\${.*?}/g,'')
1543
+ rightcontext = rightcontext.replace(/\${.*?}/g,'').replace(/\${name}/g,data["name"])
1533
1544
  if (rightcontext.length > 0) {
1534
1545
  var rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<b>"+data["name"]+"</b><br/>"+rightcontext);
1535
1546
  if (hiderightclick !== true) {
@@ -1698,7 +1709,7 @@ function setMarker(data) {
1698
1709
  // if clickable then add popup
1699
1710
  if (opt.clickable === true) {
1700
1711
  var words = "<b>"+data["name"]+"</b>";
1701
- if (data.popup) { words = words + "<br/>" + data.popup; }
1712
+ if (data.popup) { words = words + "<br/>" + data.popup.replace(/\${name}/g,data["name"]); }
1702
1713
  polygons[data["name"]].bindPopup(words, {autoClose:false, closeButton:true, closeOnClick:true, minWidth:200});
1703
1714
  }
1704
1715
  // add a tooltip (if supplied)
@@ -2547,11 +2558,11 @@ function doCommand(cmd) {
2547
2558
  try { coords.removeFrom(map); }
2548
2559
  catch(e) {}
2549
2560
  var opts = {gps:false, gpsLong:false, utm:false, utmref:false, position:"bottomleft"}
2550
- if (cmd.coords == "deg") { opts.gps = true; }
2551
- if (cmd.coords == "dms") { opts.gpsLong = true; }
2552
- if (cmd.coords == "utm") { opts.utm = true; }
2553
- if (cmd.coords == "mgrs") { opts.utmref = true; }
2554
- if (cmd.coords == "qth") { opts.qth = true; }
2561
+ if (cmd.coords.includes("deg")) { opts.gps = true; }
2562
+ if (cmd.coords.includes("dms")) { opts.gpsLong = true; }
2563
+ if (cmd.coords.includes("utm")) { opts.utm = true; }
2564
+ if (cmd.coords.includes("mgrs")) { opts.utmref = true; }
2565
+ if (cmd.coords.includes("qth")) { opts.qth = true; }
2555
2566
  coords.options = opts;
2556
2567
  coords.addTo(map);
2557
2568
  }
@@ -3100,12 +3111,16 @@ function doGeojson(n,g,l,o,i) { // name, geojson, layer, options, icon
3100
3111
  st.weight = feature.properties["stroke-width"] ?? st.weight;
3101
3112
  st.fillColor = feature.properties["fill-color"] ?? feature.properties["fill"] ?? st.fillColor;
3102
3113
  st.fillOpacity = feature.properties["fill-opacity"] ?? st.fillOpacity;
3114
+ st.fontColor = feature.properties["font-color"] ?? st.fontColor ?? "#000000";
3115
+ st.fontOpacity = feature.properties["font-opacity"] ?? st.fontOpacity;
3103
3116
  delete feature.properties["stroke"];
3104
3117
  delete feature.properties["stroke-width"];
3105
- delete feature.properties["fill-color"];
3118
+ delete feature.properties["stroke-opacity"];
3106
3119
  delete feature.properties["fill"];
3120
+ delete feature.properties["fill-color"];
3107
3121
  delete feature.properties["fill-opacity"];
3108
- delete feature.properties["stroke-opacity"];
3122
+ delete feature.properties["font-color"];
3123
+ delete feature.properties["font-opacity"];
3109
3124
  }
3110
3125
  if (feature.hasOwnProperty("style")) {
3111
3126
  //console.log("GSTYLE", feature.style)
@@ -3130,17 +3145,17 @@ function doGeojson(n,g,l,o,i) { // name, geojson, layer, options, icon
3130
3145
  }
3131
3146
  if (feature.properties.hasOwnProperty("SIDC")) {
3132
3147
  myMarker = new ms.Symbol( feature.properties.SIDC.toUpperCase(), {
3133
- uniqueDesignation:unescape(encodeURIComponent(feature.properties.title||feature.properties.unit)),
3148
+ uniqueDesignation:unescape(encodeURIComponent(feature.properties.title||feature.properties.unit||'')),
3134
3149
  country:feature.properties.country,
3135
3150
  direction:feature.properties.bearing,
3136
3151
  additionalInformation:feature.properties.modifier,
3137
- size:25
3152
+ size:20
3138
3153
  });
3139
3154
  var anc = myMarker.getAnchor();
3140
- if (myMarker.hasOwnProperty("metadata") && myMarker.metadata.hasOwnProperty("echelon")) {
3141
- var sz = iconSz[myMarker.metadata.echelon];
3142
- myMarker.setOptions({size:sz});
3143
- }
3155
+ // if (myMarker.hasOwnProperty("metadata") && myMarker.metadata.hasOwnProperty("echelon")) {
3156
+ // var sz = iconSz[myMarker.metadata.echelon];
3157
+ // myMarker.setOptions({size:sz});
3158
+ // }
3144
3159
  myMarker = L.icon({
3145
3160
  iconUrl: myMarker.toDataURL(),
3146
3161
  iconAnchor: [anc.x, anc.y],
@@ -3167,8 +3182,10 @@ function doGeojson(n,g,l,o,i) { // name, geojson, layer, options, icon
3167
3182
  iconColor: 'white'
3168
3183
  });
3169
3184
  }
3170
- if (!feature.properties.hasOwnProperty("title")) {
3171
- feature.properties.title = feature.properties["marker-symbol"];
3185
+ if (!feature.properties.hasOwnProperty("title") && feature.properties.hasOwnProperty("marker-symbol")) {
3186
+ if (!feature.properties["marker-symbol"].indexOf('fa-') === 0) {
3187
+ feature.properties.title = feature.properties["marker-symbol"];
3188
+ }
3172
3189
  }
3173
3190
  if (feature.properties.hasOwnProperty("url")) {
3174
3191
  feature.properties.url = "<a target='_new' href='"+feature.properties.url+"'>"+feature.properties.url+"</a>";