diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dec334..ad9852b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### Change Log for Node-RED Worldmap + - v4.1.0 - Add optional SOG, COG, altft, altm input properties. - v4.0.0 - Breaking - Better context menu variable substitution and retention Now uses ${name} syntax rather than $name so we can handle user defined variables in context menus. diff --git a/README.md b/README.md index 61b8a25..8f77c01 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Feel free to [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D% ### Updates +- v4.1.0 - Add optional SOG, COG, altft, altm input properties. - v4.0.0 - Breaking - Better context menu variable substitution and retention Now uses ${name} syntax rather than $name so we can handle user defined variables in context menus. - v3.2.0 - Sync up drawing sessions across browsers to same map @@ -49,15 +50,17 @@ The minimum **msg.payload** must contain `name`, `lat` and `lon` properties, for msg.payload = { "name":"Jason", "lat":51.05, "lon":-1.35 } -`name` must be a unique identifier across the whole map. Repeated location updates to the same `name` move the marker. +`name` **must** be a unique identifier across the whole map. Repeated location updates to the same `name` move the marker. Optional properties for **msg.payload** include - **deleted** : set to true to remove the named marker. (default false) - **draggable** : set to true to allow marker to be moved by the mouse. (default false) - **layer** : specify a layer on the map to add marker to. (default "unknown") - - **track | hdg | heading | bearing** : when combined with speed, draws a vector. (only first will be used) - - **speed** : when combined with track, hdg, heading, or bearing, draws a leader line vector. + - **track | hdg | heading | COG | bearing** : when combined with speed, draws a vector. (only first will be used) + - **speed** : when combined with track, hdg, heading, or bearing, draws a leader line vector - should be in m/s. Can also be specified as "20 kph", or "20 mph", or "20 kt". i.e a string with units. + - **SOG** : speed over ground - speed in knots. + - **alt | altitude | altft | altm** : Altitude in meters, but can use *altft* to specify feet instead. - **accuracy** : when combined with heading vector, draws an arc of possible direction. - **color** : CSS color name or #rrggbb value for heading vector line or accuracy polygon. - **icon** : font awesome icon name, weather-lite icon, :emoji name:, or https:// uri. diff --git a/worldmap/leaflet/leaflet.boatmarker.js b/worldmap/leaflet/leaflet.boatmarker.js index 29338d7..b38e2d4 100644 --- a/worldmap/leaflet/leaflet.boatmarker.js +++ b/worldmap/leaflet/leaflet.boatmarker.js @@ -7,7 +7,7 @@ /* BOAT ICON */ L.BoatIcon = L.Icon.extend({ options: { - iconSize: new L.Point(50, 50), + iconSize: new L.Point(52, 52), className: "leaflet-boat-icon", course: 0, color: "#8ED6FF", diff --git a/worldmap/worldmap.js b/worldmap/worldmap.js index 02d54d1..b4231d3 100644 --- a/worldmap/worldmap.js +++ b/worldmap/worldmap.js @@ -327,7 +327,7 @@ var errRing; function onLocationFound(e) { if (followState === true) { map.panTo(e.latlng); } if (followMode.icon) { - var self = {name:followMode.name || "self", lat:e.latlng.lat, lon:e.latlng.lng, hdg:e.heading, speed:(e.speed*3.6 ?? undefined), layer:followMode.layer, icon:followMode.icon, iconColor:followMode.iconColor ?? "#910000" }; + var self = {name:followMode.name || "self", lat:e.latlng.lat, lon:e.latlng.lng, hdg:e.heading, speed:(e.speed*1 ?? undefined), layer:followMode.layer, icon:followMode.icon, iconColor:followMode.iconColor ?? "#910000" }; setMarker(self); } if (e.heading !== null) { map.setBearing(e.heading); } @@ -342,7 +342,7 @@ function onLocationFound(e) { // L.polygon([ e.latlng, lla ], {color:"00ffff", weight:3, opacity:0.5, clickable:false}).addTo(map); // } } - ws.send(JSON.stringify({action:"point", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5), point:"self", hdg:e.heading, speed:(e.speed*3.6 ?? undefined)})); + ws.send(JSON.stringify({action:"point", lat:e.latlng.lat.toFixed(5), lon:e.latlng.lng.toFixed(5), point:"self", hdg:e.heading, speed:(e.speed*1 ?? undefined)})); } function onLocationError(e) { console.log(e.message); } @@ -1750,7 +1750,7 @@ function setMarker(data) { if (data.icon === "ship") { marker = L.boatMarker(ll, { title: data.name, - color: (data.iconColor ?? "blue") + color: (data.iconColor ?? "#5DADE2") }); marker.setHeading(dir); q = 'https://www.bing.com/images/search?q='+data.icon+'%20%2B"'+encodeURIComponent(data.name)+'"'; @@ -2113,6 +2113,16 @@ function setMarker(data) { data.alt = +(parseFloat(data.alt)).toFixed(2); } } + if (data.hasOwnProperty("altft")) { + data.alt = +(parseFloat(data.altft)).toFixed(2) + " ft"; + delete data.altft; + } + if (data.hasOwnProperty("altm")) { + data.alt = +(parseFloat(data.altm)).toFixed(2) + " m"; + delete data.altm; + } + if (data.sog) { data.speed = data.sog * 0.514444; data.sog = data.sog + " kt"; } // SOG is in knots + if (data.SOG) { data.speed = data.SOG * 0.514444; data.SOG = data.SOG + " kt"; } // SOG is in knots // remove items from list of properties, then add all others to popup if (data.hasOwnProperty("options")) { delete data.options; } @@ -2198,7 +2208,9 @@ function setMarker(data) { // Delete more already handled properties var llc = data.lineColor ?? data.color; delete data.lat; + delete data.latitude; delete data.lon; + delete data.longitude; if (data.arc) { delete data.arc; } if (data.layer) { delete data.layer; } if (data.lineColor) { delete data.lineColor; } @@ -2259,16 +2271,17 @@ function setMarker(data) { // else if (data.bearing !== undefined) { track = data.bearing; } // Now add any leader lines - var track = data.track ?? data.hdg ?? data.heading ?? data.bearing; + var track = data.track ?? data.COG ?? data.cog ?? data.hdg ?? data.heading ?? data.bearing; if (track != undefined) { // if there is a heading + // Speed is in m/s if (data.speed != null && data.length === undefined) { // and a speed - lets convert to a leader length data.length = parseFloat(data.speed || "0") * 60; - var re1 = new RegExp('kn|knot|kt','i'); + var re1 = new RegExp('kn|knot|kt|kts','i'); var re2 = new RegExp('kph|kmh','i'); var re3 = new RegExp('mph','i'); if ( re1.test(""+data.speed) ) { data.length = data.length * 0.514444; } - else if ( re2.test(""+data.speed) ) { data.length = data.length * 0.44704; } - else if ( re3.test(""+data.speed) ) { data.length = data.length * 0.277778; } + else if ( re2.test(""+data.speed) ) { data.length = data.length * 0.277778; } + else if ( re3.test(""+data.speed) ) { data.length = data.length * 0.44704; } } if (data.length !== undefined) { if (polygons[data.name] != null && !polygons[data.name].hasOwnProperty("_layers")) { @@ -2939,7 +2952,7 @@ function doCommand(cmd) { if (cmd.hasOwnProperty("rotation") && !isNaN(cmd.rotation)) { map.setBearing(-cmd.rotation); for (const item in allData) { - if (allData[item].hasOwnProperty("hdg") || allData[item].hasOwnProperty("heading") || allData[item].hasOwnProperty("bearing") || allData[item].hasOwnProperty("track")) { + if (allData[item].hasOwnProperty("hdg") || allData[item].hasOwnProperty("heading") || allData[item].hasOwnProperty("bearing") || allData[item].hasOwnProperty("track") || allData[item].hasOwnProperty("cog") || allData[item].hasOwnProperty("COG")) { setMarker(allData[item]); } }