Events filters and Map Selection (#180)

* add filter for bounds but sort of wrong way round

* Better go at event filters

* Let user pick layers and overlays at config time

* update graticule, fix css

* Update package.json

* fix initial basemap old maps

* tidy up
This commit is contained in:
Dave Conway-Jones 2021-11-02 16:13:47 +00:00 committed by GitHub
parent 549d4a2ba9
commit fd18abd294
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 1204 additions and 476 deletions

View File

@ -12,6 +12,7 @@ map web page for plotting "things" on.
### Updates
- v2.20.0 - Add support of .pbf map layers. Issue 123.
- v2.19.1 - Add filter for bounds events only.
- v2.19.0 - Bump leaflet to latest. v1.7
- v2.18.1 - Let fillOpacity be 0.
- v2.18.0 - Add bounds event onzoom or drag.

525
package-lock.json generated Normal file
View File

@ -0,0 +1,525 @@
{
"name": "node-red-contrib-web-worldmap",
"version": "2.21.0-beta",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@turf/bezier-spline": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@turf/bezier-spline/-/bezier-spline-6.5.0.tgz",
"integrity": "sha512-vokPaurTd4PF96rRgGVm6zYYC5r1u98ZsG+wZEv9y3kJTuJRX/O3xIY2QnTGTdbVmAJN1ouOsD0RoZYaVoXORQ==",
"requires": {
"@turf/helpers": "^6.5.0",
"@turf/invariant": "^6.5.0"
}
},
"@turf/helpers": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@turf/helpers/-/helpers-6.5.0.tgz",
"integrity": "sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw=="
},
"@turf/invariant": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/@turf/invariant/-/invariant-6.5.0.tgz",
"integrity": "sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==",
"requires": {
"@turf/helpers": "^6.5.0"
}
},
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
"requires": {
"mime-types": "~2.1.24",
"negotiator": "0.6.2"
}
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
},
"body-parser": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
"requires": {
"bytes": "3.1.0",
"content-type": "~1.0.4",
"debug": "2.6.9",
"depd": "~1.1.2",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"on-finished": "~2.3.0",
"qs": "6.7.0",
"raw-body": "2.4.0",
"type-is": "~1.6.17"
},
"dependencies": {
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
}
}
},
"bufferjs": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/bufferjs/-/bufferjs-3.0.1.tgz",
"integrity": "sha1-BpLoKcsQoQVQ5kc5CwNesGw46O8="
},
"bufferlist": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/bufferlist/-/bufferlist-0.1.0.tgz",
"integrity": "sha1-Qr7y2JVztA+hCGuzng9TEBcNHd0="
},
"cgi": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cgi/-/cgi-0.3.1.tgz",
"integrity": "sha1-h1HaZKHPGEnREFYxi3YNGs+6R9w=",
"requires": {
"debug": "2",
"extend": "~2.0.0",
"header-stack": "~0.0.2",
"stream-stack": "~1.1.1"
}
},
"compressible": {
"version": "2.0.17",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz",
"integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==",
"requires": {
"mime-db": ">= 1.40.0 < 2"
}
},
"compression": {
"version": "1.7.4",
"resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz",
"integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==",
"requires": {
"accepts": "~1.3.5",
"bytes": "3.0.0",
"compressible": "~2.0.16",
"debug": "2.6.9",
"on-headers": "~1.0.2",
"safe-buffer": "5.1.2",
"vary": "~1.1.2"
},
"dependencies": {
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
}
}
},
"content-disposition": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
"requires": {
"safe-buffer": "5.1.2"
}
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"cookie": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
},
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
"requires": {
"ms": "2.0.0"
}
},
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
},
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
},
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
},
"express": {
"version": "4.17.1",
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
"requires": {
"accepts": "~1.3.7",
"array-flatten": "1.1.1",
"body-parser": "1.19.0",
"content-disposition": "0.5.3",
"content-type": "~1.0.4",
"cookie": "0.4.0",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
"depd": "~1.1.2",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"finalhandler": "~1.1.2",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
"methods": "~1.1.2",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"path-to-regexp": "0.1.7",
"proxy-addr": "~2.0.5",
"qs": "6.7.0",
"range-parser": "~1.2.1",
"safe-buffer": "5.1.2",
"send": "0.17.1",
"serve-static": "1.14.1",
"setprototypeof": "1.1.1",
"statuses": "~1.5.0",
"type-is": "~1.6.18",
"utils-merge": "1.0.1",
"vary": "~1.1.2"
}
},
"extend": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-2.0.2.tgz",
"integrity": "sha512-AgFD4VU+lVLP6vjnlNfF7OeInLTyeyckCNPEsuxz1vi786UuK/nk6ynPuhn/h+Ju9++TQyr5EpLRI14fc1QtTQ=="
},
"faye-websocket": {
"version": "0.11.3",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz",
"integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==",
"requires": {
"websocket-driver": ">=0.5.1"
}
},
"finalhandler": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
"requires": {
"debug": "2.6.9",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"on-finished": "~2.3.0",
"parseurl": "~1.3.3",
"statuses": "~1.5.0",
"unpipe": "~1.0.0"
}
},
"forwarded": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
},
"fresh": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
"header-stack": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/header-stack/-/header-stack-0.0.2.tgz",
"integrity": "sha1-Rg1ysW04ZSzkUeIyU2lxsx6E1g8=",
"requires": {
"bufferjs": ">= 0.2.3",
"bufferlist": ">= 0.0.6",
"stream-stack": ">= 1.1.1"
}
},
"http-errors": {
"version": "1.7.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
"requires": {
"depd": "~1.1.2",
"inherits": "2.0.3",
"setprototypeof": "1.1.1",
"statuses": ">= 1.5.0 < 2",
"toidentifier": "1.0.0"
}
},
"iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ipaddr.js": {
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
"integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
},
"methods": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"mime": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
"version": "1.40.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
},
"mime-types": {
"version": "2.1.24",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
"requires": {
"mime-db": "1.40.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"negotiator": {
"version": "0.6.2",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
"requires": {
"ee-first": "1.1.1"
}
},
"on-headers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
"integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="
},
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
},
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
},
"proxy-addr": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
"integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
"requires": {
"forwarded": "~0.1.2",
"ipaddr.js": "1.9.0"
}
},
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
},
"raw-body": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
"requires": {
"bytes": "3.1.0",
"http-errors": "1.7.2",
"iconv-lite": "0.4.24",
"unpipe": "1.0.0"
},
"dependencies": {
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
}
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safer-buffer": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"send": {
"version": "0.17.1",
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
"requires": {
"debug": "2.6.9",
"depd": "~1.1.2",
"destroy": "~1.0.4",
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"etag": "~1.8.1",
"fresh": "0.5.2",
"http-errors": "~1.7.2",
"mime": "1.6.0",
"ms": "2.1.1",
"on-finished": "~2.3.0",
"range-parser": "~1.2.1",
"statuses": "~1.5.0"
},
"dependencies": {
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
}
}
},
"serve-static": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
"requires": {
"encodeurl": "~1.0.2",
"escape-html": "~1.0.3",
"parseurl": "~1.3.3",
"send": "0.17.1"
}
},
"setprototypeof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
},
"sockjs": {
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
"integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==",
"requires": {
"faye-websocket": "^0.11.3",
"uuid": "^3.4.0",
"websocket-driver": "^0.7.4"
}
},
"statuses": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"stream-stack": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/stream-stack/-/stream-stack-1.1.4.tgz",
"integrity": "sha1-cIRgQrqwGFAI5Qnt/h93+TYcumk="
},
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
"type-is": {
"version": "1.6.18",
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
"requires": {
"media-typer": "0.3.0",
"mime-types": "~2.1.24"
}
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"websocket-driver": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
"integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
"requires": {
"http-parser-js": ">=0.5.1",
"safe-buffer": ">=5.1.0",
"websocket-extensions": ">=0.1.1"
},
"dependencies": {
"http-parser-js": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.2.tgz",
"integrity": "sha512-opCO9ASqg5Wy2FNo7A0sxy71yGbbkJJXLdgMK04Tcypw9jr2MgWbyubb0+WdmDmGnFflO7fRbqbaihh/ENDlRQ=="
}
}
},
"websocket-extensions": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
}
}
}

View File

@ -1,13 +1,13 @@
{
"name": "node-red-contrib-web-worldmap",
"version": "2.20.0",
"version": "2.21.0-beta",
"description": "A Node-RED node to provide a web page of a world map for plotting things on.",
"dependencies": {
"@turf/bezier-spline": "~6.5.0",
"cgi": "0.3.1",
"compression": "^1.7.4",
"express": "^4.16.4",
"sockjs": "~0.3.21",
"@turf/bezier-spline": "*"
"sockjs": "~0.3.21"
},
"bundledDependencies": [
"cgi",

View File

@ -10,24 +10,13 @@
</tr>
</table>
</div>
<div class="form-row">
<label for="node-input-maplist"><i class="fa fa-list"></i> Map list</label>
<input type="text" id="node-input-maplist" placeholder="List of Maps">
</div>
<div class="form-row">
<label for="node-input-layer"><i class="fa fa-map"></i> Base map</label>
<select id="node-input-layer" style="width:70%;">
<option value="OSM grey">OpenStreetMap Greyscale</option>
<option value="OSM">OpenStreetMap</option>
<option value="Esri">ESRI Streetmap</option>
<option value="Esri Satellite">ESRI Satellite</option>
<option value="Esri Topography">ESRI Topography</option>
<option value="Esri Ocean">ESRI Ocean</option>
<option value="Esri Dark Grey">ESRI Dark Grey</option>
<option value="Nat Geo">National Geographic</option>
<option value="UK OS Opendata">UK OS Opendata</option>
<option value="Open Topo Map">Open Topo Map</option>
<option value="Hike Bike">Hike Bike OSM</option>
<option value="Terrain">Terrain</option>
<option value="Watercolor">Stamen Watercolor</option>
<option value="Custom">Custom Map Provider</option>
</select>
<input type="text" id="node-input-layer" placeholder="Initial Map">
</div>
<div class="form-row" id="customMap">
<label for="node-input-mapname">&nbsp;&nbsp;&nbsp;Map name</label>
@ -40,6 +29,10 @@
<input type="checkbox" id="node-input-mapwms" style="display:inline-block; width:20px; vertical-align:baseline;">
Map server uses WMS
</div>
<div class="form-row">
<label for="node-input-overlist"><i class="fa fa-map-o"></i> Overlays</label>
<input type="text" id="node-input-overlist" placeholder="Initial Overlays">
</div>
<div class="form-row">
<label for="node-input-cluster"><i class="fa fa-dot-circle-o"></i>Cluster when</label>
zoom level is less than <input type="text" id="node-input-cluster" placeholder="0 (0,off - 19)" style="width:100px;">
@ -54,7 +47,7 @@
<option value="show">Show</option>
<option value="hide">Hide</option>
</select>
<i class="fa fa-bars" style="margin-left:30px;"></i> Layer menu
<i class="fa fa-bars" style="margin-left:53px;"></i> Layer menu
<select id="node-input-layers" style="width:70px;">
<option value="show">Show</option>
<option value="hide">Hide</option>
@ -66,7 +59,7 @@
<option value="false">False</option>
<option value="true">True</option>
</select>
<i class="fa fa-lock" style="margin-left:30px;"></i> Lock zoom
<i class="fa fa-lock" style="margin-left:54px;"></i> Lock zoom
<select id="node-input-zoomlock" style="width:70px;">
<option value="false">False</option>
<option value="true">True</option>
@ -78,7 +71,7 @@
<option value="true">Enable</option>
<option value="false">Disable</option>
</select>
<i class="fa fa-hand-o-right" style="margin-left:22px;"></i> Right click
<i class="fa fa-hand-o-right" style="margin-left:43px;"></i> Right click
<select id="node-input-hiderightclick" style="width:80px;">
<option value="false">Enable</option>
<option value="true">Disable</option>
@ -173,24 +166,13 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
</tr>
</table>
</div>
<div class="form-row">
<label for="node-input-maplist"><i class="fa fa-list"></i> Map list</label>
<input type="text" id="node-input-maplist" placeholder="List of Maps">
</div>
<div class="form-row">
<label for="node-input-layer"><i class="fa fa-map"></i> Base map</label>
<select id="node-input-layer">
<option value="OSM grey">OpenStreetMap Greyscale</option>
<option value="OSM">OpenStreetMap</option>
<option value="Esri">ESRI Streetmap</option>
<option value="Esri Satellite">ESRI Satellite</option>
<option value="Esri Topography">ESRI Topography</option>
<option value="Esri Ocean">ESRI Ocean</option>
<option value="Esri Dark Grey">ESRI Dark Grey</option>
<option value="Nat Geo">National Geographic</option>
<option value="UK OS Opendata">UK OS Opendata</option>
<option value="Open Topo Map">Open Topo Map</option>
<option value="Hike Bike">Hike Bike OSM</option>
<option value="Terrain">Terrain</option>
<option value="Watercolor">Stamen Watercolor</option>
<option value="Custom">Custom Map Provider</option>
</select>
<input type="text" id="node-input-layer" placeholder="Initial Map">
</div>
<div class="form-row" id="customMap">
<label for="node-input-mapname">&nbsp;&nbsp;&nbsp;Map name</label>
@ -203,6 +185,10 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
<input type="checkbox" id="node-input-mapwms" style="display:inline-block; width:20px; vertical-align:baseline;">
Map server uses WMS
</div>
<div class="form-row">
<label for="node-input-overlist"><i class="fa fa-map-o"></i> Overlays</label>
<input type="text" id="node-input-overlist" placeholder="Initial Overlays">
</div>
<div class="form-row">
<label for="node-input-cluster"><i class="fa fa-dot-circle-o"></i>Cluster when</label>
zoom level is less than <input type="text" id="node-input-cluster" placeholder="0 (0,off - 19)" style="width:100px;">
@ -217,7 +203,7 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
<option value="show">Show</option>
<option value="hide">Hide</option>
</select>
<i class="fa fa-bars" style="margin-left:30px;"></i> Layer menu
<i class="fa fa-bars" style="margin-left:53px;"></i> Layer menu
<select id="node-input-layers" style="width:70px;">
<option value="show">Show</option>
<option value="hide">Hide</option>
@ -229,7 +215,7 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
<option value="false">False</option>
<option value="true">True</option>
</select>
<i class="fa fa-lock" style="margin-left:30px;"></i> Lock zoom
<i class="fa fa-lock" style="margin-left:54px;"></i> Lock zoom
<select id="node-input-zoomlock" style="width:70px;">
<option value="false">False</option>
<option value="true">True</option>
@ -241,7 +227,7 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
<option value="true">Enable</option>
<option value="false">Disable</option>
</select>
<i class="fa fa-hand-o-right" style="margin-left:22px;"></i> Right click
<i class="fa fa-hand-o-right" style="margin-left:43px;"></i> Right click
<select id="node-input-hiderightclick" style="width:80px;">
<option value="false">Enable</option>
<option value="true">Disable</option>
@ -315,6 +301,37 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
</script>
<script type="text/javascript">
var mlist = [
{ value: "OSMG", label: "OpenStreetMap Greyscale" },
{ value: "OSMC", label: "OpenStreetMap" },
{ value: "OSMH", label: "OpenStreetMap Humanitarian" },
{ value: "EsriC", label: "ESRI Streetmap" },
{ value: "EsriS", label: "ESRI Satellite" },
{ value: "EsriT", label: "ESRI Topography" },
{ value: "EsriO", label: "ESRI Ocean" },
{ value: "EsriDG", label: "ESRI Dark Grey" },
{ value: "NatGeo", label: "National Geographic" },
{ value: "UKOS", label: "UK OS Opendata" },
{ value: "OS45", label: "UK OS 1919-47" },
{ value: "OS00", label: "UK OS 1900" },
{ value: "OpTop", label: "Open Topo Map" },
{ value: "HB", label: "Hike Bike OSM" },
{ value: "AN", label: "Autonavi (Chinese)" },
{ value: "ST", label: "Stamen Terrain" },
{ value: "SW", label: "Stamen Watercolor" }
]
var olist = [
{ value: "DR", label: "Drawing" },
{ value: "CO", label: "Countries" },
{ value: "RA", label: "Rainfall" },
{ value: "DN", label: "Day/Night" },
{ value: "BU", label: "Buildings" },
{ value: "RW", label: "Railways" },
{ value: "SN", label: "Ship Navigation" },
{ value: "AC", label: "Air Corridors" },
{ value: "TL", label: "Place Labels" },
{ value: "HM", label: "Heatmap" }
]
var lnk = document.location.host+RED.settings.httpNodeRoot+"/worldmap";
lnk = lnk.replace(new RegExp('\/{1,}','g'),'/');
if (!RED.hasOwnProperty("actions")) {
@ -345,6 +362,8 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
showgrid: {value:"false"},
allowFileDrop: {value:"false"},
path: {value:"/worldmap"},
overlist: {value:"DR,CO,RA,DN,HM"},
maplist: {value:"OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS,SW"},
mapname: {value:""},
mapurl: {value:""},
mapopt: {value:"", validate:function(v) {try{ v.length===0 || JSON.parse(v); return true;} catch(e) {return false;}}},
@ -364,6 +383,36 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
return 'The map can be found [here]('+RED.settings.httpNodeRoot.slice(0,-1)+this.path+').';
},
oneditprepare: function() {
if (this.maplist === undefined) {
$("#node-input-maplist").val("OSMG,OSMC,EsriC,EsriS,EsriT,EsriO,EsriDG,NatGeo,UKOS,OpTop,SW");
this.maplist = "OSMG,OSMC,EsriC,EsriS,EsriT,EsriO,EsriDG,NatGeo,UKOS,OpTop,SW";
}
if (this.overlist === undefined) {
$("#node-input-overlist").val("DR,CO,RA,DN,HM");
this.overlist = "DR,CO,RA,DN,HM";
}
$("#node-input-maplist").typedInput({type:"mapitem", types:[{
value: "mapitem",
multiple: true,
options: mlist
}]});
$("#node-input-layer").typedInput({type:"laye", types:[{
value: "laye",
options: mlist
}]});
$("#node-input-overlist").typedInput({type:"overlay", types:[{
value: "overlay",
multiple: true,
options: olist
}]});
$("#node-input-maplist").on('change', function(event, type, value) {
var mshort = mlist.filter(e => value.indexOf(e.value)!==-1);
mshort.push({ value:"Custom", label:"Custom Map Provider" });
$("#node-input-layer").typedInput("types", [{
value: "laye",
options: mshort
}]);
});
if ($("#node-input-path").val() === undefined) {
$("#node-input-path").val("worldmap");
this.path = "worldmap";
@ -425,6 +474,8 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
showgrid: {value:"false"},
allowFileDrop: {value:"false"},
path: {value:"/worldmap"},
overlist: {value:"DR,CO,RA,DN,HM"},
maplist: {value:"OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS,SW"},
mapname: {value:""},
mapurl: {value:""},
mapopt: {value:""},
@ -442,6 +493,36 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
if (this.maplist === undefined) {
$("#node-input-maplist").val("OSMG,OSMC,EsriC,EsriS,EsriT,EsriO,EsriDG,NatGeo,UKOS,OpTop,SW");
this.maplist = "OSMG,OSMC,EsriC,EsriS,EsriT,EsriO,EsriDG,NatGeo,UKOS,OpTop,SW";
}
if (this.overlist === undefined) {
$("#node-input-overlist").val("DR,CO,RA,DN,HM");
this.overlist = "DR,CO,RA,DN,HM";
}
$("#node-input-maplist").typedInput({type:"mapitem", types:[{
value: "mapitem",
multiple: true,
options: mlist
}]});
$("#node-input-layer").typedInput({type:"laye", types:[{
value: "laye",
options: mlist
}]});
$("#node-input-overlist").typedInput({type:"overlay", types:[{
value: "overlay",
multiple: true,
options: olist
}]});
$("#node-input-maplist").on('change', function(event, type, value) {
var mshort = mlist.filter(e => value.indexOf(e.value)!==-1);
mshort.push({ value:"Custom", label:"Custom Map Provider" });
$("#node-input-layer").typedInput("types", [{
value: "laye",
options: mshort
}]);
});
$("#node-input-size").elementSizer({
width: "#node-input-width",
height: "#node-input-height",
@ -477,18 +558,15 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
});
</script>
<script type="text/html" data-template-name="worldmap in">
<div class="form-row">
<label for="node-input-path"><i class="fa fa-globe"></i> Web Path</label>
<input type="text" id="node-input-path" placeholder="worldmap">
</div>
<div class="form-row">
<label for="node-input-events"><i class="fa fa-sign-out"></i> Output</label>
<select id="node-input-events" style="width:70%;">
<option value="all">All action events</option>
<option value="connect">Connect events only</option>
<option value="files">File events only</option>
</select>
<label for="node-input-events"><i class="fa fa-sign-out"></i> Events</label>
<input type="text" id="node-input-events" placeholder="select events">
</div>
<div class="form-row">
<label for="node-input-name"><i class="fa fa-file"></i> Name</label>
@ -526,7 +604,7 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
defaults: {
name: {value:""},
path: {value:"/worldmap"},
events: {value:"all"}
events: {value:"connect,disconnect,point,bounds,files,draw,other"}
},
inputs:0,
outputs:1,
@ -539,6 +617,27 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
},
info: function() {
return 'The map can be found [here]('+RED.settings.httpNodeRoot.slice(0,-1)+this.path+').';
},
oneditprepare: function() {
if ($("#node-input-events").val() === "all") {
$("#node-input-events").val("connect,disconnect,point,bounds,files,draw,other");
}
$("#node-input-events").typedInput({type:"event", types:[{
value: "event",
multiple: true,
options: [
{ value: "connect", label: "Connect"},
{ value: "disconnect", label: "Disconnect"},
{ value: "point", label: "Add, move, delete point"},
{ value: "bounds", label: "Boundary change"},
{ value: "files", label: "File drop"},
{ value: "draw", label: "Drawing"},
{ value: "other", label: "All other"}
]
}]});
$("#node-input-events").on('change', function(event, type, value) {
this.events = value;
});
}
});
</script>
@ -566,42 +665,42 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
<label for="node-input-name"><i class="fa fa-file"></i> Name</label>
<input type="text" id="node-input-name" placeholder="name">
</div>
</script>
</script>
<script type="text/html" data-help-name="worldmap-tracks">
<p>Creates tracks lines based on a specified number of previous locations.</p>
<p>The number of tracked points can be set per marker by specifying <code>msg.payload.trackpoints</code> as part of the update for a marker.</p>
<p>You can also specify the msg.payload.color, weight, opacity and dashArray properties for the track if required.</p>
<p>Holds all the points in memory, so if you have a lot of points held for a
large depth then memory usage may become excessive.</p>
<p>To delete a track send a msg.payload containing both the name of the object and
set deleted to true - for example <code>msg.payload = { "name":"Fred", "deleted":true }</code>.</p>
<p>This will also delete the point. If you just want to clear the track set the msg.payload to the
name+"_", for example <code>msg.payload = { "name":"Fred_", "deleted":true }</code></p>
</script>
<script type="text/html" data-help-name="worldmap-tracks">
<p>Creates tracks lines based on a specified number of previous locations.</p>
<p>The number of tracked points can be set per marker by specifying <code>msg.payload.trackpoints</code> as part of the update for a marker.</p>
<p>You can also specify the msg.payload.color, weight, opacity and dashArray properties for the track if required.</p>
<p>Holds all the points in memory, so if you have a lot of points held for a
large depth then memory usage may become excessive.</p>
<p>To delete a track send a msg.payload containing both the name of the object and
set deleted to true - for example <code>msg.payload = { "name":"Fred", "deleted":true }</code>.</p>
<p>This will also delete the point. If you just want to clear the track set the msg.payload to the
name+"_", for example <code>msg.payload = { "name":"Fred_", "deleted":true }</code></p>
</script>
<script type="text/javascript">
RED.nodes.registerType('worldmap-tracks',{
category: 'location',
color:"darksalmon",
defaults: {
name: {value:""},
depth: {value:20},
layer: {value:"combined"},
smooth: {value:false}
},
inputs:1,
outputs:1,
icon: "white-globe.png",
paletteLabel: "tracks",
label: function() {
return this.name||"tracks";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/javascript">
RED.nodes.registerType('worldmap-tracks',{
category: 'location',
color:"darksalmon",
defaults: {
name: {value:""},
depth: {value:20},
layer: {value:"combined"},
smooth: {value:false}
},
inputs:1,
outputs:1,
icon: "white-globe.png",
paletteLabel: "tracks",
label: function() {
return this.name||"tracks";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/html" data-template-name="worldmap-hull">
@ -613,33 +712,33 @@ If <i>Web Path</i> is left empty, then by default <code>⌘⇧m</code> - <code>c
<label for="node-input-name"><i class="fa fa-file"></i> Name</label>
<input type="text" id="node-input-name" placeholder="name">
</div>
</script>
</script>
<script type="text/html" data-help-name="worldmap-hull">
<p>Creates a convex-hull polygon around a set of supplied points.</p>
<p>Points can be made part of the same shape if they have the same <code>msg.payload.layer</code>
by default - this can be configured to another msg.payload property if desired.</p>
<p><b>Note</b>: the outgoing msg only contains the polygon to draw, so this node should be wired
in parallel to other paths going to the worldmap node.</p>
</script>
<script type="text/html" data-help-name="worldmap-hull">
<p>Creates a convex-hull polygon around a set of supplied points.</p>
<p>Points can be made part of the same shape if they have the same <code>msg.payload.layer</code>
by default - this can be configured to another msg.payload property if desired.</p>
<p><b>Note</b>: the outgoing msg only contains the polygon to draw, so this node should be wired
in parallel to other paths going to the worldmap node.</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('worldmap-hull',{
category: 'location',
color:"darksalmon",
defaults: {
name: {value:""},
prop: {value:"layer",required:true}
},
inputs:1,
outputs:1,
icon: "white-globe.png",
paletteLabel: "convex-hull",
label: function() {
return this.name||"convex-hull";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>
<script type="text/javascript">
RED.nodes.registerType('worldmap-hull',{
category: 'location',
color:"darksalmon",
defaults: {
name: {value:""},
prop: {value:"layer",required:true}
},
inputs:1,
outputs:1,
icon: "white-globe.png",
paletteLabel: "convex-hull",
label: function() {
return this.name||"convex-hull";
},
labelStyle: function() {
return this.name?"node_label_italic":"";
}
});
</script>

View File

@ -32,10 +32,14 @@ module.exports = function(RED) {
node.showgrid = n.showgrid || "false";
node.allowFileDrop = n.allowFileDrop || "false";
node.path = n.path || "/worldmap";
node.maplist = n.maplist;
node.overlist = n.overlist;
node.mapname = n.mapname || "";
node.mapurl = n.mapurl || "";
node.mapopt = n.mapopt || "";
node.mapwms = n.mapwms || false;
if (n.maplist === undefined) { node.maplist = "OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS,SW"; }
if (n.overlist === undefined) { node.overlist = "DR,CO,RA,DN,HM"; }
try { node.mapopt2 = JSON.parse(node.mapopt); }
catch(e) { node.mapopt2 = null; }
@ -43,7 +47,7 @@ module.exports = function(RED) {
if (!sockets[node.path]) {
var libPath = path.posix.join(RED.settings.httpNodeRoot, node.path, 'leaflet', 'sockjs.min.js');
var sockPath = path.posix.join(RED.settings.httpNodeRoot,node.path,'socket');
sockets[node.path] = sockjs.createServer({prefix:sockPath, sockjs_url:libPath, log:function() { return; }});
sockets[node.path] = sockjs.createServer({prefix:sockPath, sockjs_url:libPath, log:function(s,e) { return; }});
sockets[node.path].installHandlers(RED.server);
sockets[node.path].on('error', function(e) { node.error("Socket Connection Error: "+e.stack); });
}
@ -63,6 +67,8 @@ module.exports = function(RED) {
if (message.action === "connected") {
var m = {};
var c = {init:true};
c.maplist = node.maplist;
c.overlist = node.overlist;
if (node.layer && node.layer == "Custom") {
m.name = node.mapname;
m.url = node.mapurl;
@ -88,7 +94,8 @@ module.exports = function(RED) {
c.hiderightclick = node.hiderightclick;
c.allowFileDrop = node.allowFileDrop;
c.coords = node.coords;
c.toptitle = node.name;
if (node.name) { c.toptitle = node.name; }
//console.log("INIT",c)
client.write(JSON.stringify({command:c}));
}
});
@ -217,7 +224,7 @@ module.exports = function(RED) {
var WorldMapIn = function(n) {
RED.nodes.createNode(this,n);
this.path = n.path || "/worldmap";
this.events = n.events || "all";
this.events = n.events || "connect,disconnect,point,bounds,files,draw,other";
if (this.path.charAt(0) != "/") { this.path = "/" + this.path; }
if (!sockets[this.path]) {
var libPath = path.posix.join(RED.settings.httpNodeRoot, this.path, 'leaflet', 'sockjs.min.js');
@ -237,14 +244,23 @@ module.exports = function(RED) {
client.on('data', function(message) {
message = JSON.parse(message);
if (message.hasOwnProperty("action")) {
if ((node.events === "files") && (message.action === "file")) {
if ((node.events.indexOf("connect")!==-1) && (message.action === "connected")) {
setImmediate(function() {node.send({payload:message, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip})});
}
if ((node.events.indexOf("bounds")!==-1) && (message.action === "bounds")) {
setImmediate(function() {node.send({payload:message, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip})});
}
if ((node.events.indexOf("point")!==-1) && ((message.action === "point")||(message.action === "move")||(message.action === "delete") )) {
setImmediate(function() {node.send({payload:message, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip})});
}
if ((node.events.indexOf("files")!==-1) && (message.action === "file")) {
message.content = Buffer.from(message.content.split('base64,')[1], 'base64');
setImmediate(function() {node.send({payload:message, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip})});
}
else if ((node.events === "connect") && (message.action === "connected")) {
if ((node.events.indexOf("draw")!==-1) && (message.action === "draw")) {
setImmediate(function() {node.send({payload:message, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip})});
}
else if (node.events === "all") {
if (node.events.indexOf("other")!==-1 && "connected,point,delete,move,draw,files,bounds".indexOf(message.action) === -1) {
setImmediate(function() {node.send({payload:message, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip})});
}
}
@ -252,7 +268,7 @@ module.exports = function(RED) {
client.on('close', function() {
delete clients[client.id];
node.status({fill:"green",shape:"ring",text:"connected "+Object.keys(clients).length,_sessionid:client.id});
if (node.events !== "files") {
if (node.events.indexOf("disconnect")!==-1) {
node.send({payload:{action:"disconnect", clients:Object.keys(clients).length}, topic:node.path.substr(1), _sessionid:client.id, _sessionip:sessionip});
}
});

View File

@ -167,7 +167,7 @@
/* zoom and fade animations */
.leaflet-fade-anim .leaflet-tile {
will-change: opacity;
/* will-change: opacity; */
}
.leaflet-fade-anim .leaflet-popup {
opacity: 0;
@ -184,7 +184,7 @@
transform-origin: 0 0;
}
.leaflet-zoom-anim .leaflet-zoom-animated {
will-change: transform;
/* will-change: transform; */
}
.leaflet-zoom-anim .leaflet-zoom-animated {
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);

File diff suppressed because one or more lines are too long

View File

@ -5,11 +5,10 @@
* Author: lanwei@cloudybay.com.tw
*/
(function (window, document, undefined) {
(function (window, document, undefined) {
L.LatLngGraticule = L.Layer.extend({
includes: L.Mixin.Events,
includes: (L.Evented.prototype || L.Mixin.Events),
options: {
showLabel: true,
opacity: 1,
@ -25,7 +24,8 @@
{start: 4, end: 4, interval: 10},
{start: 5, end: 7, interval: 5},
{start: 8, end: 20, interval: 1}
]
],
sides: ['N', 'S', 'E', 'W']
},
initialize: function (options) {
@ -190,10 +190,10 @@
// todo: format type of float
if (lat < 0) {
return '' + (lat*-1) + 'S';
return '' + (lat*-1) + this.options.sides[1];
}
else if (lat > 0) {
return '' + lat + 'N';
return '' + lat + this.options.sides[0];
}
return '' + lat;
},
@ -205,19 +205,19 @@
// todo: format type of float
if (lng > 180) {
return '' + (360 - lng) + 'W';
return '' + (360 - lng) + this.options.sides[3];
}
else if (lng > 0 && lng < 180) {
return '' + lng + 'E';
return '' + lng + this.options.sides[2];
}
else if (lng < 0 && lng > -180) {
return '' + (lng*-1) + 'W';
return '' + (lng*-1) + this.options.sides[3];
}
else if (lng == -180) {
return '' + (lng*-1);
}
else if (lng < -180) {
return '' + (360 + lng) + 'W';
return '' + (360 + lng) + this.options.sides[3];
}
return '' + lng;
},
@ -308,7 +308,7 @@
var txtWidth = ctx.measureText('0').width;
var txtHeight = 12;
try {
var _font_size = ctx.font.split(' ')[0];
var _font_size = ctx.font.trim().split(' ')[0];
txtHeight = _parse_px_to_int(_font_size);
}
catch(e) {}
@ -358,6 +358,7 @@
ll = self._latLngToCanvasPoint(L.latLng(lat_tick, _lon_l));
latstr = self.__format_lat(lat_tick);
txtWidth = ctx.measureText(latstr).width;
var spacer = self.options.showLabel && label ? txtWidth + 10 : 0;
if (curvedLat) {
if (typeof(curvedLat) == 'number') {
@ -380,11 +381,11 @@
}
ctx.beginPath();
ctx.moveTo(ll.x, ll.y);
ctx.moveTo(ll.x + spacer, ll.y);
var _prev_p = null;
for (var j=__lon_left; j<=__lon_right; j+=_lon_delta) {
rr = self._latLngToCanvasPoint(L.latLng(lat_tick, j));
ctx.lineTo(rr.x, rr.y);
ctx.lineTo(rr.x - spacer, rr.y);
if (self.options.showLabel && label && _prev_p != null) {
if (_prev_p.x < 0 && rr.x >= 0) {
@ -417,8 +418,8 @@
}
ctx.beginPath();
ctx.moveTo(ll.x+1, ll.y);
ctx.lineTo(rr.x-1, rr.y);
ctx.moveTo(1 + spacer, ll.y);
ctx.lineTo(rr.x-1 - spacer, rr.y);
ctx.stroke();
if (self.options.showLabel && label) {
var _yy = ll.y + (txtHeight/2)-2;
@ -445,6 +446,7 @@
lngstr = self.__format_lng(lon_tick);
txtWidth = ctx.measureText(lngstr).width;
var bb = self._latLngToCanvasPoint(L.latLng(_lat_b, lon_tick));
var spacer = self.options.showLabel && label ? txtHeight + 5 : 0;
if (curvedLon) {
if (typeof(curvedLon) == 'number') {
@ -452,15 +454,15 @@
}
ctx.beginPath();
ctx.moveTo(bb.x, bb.y);
ctx.moveTo(bb.x, 5 + spacer);
var _prev_p = null;
for (var j=_lat_b; j<_lat_t; j+=_lat_delta) {
var tt = self._latLngToCanvasPoint(L.latLng(j, lon_tick));
ctx.lineTo(tt.x, tt.y);
ctx.lineTo(tt.x, tt.y - spacer);
if (self.options.showLabel && label && _prev_p != null) {
if (_prev_p.y > 8 && tt.y <= 8) {
ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight);
ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight + 5);
}
else if (_prev_p.y >= hh && tt.y < hh) {
ctx.fillText(lngstr, tt.x - (txtWidth/2), hh-2);
@ -487,12 +489,12 @@
}
ctx.beginPath();
ctx.moveTo(tt.x, tt.y+1);
ctx.lineTo(bb.x, bb.y-1);
ctx.moveTo(tt.x, 5 + spacer);
ctx.lineTo(bb.x, hh-1 - spacer);
ctx.stroke();
if (self.options.showLabel && label) {
ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight+1);
ctx.fillText(lngstr, tt.x - (txtWidth/2), txtHeight+5);
ctx.fillText(lngstr, bb.x - (txtWidth/2), hh-3);
}
}

View File

@ -24,6 +24,7 @@ var showUserMenu = true;
var showLayerMenu = true;
var showMouseCoords = false;
var allowFileDrop = false;
var heat;
var minimap;
var sidebyside;
var layercontrol;
@ -112,7 +113,9 @@ var handleData = function(data) {
if (data.hasOwnProperty("type") && data.type.indexOf("Feature") === 0) { doGeojson("geojson",data); }
else if (data.hasOwnProperty("name")) { setMarker(data); }
else {
console.log("SKIP",data);
if (JSON.stringify(data) !== '{}') {
console.log("SKIP",data);
}
// if (typeof data === "string") { doDialog(data); }
// else { console.log("SKIP",data); }
}
@ -410,7 +413,7 @@ setMaxAge();
// move the daylight / nighttime boundary (if enabled) every minute
function moveTerminator() { // if terminator line plotted move it every minute
if (layers["_daynight"].getLayers().length > 0) {
if (layers["_daynight"] && layers["_daynight"].getLayers().length > 0) {
layers["_daynight"].clearLayers();
layers["_daynight"].addLayer(L.terminator());
}
@ -590,7 +593,7 @@ map.on('baselayerchange', function(e) {
});
function showMapCurrentZoom() {
console.log("zoom:",map.getZoom(),". clusterAt:",clusterAt);
//console.log("zoom:",map.getZoom());
for (var l in layers) {
if (layers[l].hasOwnProperty("_zoom")) {
if (map.getZoom() >= clusterAt) {
@ -727,378 +730,453 @@ map.on('contextmenu', function(e) {
}
});
// Add all the base layer maps
if (navigator.onLine) {
// Add all the base layer maps if we are online.
var addBaseMaps = function(maplist,first) {
//console.log("MAPS",first,maplist)
if (navigator.onLine) {
var layerlookup = { OSMG:"OSM grey", OSMC:"OSM", OSMH:"OSM Humanitarian", EsriC:"Esri", EsriS:"Esri Satellite",
EsriT:"Esri Topography", EsriO:"Esri Ocean", EsriDG:"Esri Dark Grey", NatGeo: "National Geographic",
UKOS:"UK OS OpenData", UKOS45:"UK OS 1919-1947", UKOS00:"UK OS 1900", OpTop:"Open Topo Map",
HB:"Hike Bike OSM", ST:"Stamen Topography", SW: "Stamen Watercolor", AN:"AutoNavi (Chinese)" }
// Use this for OSM online maps
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
//var osmUrl='https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png';
var osmAttrib='Map data © OpenStreetMap contributors';
var osmg = new L.TileLayer.Grayscale(osmUrl, {attribution:osmAttrib, maxNativeZoom:19, maxZoom:20});
basemaps["OSM grey"] = osmg;
// Use this for OSM online maps
var osmUrl='https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
var osmAttrib='Map data © OpenStreetMap contributors';
var osm = new L.TileLayer(osmUrl, {attribution:osmAttrib, maxNativeZoom:19, maxZoom:20});
basemaps["OSM"] = osm;
if (maplist.indexOf("OSMG")!==-1) {
basemaps[layerlookup["OSMG"]] = new L.TileLayer.Grayscale(osmUrl, {
attribution:osmAttrib,
maxNativeZoom:19,
maxZoom:20,
subdomains: ['a','b','c']
});
}
if (maplist.indexOf("OSMC")!==-1) {
basemaps[layerlookup["OSMC"]] = new L.TileLayer(osmUrl, {
attribution:osmAttrib,
maxNativeZoom:19,
maxZoom:20,
subdomains: ['a','b','c']
});
}
if (maplist.indexOf("OSMH")!==-1) {
basemaps[layerlookup["OSMH"]] = new L.TileLayer("https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", {
attribution:"Map data © OpenStreetMap Contributors. Courtesy of Humanitarian OpenStreetMap Team",
maxNativeZoom:19,
maxZoom:20,
subdomains: ['a','b']
});
}
// Extra Leaflet map layers from https://leaflet-extras.github.io/leaflet-providers/preview/
var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri', maxNativeZoom:19, maxZoom:20
});
basemaps["Esri"] = Esri_WorldStreetMap;
// Extra Leaflet map layers from https://leaflet-extras.github.io/leaflet-providers/preview/
if (maplist.indexOf("EsriC")!==-1) {
basemaps[layerlookup["EsriC"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution:'Tiles &copy; Esri',
maxNativeZoom:19,
maxZoom:20
});
}
var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
//var Esri_WorldImagery = L.tileLayer('http://clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution:'Tiles &copy; Esri', maxNativeZoom:17, maxZoom:20
});
basemaps["Esri Satellite"] = Esri_WorldImagery;
if (maplist.indexOf("EsriS")!==-1) {
basemaps[layerlookup["EsriS"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
//var Esri_WorldImagery = L.tileLayer('http://clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {{
attribution:'Tiles &copy; Esri',
maxNativeZoom:17, maxZoom:20
});
}
var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
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'
});
basemaps["Esri Topography"] = Esri_WorldTopoMap;
if (maplist.indexOf("EsriT")!==-1) {
basemaps[layerlookup["EsriT"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
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'
});
}
// var Esri_WorldShadedRelief = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
// attribution: 'Tiles &copy; Esri',
// maxNativeZoom:13
// });
// basemaps["Esri Terrain"] = Esri_WorldShadedRelief;
if (maplist.indexOf("EsriR")!==-1) {
basemaps[layerlookup["EsriR"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}', {
attribution:'Tiles &copy; Esri',
maxNativeZoom:13
});
}
var Esri_OceanBasemap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
maxNativeZoom:13
});
basemaps["Esri Ocean"] = Esri_OceanBasemap;
if (maplist.indexOf("EsriO")!==-1) {
basemaps[layerlookup["EsriO"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Ocean_Basemap/MapServer/tile/{z}/{y}/{x}', {
attribution:'Tiles &copy; Esri &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri',
maxNativeZoom:13
});
}
var Esri_WorldGrayCanvas = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
maxNativeZoom:13
});
basemaps["Esri Dark Grey"] = Esri_WorldGrayCanvas;
if (maplist.indexOf("EsriDG")!==-1) {
basemaps[layerlookup["EsriDG"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
maxNativeZoom:13
});
}
// var OpenMapSurfer_Roads = L.tileLayer('https://korona.geog.uni-heidelberg.de/tiles/roads/x={x}&y={y}&z={z}', {
// maxZoom: 18,
// 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>'
// });
// basemaps["Mapsurfer"] = OpenMapSurfer_Roads;
if (maplist.indexOf("NatGeo")!==-1) {
basemaps[layerlookup["NatGeo"]] = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri',
maxNativeZoom:12
});
}
// var MapQuestOpen_OSM = L.tileLayer('https://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.{ext}', {
// type: 'map',
// ext: 'jpg',
// 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>',
// subdomains: '1234',
// maxNativeZoom: 17
// });
//basemaps["MapQuest OSM"] = MapQuestOpen_OSM;
if (maplist.indexOf("UKOS")!==-1) {
basemaps[layerlookup["UKOS"]] = L.tileLayer('https://geo.nls.uk/maps/opendata/{z}/{x}/{y}.png', {
attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom:1, maxNativeZoom:17, maxZoom:20,
subdomains: '0123'
});
}
var Esri_NatGeoWorldMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri',
maxNativeZoom:12
});
basemaps["Nat Geo"] = Esri_NatGeoWorldMap;
if (maplist.indexOf("OpTop")!==-1) {
basemaps[layerlookup["OpTop"]] = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
subdomains: 'abc',
maxZoom: 19,
attribution: '&copy; <a href="https://www.opentopomap.org/copyright">OpenTopoMap</a> contributors'
});
}
var NLS_OS_opendata = L.tileLayer('https://geo.nls.uk/maps/opendata/{z}/{x}/{y}.png', {
attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom:1, maxNativeZoom:18, maxZoom:18,
subdomains: '0123'
});
basemaps["UK OS Opendata"] = NLS_OS_opendata;
if (maplist.indexOf("HB")!==-1) {
basemaps[layerlookup["HB"]] = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
});
}
var Open_Topo_Map = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
subdomains: 'abc',
maxZoom: 19,
attribution: '&copy; <a href="https://www.opentopomap.org/copyright">OpenTopoMap</a> contributors'
});
basemaps["Open Topo Map"] = Open_Topo_Map;
if (maplist.indexOf("AN")!==-1) {
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}', {
attribution: 'Tiles &copy; 高德地图',
maxNativeZoom:14,
maxZoom: 19,
});
}
var HikeBike_HikeBike = L.tileLayer('https://tiles.wmflabs.org/hikebike/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
});
basemaps["Hike Bike"] = HikeBike_HikeBike;
if (maplist.indexOf("OS45")!==-1) {
basemaps[layerlookup["OS45"]] = L.tileLayer( 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
attribution: 'Historical Maps Layer, from <a href="https://maps.nls.uk/projects/api/">NLS Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom:1, maxZoom:18,
subdomains: '0123'
});
}
var NLS_OS_1919_1947 = L.tileLayer( 'https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg', {
attribution: 'Historical Maps Layer, from <a href="https://maps.nls.uk/projects/api/">NLS Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom:1, maxZoom:18,
subdomains: '0123'
});
basemaps["UK OS 1919-47"] = NLS_OS_1919_1947;
if (maplist.indexOf("OS00")!==-1) {
//var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/NLS_API/{z}/{x}/{y}.jpg', {
basemaps[layerlookup["OS00"]] = L.tileLayer('https://nls-{s}.tileserver.com/fpsUZbzrfb5d/{z}/{x}/{y}.jpg', {
attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom:1, maxNativeZoom:19, maxZoom:20,
subdomains: '0123'
});
}
//var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/NLS_API/{z}/{x}/{y}.jpg', {
var NLS_OS_1900 = L.tileLayer('https://nls-{s}.tileserver.com/fpsUZbzrfb5d/{z}/{x}/{y}.jpg', {
attribution: '<a href="https://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',
bounds: [[49.6, -12], [61.7, 3]],
minZoom:1, maxNativeZoom:19, maxZoom:20,
subdomains: '0123'
});
basemaps["UK OS 1900"] = NLS_OS_1900;
// Nice terrain based maps by Stamen Design
if (maplist.indexOf("ST")!==-1) {
var terrainUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg";
basemaps[layerlookup["ST"]] = L.tileLayer(terrainUrl, {
subdomains: ['a','b','c','d'],
minZoom: 0,
maxZoom: 20,
type: 'jpg',
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>'
});
}
//var CartoPos = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
// attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, &copy; <a href="https://cartodb.com/attributions">CartoDB</a>'
//});
//basemaps["CartoDB Light"] = CartoPos;
// Nice watercolour based maps by Stamen Design
if (maplist.indexOf("SW")!==-1) {
var watercolorUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg";
basemaps[layerlookup["SW"]] = L.tileLayer(watercolorUrl, {
subdomains: ['a','b','c','d'],
minZoom: 0,
maxZoom: 20,
type: 'jpg',
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>'
});
}
// Nice terrain based maps by Stamen Design
var terrainUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/terrain/{z}/{x}/{y}.jpg";
basemaps["Terrain"] = L.tileLayer(terrainUrl, {
subdomains: ['a','b','c','d'],
minZoom: 0,
maxZoom: 20,
type: 'jpg',
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>'
});
// Nice watercolour based maps by Stamen Design
var watercolorUrl = "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.jpg";
basemaps["Watercolor"] = L.tileLayer(watercolorUrl, {
subdomains: ['a','b','c','d'],
minZoom: 0,
maxZoom: 20,
type: 'jpg',
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>'
});
if (first) {
if (layerlookup[first]) { basemaps[layerlookup[first]].addTo(map); }
else { basemaps[first].addTo(map); }
}
else {
basemaps[Object.keys(basemaps)[0]].addTo(map);
}
if (showLayerMenu) {
map.removeControl(layercontrol);
layercontrol = L.control.layers(basemaps, overlays).addTo(map);
}
}
}
// Now add the overlays
var addOverlays = function(overlist) {
//console.log("OVERLAYS",overlist)
// var overlookup = { DR:"Drawing", CO:"Countries", DN:"Day/Night", BU:"Buildings", SN:"Ship Navigaion", HM:"Heatmap", AC:"Air corridors", TL:"Place labels" };
// "DR,CO,DN,BU,SN,HM"
// Add the drawing layer for fun...
layers["_drawing"] = new L.FeatureGroup();
overlays["drawing"] = layers["_drawing"];
map.options.drawControlTooltips = false;
var drawCount = 0;
var drawControl = new L.Control.Draw({
draw: {
polyline: { shapeOptions: { clickable:true } },
marker: false,
//circle: false,
circle: { shapeOptions: { clickable:true } },
circlemarker: false,
rectangle: { shapeOptions: { clickable:true } },
polygon: { shapeOptions: { clickable:true } }
}
//edit: none
// {
// featureGroup: layers["_drawing"],
// remove: true,
// edit: true
// }
});
var changeDrawColour = function(col) {
drawControl.setDrawingOptions({
polyline: { shapeOptions: { color:col } },
circle: { shapeOptions: { color:col } },
rectangle: { shapeOptions: { color:col } },
polygon: { shapeOptions: { color:col } }
});
}
var shape;
map.on('draw:created', function (e) {
var name = e.layerType + drawCount;
drawCount = drawCount + 1;
e.layer.on('contextmenu', function(e) {
L.DomEvent.stopPropagation(e);
var rmen = L.popup({offset:[0,-12]}).setLatLng(e.latlng);
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>");
map.openPopup(rmen);
});
var la, lo, cent;
if (e.layer.hasOwnProperty("_latlng")) {
la = e.layer._latlng.lat;
lo = e.layer._latlng.lng;
cent = e.layer._latlng;
}
else {
cent = e.layer.getBounds().getCenter();
}
var m = {action:"draw", name:name, layer:"_drawing", options:e.layer.options, radius:e.layer._mRadius, lat:la, lon:lo};
if (e.layer.hasOwnProperty("_latlngs")) {
if (e.layer.options.fill === false) { m.line = e.layer._latlngs; }
else { m.area = e.layer._latlngs[0]; }
}
shape = {m:m, layer:e.layer};
polygons[name] = shape.layer;
polygons[name].lay = "_drawing";
polygons[name].name = name;
layers["_drawing"].addLayer(shape.layer);
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>");
if (e.layer.options.fill === false && navigator.onLine) {
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>");
}
rightmenuMarker.setLatLng(cent);
setTimeout(function() {map.openPopup(rightmenuMarker)},25);
});
var defaultOptions = function () {
var options = {};
options.precision = 5;
options.factor = Math.pow(10, options.precision);
options.dimension = 2;
return options;
};
var decode = function (encoded, options) {
options = defaultOptions(options);
var flatPoints = decodeDeltas(encoded);
var points = [];
for (var i = 0, len = flatPoints.length; i + (options.dimension - 1) < len;) {
var point = [];
for (var dim = 0; dim < options.dimension; ++dim) {
point.push(flatPoints[i++]);
}
points.push(point);
}
return points;
}
var decodeDeltas = function (encoded, options) {
options = defaultOptions(options);
var lastNumbers = [];
var numbers = decodeFloats(encoded, options);
for (var i = 0, len = numbers.length; i < len;) {
for (var d = 0; d < options.dimension; ++d, ++i) {
numbers[i] = Math.round((lastNumbers[d] = numbers[i] + (lastNumbers[d] || 0)) * options.factor) / options.factor;
}
}
return numbers;
}
var decodeFloats = function (encoded, options) {
options = defaultOptions(options);
var numbers = decodeSignedIntegers(encoded);
for (var i = 0, len = numbers.length; i < len; ++i) {
numbers[i] /= options.factor;
}
return numbers;
}
var decodeSignedIntegers = function (encoded) {
var numbers = decodeUnsignedIntegers(encoded);
for (var i = 0, len = numbers.length; i < len; ++i) {
var num = numbers[i];
numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
}
return numbers;
}
var decodeUnsignedIntegers = function (encoded) {
var numbers = [];
var current = 0;
var shift = 0;
for (var i = 0, len = encoded.length; i < len; ++i) {
var b = encoded.charCodeAt(i) - 63;
current |= (b & 0x1f) << shift;
if (b < 0x20) {
numbers.push(current);
current = 0;
shift = 0;
} else {
shift += 5;
}
}
return numbers;
}
var sendRoute = function(n) {
var p = (polygons[n]._latlngs.map(function(x) {
return x.lng+","+x.lat;
})).join(';');
fetch('https://router.project-osrm.org/route/v1/driving/'+p)
.then(response => response.json())
.then(data => {
if (data.code !== "Ok") { sendDrawing(n); }
var r = decode(data.routes[0].geometry).map( x => L.latLng(x[0],x[1]) );
polygons[n]._latlngs = r;
shape.m.line = r;
sendDrawing(n);
// Add the drawing layer...
if (overlist.indexOf("DR")!==-1) {
layers["_drawing"] = new L.FeatureGroup();
overlays["drawing"] = layers["_drawing"];
map.options.drawControlTooltips = false;
var drawCount = 0;
var drawControl = new L.Control.Draw({
draw: {
polyline: { shapeOptions: { clickable:true } },
marker: false,
//circle: false,
circle: { shapeOptions: { clickable:true } },
circlemarker: false,
rectangle: { shapeOptions: { clickable:true } },
polygon: { shapeOptions: { clickable:true } }
}
//edit: none
// {
// featureGroup: layers["_drawing"],
// remove: true,
// edit: true
// }
});
}
var changeDrawColour = function(col) {
drawControl.setDrawingOptions({
polyline: { shapeOptions: { color:col } },
circle: { shapeOptions: { color:col } },
rectangle: { shapeOptions: { color:col } },
polygon: { shapeOptions: { color:col } }
});
}
var shape;
map.on('draw:created', function (e) {
var name = e.layerType + drawCount;
drawCount = drawCount + 1;
var sendDrawing = function(n) {
var thing = document.getElementById('dinput').value;
map.closePopup();
shape.m.name = thing;
delMarker(n,true);
e.layer.on('contextmenu', function(e) {
L.DomEvent.stopPropagation(e);
var rmen = L.popup({offset:[0,-12]}).setLatLng(e.latlng);
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>");
map.openPopup(rmen);
});
polygons[thing] = shape.layer;
polygons[thing].lay = "_drawing";
polygons[thing].name = thing;
layers["_drawing"].addLayer(shape.layer);
ws.send(JSON.stringify(shape.m));
}
var la, lo, cent;
if (e.layer.hasOwnProperty("_latlng")) {
la = e.layer._latlng.lat;
lo = e.layer._latlng.lng;
cent = e.layer._latlng;
}
else {
cent = e.layer.getBounds().getCenter();
}
var m = {action:"draw", name:name, layer:"_drawing", options:e.layer.options, radius:e.layer._mRadius, lat:la, lon:lo};
if (e.layer.hasOwnProperty("_latlngs")) {
if (e.layer.options.fill === false) { m.line = e.layer._latlngs; }
else { m.area = e.layer._latlngs[0]; }
}
// Add the countries (world-110m) for offline use
var customTopoLayer = L.geoJson(null, {clickable:false, style: {color:"blue", weight:2, fillColor:"#cf6", fillOpacity:0.04}});
layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,customTopoLayer);
overlays["countries"] = layers["_countries"];
shape = {m:m, layer:e.layer};
polygons[name] = shape.layer;
polygons[name].lay = "_drawing";
polygons[name].name = name;
layers["_drawing"].addLayer(shape.layer);
// Add the day/night overlay
layers["_daynight"] = new L.LayerGroup();
overlays["day/night"] = layers["_daynight"];
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>");
if (e.layer.options.fill === false && navigator.onLine) {
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>");
}
rightmenuMarker.setLatLng(cent);
setTimeout(function() {map.openPopup(rightmenuMarker)},25);
});
// Add live rain data
if (navigator.onLine) {
overlays["rainfall"] = new L.TileLayer('https://tilecache.rainviewer.com/v2/radar/' + parseInt(Date.now()/600000)*600 + '/256/{z}/{x}/{y}/2/1_1.png', {
tileSize: 256,
opacity: 0.4,
transparent: true,
attribution: '<a href="https://rainviewer.com" target="_blank">rainviewer.com</a>'
});
var sendDrawing = function(n) {
var thing = document.getElementById('dinput').value;
map.closePopup();
shape.m.name = thing;
delMarker(n,true);
polygons[thing] = shape.layer;
polygons[thing].lay = "_drawing";
polygons[thing].name = thing;
layers["_drawing"].addLayer(shape.layer);
ws.send(JSON.stringify(shape.m));
}
var defaultOptions = function () {
var options = {};
options.precision = 5;
options.factor = Math.pow(10, options.precision);
options.dimension = 2;
return options;
};
var decode = function (encoded, options) {
options = defaultOptions(options);
var flatPoints = decodeDeltas(encoded);
var points = [];
for (var i = 0, len = flatPoints.length; i + (options.dimension - 1) < len;) {
var point = [];
for (var dim = 0; dim < options.dimension; ++dim) {
point.push(flatPoints[i++]);
}
points.push(point);
}
return points;
}
var decodeDeltas = function (encoded, options) {
options = defaultOptions(options);
var lastNumbers = [];
var numbers = decodeFloats(encoded, options);
for (var i = 0, len = numbers.length; i < len;) {
for (var d = 0; d < options.dimension; ++d, ++i) {
numbers[i] = Math.round((lastNumbers[d] = numbers[i] + (lastNumbers[d] || 0)) * options.factor) / options.factor;
}
}
return numbers;
}
var decodeFloats = function (encoded, options) {
options = defaultOptions(options);
var numbers = decodeSignedIntegers(encoded);
for (var i = 0, len = numbers.length; i < len; ++i) {
numbers[i] /= options.factor;
}
return numbers;
}
var decodeSignedIntegers = function (encoded) {
var numbers = decodeUnsignedIntegers(encoded);
for (var i = 0, len = numbers.length; i < len; ++i) {
var num = numbers[i];
numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);
}
return numbers;
}
var decodeUnsignedIntegers = function (encoded) {
var numbers = [];
var current = 0;
var shift = 0;
for (var i = 0, len = encoded.length; i < len; ++i) {
var b = encoded.charCodeAt(i) - 63;
current |= (b & 0x1f) << shift;
if (b < 0x20) {
numbers.push(current);
current = 0;
shift = 0;
} else {
shift += 5;
}
}
return numbers;
}
var sendRoute = function(n) {
var p = (polygons[n]._latlngs.map(function(x) {
return x.lng+","+x.lat;
})).join(';');
fetch('https://router.project-osrm.org/route/v1/driving/'+p)
.then(response => response.json())
.then(data => {
if (data.code !== "Ok") { sendDrawing(n); }
var r = decode(data.routes[0].geometry).map( x => L.latLng(x[0],x[1]) );
polygons[n]._latlngs = r;
shape.m.line = r;
sendDrawing(n);
});
}
}
// Add the countries (world-110m) for offline use
if (overlist.indexOf("CO")!==-1 || (!navigator.onLine)) {
var customTopoLayer = L.geoJson(null, {clickable:false, style: {color:"blue", weight:2, fillColor:"#cf6", fillOpacity:0.04}});
layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,customTopoLayer);
overlays["countries"] = layers["_countries"];
}
// Add the day/night overlay
if (overlist.indexOf("DN")!==-1) {
layers["_daynight"] = new L.LayerGroup();
overlays["day/night"] = layers["_daynight"];
}
// Add live rain data
if (overlist.indexOf("RA")!==-1) {
if (navigator.onLine) {
overlays["rainfall"] = new L.TileLayer('https://tilecache.rainviewer.com/v2/radar/' + parseInt(Date.now()/600000)*600 + '/256/{z}/{x}/{y}/2/1_1.png', {
tileSize: 256,
opacity: 0.4,
transparent: true,
attribution: '<a href="https://rainviewer.com" target="_blank">rainviewer.com</a>'
});
}
}
// Add the buildings layer
// overlays["buildings"] = new OSMBuildings(map).load();
// map.removeLayer(overlays["buildings"]); // Hide it at start
if (overlist.indexOf("BU")!==-1) {
overlays["buildings"] = new OSMBuildings(map).load();
// map.removeLayer(overlays["buildings"]); // Hide it at start
}
// Add Roads
// overlays["roads"] = L.tileLayer('https://{s}.tile.openstreetmap.se/hydda/roads_and_labels/{z}/{x}/{y}.png', {
// maxZoom: 18,
// 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>',
// opacity: 0.8
// });
// Add Railways
if (overlist.indexOf("RW")!==-1) {
// eg https://a.tiles.openrailwaymap.org/standard/11/1015/686.png
overlays["railways"] = L.tileLayer('https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', {
maxZoom: 19,
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>)'
});
}
// // Add Railways
// overlays["railways"] = L.tileLayer('https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png', {
// maxZoom: 19,
// 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>)'
// });
// // Add Public Transport (Buses)
// overlays["public transport"] = L.tileLayer('https://openptmap.org/tiles/{z}/{x}/{y}.png', {
// maxZoom: 17,
// attribution: 'Map data: &copy; <a href="https://www.openptmap.org">OpenPtMap</a> contributors'
// });
// Add Air Corridors
if (overlist.indexOf("AC")!==-1) {
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}', {
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>)',
ext: 'png',
minZoom: 4,
maxZoom: 15,
maxNativeZoom: 14,
tms: true,
detectRetina: true,
subdomains: '12'
});
}
// Add the OpenSea markers layer
overlays["ship nav"] = L.tileLayer('https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: 'Map data: &copy; <a href="https://www.openseamap.org">OpenSeaMap</a> contributors'
});
}
if (overlist.indexOf("SN")!==-1) {
overlays["ship nav"] = L.tileLayer('https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: 'Map data: &copy; <a href="https://www.openseamap.org">OpenSeaMap</a> contributors'
});
}
// Add the heatmap layer
var heat = L.heatLayer([], {radius:60, gradient:{0.2:'blue', 0.4:'lime', 0.6:'red', 0.8:'yellow', 1:'white'}});
layers["_heat"] = new L.LayerGroup().addLayer(heat);
overlays["heatmap"] = layers["_heat"];
// Add the Stamen Toner Labels layer
if (overlist.indexOf("TL")!==-1) {
overlays["place labels"] = L.tileLayer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-labels/{z}/{x}/{y}{r}.{ext}', {
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',
subdomains: 'abcd',
minZoom: 0,
maxZoom: 20,
ext: 'png'
});
}
if (showUserMenu) {
if ( window.localStorage.hasOwnProperty("lastlayer") ) {
if ( basemaps[window.localStorage.getItem("lastlayer")] ) {
baselayername = window.localStorage.getItem("lastlayer");
}
// Add the heatmap layer
if (overlist.indexOf("HM")!==-1) {
heat = L.heatLayer([], {radius:60, gradient:{0.2:'blue', 0.4:'lime', 0.6:'red', 0.8:'yellow', 1:'white'}});
layers["_heat"] = new L.LayerGroup().addLayer(heat);
overlays["heatmap"] = layers["_heat"];
}
if (showLayerMenu) {
map.removeControl(layercontrol);
layercontrol = L.control.layers(basemaps, overlays).addTo(map);
}
}
if (navigator.onLine) { basemaps[baselayername].addTo(map); }
// Layer control based on select box rather than radio buttons.
//var layercontrol = L.control.selectLayers(basemaps, overlays).addTo(map);
layercontrol = L.control.layers(basemaps, overlays);
var layercontrol = L.control.layers(basemaps, overlays);
// Add the layers control widget
if (!inIframe) { layercontrol.addTo(map); }
@ -1891,7 +1969,7 @@ function setMarker(data) {
fb.action = "click";
ws.send(JSON.stringify(fb));
});
if ((data.addtoheatmap !== "false") || (!data.hasOwnProperty("addtoheatmap"))) { // Added to give ability to control if points from active layer contribute to heatmap
if (heat && ((data.addtoheatmap !== "false") || (!data.hasOwnProperty("addtoheatmap")))) { // Added to give ability to control if points from active layer contribute to heatmap
if (heatAll || map.hasLayer(layers[lay])) { heat.addLatLng(lli); }
}
markers[data.name] = marker;
@ -1962,7 +2040,13 @@ function setMarker(data) {
// handle any incoming COMMANDS to control the map remotely
function doCommand(cmd) {
//console.log("COMMAND",cmd);
// console.log("COMMAND",cmd);
if (cmd.init && cmd.hasOwnProperty("maplist")) {
addBaseMaps(cmd.maplist,cmd.layer);
}
if (cmd.init && cmd.hasOwnProperty("overlist")) {
addOverlays(cmd.overlist);
}
if (cmd.hasOwnProperty("toptitle")) {
if (!inIframe ) {
document.title = cmd.toptitle;
@ -2089,7 +2173,7 @@ function doCommand(cmd) {
var existsalready = false;
// Add a new base map layer
if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.name.length>0 && cmd.map.hasOwnProperty("url") && cmd.map.hasOwnProperty("opt")) {
console.log("BASE",cmd.map);
if (basemaps.hasOwnProperty(cmd.map.name)) { existsalready = true; }
if (cmd.map.hasOwnProperty("wms")) { // special case for wms