From 1abcc7fccf685e25f4c470ee24877799cdb2ab22 Mon Sep 17 00:00:00 2001 From: Quincy Morgan Date: Fri, 13 Sep 2019 15:17:48 -0400 Subject: [PATCH] Show warning for elevator nodes that are disconnected from the highway network (close #6812) Simplify disconnected way validation code --- modules/validations/disconnected_way.js | 73 ++++++++++++++----------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/modules/validations/disconnected_way.js b/modules/validations/disconnected_way.js index b16323f25..ef1a566f4 100644 --- a/modules/validations/disconnected_way.js +++ b/modules/validations/disconnected_way.js @@ -110,37 +110,58 @@ export function validationDisconnectedWay() { function routingIslandForEntity(entity) { - if (entity.type !== 'way') return null; + var routingIsland = new Set(); // the interconnected routable features + var waysToCheck = []; // the queue of remaining routable ways to traverse - if (!isRoutableWay(entity, true)) return null; + function queueParentWays(node) { + graph.parentWays(node).forEach(function(parentWay) { + if (!routingIsland.has(parentWay) && // only check each feature once + isRoutableWay(parentWay, false)) { // only check routable features + routingIsland.add(parentWay); + waysToCheck.push(parentWay); + } + }); + } - var waysToCheck = [entity]; - var routingIsland = new Set([entity]); + if (entity.type === 'way' && isRoutableWay(entity, true)) { + + routingIsland.add(entity); + waysToCheck.push(entity); + + } else if (entity.type === 'node' && isRoutableNode(entity)) { + + routingIsland.add(entity); + queueParentWays(entity); + + } else { + // this feature isn't routable, cannot be a routing island + return null; + } while (waysToCheck.length) { var wayToCheck = waysToCheck.pop(); var childNodes = graph.childNodes(wayToCheck); for (var i in childNodes) { var vertex = childNodes[i]; - var result = isConnectedVertex(vertex, routingIsland); - if (result === true) { + + if (isConnectedVertex(vertex)) { + // found a link to the wider network, not a routing island return null; - } else if (result === false) { - continue; } - result.forEach(function(connectedWay) { - if (!routingIsland.has(connectedWay)) { - routingIsland.add(connectedWay); - waysToCheck.push(connectedWay); - } - }); + + if (isRoutableNode(vertex)) { + routingIsland.add(vertex); + } + + queueParentWays(vertex); } } + // no network link found, this is a routing island, return its members return routingIsland; } - function isConnectedVertex(vertex, routingIslandWays) { + function isConnectedVertex(vertex) { // assume ways overlapping unloaded tiles are connected to the wider road network - #5938 var osm = services.osm; if (osm && !osm.isDataLoaded(vertex.loc)) return true; @@ -150,24 +171,12 @@ export function validationDisconnectedWay() { vertex.tags.entrance !== 'no') return true; if (vertex.tags.amenity === 'parking_entrance') return true; - var parentsWays = graph.parentWays(vertex); - - // standalone vertex - if (parentsWays.length === 1) return false; - - var connectedWays = new Set(); - - for (var i in parentsWays) { - var parentWay = parentsWays[i]; - - // ignore any way we've already accounted for - if (routingIslandWays.has(parentWay)) continue; - - if (isRoutableWay(parentWay, false)) connectedWays.add(parentWay); - } - - if (connectedWays.size) return connectedWays; + return false; + } + function isRoutableNode(node) { + // treat elevators as distinct features in the highway network + if (node.tags.highway === 'elevator') return true; return false; }