node-red-contrib-web-worldmap 4.3.2 → 4.4.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.
@@ -0,0 +1,50 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # ESLint is a tool for identifying and reporting on patterns
6
+ # found in ECMAScript/JavaScript code.
7
+ # More details at https://github.com/eslint/eslint
8
+ # and https://eslint.org
9
+
10
+ name: ESLint
11
+
12
+ on:
13
+ push:
14
+ branches: [ "master" ]
15
+ pull_request:
16
+ # The branches below must be a subset of the branches above
17
+ branches: [ "master" ]
18
+ schedule:
19
+ - cron: '38 2 * * 4'
20
+
21
+ jobs:
22
+ eslint:
23
+ name: Run eslint scanning
24
+ runs-on: ubuntu-latest
25
+ permissions:
26
+ contents: read
27
+ security-events: write
28
+ actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
29
+ steps:
30
+ - name: Checkout code
31
+ uses: actions/checkout@v3
32
+
33
+ - name: Install ESLint
34
+ run: |
35
+ npm install eslint@8.10.0
36
+ npm install @microsoft/eslint-formatter-sarif@2.1.7
37
+
38
+ - name: Run ESLint
39
+ run: npx eslint .
40
+ --config .eslintrc.js
41
+ --ext .js,.jsx,.ts,.tsx
42
+ --format @microsoft/eslint-formatter-sarif
43
+ --output-file eslint-results.sarif
44
+ continue-on-error: true
45
+
46
+ - name: Upload analysis results to GitHub
47
+ uses: github/codeql-action/upload-sarif@v2
48
+ with:
49
+ sarif_file: eslint-results.sarif
50
+ wait-for-processing: true
package/CHANGELOG.md CHANGED
@@ -1,5 +1,7 @@
1
1
  ### Change Log for Node-RED Worldmap
2
2
 
3
+ - v4.4.0 - Add quad(copter) drone icon.
4
+ - v4.3.3 - Fix for objects changing layers.
3
5
  - v4.3.2 - Fix geojson popup missing label name.
4
6
  - v4.3.1 - Small fix to icon transparency, and routing detail.
5
7
  - v4.3.0 - Add support for PMtiles files.
package/README.md CHANGED
@@ -13,6 +13,8 @@ Feel free to [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%
13
13
 
14
14
  ### Updates
15
15
 
16
+ - v4.4.0 - Add quad(copter) drone icon.
17
+ - v4.3.3 - Fix for objects changing layers.
16
18
  - v4.3.2 - Fix geojson popup missing label name.
17
19
  - v4.3.1 - Small fix to icon transparency, and routing detail.
18
20
  - v4.3.0 - Add support for PMtiles files.
@@ -105,7 +107,8 @@ There are also several special icons...
105
107
  - **ship** : a ship icon that aligns with the heading of travel.
106
108
  - **car** : a car icon that aligns with the heading of travel.
107
109
  - **bus** : a bus/coach icon that aligns with the heading of travel.
108
- - **uav** : a small uav like icon that aligns with the heading of travel.
110
+ - **uav** : a small drone uav like icon that aligns with the heading of travel.
111
+ - **quad** : a small quadcopter uav like icon that aligns with the heading of travel.
109
112
  - **helicopter** : a small helicopter icon that aligns with the heading of travel.
110
113
  - **sensor** : a camera icon that points to the heading angle.
111
114
  - **arrow** : a map GPS arrow type pointer that aligns with the heading of travel.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-red-contrib-web-worldmap",
3
- "version": "4.3.2",
3
+ "version": "4.4.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",
@@ -1502,28 +1502,30 @@ var rangerings = function(latlng, options) {
1502
1502
  function setMarker(data) {
1503
1503
  var rightmenu = function(m) {
1504
1504
  m.on('click', function(e) {
1505
- var fb = allData[data.name];
1505
+ var fb = allData[data["name"]];
1506
1506
  fb.action = "click";
1507
1507
  ws.send(JSON.stringify(fb));
1508
1508
  });
1509
1509
  // customise right click context menu
1510
1510
  var rightcontext = "";
1511
- //if (polygons[data.name] == undefined) {
1512
- rightcontext = "<button id='delbutton' onclick='delMarker(\""+data.name+"\",true);'>Delete</button>";
1511
+ //if (polygons[data["name"]] == undefined) {
1512
+ rightcontext = "<button id='delbutton' onclick='delMarker(\""+data["name"]+"\",true);'>Delete</button>";
1513
1513
  //}
1514
1514
  if (data.editable) {
1515
- rightcontext = "<button onclick='editPoly(\""+data.name+"\");'>Edit</button><button onclick='delMarker(\""+data.name+"\",true);'>Delete</button>";
1515
+ rightcontext = "<button onclick='editPoly(\""+data["name"]+"\");'>Edit</button><button onclick='delMarker(\""+data["name"]+"\",true);'>Delete</button>";
1516
1516
  }
1517
1517
  if ((data.contextmenu !== undefined) && (typeof data.contextmenu === "string")) {
1518
- rightcontext = data.contextmenu.replace(/\${name}/g,data.name);
1518
+ rightcontext = data.contextmenu.replace(/\${name}/g,data["name"]);
1519
1519
  delete data.contextmenu;
1520
1520
  }
1521
- for (const item in allData[data.name].value) {
1522
- rightcontext = rightcontext.replace(new RegExp("\\${"+item+"}","g"),allData[data.name].value[item]);
1521
+ if (allData.hasOwnProperty(data["name"]) && allData[data["name"]].hasOwnProperty("value")) {
1522
+ for (const item in allData[data["name"]].value) {
1523
+ rightcontext = rightcontext.replace(new RegExp("\\${"+item+"}","g"),allData[data["name"]].value[item]);
1524
+ }
1523
1525
  }
1524
1526
  rightcontext = rightcontext.replace(/\${.*?}/g,'')
1525
1527
  if (rightcontext.length > 0) {
1526
- var rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<b>"+data.name+"</b><br/>"+rightcontext);
1528
+ var rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<b>"+data["name"]+"</b><br/>"+rightcontext);
1527
1529
  if (hiderightclick !== true) {
1528
1530
  m.on('contextmenu', function(e) {
1529
1531
  L.DomEvent.stopPropagation(e);
@@ -1544,7 +1546,7 @@ function setMarker(data) {
1544
1546
 
1545
1547
  // console.log("DATA", typeof data, data);
1546
1548
  if (data.deleted == true) { // remove markers we are told to
1547
- delMarker(data.name);
1549
+ delMarker(data["name"]);
1548
1550
  return;
1549
1551
  }
1550
1552
 
@@ -1576,8 +1578,8 @@ function setMarker(data) {
1576
1578
  }
1577
1579
 
1578
1580
  var lll = "unknown";
1579
- if (markers.hasOwnProperty(data.name) && markers[data.name].hasOwnProperty("lay")) {
1580
- lll = markers[data.name].lay;
1581
+ if (markers.hasOwnProperty(data["name"]) && markers[data["name"]].hasOwnProperty("lay")) {
1582
+ lll = markers[data["name"]].lay;
1581
1583
  }
1582
1584
  var lay = data.layer ?? lll;
1583
1585
  if (!data.hasOwnProperty("action") || data.action.indexOf("layer") === -1) {
@@ -1600,27 +1602,27 @@ function setMarker(data) {
1600
1602
  map.addLayer(overlays[lay]);
1601
1603
  //console.log("ADDED LAYER",lay,layers);
1602
1604
  }
1603
- if (!allData.hasOwnProperty(data.name)) { allData[data.name] = {}; }
1605
+ if (!allData.hasOwnProperty(data["name"])) { allData[data["name"]] = {}; }
1604
1606
  delete data.action;
1605
1607
  Object.keys(data).forEach(function(key) {
1606
- if (data[key] == null) { delete allData[data.name][key]; }
1607
- else { allData[data.name][key] = data[key]; }
1608
+ if (data[key] == null) { delete allData[data["name"]][key]; }
1609
+ else { allData[data["name"]][key] = data[key]; }
1608
1610
  });
1609
- data = Object.assign({},allData[data.name]);
1611
+ data = Object.assign({},allData[data["name"]]);
1610
1612
  }
1611
1613
  delete data.action;
1612
1614
 
1613
- if (typeof markers[data.name] != "undefined") {
1614
- if (markers[data.name].lay !== lay) {
1615
- delMarker(data.name);
1615
+ if (typeof markers[data["name"]] != "undefined") {
1616
+ if (markers[data["name"]].lay !== lay) {
1617
+ delMarker(data["name"]);
1616
1618
  }
1617
1619
  else {
1618
- try {layers[lay].removeLayer(markers[data.name]); }
1620
+ try {layers[lay].removeLayer(markers[data["name"]]); }
1619
1621
  catch(e) { console.log("OOPS"); }
1620
1622
  }
1621
1623
  }
1622
1624
 
1623
- if (typeof polygons[data.name] != "undefined") { layers[lay].removeLayer(polygons[data.name]); }
1625
+ if (typeof polygons[data["name"]] != "undefined") { layers[lay].removeLayer(polygons[data["name"]]); }
1624
1626
 
1625
1627
  if (data.hasOwnProperty("drawCount")) { drawCount = data.drawCount; }
1626
1628
  // Draw lines
@@ -1629,14 +1631,14 @@ function setMarker(data) {
1629
1631
  if (!data.hasOwnProperty("weight")) { opt.weight = 3; } //Standard settings different for lines
1630
1632
  if (!data.hasOwnProperty("opacity")) { opt.opacity = 0.8; }
1631
1633
  var polyln = L.polyline(data.line, opt);
1632
- polygons[data.name] = rightmenu(polyln);
1634
+ polygons[data["name"]] = rightmenu(polyln);
1633
1635
  }
1634
1636
  // Draw Areas
1635
1637
  else if (data.hasOwnProperty("area") && Array.isArray(data.area)) {
1636
1638
  var polyarea;
1637
1639
  if (data.area.length === 2) { polyarea = L.rectangle(data.area, opt); }
1638
1640
  else { polyarea = L.polygon(data.area, opt); }
1639
- polygons[data.name] = rightmenu(polyarea);
1641
+ polygons[data["name"]] = rightmenu(polyarea);
1640
1642
  }
1641
1643
  // Draw Great circles
1642
1644
  if (data.hasOwnProperty("greatcircle") && Array.isArray(data.greatcircle) && data.greatcircle.length === 2) {
@@ -1646,14 +1648,14 @@ function setMarker(data) {
1646
1648
  if (!data.hasOwnProperty("opacity")) { opt.opacity = 0.8; }
1647
1649
  var greatc = L.Polyline.Arc(data.greatcircle[0], data.greatcircle[1], opt);
1648
1650
  var aml = new L.Wrapped.Polyline(greatc._latlngs, opt);
1649
- polygons[data.name] = rightmenu(aml);
1651
+ polygons[data["name"]] = rightmenu(aml);
1650
1652
  }
1651
1653
  // Draw error ellipses
1652
1654
  else if (data.hasOwnProperty("sdlat") && data.hasOwnProperty("sdlon")) {
1653
1655
  if (!data.hasOwnProperty("iconColor")) { opt.color = "blue"; } //different standard Color Settings
1654
1656
  if (!data.hasOwnProperty("fillColor")) { opt.fillColor = "blue"; }
1655
1657
  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);
1656
- polygons[data.name] = rightmenu(ellipse);
1658
+ polygons[data["name"]] = rightmenu(ellipse);
1657
1659
  }
1658
1660
  // Draw circles and ellipses
1659
1661
  else if (data.hasOwnProperty("radius")) {
@@ -1665,7 +1667,7 @@ function setMarker(data) {
1665
1667
  else {
1666
1668
  polycirc = L.circle(new L.LatLng((data.lat*1), (data.lon*1)), data.radius*1, opt);
1667
1669
  }
1668
- polygons[data.name] = rightmenu(polycirc);
1670
+ polygons[data["name"]] = rightmenu(polycirc);
1669
1671
  if (!data.hasOwnProperty("icon")) {
1670
1672
  delete (data.lat);
1671
1673
  delete (data.lon);
@@ -1675,34 +1677,34 @@ function setMarker(data) {
1675
1677
  // Draw arcs (and range rings)
1676
1678
  else if (data.hasOwnProperty("arc")) {
1677
1679
  if (data.hasOwnProperty("lat") && data.hasOwnProperty("lon")) {
1678
- polygons[data.name] = rangerings(new L.LatLng((data.lat*1), (data.lon*1)), data.arc);
1680
+ polygons[data["name"]] = rangerings(new L.LatLng((data.lat*1), (data.lon*1)), data.arc);
1679
1681
  }
1680
1682
  }
1681
1683
  // Draw a geojson "shape"
1682
1684
  else if (data.hasOwnProperty("geojson")) {
1683
- doGeojson(data.name,data.geojson,(data.layer || "unknown"),opt);
1685
+ doGeojson(data["name"],data.geojson,(data.layer || "unknown"),opt);
1684
1686
  }
1685
1687
 
1686
1688
  // If we created a shape then apply some generic things to it
1687
- if (polygons[data.name] !== undefined) {
1689
+ if (polygons[data["name"]] !== undefined) {
1688
1690
  // Set the layer
1689
- polygons[data.name].lay = lay;
1691
+ polygons[data["name"]].lay = lay;
1690
1692
  // if clickable then add popup
1691
1693
  if (opt.clickable === true) {
1692
- var words = "<b>"+data.name+"</b>";
1694
+ var words = "<b>"+data["name"]+"</b>";
1693
1695
  if (data.popup) { words = words + "<br/>" + data.popup; }
1694
- polygons[data.name].bindPopup(words, {autoClose:false, closeButton:true, closeOnClick:true, minWidth:200});
1696
+ polygons[data["name"]].bindPopup(words, {autoClose:false, closeButton:true, closeOnClick:true, minWidth:200});
1695
1697
  }
1696
1698
  // add a tooltip (if supplied)
1697
- if (data.hasOwnProperty("tooltip")) { polygons[data.name].bindTooltip(data.tooltip); }
1699
+ if (data.hasOwnProperty("tooltip")) { polygons[data["name"]].bindTooltip(data.tooltip); }
1698
1700
  // add to the layers
1699
- layers[lay].addLayer(polygons[data.name]);
1701
+ layers[lay].addLayer(polygons[data["name"]]);
1700
1702
  // fly or fit to the bounds if required
1701
1703
  if (data.hasOwnProperty("fly") && data.fly === true) {
1702
- map.flyToBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1704
+ map.flyToBounds(polygons[data["name"]].getBounds(),{padding:[50,50]})
1703
1705
  }
1704
1706
  else if (data.hasOwnProperty("fit") && data.fit === true) {
1705
- map.fitBounds(polygons[data.name].getBounds(),{padding:[50,50]})
1707
+ map.fitBounds(polygons[data["name"]].getBounds(),{padding:[50,50]})
1706
1708
  }
1707
1709
  }
1708
1710
 
@@ -1733,7 +1735,7 @@ function setMarker(data) {
1733
1735
 
1734
1736
  if (ll.lat === 0 && ll.lng === 0) {
1735
1737
  // Add a little wobble so we can zoom into each if required.
1736
- console.log(data.name,"is at null island.");
1738
+ console.log(data["name"],"is at null island.");
1737
1739
  ll.lat = Math.round(1000000 * ll.lat + Math.random() * 10000 - 5000) / 1000000;
1738
1740
  ll.lng = Math.round(1000000 * ll.lng + Math.random() * 10000 - 5000) / 1000000;
1739
1741
  }
@@ -1757,11 +1759,11 @@ function setMarker(data) {
1757
1759
  var dir = parseFloat(data.track ?? data.hdg ?? data.heading ?? data.bearing ?? "0") + map.getBearing();
1758
1760
  if (data.icon === "ship") {
1759
1761
  marker = L.boatMarker(ll, {
1760
- title: data.name,
1762
+ title: data["name"],
1761
1763
  color: (data.iconColor ?? "#5DADE2")
1762
1764
  });
1763
1765
  marker.setHeading(dir);
1764
- q = 'https://www.bing.com/images/search?q='+data.icon+'%20%2B"'+encodeURIComponent(data.name)+'"';
1766
+ q = 'https://www.bing.com/images/search?q='+data.icon+'%20%2B"'+encodeURIComponent(data["name"])+'"';
1765
1767
  words += '<a href=\''+q+'\' target="_thingpic">Pictures</a><br>';
1766
1768
  }
1767
1769
  else if (data.icon === "plane") {
@@ -1779,7 +1781,7 @@ function setMarker(data) {
1779
1781
  iconAnchor: [16, 16],
1780
1782
  html:'<img src="'+svgplane+'" style="width:32px; height:32px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>'
1781
1783
  });
1782
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1784
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1783
1785
  }
1784
1786
  else if (data.icon === "smallplane") {
1785
1787
  data.iconColor = data.iconColor ?? "black";
@@ -1791,7 +1793,7 @@ function setMarker(data) {
1791
1793
  iconAnchor: [16, 16],
1792
1794
  html:'<img src="'+svgplane+'" style="width:32px; height:32px; -webkit-transform:rotate('+(dir - 45)+'deg); -moz-transform:rotate('+(dir - 45)+'deg);"/>'
1793
1795
  });
1794
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1796
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1795
1797
  }
1796
1798
  else if (data.icon === "bus") {
1797
1799
  dir = dir - 90;
@@ -1807,7 +1809,7 @@ function setMarker(data) {
1807
1809
  iconAnchor: [16, 16],
1808
1810
  html:'<img src="'+svgbus+'" style="width:32px; height:32px; -webkit-transform:scaleY('+sc+') rotate('+dir*sc+'deg); -moz-transform:scaleY('+sc+') rotate('+dir*sc+'deg);"/>'
1809
1811
  });
1810
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1812
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1811
1813
  }
1812
1814
  else if (data.icon === "helicopter") {
1813
1815
  data.iconColor = data.iconColor ?? "black";
@@ -1824,7 +1826,7 @@ function setMarker(data) {
1824
1826
  iconAnchor: [16, 16],
1825
1827
  html:'<img src="'+svgheli+'" style="width:32px; height:32px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>'
1826
1828
  });
1827
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1829
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1828
1830
  }
1829
1831
  else if (data.icon === "uav") {
1830
1832
  data.iconColor = data.iconColor || "black";
@@ -1841,7 +1843,19 @@ function setMarker(data) {
1841
1843
  iconAnchor: [16, 16],
1842
1844
  html:'<img src="'+svguav+'" style="width:32px; height:32px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
1843
1845
  });
1844
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1846
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1847
+ }
1848
+ else if (data.icon === "quad") {
1849
+ data.iconColor = data.iconColor || "black";
1850
+ icon = '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 22 22">';
1851
+ icon+= '<path d="m6 3a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 1.0859375-.2070312c.5392711.8209481.9140625 1.6424172.9140625 2.2070312 0 .563623-.3724493 1.384498-.9101562 2.205078a3 3 0 0 0 -1.0898438-.205078 3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0 -.2050781-1.080078c.8233483-.542436 1.6446221-.919922 2.2050781-.919922.55949 0 1.37815.375313 2.201172.916016a3 3 0 0 0 -.201172 1.083984 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0 -3-3 3 3 0 0 0 -1.085938.207031c-.539273-.820943-.914062-1.642417-.914062-2.207031 0-.563623.372445-1.3844956.910156-2.2050781a3 3 0 0 0 .002.00195 3 3 0 0 0 1.087844.2031281 3 3 0 0 0 3-3 3 3 0 0 0 -3-3 3 3 0 0 0 -3 3 3 3 0 0 0 .205078 1.0800781c-.823351.5424443-1.644622.9199219-2.205078.9199219-.55949 0-1.3781473-.3753084-2.2011719-.9160156a3 3 0 0 0 .2011719-1.0839844 3 3 0 0 0 -3-3zm0 1a2 2 0 0 1 2 2 2 2 0 0 1 -.0527344.453125c-.4577913-.368834-.8926099-.7589139-1.2402344-1.1601562a1 1 0 0 0 -.6933593-.2929688 1 1 0 0 0 -.7207031.2929688 1 1 0 0 0 0 1.4140624 1 1 0 0 0 .058594.054688c.3824613.333788.7551689.7476371 1.1074216 1.1835933a2 2 0 0 1 -.4589844.0546875 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm10 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -.457031-.054687c.37051-.4592027.761959-.8951713 1.164062-1.2382813a1 1 0 0 0 0-1.4140624 1 1 0 0 0 -1.414062 0 1 1 0 0 0 -.05274.054687c-.337606.3818392-.750702.7543351-1.185541 1.1054687a2 2 0 0 1 -.054688-.453125 2 2 0 0 1 2-2zm-10 10a2 2 0 0 1 .4570312.05469c-.3705108.459203-.7619484.895165-1.1640624 1.238281a1 1 0 0 0 0 1.414062 1 1 0 0 0 1.4140624 0 1 1 0 0 0 .052734-.05469c.3376223-.381857.7507063-.754333 1.1855473-1.105468a2 2 0 0 1 .0546875.453125 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 2-2zm10 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2-2 2 2 0 0 1 .05273-.453125c.457792.368835.892604.758903 1.240235 1.160156a1 1 0 0 0 1.414062 0 1 1 0 0 0 0-1.414062c-.01717-.01465-.0336-.03387-.05078-.04883a1 1 0 0 0 -.0078-.0059c-.382475-.333732-.755177-.747602-1.107431-1.183551a2 2 0 0 1 .458984-.054688z" fill="'+data.iconColor+'"/></svg>';
1852
+ var svgquad = "data:image/svg+xml;base64," + btoa(icon);
1853
+ myMarker = L.divIcon({
1854
+ className:"quadicon",
1855
+ iconAnchor: [16, 16],
1856
+ html:'<img src="'+svgquad+'" style="width:32px; height:32px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
1857
+ });
1858
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1845
1859
  }
1846
1860
  else if (data.icon === "car") {
1847
1861
  data.iconColor = data.iconColor || "black";
@@ -1853,7 +1867,7 @@ function setMarker(data) {
1853
1867
  iconAnchor: [16, 16],
1854
1868
  html:'<img src="'+svgcar+'" style="width:32px; height:32px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
1855
1869
  });
1856
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1870
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1857
1871
  }
1858
1872
  else if (data.icon === "sensor") {
1859
1873
  data.iconColor = data.iconColor || "#F39C12";
@@ -1864,7 +1878,7 @@ function setMarker(data) {
1864
1878
  iconAnchor: [12, 12],
1865
1879
  html:'<img src="'+svgcam+'" style="width:24px; height:24px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
1866
1880
  });
1867
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1881
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1868
1882
  }
1869
1883
  else if (data.icon === "arrow") {
1870
1884
  data.iconColor = data.iconColor || "black";
@@ -1876,7 +1890,7 @@ function setMarker(data) {
1876
1890
  iconAnchor: [16, 16],
1877
1891
  html:"'<img src='"+svgarrow+"' style='width:32px; height:32px; -webkit-transform:translate(0px,-16px) rotate("+dir+"deg); -moz-transform:translate(0px,-16px) rotate("+dir+"deg);'/>",
1878
1892
  });
1879
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1893
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1880
1894
  }
1881
1895
  else if (data.icon === "wind") {
1882
1896
  data.iconColor = data.iconColor || "black";
@@ -1888,7 +1902,7 @@ function setMarker(data) {
1888
1902
  iconAnchor: [16, 16],
1889
1903
  html:'<img src="'+svgwind+'" style="width:32px; height:32px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
1890
1904
  });
1891
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1905
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1892
1906
  }
1893
1907
  else if (data.icon === "satellite") {
1894
1908
  data.iconColor = data.iconColor || "black";
@@ -1905,7 +1919,7 @@ function setMarker(data) {
1905
1919
  iconAnchor: [16, 16],
1906
1920
  html:'<img src="'+svgsat+'" style="width:32px; height:32px;"/>',
1907
1921
  });
1908
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1922
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1909
1923
  }
1910
1924
  else if ((data.icon === "iss") || (data.icon === "ISS")) {
1911
1925
  data.iconColor = data.iconColor || "black";
@@ -1921,7 +1935,7 @@ function setMarker(data) {
1921
1935
  iconAnchor: [25, 25],
1922
1936
  html:'<img src="'+svgiss+'" style="width:50px; height:50px;"/>',
1923
1937
  });
1924
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1938
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1925
1939
  }
1926
1940
  else if (data.icon === "mayflower") {
1927
1941
  data.iconColor = data.iconColor || "#910000";
@@ -1933,7 +1947,7 @@ function setMarker(data) {
1933
1947
  iconAnchor: [12, 24],
1934
1948
  html:'<img src="'+svgmay+'" style="width:24px; height:48px; -webkit-transform:rotate('+dir+'deg); -moz-transform:rotate('+dir+'deg);"/>',
1935
1949
  });
1936
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1950
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1937
1951
  }
1938
1952
  else if (data.icon === "locate") {
1939
1953
  data.iconColor = data.iconColor || "#00ffff";
@@ -1950,26 +1964,26 @@ function setMarker(data) {
1950
1964
  iconAnchor: [16, 16],
1951
1965
  html:'<img src="'+svglocate+'" style="width:32px; height:32px;"/>',
1952
1966
  });
1953
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1967
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1954
1968
  labelOffset = [12,-4];
1955
1969
  }
1956
1970
  else if (data.icon === "friend") {
1957
- marker = L.marker(ll, { icon: L.divIcon({ className: 'circle f', iconSize: [20, 12] }), title: data.name, draggable:drag });
1971
+ marker = L.marker(ll, { icon: L.divIcon({ className: 'circle f', iconSize: [20, 12] }), title: data["name"], draggable:drag });
1958
1972
  }
1959
1973
  else if (data.icon === "hostile") {
1960
- marker = L.marker(ll, { icon: L.divIcon({ className: 'circle h', iconSize: [16, 16] }), title: data.name, draggable:drag });
1974
+ marker = L.marker(ll, { icon: L.divIcon({ className: 'circle h', iconSize: [16, 16] }), title: data["name"], draggable:drag });
1961
1975
  }
1962
1976
  else if (data.icon === "neutral") {
1963
- marker = L.marker(ll, { icon: L.divIcon({ className: 'circle n', iconSize: [16, 16] }), title: data.name, draggable:drag });
1977
+ marker = L.marker(ll, { icon: L.divIcon({ className: 'circle n', iconSize: [16, 16] }), title: data["name"], draggable:drag });
1964
1978
  }
1965
1979
  else if (data.icon === "unknown") {
1966
- marker = L.marker(ll, { icon: L.divIcon({ className: 'circle', iconSize: [16, 16] }), title: data.name, draggable:drag });
1980
+ marker = L.marker(ll, { icon: L.divIcon({ className: 'circle', iconSize: [16, 16] }), title: data["name"], draggable:drag });
1967
1981
  }
1968
1982
  else if (data.icon === "danger") {
1969
- marker = L.marker(ll, { icon: L.divIcon({ className: 'up-triangle' }), title: data.name, draggable:drag });
1983
+ marker = L.marker(ll, { icon: L.divIcon({ className: 'up-triangle' }), title: data["name"], draggable:drag });
1970
1984
  }
1971
1985
  else if (data.icon === "earthquake") {
1972
- marker = L.marker(ll, { icon: L.divIcon({ className: 'circle e', iconSize: [data.mag*5, data.mag*5] }), title: data.name, draggable:drag });
1986
+ marker = L.marker(ll, { icon: L.divIcon({ className: 'circle e', iconSize: [data.mag*5, data.mag*5] }), title: data["name"], draggable:drag });
1973
1987
  }
1974
1988
  else if (data.icon.match(/^:.*:$/g)) { // emoji icon :smile:
1975
1989
  var em = emojify(data.icon);
@@ -1979,7 +1993,7 @@ function setMarker(data) {
1979
1993
  html: '<center><span style="font-size:2em; color:'+col+'">'+em+'</span></center>',
1980
1994
  iconSize: [32, 32]
1981
1995
  });
1982
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
1996
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
1983
1997
  labelOffset = [12,-4];
1984
1998
  }
1985
1999
  else if (data.icon.match(/^https?:.*$|^\/|^data:image\//)) { // web url icon https://...
@@ -1990,7 +2004,7 @@ function setMarker(data) {
1990
2004
  iconAnchor: [sz/2, sz/2],
1991
2005
  popupAnchor: [0, -sz/2]
1992
2006
  });
1993
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag, rotationAngle:dir, rotationOrigin:"center"});
2007
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag, rotationAngle:dir, rotationOrigin:"center"});
1994
2008
  labelOffset = [sz/2-4,-4];
1995
2009
  delete data.iconSize;
1996
2010
  }
@@ -2005,7 +2019,7 @@ function setMarker(data) {
2005
2019
  iconAnchor: [16, 12],
2006
2020
  popupAnchor: [0, -16]
2007
2021
  });
2008
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
2022
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
2009
2023
  labelOffset = [8,-8];
2010
2024
  }
2011
2025
  else if (data.icon.substr(0,3) === "wi-") { // weather icon
@@ -2019,7 +2033,7 @@ function setMarker(data) {
2019
2033
  iconAnchor: [16, 16],
2020
2034
  popupAnchor: [0, -16]
2021
2035
  });
2022
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
2036
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
2023
2037
  labelOffset = [16,-16];
2024
2038
  }
2025
2039
  else {
@@ -2029,13 +2043,13 @@ function setMarker(data) {
2029
2043
  prefix: 'fa',
2030
2044
  iconColor: 'white'
2031
2045
  });
2032
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
2046
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
2033
2047
  labelOffset = [6,-6];
2034
2048
  }
2035
2049
  }
2036
2050
  else if (data.hasOwnProperty("SIDC")) { // NATO mil2525 icons
2037
2051
  // "SIDC":"SFGPU------E***","name":"1.C2 komp","fullname":"1.C2 komp/FTS/INSS"
2038
- myMarker = new ms.Symbol( data.SIDC.toUpperCase(), { uniqueDesignation:unescape(encodeURIComponent(data.name)) });
2052
+ myMarker = new ms.Symbol( data.SIDC.toUpperCase(), { uniqueDesignation:unescape(encodeURIComponent(data["name"])) });
2039
2053
  // Now that we have a symbol we can ask for the echelon and set the symbol size
2040
2054
  var opts = data.options || {};
2041
2055
  var sz = 25;
@@ -2059,7 +2073,7 @@ function setMarker(data) {
2059
2073
  iconAnchor: [myMarker.getAnchor().x, myMarker.getAnchor().y],
2060
2074
  className: "natoicon",
2061
2075
  });
2062
- marker = L.marker(ll, { title:data.name, icon:myicon, draggable:drag });
2076
+ marker = L.marker(ll, { title:data["name"], icon:myicon, draggable:drag });
2063
2077
  edgeAware();
2064
2078
  delete data.options;
2065
2079
  }
@@ -2070,10 +2084,10 @@ function setMarker(data) {
2070
2084
  prefix: 'fa',
2071
2085
  iconColor: 'white'
2072
2086
  });
2073
- marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag});
2087
+ marker = L.marker(ll, {title:data["name"], icon:myMarker, draggable:drag});
2074
2088
  labelOffset = [6,-6];
2075
2089
  }
2076
- marker.name = data.name;
2090
+ marker.name = data["name"];
2077
2091
 
2078
2092
  // var createLabelIcon = function(labelText) {
2079
2093
  // return L.marker(new L.LatLng(51.05, -1.35), {icon:L.divIcon({ html:labelText })});
@@ -2195,7 +2209,7 @@ function setMarker(data) {
2195
2209
  // If .label then use that rather than name tooltip
2196
2210
  if (data.label) {
2197
2211
  if (typeof data.label === "boolean" && data.label === true) {
2198
- marker.bindTooltip(data.name, { permanent:true, direction:"right", offset:labelOffset });
2212
+ marker.bindTooltip(data["name"], { permanent:true, direction:"right", offset:labelOffset });
2199
2213
  }
2200
2214
  else if (typeof data.label === "string" && data.label.length > 0) {
2201
2215
  marker.bindTooltip(data.label, { permanent:true, direction:"right", offset:labelOffset });
@@ -2253,13 +2267,22 @@ function setMarker(data) {
2253
2267
  words += '<tr><td>lat, lon</td><td>'+ marker.getLatLng().toString().replace('LatLng(','').replace(')','') + '</td></tr>';
2254
2268
  words += '</table>';
2255
2269
  }
2256
- 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;
2270
+ 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;
2257
2271
  var wopt = {autoClose:false, closeButton:true, closeOnClick:false, minWidth:200};
2258
2272
  if (words.indexOf('<video ') >=0 || words.indexOf('<img ') >=0 ) { wopt.maxWidth="640"; } // make popup wider if it has an image or video
2259
2273
  if (!data.hasOwnProperty("clickable") && data.clickable != false) {
2260
2274
  marker.bindPopup(words, wopt);
2261
- marker._popup.dname = data.name;
2275
+ marker._popup.dname = data["name"];
2262
2276
  }
2277
+
2278
+ if (data.hasOwnProperty("clickURL")) {
2279
+ marker.on('click', function () {
2280
+ console.log("Click URL - ",data.clickURL)
2281
+ window.open(data.clickURL.replace('@',''), 'newwindow', 'width=640, height=480');
2282
+ return false;
2283
+ });
2284
+ }
2285
+
2263
2286
  marker.lay = lay; // and the layer it is on
2264
2287
 
2265
2288
  // marker.on('click', function(e) {
@@ -2271,7 +2294,7 @@ function setMarker(data) {
2271
2294
  if (heat && ((data.addtoheatmap != false) || (!data.hasOwnProperty("addtoheatmap")))) { // Added to give ability to control if points from active layer contribute to heatmap
2272
2295
  if (heatAll || map.hasLayer(layers[lay])) { heat.addLatLng(lli); }
2273
2296
  }
2274
- markers[data.name] = marker;
2297
+ markers[data["name"]] = marker;
2275
2298
  layers[lay].addLayer(marker);
2276
2299
 
2277
2300
  // var track;
@@ -2294,11 +2317,11 @@ function setMarker(data) {
2294
2317
  else if ( re3.test(""+data.speed) ) { data.length = data.length * 0.44704; }
2295
2318
  }
2296
2319
  if (data.length !== undefined) {
2297
- if (polygons[data.name] != null && !polygons[data.name].hasOwnProperty("_layers")) {
2298
- map.removeLayer(polygons[data.name]);
2320
+ if (polygons[data["name"]] != null && !polygons[data["name"]].hasOwnProperty("_layers")) {
2321
+ map.removeLayer(polygons[data["name"]]);
2299
2322
  }
2300
- if (polygons[data.name] != null && polygons[data.name].hasOwnProperty("name") ) {
2301
- delete(layers[lay]._layers[polygons[data.name]._leaflet_id]);
2323
+ if (polygons[data["name"]] != null && polygons[data["name"]].hasOwnProperty("name") ) {
2324
+ delete(layers[lay]._layers[polygons[data["name"]]._leaflet_id]);
2302
2325
  }
2303
2326
  var x = ll.lng * 1; // X coordinate
2304
2327
  var y = ll.lat * 1; // Y coordinate
@@ -2328,14 +2351,14 @@ function setMarker(data) {
2328
2351
  polygon.setStyle({opacity:0});
2329
2352
  }
2330
2353
  }
2331
- polygon.name = data.name;
2332
- if (polygons[data.name] != null && polygons[data.name].hasOwnProperty("_layers")) {
2333
- polygons[data.name].addLayer(polygon);
2354
+ polygon.name = data["name"];
2355
+ if (polygons[data["name"]] != null && polygons[data["name"]].hasOwnProperty("_layers")) {
2356
+ polygons[data["name"]].addLayer(polygon);
2334
2357
  }
2335
2358
  else {
2336
- polygons[data.name] = polygon;
2359
+ polygons[data["name"]] = polygon;
2337
2360
  }
2338
- polygons[data.name].lay = lay;
2361
+ polygons[data["name"]].lay = lay;
2339
2362
  layers[lay].addLayer(polygon);
2340
2363
  }
2341
2364
  }