From 73e27c96571aa7fa4470fbe8ed3528b4e8ef70ca Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Mon, 9 Jan 2017 19:41:38 -0500 Subject: [PATCH] Now that updateNode preserves circularity, provide close/unclose functions This lets us break closed ways at their connecting node in the few situations where we actually want that behavior (disconnect action for circular non-area ways) --- modules/actions/disconnect.js | 7 +++++-- modules/osm/way.js | 36 ++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/modules/actions/disconnect.js b/modules/actions/disconnect.js index 85f9ce454..82274234f 100644 --- a/modules/actions/disconnect.js +++ b/modules/actions/disconnect.js @@ -31,6 +31,9 @@ export function actionDisconnect(nodeId, newNodeId) { if (connection.index === 0 && way.isArea()) { // replace shared node with shared node.. graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id)); + } else if (way.isClosed() && connection.index === way.nodes.length - 1) { + // replace closing node with new new node.. + graph = graph.replace(way.unclose().addNode(newNode.id)); } else { // replace shared node with multiple new nodes.. graph = graph.replace(way.updateNode(newNode.id, connection.index)); @@ -52,11 +55,11 @@ export function actionDisconnect(nodeId, newNodeId) { return; } if (way.isArea() && (way.nodes[0] === nodeId)) { - candidates.push({wayID: way.id, index: 0}); + candidates.push({ wayID: way.id, index: 0 }); } else { way.nodes.forEach(function(waynode, index) { if (waynode === nodeId) { - candidates.push({wayID: way.id, index: index}); + candidates.push({ wayID: way.id, index: index }); } }); } diff --git a/modules/osm/way.js b/modules/osm/way.js index 5f71ca599..bd7a28b8c 100644 --- a/modules/osm/way.js +++ b/modules/osm/way.js @@ -188,6 +188,36 @@ _.extend(osmWay.prototype, { }, + // If this way is not closed, append the beginning node to the end of the nodelist to close it. + close: function() { + if (this.isClosed() || !this.nodes.length) return this; + + var nodes = this.nodes.slice(); + nodes.push(nodes[0]); + nodes = nodes.filter(noRepeatNodes); + return this.update({ nodes: nodes }); + }, + + + // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it. + unclose: function() { + if (!this.isClosed()) return this; + + var nodes = this.nodes.slice(), + connector = this.first(), + i = nodes.length - 1; + + // remove trailing connectors.. + while (i > 0 && nodes.length > 1 && nodes[i] === connector) { + nodes.splice(i, 1); + i = nodes.length - 1; + } + + nodes = nodes.filter(noRepeatNodes); + return this.update({ nodes: nodes }); + }, + + // Adds a node (id) in front of the node which is currently at position index. // If index is undefined, the node will be added to the end of the way for linear ways, // or just before the final connecting node for circular ways. @@ -207,7 +237,7 @@ _.extend(osmWay.prototype, { } // If this is a closed way, remove all connector nodes except the first one - // (there may be duplicates) + // (there may be duplicates) and adjust index if necessary.. if (isClosed) { var connector = this.first(); @@ -252,7 +282,7 @@ _.extend(osmWay.prototype, { } // If this is a closed way, remove all connector nodes except the first one - // (there may be duplicates) + // (there may be duplicates) and adjust index if necessary.. if (isClosed) { var connector = this.first(); @@ -316,7 +346,7 @@ _.extend(osmWay.prototype, { isClosed = this.isClosed(); nodes = nodes - .filter(function(node, i, arr) { return node !== id }) + .filter(function(node) { return node !== id; }) .filter(noRepeatNodes); // If the way was closed before, append a connector node to keep it closed..