node-red-contrib-web-worldmap 2.17.3 → 2.21.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +7 -0
  3. package/node_modules/@turf/bezier-spline/dist/es/index.js +7 -3
  4. package/node_modules/@turf/bezier-spline/dist/es/lib/spline.js +0 -0
  5. package/node_modules/@turf/bezier-spline/dist/js/index.d.ts +0 -0
  6. package/node_modules/@turf/bezier-spline/dist/js/index.js +7 -3
  7. package/node_modules/@turf/bezier-spline/dist/js/lib/spline.d.ts +1 -1
  8. package/node_modules/@turf/bezier-spline/dist/js/lib/spline.js +0 -0
  9. package/node_modules/@turf/bezier-spline/package.json +23 -19
  10. package/node_modules/@turf/helpers/dist/es/index.js +2 -2
  11. package/node_modules/@turf/helpers/dist/es/lib/geojson.js +0 -0
  12. package/node_modules/@turf/helpers/dist/js/index.d.ts +1 -1
  13. package/node_modules/@turf/helpers/dist/js/index.js +2 -2
  14. package/node_modules/@turf/helpers/dist/js/lib/geojson.d.ts +0 -0
  15. package/node_modules/@turf/helpers/dist/js/lib/geojson.js +0 -0
  16. package/node_modules/@turf/helpers/package.json +22 -18
  17. package/node_modules/@turf/invariant/dist/es/index.js +0 -0
  18. package/node_modules/@turf/invariant/dist/js/index.d.ts +0 -0
  19. package/node_modules/@turf/invariant/dist/js/index.js +0 -0
  20. package/node_modules/@turf/invariant/package.json +22 -18
  21. package/node_modules/accepts/package.json +13 -10
  22. package/node_modules/array-flatten/package.json +8 -5
  23. package/node_modules/body-parser/node_modules/bytes/package.json +8 -5
  24. package/node_modules/body-parser/package.json +8 -5
  25. package/node_modules/bufferjs/package.json +13 -10
  26. package/node_modules/bufferlist/package.json +13 -13
  27. package/node_modules/cgi/package.json +7 -4
  28. package/node_modules/compressible/package.json +4 -4
  29. package/node_modules/compression/node_modules/bytes/package.json +4 -4
  30. package/node_modules/compression/package.json +12 -9
  31. package/node_modules/content-disposition/package.json +8 -5
  32. package/node_modules/content-type/package.json +13 -10
  33. package/node_modules/cookie/package.json +8 -5
  34. package/node_modules/cookie-signature/package.json +8 -5
  35. package/node_modules/debug/package.json +13 -10
  36. package/node_modules/depd/package.json +13 -10
  37. package/node_modules/destroy/package.json +13 -10
  38. package/node_modules/ee-first/package.json +8 -5
  39. package/node_modules/encodeurl/package.json +13 -10
  40. package/node_modules/escape-html/package.json +13 -10
  41. package/node_modules/etag/package.json +13 -10
  42. package/node_modules/express/package.json +12 -9
  43. package/node_modules/extend/package.json +13 -10
  44. package/node_modules/faye-websocket/package.json +13 -10
  45. package/node_modules/finalhandler/package.json +13 -10
  46. package/node_modules/forwarded/package.json +13 -10
  47. package/node_modules/fresh/package.json +8 -5
  48. package/node_modules/header-stack/package.json +13 -10
  49. package/node_modules/header-stack/parser.js +2 -2
  50. package/node_modules/http-errors/package.json +8 -5
  51. package/node_modules/iconv-lite/package.json +8 -5
  52. package/node_modules/inherits/package.json +8 -5
  53. package/node_modules/ipaddr.js/package.json +4 -4
  54. package/node_modules/media-typer/package.json +8 -5
  55. package/node_modules/merge-descriptors/package.json +8 -5
  56. package/node_modules/methods/package.json +13 -10
  57. package/node_modules/mime/package.json +8 -5
  58. package/node_modules/mime-db/package.json +5 -5
  59. package/node_modules/mime-types/package.json +5 -5
  60. package/node_modules/ms/package.json +8 -5
  61. package/node_modules/negotiator/package.json +8 -5
  62. package/node_modules/on-finished/package.json +13 -10
  63. package/node_modules/on-headers/package.json +13 -10
  64. package/node_modules/parseurl/package.json +13 -10
  65. package/node_modules/path-to-regexp/package.json +8 -5
  66. package/node_modules/proxy-addr/package.json +4 -4
  67. package/node_modules/qs/package.json +8 -5
  68. package/node_modules/range-parser/package.json +13 -10
  69. package/node_modules/raw-body/node_modules/bytes/package.json +8 -5
  70. package/node_modules/raw-body/package.json +8 -5
  71. package/node_modules/safe-buffer/package.json +8 -5
  72. package/node_modules/safer-buffer/package.json +13 -10
  73. package/node_modules/send/node_modules/ms/package.json +8 -5
  74. package/node_modules/send/package.json +8 -5
  75. package/node_modules/serve-static/package.json +8 -5
  76. package/node_modules/setprototypeof/package.json +8 -5
  77. package/node_modules/sockjs/package.json +12 -9
  78. package/node_modules/statuses/package.json +13 -10
  79. package/node_modules/stream-stack/package.json +13 -10
  80. package/node_modules/toidentifier/package.json +8 -5
  81. package/node_modules/type-is/package.json +13 -10
  82. package/node_modules/unpipe/package.json +8 -5
  83. package/node_modules/utils-merge/package.json +8 -5
  84. package/node_modules/uuid/package.json +13 -10
  85. package/node_modules/vary/package.json +13 -10
  86. package/node_modules/websocket-driver/lib/websocket/driver/base.js +2 -0
  87. package/node_modules/websocket-driver/node_modules/http-parser-js/package.json +4 -4
  88. package/node_modules/websocket-driver/package.json +13 -10
  89. package/node_modules/websocket-extensions/package.json +13 -10
  90. package/package.json +3 -3
  91. package/worldmap/index.html +1 -0
  92. package/worldmap/leaflet/VectorTileLayer.umd.min.js +4 -0
  93. package/worldmap/leaflet/leaflet.css +13 -8
  94. package/worldmap/leaflet/leaflet.js +4 -3
  95. package/worldmap/leaflet/leaflet.js.map +1 -0
  96. package/worldmap/leaflet/leaflet.latlng-graticule.js +23 -21
  97. package/worldmap/worldmap.js +433 -365
  98. package/worldmap.html +206 -107
  99. package/worldmap.js +23 -7
@@ -24,6 +24,7 @@ var showUserMenu = true;
24
24
  var showLayerMenu = true;
25
25
  var showMouseCoords = false;
26
26
  var allowFileDrop = false;
27
+ var heat;
27
28
  var minimap;
28
29
  var sidebyside;
29
30
  var layercontrol;
@@ -46,34 +47,6 @@ var iconSz = {
46
47
  "Command": 44
47
48
  };
48
49
 
49
- // Polyfill assign for IE11 for now
50
- if (typeof Object.assign !== 'function') {
51
- // Must be writable: true, enumerable: false, configurable: true
52
- Object.defineProperty(Object, "assign", {
53
- value: function assign(target, varArgs) { // .length of function is 2
54
- 'use strict';
55
- if (target === null || target === undefined) {
56
- throw new TypeError('Cannot convert undefined or null to object');
57
- }
58
- var to = Object(target);
59
- for (var index = 1; index < arguments.length; index++) {
60
- var nextSource = arguments[index];
61
- if (nextSource !== null && nextSource !== undefined) {
62
- for (var nextKey in nextSource) {
63
- // Avoid bugs when hasOwnProperty is shadowed
64
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
65
- to[nextKey] = nextSource[nextKey];
66
- }
67
- }
68
- }
69
- }
70
- return to;
71
- },
72
- writable: true,
73
- configurable: true
74
- });
75
- }
76
-
77
50
  // Create the socket
78
51
  var connect = function() {
79
52
  // var transports = ["websocket", "xhr-streaming", "xhr-polling"],
@@ -94,7 +67,11 @@ var connect = function() {
94
67
  setTimeout(function() { connect(); }, 2500);
95
68
  };
96
69
  ws.onmessage = function(e) {
97
- try { var data = JSON.parse(e.data); handleData(data); }
70
+ try {
71
+ var data = JSON.parse(e.data);
72
+ if (data.hasOwnProperty("type") && data.hasOwnProperty("data") && data.type === "Buffer") { data = data.data.toString(); }
73
+ handleData(data);
74
+ }
98
75
  catch (e) { if (data) { console.log("BAD DATA",data); } }
99
76
  // console.log("DATA",typeof data,data);
100
77
  };
@@ -136,7 +113,9 @@ var handleData = function(data) {
136
113
  if (data.hasOwnProperty("type") && data.type.indexOf("Feature") === 0) { doGeojson("geojson",data); }
137
114
  else if (data.hasOwnProperty("name")) { setMarker(data); }
138
115
  else {
139
- console.log("SKIP",data);
116
+ if (JSON.stringify(data) !== '{}') {
117
+ console.log("SKIP",data);
118
+ }
140
119
  // if (typeof data === "string") { doDialog(data); }
141
120
  // else { console.log("SKIP",data); }
142
121
  }
@@ -434,7 +413,7 @@ setMaxAge();
434
413
 
435
414
  // move the daylight / nighttime boundary (if enabled) every minute
436
415
  function moveTerminator() { // if terminator line plotted move it every minute
437
- if (layers["_daynight"].getLayers().length > 0) {
416
+ if (layers["_daynight"] && layers["_daynight"].getLayers().length > 0) {
438
417
  layers["_daynight"].clearLayers();
439
418
  layers["_daynight"].addLayer(L.terminator());
440
419
  }
@@ -614,7 +593,7 @@ map.on('baselayerchange', function(e) {
614
593
  });
615
594
 
616
595
  function showMapCurrentZoom() {
617
- console.log("zoom:",map.getZoom(),". clusterAt:",clusterAt);
596
+ //console.log("zoom:",map.getZoom());
618
597
  for (var l in layers) {
619
598
  if (layers[l].hasOwnProperty("_zoom")) {
620
599
  if (map.getZoom() >= clusterAt) {
@@ -655,9 +634,13 @@ function showMapCurrentZoom() {
655
634
  map.on('zoomend', function() {
656
635
  showMapCurrentZoom();
657
636
  window.localStorage.setItem("lastzoom", map.getZoom());
637
+ var b = map.getBounds();
638
+ ws.send(JSON.stringify({action:"bounds", south:b._southWest.lat, west:b._southWest.lng, north:b._northEast.lat, east:b._northEast.lng }));
658
639
  });
659
640
  map.on('moveend', function() {
660
641
  window.localStorage.setItem("lastpos",JSON.stringify(map.getCenter()));
642
+ var b = map.getBounds();
643
+ ws.send(JSON.stringify({action:"bounds", south:b._southWest.lat, west:b._southWest.lng, north:b._northEast.lat, east:b._northEast.lng }));
661
644
  });
662
645
 
663
646
  //map.on('contextmenu', function(e) {
@@ -747,378 +730,453 @@ map.on('contextmenu', function(e) {
747
730
  }
748
731
  });
749
732
 
750
- // Add all the base layer maps
751
- if (navigator.onLine) {
733
+ // Add all the base layer maps if we are online.
734
+ var addBaseMaps = function(maplist,first) {
735
+ //console.log("MAPS",first,maplist)
736
+ if (navigator.onLine) {
737
+ var layerlookup = { OSMG:"OSM grey", OSMC:"OSM", OSMH:"OSM Humanitarian", EsriC:"Esri", EsriS:"Esri Satellite",
738
+ EsriT:"Esri Topography", EsriO:"Esri Ocean", EsriDG:"Esri Dark Grey", NatGeo: "National Geographic",
739
+ UKOS:"UK OS OpenData", UKOS45:"UK OS 1919-1947", UKOS00:"UK OS 1900", OpTop:"Open Topo Map",
740
+ HB:"Hike Bike OSM", ST:"Stamen Topography", SW: "Stamen Watercolor", AN:"AutoNavi (Chinese)" }
741
+
742
+ // Use this for OSM online maps
743
+ var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
744
+ var osmAttrib='Map data © OpenStreetMap contributors';
745
+
746
+ if (maplist.indexOf("OSMG")!==-1) {
747
+ basemaps[layerlookup["OSMG"]] = new L.TileLayer.Grayscale(osmUrl, {
748
+ attribution:osmAttrib,
749
+ maxNativeZoom:19,
750
+ maxZoom:20,
751
+ subdomains: ['a','b','c']
752
+ });
753
+ }
754
+ if (maplist.indexOf("OSMC")!==-1) {
755
+ basemaps[layerlookup["OSMC"]] = new L.TileLayer(osmUrl, {
756
+ attribution:osmAttrib,
757
+ maxNativeZoom:19,
758
+ maxZoom:20,
759
+ subdomains: ['a','b','c']
760
+ });
761
+ }
762
+ if (maplist.indexOf("OSMH")!==-1) {
763
+ basemaps[layerlookup["OSMH"]] = new L.TileLayer("https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", {
764
+ attribution:"Map data © OpenStreetMap Contributors. Courtesy of Humanitarian OpenStreetMap Team",
765
+ maxNativeZoom:19,
766
+ maxZoom:20,
767
+ subdomains: ['a','b']
768
+ });
769
+ }
752
770
 
753
- // Use this for OSM online maps
754
- var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
755
- //var osmUrl='https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png';
756
- var osmAttrib='Map data © OpenStreetMap contributors';
757
- var osmg = new L.TileLayer.Grayscale(osmUrl, {attribution:osmAttrib, maxNativeZoom:19, maxZoom:20});
758
- basemaps["OSM grey"] = osmg;
771
+ // Extra Leaflet map layers from https://leaflet-extras.github.io/leaflet-providers/preview/
772
+ if (maplist.indexOf("EsriC")!==-1) {
773
+ basemaps[layerlookup["EsriC"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
774
+ attribution:'Tiles &copy; Esri',
775
+ maxNativeZoom:19,
776
+ maxZoom:20
777
+ });
778
+ }
759
779
 
760
- var osm = new L.TileLayer(osmUrl, {attribution:osmAttrib, maxNativeZoom:19, maxZoom:20});
761
- basemaps["OSM"] = osm;
780
+ if (maplist.indexOf("EsriS")!==-1) {
781
+ basemaps[layerlookup["EsriS"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
782
+ //var Esri_WorldImagery = L.tileLayer('http://clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {{
783
+ attribution:'Tiles &copy; Esri',
784
+ maxNativeZoom:17, maxZoom:20
785
+ });
786
+ }
762
787
 
763
- // Extra Leaflet map layers from https://leaflet-extras.github.io/leaflet-providers/preview/
764
- var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
765
- attribution: 'Tiles &copy; Esri', maxNativeZoom:19, maxZoom:20
766
- });
767
- basemaps["Esri"] = Esri_WorldStreetMap;
788
+ if (maplist.indexOf("EsriT")!==-1) {
789
+ basemaps[layerlookup["EsriT"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
790
+ attribution:'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
791
+ });
792
+ }
768
793
 
769
- var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
770
- //var Esri_WorldImagery = L.tileLayer('http://clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
771
- attribution:'Tiles &copy; Esri', maxNativeZoom:17, maxZoom:20
772
- });
773
- basemaps["Esri Satellite"] = Esri_WorldImagery;
794
+ if (maplist.indexOf("EsriR")!==-1) {
795
+ basemaps[layerlookup["EsriR"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
796
+ attribution:'Tiles &copy; Esri',
797
+ maxNativeZoom:13
798
+ });
799
+ }
774
800
 
775
- var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
776
- attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
777
- });
778
- basemaps["Esri Topography"] = Esri_WorldTopoMap;
801
+ if (maplist.indexOf("EsriO")!==-1) {
802
+ basemaps[layerlookup["EsriO"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
803
+ attribution:'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
804
+ maxNativeZoom:13
805
+ });
806
+ }
779
807
 
780
- // var Esri_WorldShadedRelief = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
781
- // attribution: 'Tiles &copy; Esri',
782
- // maxNativeZoom:13
783
- // });
784
- // basemaps["Esri Terrain"] = Esri_WorldShadedRelief;
808
+ if (maplist.indexOf("EsriDG")!==-1) {
809
+ basemaps[layerlookup["EsriDG"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
810
+ attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
811
+ maxNativeZoom:13
812
+ });
813
+ }
785
814
 
786
- var Esri_OceanBasemap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
787
- attribution: 'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
788
- maxNativeZoom:13
789
- });
790
- basemaps["Esri Ocean"] = Esri_OceanBasemap;
815
+ if (maplist.indexOf("NatGeo")!==-1) {
816
+ basemaps[layerlookup["NatGeo"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
817
+ attribution: 'Tiles &copy; Esri',
818
+ maxNativeZoom:12
819
+ });
820
+ }
791
821
 
792
- var Esri_WorldGrayCanvas = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
793
- attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
794
- maxNativeZoom:13
795
- });
796
- basemaps["Esri Dark Grey"] = Esri_WorldGrayCanvas;
797
-
798
- // var OpenMapSurfer_Roads = L.tileLayer('https://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}', {
799
- // maxZoom: 18,
800
- // attribution: 'Imagery from <a href="https://giscience.uni-hd.de/">University of Heidelberg</a> &mdash; Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
801
- // });
802
- // basemaps["Mapsurfer"] = OpenMapSurfer_Roads;
803
-
804
- // var MapQuestOpen_OSM = L.tileLayer('https://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
805
- // type: 'map',
806
- // ext: 'jpg',
807
- // attribution: 'Tiles Courtesy of <a href="https://www.mapquest.com/">MapQuest</a> &mdash; Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
808
- // subdomains: '1234',
809
- // maxNativeZoom: 17
810
- // });
811
- //basemaps["MapQuest OSM"] = MapQuestOpen_OSM;
812
-
813
- var Esri_NatGeoWorldMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
814
- attribution: 'Tiles &copy; Esri',
815
- maxNativeZoom:12
816
- });
817
- basemaps["Nat Geo"] = Esri_NatGeoWorldMap;
822
+ if (maplist.indexOf("UKOS")!==-1) {
823
+ basemaps[layerlookup["UKOS"]] = L.tileLayer('https://geo.nls.uk/maps/opendata/{z}/{x}/{y}.png', {
824
+ attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
825
+ bounds: [[49.6, -12], [61.7, 3]],
826
+ minZoom:1, maxNativeZoom:17, maxZoom:20,
827
+ subdomains: '0123'
828
+ });
829
+ }
818
830
 
819
- var NLS_OS_opendata = L.tileLayer('https://geo.nls.uk/maps/opendata/{z}/{x}/{y}.png', {
820
- attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
821
- bounds: [[49.6, -12], [61.7, 3]],
822
- minZoom:1, maxNativeZoom:18, maxZoom:18,
823
- subdomains: '0123'
824
- });
825
- basemaps["UK OS Opendata"] = NLS_OS_opendata;
831
+ if (maplist.indexOf("OpTop")!==-1) {
832
+ basemaps[layerlookup["OpTop"]] = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
833
+ subdomains: 'abc',
834
+ maxZoom: 19,
835
+ attribution: '&copy; <a href="https://www.opentopomap.org/copyright">OpenTopoMap</a> contributors'
836
+ });
837
+ }
826
838
 
827
- var Open_Topo_Map = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
828
- subdomains: 'abc',
829
- maxZoom: 19,
830
- attribution: '&copy; <a href="https://www.opentopomap.org/copyright">OpenTopoMap</a> contributors'
831
- });
832
- basemaps["Open Topo Map"] = Open_Topo_Map;
839
+ if (maplist.indexOf("HB")!==-1) {
840
+ basemaps[layerlookup["HB"]] = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
841
+ maxZoom: 19,
842
+ attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
843
+ });
844
+ }
833
845
 
834
- var HikeBike_HikeBike = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
835
- maxZoom: 19,
836
- attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
837
- });
838
- basemaps["Hike Bike"] = HikeBike_HikeBike;
846
+ if (maplist.indexOf("AN")!==-1) {
847
+ basemaps["AutoNavi"] = L.tileLayer('https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
848
+ attribution: 'Tiles &copy; 高德地图',
849
+ maxNativeZoom:14,
850
+ maxZoom: 19,
851
+ });
852
+ }
839
853
 
840
- var NLS_OS_1919_1947 = L.tileLayer( 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
841
- attribution: 'Historical Maps Layer, from <a href="https://maps.nls.uk/projects/api/">NLS Maps</a>',
842
- bounds: [[49.6, -12], [61.7, 3]],
843
- minZoom:1, maxZoom:18,
844
- subdomains: '0123'
845
- });
846
- basemaps["UK OS 1919-47"] = NLS_OS_1919_1947;
847
-
848
- //var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/NLS_API/{z}/{x}/{y}.jpg', {
849
- var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/fpsUZbzrfb5d/{z}/{x}/{y}.jpg', {
850
- attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
851
- bounds: [[49.6, -12], [61.7, 3]],
852
- minZoom:1, maxNativeZoom:19, maxZoom:20,
853
- subdomains: '0123'
854
- });
855
- basemaps["UK OS 1900"] = NLS_OS_1900;
856
-
857
- //var CartoPos = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
858
- // attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://cartodb.com/attributions">CartoDB</a>'
859
- //});
860
- //basemaps["CartoDB Light"] = CartoPos;
861
-
862
- // Nice terrain based maps by Stamen Design
863
- var terrainUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg";
864
- basemaps["Terrain"] = L.tileLayer(terrainUrl, {
865
- subdomains: ['a','b','c','d'],
866
- minZoom: 0,
867
- maxZoom: 20,
868
- type: 'jpg',
869
- attribution: 'Map tiles by <a href="https://stamen.com">Stamen Design</a>, under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under <a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>'
870
- });
854
+ if (maplist.indexOf("OS45")!==-1) {
855
+ basemaps[layerlookup["OS45"]] = L.tileLayer( 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
856
+ attribution: 'Historical Maps Layer, from <a href="https://maps.nls.uk/projects/api/">NLS Maps</a>',
857
+ bounds: [[49.6, -12], [61.7, 3]],
858
+ minZoom:1, maxZoom:18,
859
+ subdomains: '0123'
860
+ });
861
+ }
871
862
 
872
- // Nice watercolour based maps by Stamen Design
873
- var watercolorUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg";
874
- basemaps["Watercolor"] = L.tileLayer(watercolorUrl, {
875
- subdomains: ['a','b','c','d'],
876
- minZoom: 0,
877
- maxZoom: 20,
878
- type: 'jpg',
879
- attribution: 'Map tiles by <a href="https://stamen.com">Stamen Design</a>, under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under <a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>'
880
- });
881
- }
863
+ if (maplist.indexOf("OS00")!==-1) {
864
+ //var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/NLS_API/{z}/{x}/{y}.jpg', {
865
+ basemaps[layerlookup["OS00"]] = L.tileLayer('https://nls-{s}.tileserver.com/fpsUZbzrfb5d/{z}/{x}/{y}.jpg', {
866
+ attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
867
+ bounds: [[49.6, -12], [61.7, 3]],
868
+ minZoom:1, maxNativeZoom:19, maxZoom:20,
869
+ subdomains: '0123'
870
+ });
871
+ }
882
872
 
873
+ // Nice terrain based maps by Stamen Design
874
+ if (maplist.indexOf("ST")!==-1) {
875
+ var terrainUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg";
876
+ basemaps[layerlookup["ST"]] = L.tileLayer(terrainUrl, {
877
+ subdomains: ['a','b','c','d'],
878
+ minZoom: 0,
879
+ maxZoom: 20,
880
+ type: 'jpg',
881
+ attribution: 'Map tiles by <a href="https://stamen.com">Stamen Design</a>, under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under <a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>'
882
+ });
883
+ }
883
884
 
884
- // Now add the overlays
885
+ // Nice watercolour based maps by Stamen Design
886
+ if (maplist.indexOf("SW")!==-1) {
887
+ var watercolorUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg";
888
+ basemaps[layerlookup["SW"]] = L.tileLayer(watercolorUrl, {
889
+ subdomains: ['a','b','c','d'],
890
+ minZoom: 0,
891
+ maxZoom: 20,
892
+ type: 'jpg',
893
+ attribution: 'Map tiles by <a href="https://stamen.com">Stamen Design</a>, under <a href="https://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="https://openstreetmap.org">OpenStreetMap</a>, under <a href="https://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>'
894
+ });
895
+ }
885
896
 
886
- // Add the drawing layer for fun...
887
- layers["_drawing"] = new L.FeatureGroup();
888
- overlays["drawing"] = layers["_drawing"];
889
- map.options.drawControlTooltips = false;
890
- var drawCount = 0;
891
- var drawControl = new L.Control.Draw({
892
- draw: {
893
- polyline: { shapeOptions: { clickable:true } },
894
- marker: false,
895
- //circle: false,
896
- circle: { shapeOptions: { clickable:true } },
897
- circlemarker: false,
898
- rectangle: { shapeOptions: { clickable:true } },
899
- polygon: { shapeOptions: { clickable:true } }
900
- }
901
- //edit: none
902
- // {
903
- // featureGroup: layers["_drawing"],
904
- // remove: true,
905
- // edit: true
906
- // }
907
- });
908
- var changeDrawColour = function(col) {
909
- drawControl.setDrawingOptions({
910
- polyline: { shapeOptions: { color:col } },
911
- circle: { shapeOptions: { color:col } },
912
- rectangle: { shapeOptions: { color:col } },
913
- polygon: { shapeOptions: { color:col } }
914
- });
897
+ if (first) {
898
+ if (layerlookup[first]) { basemaps[layerlookup[first]].addTo(map); }
899
+ else { basemaps[first].addTo(map); }
900
+ }
901
+ else {
902
+ basemaps[Object.keys(basemaps)[0]].addTo(map);
903
+ }
904
+ if (showLayerMenu) {
905
+ map.removeControl(layercontrol);
906
+ layercontrol = L.control.layers(basemaps, overlays).addTo(map);
907
+ }
908
+ }
915
909
  }
916
- var shape;
917
- map.on('draw:created', function (e) {
918
- var name = e.layerType + drawCount;
919
- drawCount = drawCount + 1;
920
910
 
921
- e.layer.on('contextmenu', function(e) {
922
- L.DomEvent.stopPropagation(e);
923
- var rmen = L.popup({offset:[0,-12]}).setLatLng(e.latlng);
924
- rmen.setContent("<input type='text' autofocus value='"+e.target.name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+e.target.name+"\",true);'>Edit points</button><button onclick='delMarker(\""+e.target.name+"\",true);'>Delete</button><button onclick='sendDrawing();'>OK</button>");
925
- map.openPopup(rmen);
926
- });
927
911
 
928
- var la, lo, cent;
929
- if (e.layer.hasOwnProperty("_latlng")) {
930
- la = e.layer._latlng.lat;
931
- lo = e.layer._latlng.lng;
932
- cent = e.layer._latlng;
933
- }
934
- else {
935
- cent = e.layer.getBounds().getCenter();
936
- }
937
- var m = {action:"draw", name:name, layer:"_drawing", options:e.layer.options, radius:e.layer._mRadius, lat:la, lon:lo};
938
- if (e.layer.hasOwnProperty("_latlngs")) {
939
- if (e.layer.options.fill === false) { m.line = e.layer._latlngs; }
940
- else { m.area = e.layer._latlngs[0]; }
941
- }
912
+ // Now add the overlays
913
+ var addOverlays = function(overlist) {
914
+ //console.log("OVERLAYS",overlist)
915
+ // var overlookup = { DR:"Drawing", CO:"Countries", DN:"Day/Night", BU:"Buildings", SN:"Ship Navigaion", HM:"Heatmap", AC:"Air corridors", TL:"Place labels" };
916
+ // "DR,CO,DN,BU,SN,HM"
917
+
918
+ // Add the drawing layer...
919
+ if (overlist.indexOf("DR")!==-1) {
920
+ layers["_drawing"] = new L.FeatureGroup();
921
+ overlays["drawing"] = layers["_drawing"];
922
+ map.options.drawControlTooltips = false;
923
+ var drawCount = 0;
924
+ var drawControl = new L.Control.Draw({
925
+ draw: {
926
+ polyline: { shapeOptions: { clickable:true } },
927
+ marker: false,
928
+ //circle: false,
929
+ circle: { shapeOptions: { clickable:true } },
930
+ circlemarker: false,
931
+ rectangle: { shapeOptions: { clickable:true } },
932
+ polygon: { shapeOptions: { clickable:true } }
933
+ }
934
+ //edit: none
935
+ // {
936
+ // featureGroup: layers["_drawing"],
937
+ // remove: true,
938
+ // edit: true
939
+ // }
940
+ });
941
+ var changeDrawColour = function(col) {
942
+ drawControl.setDrawingOptions({
943
+ polyline: { shapeOptions: { color:col } },
944
+ circle: { shapeOptions: { color:col } },
945
+ rectangle: { shapeOptions: { color:col } },
946
+ polygon: { shapeOptions: { color:col } }
947
+ });
948
+ }
949
+ var shape;
950
+ map.on('draw:created', function (e) {
951
+ var name = e.layerType + drawCount;
952
+ drawCount = drawCount + 1;
942
953
 
943
- shape = {m:m, layer:e.layer};
944
- polygons[name] = shape.layer;
945
- polygons[name].lay = "_drawing";
946
- polygons[name].name = name;
947
- layers["_drawing"].addLayer(shape.layer);
954
+ e.layer.on('contextmenu', function(e) {
955
+ L.DomEvent.stopPropagation(e);
956
+ var rmen = L.popup({offset:[0,-12]}).setLatLng(e.latlng);
957
+ rmen.setContent("<input type='text' autofocus value='"+e.target.name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+e.target.name+"\",true);'>Edit points</button><button onclick='delMarker(\""+e.target.name+"\",true);'>Delete</button><button onclick='sendDrawing();'>OK</button>");
958
+ map.openPopup(rmen);
959
+ });
948
960
 
949
- 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+"\",true);'>Edit points</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
950
- if (e.layer.options.fill === false && navigator.onLine) {
951
- rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<input type='text' autofocus value='"+name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+name+"\",true);'>Edit points</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendRoute(\""+name+"\");'>Route</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
952
- }
953
- rightmenuMarker.setLatLng(cent);
954
- setTimeout(function() {map.openPopup(rightmenuMarker)},25);
955
- });
961
+ var la, lo, cent;
962
+ if (e.layer.hasOwnProperty("_latlng")) {
963
+ la = e.layer._latlng.lat;
964
+ lo = e.layer._latlng.lng;
965
+ cent = e.layer._latlng;
966
+ }
967
+ else {
968
+ cent = e.layer.getBounds().getCenter();
969
+ }
970
+ var m = {action:"draw", name:name, layer:"_drawing", options:e.layer.options, radius:e.layer._mRadius, lat:la, lon:lo};
971
+ if (e.layer.hasOwnProperty("_latlngs")) {
972
+ if (e.layer.options.fill === false) { m.line = e.layer._latlngs; }
973
+ else { m.area = e.layer._latlngs[0]; }
974
+ }
956
975
 
976
+ shape = {m:m, layer:e.layer};
977
+ polygons[name] = shape.layer;
978
+ polygons[name].lay = "_drawing";
979
+ polygons[name].name = name;
980
+ layers["_drawing"].addLayer(shape.layer);
957
981
 
958
- var defaultOptions = function () {
959
- var options = {};
960
- options.precision = 5;
961
- options.factor = Math.pow(10, options.precision);
962
- options.dimension = 2;
963
- return options;
964
- };
982
+ 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+"\",true);'>Edit points</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
983
+ if (e.layer.options.fill === false && navigator.onLine) {
984
+ rightmenuMarker = L.popup({offset:[0,-12]}).setContent("<input type='text' autofocus value='"+name+"' id='dinput' placeholder='name (,icon, layer)'/><br/><button onclick='editPoly(\""+name+"\",true);'>Edit points</button><button onclick='delMarker(\""+name+"\",true);'>Delete</button><button onclick='sendRoute(\""+name+"\");'>Route</button><button onclick='sendDrawing(\""+name+"\");'>OK</button>");
985
+ }
986
+ rightmenuMarker.setLatLng(cent);
987
+ setTimeout(function() {map.openPopup(rightmenuMarker)},25);
988
+ });
965
989
 
966
- var decode = function (encoded, options) {
967
- options = defaultOptions(options);
968
- var flatPoints = decodeDeltas(encoded);
969
- var points = [];
970
- for (var i = 0, len = flatPoints.length; i + (options.dimension - 1) < len;) {
971
- var point = [];
972
- for (var dim = 0; dim < options.dimension; ++dim) {
973
- point.push(flatPoints[i++]);
990
+ var sendDrawing = function(n) {
991
+ var thing = document.getElementById('dinput').value;
992
+ map.closePopup();
993
+ shape.m.name = thing;
994
+ delMarker(n,true);
995
+
996
+ polygons[thing] = shape.layer;
997
+ polygons[thing].lay = "_drawing";
998
+ polygons[thing].name = thing;
999
+ layers["_drawing"].addLayer(shape.layer);
1000
+ ws.send(JSON.stringify(shape.m));
1001
+ }
1002
+
1003
+ var defaultOptions = function () {
1004
+ var options = {};
1005
+ options.precision = 5;
1006
+ options.factor = Math.pow(10, options.precision);
1007
+ options.dimension = 2;
1008
+ return options;
1009
+ };
1010
+
1011
+ var decode = function (encoded, options) {
1012
+ options = defaultOptions(options);
1013
+ var flatPoints = decodeDeltas(encoded);
1014
+ var points = [];
1015
+ for (var i = 0, len = flatPoints.length; i + (options.dimension - 1) < len;) {
1016
+ var point = [];
1017
+ for (var dim = 0; dim < options.dimension; ++dim) {
1018
+ point.push(flatPoints[i++]);
1019
+ }
1020
+ points.push(point);
1021
+ }
1022
+ return points;
974
1023
  }
975
- points.push(point);
976
- }
977
- return points;
978
- }
979
1024
 
980
- var decodeDeltas = function (encoded, options) {
981
- options = defaultOptions(options);
982
- var lastNumbers = [];
983
- var numbers = decodeFloats(encoded, options);
984
- for (var i = 0, len = numbers.length; i < len;) {
985
- for (var d = 0; d < options.dimension; ++d, ++i) {
986
- numbers[i] = Math.round((lastNumbers[d] = numbers[i] + (lastNumbers[d] || 0)) * options.factor) / options.factor;
1025
+ var decodeDeltas = function (encoded, options) {
1026
+ options = defaultOptions(options);
1027
+ var lastNumbers = [];
1028
+ var numbers = decodeFloats(encoded, options);
1029
+ for (var i = 0, len = numbers.length; i < len;) {
1030
+ for (var d = 0; d < options.dimension; ++d, ++i) {
1031
+ numbers[i] = Math.round((lastNumbers[d] = numbers[i] + (lastNumbers[d] || 0)) * options.factor) / options.factor;
1032
+ }
1033
+ }
1034
+ return numbers;
1035
+ }
1036
+
1037
+ var decodeFloats = function (encoded, options) {
1038
+ options = defaultOptions(options);
1039
+ var numbers = decodeSignedIntegers(encoded);
1040
+ for (var i = 0, len = numbers.length; i < len; ++i) {
1041
+ numbers[i] /= options.factor;
1042
+ }
1043
+ return numbers;
987
1044
  }
1045
+
1046
+ var decodeSignedIntegers = function (encoded) {
1047
+ var numbers = decodeUnsignedIntegers(encoded);
1048
+ for (var i = 0, len = numbers.length; i < len; ++i) {
1049
+ var num = numbers[i];
1050
+ numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
1051
+ }
1052
+ return numbers;
1053
+ }
1054
+
1055
+ var decodeUnsignedIntegers = function (encoded) {
1056
+ var numbers = [];
1057
+ var current = 0;
1058
+ var shift = 0;
1059
+ for (var i = 0, len = encoded.length; i < len; ++i) {
1060
+ var b = encoded.charCodeAt(i) - 63;
1061
+ current |= (b & 0x1f) << shift;
1062
+ if (b < 0x20) {
1063
+ numbers.push(current);
1064
+ current = 0;
1065
+ shift = 0;
1066
+ } else {
1067
+ shift += 5;
1068
+ }
1069
+ }
1070
+ return numbers;
1071
+ }
1072
+
1073
+ var sendRoute = function(n) {
1074
+ var p = (polygons[n]._latlngs.map(function(x) {
1075
+ return x.lng+","+x.lat;
1076
+ })).join(';');
1077
+
1078
+ fetch('https://router.project-osrm.org/route/v1/driving/'+p)
1079
+ .then(response => response.json())
1080
+ .then(data => {
1081
+ if (data.code !== "Ok") { sendDrawing(n); }
1082
+ var r = decode(data.routes[0].geometry).map( x => L.latLng(x[0],x[1]) );
1083
+ polygons[n]._latlngs = r;
1084
+ shape.m.line = r;
1085
+ sendDrawing(n);
1086
+ });
1087
+ }
1088
+
988
1089
  }
989
- return numbers;
990
- }
991
1090
 
992
- var decodeFloats = function (encoded, options) {
993
- options = defaultOptions(options);
994
- var numbers = decodeSignedIntegers(encoded);
995
- for (var i = 0, len = numbers.length; i < len; ++i) {
996
- numbers[i] /= options.factor;
1091
+ // Add the countries (world-110m) for offline use
1092
+ if (overlist.indexOf("CO")!==-1 || (!navigator.onLine)) {
1093
+ var customTopoLayer = L.geoJson(null, {clickable:false, style: {color:"blue", weight:2, fillColor:"#cf6", fillOpacity:0.04}});
1094
+ layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,customTopoLayer);
1095
+ overlays["countries"] = layers["_countries"];
997
1096
  }
998
- return numbers;
999
- }
1000
1097
 
1001
- var decodeSignedIntegers = function (encoded) {
1002
- var numbers = decodeUnsignedIntegers(encoded);
1003
- for (var i = 0, len = numbers.length; i < len; ++i) {
1004
- var num = numbers[i];
1005
- numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
1098
+ // Add the day/night overlay
1099
+ if (overlist.indexOf("DN")!==-1) {
1100
+ layers["_daynight"] = new L.LayerGroup();
1101
+ overlays["day/night"] = layers["_daynight"];
1006
1102
  }
1007
- return numbers;
1008
- }
1009
1103
 
1010
- var decodeUnsignedIntegers = function (encoded) {
1011
- var numbers = [];
1012
- var current = 0;
1013
- var shift = 0;
1014
- for (var i = 0, len = encoded.length; i < len; ++i) {
1015
- var b = encoded.charCodeAt(i) - 63;
1016
- current |= (b & 0x1f) << shift;
1017
- if (b < 0x20) {
1018
- numbers.push(current);
1019
- current = 0;
1020
- shift = 0;
1021
- } else {
1022
- shift += 5;
1104
+ // Add live rain data
1105
+ if (overlist.indexOf("RA")!==-1) {
1106
+ if (navigator.onLine) {
1107
+ overlays["rainfall"] = new L.TileLayer('https://tilecache.rainviewer.com/v2/radar/' + parseInt(Date.now()/600000)*600 + '/256/{z}/{x}/{y}/2/1_1.png', {
1108
+ tileSize: 256,
1109
+ opacity: 0.4,
1110
+ transparent: true,
1111
+ attribution: '<a href="https://rainviewer.com" target="_blank">rainviewer.com</a>'
1112
+ });
1023
1113
  }
1024
1114
  }
1025
- return numbers;
1026
- }
1027
1115
 
1028
- var sendRoute = function(n) {
1029
- var p = (polygons[n]._latlngs.map(function(x) {
1030
- return x.lng+","+x.lat;
1031
- })).join(';');
1032
-
1033
- fetch('https://router.project-osrm.org/route/v1/driving/'+p)
1034
- .then(response => response.json())
1035
- .then(data => {
1036
- if (data.code !== "Ok") { sendDrawing(n); }
1037
- var r = decode(data.routes[0].geometry).map( x => L.latLng(x[0],x[1]) );
1038
- polygons[n]._latlngs = r;
1039
- shape.m.line = r;
1040
- sendDrawing(n);
1041
- });
1042
- }
1043
-
1044
- var sendDrawing = function(n) {
1045
- var thing = document.getElementById('dinput').value;
1046
- map.closePopup();
1047
- shape.m.name = thing;
1048
- delMarker(n,true);
1049
-
1050
- polygons[thing] = shape.layer;
1051
- polygons[thing].lay = "_drawing";
1052
- polygons[thing].name = thing;
1053
- layers["_drawing"].addLayer(shape.layer);
1054
- ws.send(JSON.stringify(shape.m));
1055
- }
1116
+ // Add the buildings layer
1117
+ if (overlist.indexOf("BU")!==-1) {
1118
+ overlays["buildings"] = new OSMBuildings(map).load();
1119
+ // map.removeLayer(overlays["buildings"]); // Hide it at start
1120
+ }
1056
1121
 
1057
- // Add the countries (world-110m) for offline use
1058
- var customTopoLayer = L.geoJson(null, {clickable:false, style: {color:"blue", weight:2, fillColor:"#cf6", fillOpacity:0.04}});
1059
- layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,customTopoLayer);
1060
- overlays["countries"] = layers["_countries"];
1061
-
1062
- // Add the day/night overlay
1063
- layers["_daynight"] = new L.LayerGroup();
1064
- overlays["day/night"] = layers["_daynight"];
1065
-
1066
- // Add live rain data
1067
- if (navigator.onLine) {
1068
- overlays["rainfall"] = new L.TileLayer('https://tilecache.rainviewer.com/v2/radar/' + parseInt(Date.now()/600000)*600 + '/256/{z}/{x}/{y}/2/1_1.png', {
1069
- tileSize: 256,
1070
- opacity: 0.4,
1071
- transparent: true,
1072
- attribution: '<a href="https://rainviewer.com" target="_blank">rainviewer.com</a>'
1073
- });
1122
+ // Add Railways
1123
+ if (overlist.indexOf("RW")!==-1) {
1124
+ // eg https://a.tiles.openrailwaymap.org/standard/11/1015/686.png
1125
+ overlays["railways"] = L.tileLayer('https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', {
1126
+ maxZoom: 19,
1127
+ attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> | Map style: &copy; <a href="https://www.OpenRailwayMap.org">OpenRailwayMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
1128
+ });
1129
+ }
1074
1130
 
1075
- // Add the buildings layer
1076
- // overlays["buildings"] = new OSMBuildings(map).load();
1077
- // map.removeLayer(overlays["buildings"]); // Hide it at start
1078
-
1079
- // Add Roads
1080
- // overlays["roads"] = L.tileLayer('https://{s}.tile.openstreetmap.se/hydda/roads_and_labels/{z}/{x}/{y}.png', {
1081
- // maxZoom: 18,
1082
- // attribution: 'Tiles courtesy of <a href="https://openstreetmap.se/" target="_blank">OpenStreetMap Sweden</a> &mdash; Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
1083
- // opacity: 0.8
1084
- // });
1085
-
1086
- // // Add Railways
1087
- // overlays["railways"] = L.tileLayer('https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', {
1088
- // maxZoom: 19,
1089
- // attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> | Map style: &copy; <a href="https://www.OpenRailwayMap.org">OpenRailwayMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
1090
- // });
1091
-
1092
- // // Add Public Transport (Buses)
1093
- // overlays["public transport"] = L.tileLayer('https://openptmap.org/tiles/{z}/{x}/{y}.png', {
1094
- // maxZoom: 17,
1095
- // attribution: 'Map data: &copy; <a href="https://www.openptmap.org">OpenPtMap</a> contributors'
1096
- // });
1131
+ // Add Air Corridors
1132
+ if (overlist.indexOf("AC")!==-1) {
1133
+ overlays["air corridors"] = L.tileLayer('https://{s}.tile.maps.openaip.net/geowebcache/service/tms/1.0.0/openaip_basemap@EPSG%3A900913@png/{z}/{x}/{y}.{ext}', {
1134
+ attribution: '<a href="https://www.openaip.net/">openAIP Data</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-NC-SA</a>)',
1135
+ ext: 'png',
1136
+ minZoom: 4,
1137
+ maxZoom: 15,
1138
+ maxNativeZoom: 14,
1139
+ tms: true,
1140
+ detectRetina: true,
1141
+ subdomains: '12'
1142
+ });
1143
+ }
1097
1144
 
1098
1145
  // Add the OpenSea markers layer
1099
- overlays["ship nav"] = L.tileLayer('https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
1100
- maxZoom: 19,
1101
- attribution: 'Map data: &copy; <a href="https://www.openseamap.org">OpenSeaMap</a> contributors'
1102
- });
1103
- }
1146
+ if (overlist.indexOf("SN")!==-1) {
1147
+ overlays["ship nav"] = L.tileLayer('https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
1148
+ maxZoom: 19,
1149
+ attribution: 'Map data: &copy; <a href="https://www.openseamap.org">OpenSeaMap</a> contributors'
1150
+ });
1151
+ }
1104
1152
 
1105
- // Add the heatmap layer
1106
- var heat = L.heatLayer([], {radius:60, gradient:{0.2:'blue', 0.4:'lime', 0.6:'red', 0.8:'yellow', 1:'white'}});
1107
- layers["_heat"] = new L.LayerGroup().addLayer(heat);
1108
- overlays["heatmap"] = layers["_heat"];
1153
+ // Add the Stamen Toner Labels layer
1154
+ if (overlist.indexOf("TL")!==-1) {
1155
+ overlays["place labels"] = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-labels/{z}/{x}/{y}{r}.{ext}', {
1156
+ attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
1157
+ subdomains: 'abcd',
1158
+ minZoom: 0,
1159
+ maxZoom: 20,
1160
+ ext: 'png'
1161
+ });
1162
+ }
1109
1163
 
1110
- if (showUserMenu) {
1111
- if ( window.localStorage.hasOwnProperty("lastlayer") ) {
1112
- if ( basemaps[window.localStorage.getItem("lastlayer")] ) {
1113
- baselayername = window.localStorage.getItem("lastlayer");
1114
- }
1164
+ // Add the heatmap layer
1165
+ if (overlist.indexOf("HM")!==-1) {
1166
+ heat = L.heatLayer([], {radius:60, gradient:{0.2:'blue', 0.4:'lime', 0.6:'red', 0.8:'yellow', 1:'white'}});
1167
+ layers["_heat"] = new L.LayerGroup().addLayer(heat);
1168
+ overlays["heatmap"] = layers["_heat"];
1169
+ }
1170
+
1171
+ if (showLayerMenu) {
1172
+ map.removeControl(layercontrol);
1173
+ layercontrol = L.control.layers(basemaps, overlays).addTo(map);
1115
1174
  }
1116
1175
  }
1117
- if (navigator.onLine) { basemaps[baselayername].addTo(map); }
1118
1176
 
1119
1177
  // Layer control based on select box rather than radio buttons.
1120
1178
  //var layercontrol = L.control.selectLayers(basemaps, overlays).addTo(map);
1121
- layercontrol = L.control.layers(basemaps, overlays);
1179
+ var layercontrol = L.control.layers(basemaps, overlays);
1122
1180
 
1123
1181
  // Add the layers control widget
1124
1182
  if (!inIframe) { layercontrol.addTo(map); }
@@ -1283,10 +1341,11 @@ function setMarker(data) {
1283
1341
  opt.stroke = (data.hasOwnProperty("stroke")) ? data.stroke : true;
1284
1342
  opt.weight = data.weight || 2;
1285
1343
  opt.opacity = data.opacity || 1;
1286
- opt.fillOpacity = data.fillOpacity || 0.2;
1344
+ opt.fillOpacity = data.fillOpacity;
1287
1345
  opt.clickable = (data.hasOwnProperty("clickable")) ? data.clickable : false;
1288
1346
  opt.fill = (data.hasOwnProperty("fill")) ? data.fill : true;
1289
1347
  if (data.hasOwnProperty("dashArray")) { opt.dashArray = data.dashArray; }
1348
+ if (opt.fillOpacity === undefined) { opt.fillOpacity = 0.2; }
1290
1349
 
1291
1350
  // Replace building
1292
1351
  if (data.hasOwnProperty("building")) {
@@ -1780,13 +1839,13 @@ function setMarker(data) {
1780
1839
  var reft = new RegExp('feet|ft','i');
1781
1840
  var refm = new RegExp('metres|m','i');
1782
1841
  if ( reft.test(""+data.alt) ) {
1783
- data.alt = (parseFloat(data.alt)).toFixed(2) + " ft";
1842
+ data.alt = +(parseFloat(data.alt)).toFixed(2) + " ft";
1784
1843
  }
1785
1844
  else if ( refm.test(""+data.alt) ) {
1786
- data.alt = (parseFloat(data.alt)).toFixed(2) + " m";
1845
+ data.alt = +(parseFloat(data.alt)).toFixed(2) + " m";
1787
1846
  }
1788
1847
  else {
1789
- data.alt = (parseFloat(data.alt)).toFixed(2);
1848
+ data.alt = +(parseFloat(data.alt)).toFixed(2);
1790
1849
  }
1791
1850
  }
1792
1851
 
@@ -1803,7 +1862,7 @@ function setMarker(data) {
1803
1862
  delete data.photoUrl;
1804
1863
  }
1805
1864
  if (data.hasOwnProperty("videoUrl")) {
1806
- words += '<video controls muted autoplay width="320" height="240"><source src="'+data.videoUrl+'" type="video/mp4">Your browser does not support the video tag.</video>';
1865
+ words += '<video controls muted autoplay width="320" height="240"><source src="'+data.videoUrl+'" type="video/mp4">Your browser does not support the video tag.</video><br/>';
1807
1866
  delete data.videoUrl;
1808
1867
  }
1809
1868
  if (data.hasOwnProperty("ttl")) { // save expiry time for this marker
@@ -1910,7 +1969,7 @@ function setMarker(data) {
1910
1969
  fb.action = "click";
1911
1970
  ws.send(JSON.stringify(fb));
1912
1971
  });
1913
- if ((data.addtoheatmap !== "false") || (!data.hasOwnProperty("addtoheatmap"))) { // Added to give ability to control if points from active layer contribute to heatmap
1972
+ if (heat && ((data.addtoheatmap !== "false") || (!data.hasOwnProperty("addtoheatmap")))) { // Added to give ability to control if points from active layer contribute to heatmap
1914
1973
  if (heatAll || map.hasLayer(layers[lay])) { heat.addLatLng(lli); }
1915
1974
  }
1916
1975
  markers[data.name] = marker;
@@ -1981,7 +2040,13 @@ function setMarker(data) {
1981
2040
 
1982
2041
  // handle any incoming COMMANDS to control the map remotely
1983
2042
  function doCommand(cmd) {
1984
- //console.log("COMMAND",cmd);
2043
+ // console.log("COMMAND",cmd);
2044
+ if (cmd.init && cmd.hasOwnProperty("maplist")) {
2045
+ addBaseMaps(cmd.maplist,cmd.layer);
2046
+ }
2047
+ if (cmd.init && cmd.hasOwnProperty("overlist")) {
2048
+ addOverlays(cmd.overlist);
2049
+ }
1985
2050
  if (cmd.hasOwnProperty("toptitle")) {
1986
2051
  if (!inIframe ) {
1987
2052
  document.title = cmd.toptitle;
@@ -2108,7 +2173,7 @@ function doCommand(cmd) {
2108
2173
 
2109
2174
  var existsalready = false;
2110
2175
  // Add a new base map layer
2111
- if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
2176
+ if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.name.length>0 && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
2112
2177
  console.log("BASE",cmd.map);
2113
2178
  if (basemaps.hasOwnProperty(cmd.map.name)) { existsalready = true; }
2114
2179
  if (cmd.map.hasOwnProperty("wms")) { // special case for wms
@@ -2381,6 +2446,9 @@ function doCommand(cmd) {
2381
2446
  overlays[cmd.map.overlay] = new L.imageOverlay(cmd.map.url, L.latLngBounds(cmd.map.bounds), cmd.map.opt);
2382
2447
  }
2383
2448
  }
2449
+ else if (cmd.map.url.slice(-4).toLowerCase() === ".pbf") {
2450
+ overlays[cmd.map.overlay] = VectorTileLayer(cmd.map.url, cmd.map.opt);
2451
+ }
2384
2452
  else {
2385
2453
  overlays[cmd.map.overlay] = L.tileLayer(cmd.map.url, cmd.map.opt);
2386
2454
  }