Add ability for pmtiles to be slightly styled

bump to 4.6.0
This commit is contained in:
Dave Conway-Jones 2023-12-13 15:29:19 +00:00
parent 4b0c979d27
commit 706ace2769
No known key found for this signature in database
GPG Key ID: 1DDB0E91A28C2643
5 changed files with 31 additions and 6 deletions

View File

@ -1,5 +1,6 @@
### Change Log for Node-RED Worldmap ### Change Log for Node-RED Worldmap
- v4.6.0 - let default pmtiles be light/dark or monocolored.
- v4.5.2 - Tidy up when pmtiles removed. - v4.5.2 - Tidy up when pmtiles removed.
- v4.5.0 - Fix pmtiles to look for maps in userdir rather than modules. - v4.5.0 - Fix pmtiles to look for maps in userdir rather than modules.
- v4.4.0 - Add quad(copter) drone icon. - v4.4.0 - Add quad(copter) drone icon.

View File

@ -13,6 +13,7 @@ Feel free to [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%
### Updates ### Updates
- v4.6.0 - let default pmtiles be light/dark or monocolored.
- v4.5.2 - Tidy up when pmtiles removed. - v4.5.2 - Tidy up when pmtiles removed.
- v4.5.0 - Fix pmtiles to look for maps in userdir rather than modules - v4.5.0 - Fix pmtiles to look for maps in userdir rather than modules
- v4.4.0 - Add quad(copter) drone icon. - v4.4.0 - Add quad(copter) drone icon.
@ -724,9 +725,23 @@ You can use a PMtiles format map archive file from [Protomaps](https://docs.prot
Copy your .pmtiles file(s) into your `~/.node-red` user directory. On re-starting Node-RED the node will detect the file(s) and add them to the base map layer menu, using the file name as the layer name. Copy your .pmtiles file(s) into your `~/.node-red` user directory. On re-starting Node-RED the node will detect the file(s) and add them to the base map layer menu, using the file name as the layer name.
You can set some default options for the pmtiles by creating a file called **pmtiles.opts** in your user directory. For example to create a nightvision style
{
"attribution": "Protomaps and OSM",
"maxDataZoom": 15,
"maxZoom": 20,
"shade": "red",
"dark": true
}
The `maxDataZoom` should match the maximum zoom level in you pmtiles file(s) - whereas the `maxZoom` is the leaflet maximum zoom level you want to support. `shade` can be any valid html colour or #rrggbb string, and `dark` is a boolean (default false).
You can also load them dynamically with a command like You can also load them dynamically with a command like
msg.payload = {"command":{"map":{"name":"MyMap","pmtiles":"/path/to/mymap.pmtiles"}}} msg.payload = {"command":{"map":{"name":"MyMap", "pmtiles":"/path/to/mymap.pmtiles", "opt":"myOptionsObject"}}}
Where `opt` can be as per the options file mentioned above - or omitted completely.
### Using a Docker Map Server ### Using a Docker Map Server

View File

@ -1,6 +1,6 @@
{ {
"name": "node-red-contrib-web-worldmap", "name": "node-red-contrib-web-worldmap",
"version": "4.5.2", "version": "4.6.0",
"description": "A Node-RED node to provide a web page of a world map for plotting things on.", "description": "A Node-RED node to provide a web page of a world map for plotting things on.",
"dependencies": { "dependencies": {
"@turf/bezier-spline": "~6.5.0", "@turf/bezier-spline": "~6.5.0",

View File

@ -16,6 +16,12 @@ module.exports = function(RED) {
var pmtiles = fs.readdirSync(__dirname + '/worldmap').filter(fn => fn.endsWith('.pmtiles')); var pmtiles = fs.readdirSync(__dirname + '/worldmap').filter(fn => fn.endsWith('.pmtiles'));
pmtiles.forEach(file => { fs.unlinkSync(__dirname + '/worldmap/'+file); }) pmtiles.forEach(file => { fs.unlinkSync(__dirname + '/worldmap/'+file); })
pmtiles = fs.readdirSync(RED.settings.userDir).filter(fn => fn.endsWith('.pmtiles')); pmtiles = fs.readdirSync(RED.settings.userDir).filter(fn => fn.endsWith('.pmtiles'));
var pmtilesopts;
try {
pmtilesopts = fs.readFileSync(RED.settings.userDir+'/pmtiles.opts');
pmtilesopts = JSON.parse(pmtilesopts);
}
catch(e) {};
function worldMap(node, n) { function worldMap(node, n) {
var allPoints = {}; var allPoints = {};
@ -128,7 +134,7 @@ module.exports = function(RED) {
if (err.code !== "EEXIST") { console.log(err); } if (err.code !== "EEXIST") { console.log(err); }
} }
}) })
client.write(JSON.stringify({command: {map: {name:pmtiles[p].split('.')[0], pmtiles:pmtiles[p] }}})); client.write(JSON.stringify({command: {map: {name:pmtiles[p].split('.')[0], pmtiles:pmtiles[p], opt:pmtilesopts }}}));
} }
var o = Object.values(allPoints); var o = Object.values(allPoints);
o.map(v => delete v.tout); o.map(v => delete v.tout);

View File

@ -1296,7 +1296,7 @@ var addOverlays = function(overlist) {
changeDrawColour("#4040F0"); // Set default drawing color to blue on start changeDrawColour("#4040F0"); // Set default drawing color to blue on start
} }
// Add the countries (world-110m) for offline use // Add the countries (world-50m geojson) outline for offline use
if (overlist.indexOf("CO") !== -1 || !navigator.onLine) { if (overlist.indexOf("CO") !== -1 || !navigator.onLine) {
var customTopoLayer = L.geoJson(null, {clickable:false, style: {color:"blue", weight:2, fillColor:"#cf6", fillOpacity:0.04}}); 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); layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,customTopoLayer);
@ -2605,11 +2605,14 @@ function doCommand(cmd) {
existsalready = true; existsalready = true;
} }
var opt = {}; var opt = {};
if (cmd.map.hasOwnProperty("opt")) { opt = cmd.map.opt; } if (cmd.map.hasOwnProperty("opt")) { opt = cmd.map.opt || {}; }
opt.url = cmd.map.pmtiles; opt.url = cmd.map.pmtiles;
opt.attribution = opt.attribution || '© Protomaps'; opt.attribution = opt.attribution || '© Protomaps & OSM';
opt.maxDataZoom = opt.maxDataZoom || 15; opt.maxDataZoom = opt.maxDataZoom || 15;
opt.maxZoom = opt.maxZoom || 20; opt.maxZoom = opt.maxZoom || 20;
// opt.shade = "grey";
// opt.dark = false;
// opt.xray = true;
console.log("New PMtiles:",cmd.map.name,opt); console.log("New PMtiles:",cmd.map.name,opt);
basemaps[cmd.map.name] = protomapsL.leafletLayer(opt); basemaps[cmd.map.name] = protomapsL.leafletLayer(opt);
if (!existsalready) { if (!existsalready) {