From 444c1f1fcf9fb0d33a1720b24d9382d88ba1c260 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Thu, 9 Jul 2020 22:09:57 +0100 Subject: [PATCH] add covex-hull node and update info --- CHANGELOG.md | 3 +- README.md | 3 +- package.json | 2 +- worldmap.html | 140 ++++++++++++++++++++++++++++--------------- worldmap.js | 88 +++++++++++++++++++++++++++ worldmap/worldmap.js | 1 + 6 files changed, 185 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73989d7..78b977e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ### Change Log for Node-RED Worldmap - - v2.3.15 - Add heading to default addMarker, allow custom http icon size. + - v2.4.1 - Add convex-hull node for grouping objects. + - v2.3.16 - Add heading to default addMarker, allow custom http icon size. - v2.3.13 - Fix geoson feature properties fill color, and better marker handling - v2.3.11 - Better editing of drawing layer, add OpenTopoMap, and better Esri satellite - v2.3.10 - Improve geojson layer and name handling. diff --git a/README.md b/README.md index 8bf66b9..5e8a277 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,8 @@ map web page for plotting "things" on. ### Updates -- v2.3.15 - Add heading to default addMarker, allow custom http icon size. +- v2.4.1 - Add convex-hull node for grouping objects. +- v2.3.16 - Add heading to default addMarker, allow custom http icon size. - v2.3.13 - Fix geoson feature properties fill color, and better marker handling - v2.3.11 - Better editing of drawing layer, add OpenTopoMap, and better Esri satellite - v2.3.10 - Improve geojson layer and name handling. diff --git a/package.json b/package.json index ecf9c72..55b0416 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-web-worldmap", - "version": "2.3.15", + "version": "2.4.1", "description": "A Node-RED node to provide a web page of a world map for plotting things on.", "dependencies": { "cgi": "0.3.1", diff --git a/worldmap.html b/worldmap.html index 16f7ef3..05d20b9 100644 --- a/worldmap.html +++ b/worldmap.html @@ -504,54 +504,96 @@ then by default ⌘⇧m - ctrl-shift-m will load the m +
+ + points in track +
+
+ + +
+
+ + +
+ + + + + - - + + + + + + \ No newline at end of file diff --git a/worldmap.js b/worldmap.js index 8d6e871..d041559 100644 --- a/worldmap.js +++ b/worldmap.js @@ -366,6 +366,94 @@ module.exports = function(RED) { } RED.nodes.registerType("worldmap-tracks",WorldMapTracks); + + var WorldMapHull = function(n) { + RED.nodes.createNode(this,n); + this.prop = n.prop || "layer"; + var node = this; + node.hulls = {}; + + var convexHull = function(points) { + var arr = []; + for (const val of Object.values(points)) { + arr.push(val); + } + + arr.sort(function (a, b) { + return a.lat != b.lat ? a.lat - b.lat : a.lon - b.lon; + }); + + var n = arr.length; + var hull = []; + + for (var i = 0; i < 2 * n; i++) { + var j = i < n ? i : 2 * n - 1 - i; + while (hull.length >= 2 && removeMiddle(hull[hull.length - 2], hull[hull.length - 1], arr[j])) + hull.pop(); + hull.push(arr[j]); + } + + hull.pop(); + return hull; + } + + var removeMiddle = function(a, b, c) { + var cross = (a.lat- b.lat) * (c.lon - b.lon) - (a.lon - b.lon) * (c.lat- b.lat); + var dot = (a.lat- b.lat) * (c.lat- b.lat) + (a.lon - b.lon) * (c.lon - b.lon); + return cross < 0 || cross == 0 && dot <= 0; + } + + var doHull = function(msg) { + if (msg.hasOwnProperty("payload") && msg.payload.hasOwnProperty("name")) { + var newmsg = RED.util.cloneMessage(msg); + newmsg.payload = {}; + newmsg.payload[node.prop] = msg.payload[node.prop] || "unknown"; + if (msg.payload.deleted === true) { + if (node.hulls.hasOwnProperty(newmsg.payload[node.prop])) { + delete node.hulls[newmsg.payload[node.prop]][msg.payload.name]; + } + } + else { + if (!msg.payload.hasOwnProperty("lat") || !msg.payload.hasOwnProperty("lon")) { return; } + if (!node.hulls.hasOwnProperty(newmsg.payload[node.prop])) { + node.hulls[newmsg.payload[node.prop]] = {}; + } + node.hulls[newmsg.payload[node.prop]][msg.payload.name] = {lat:msg.payload.lat,lon:msg.payload.lon}; + } + var convexHullPoints = convexHull(node.hulls[newmsg.payload[node.prop]]); + var leafletHull = convexHullPoints.map(function (element) {return ([element.lat,element.lon])}) + + if (leafletHull.length > 1) { + // if (leafletHull.length === 2) { newmsg.payload.line = leafletHull; } + // else { + newmsg.payload.area = leafletHull; + // } + newmsg.payload.name = newmsg.payload[node.prop]; + newmsg.payload.clickable = true; + node.send(newmsg); + } + } + } + + node.on("input", function(m) { + if (Array.isArray(m.payload)) { + m.payload.forEach(function (pay) { + var n = RED.util.cloneMessage(m) + n.payload = pay; + doHull(n); + }); + } + else { + doHull(m); + } + }); + + node.on("close", function() { + node.hulls = {}; + }); + } + RED.nodes.registerType("worldmap-hull",WorldMapHull); + RED.httpNode.get("/.ui-worldmap", function(req, res) { res.send(ui ? "true": "false"); }); diff --git a/worldmap/worldmap.js b/worldmap/worldmap.js index 4beac71..42f11fc 100644 --- a/worldmap/worldmap.js +++ b/worldmap/worldmap.js @@ -1399,6 +1399,7 @@ function setMarker(data) { var dir = parseFloat(data.hdg || data.bearing || "0"); marker = L.marker(ll, {title:data.name, icon:myMarker, draggable:drag, rotationAngle:dir, rotationOrigin:"center"}); labelOffset = [sz/2-4,-4]; + delete data.iconSize; } else if (data.icon.substr(0,3) === "fa-") { var col = data.iconColor || "#910000";