diff --git a/modules/osm/node.js b/modules/osm/node.js index f72dbcae2..a407750b2 100644 --- a/modules/osm/node.js +++ b/modules/osm/node.js @@ -55,6 +55,28 @@ _.extend(osmNode.prototype, { }, + isConnected: function(resolver) { + return resolver.transient(this, 'isConnected', function() { + var parents = resolver.parentWays(this); + + // vertex is connected to multiple parent ways + if (parents.length > 1) { + return true; + + } else if (parents.length === 1) { + var way = parents[0], + nodes = way.nodes.slice(); + if (way.isClosed()) { nodes.pop(); } // ignore connecting node if closed + + // return true if vertex appears multiple times (way is self intersecting) + return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id); + } + + return false; + }); + }, + + isIntersection: function(resolver) { return resolver.transient(this, 'isIntersection', function() { return resolver.parentWays(this).filter(function(parent) { diff --git a/modules/svg/vertices.js b/modules/svg/vertices.js index bd332abb5..d3a850768 100644 --- a/modules/svg/vertices.js +++ b/modules/svg/vertices.js @@ -13,6 +13,7 @@ export function svgVertices(projection, context) { var hover; + function siblingAndChildVertices(ids, graph, extent) { var vertices = {}; @@ -78,7 +79,7 @@ export function svgVertices(projection, context) { r = rads[i ? 3 : z]; // slightly increase the size of unconnected endpoints #3775 - if (entity.isEndpoint(graph) && !graph.isShared(entity)) { + if (entity.isEndpoint(graph) && !entity.isConnected(graph)) { r += 1.5; } @@ -166,7 +167,7 @@ export function svgVertices(projection, context) { if (entity.id in selected || entity.hasInterestingTags() || entity.isEndpoint(graph) || - entity.isIntersection(graph)) { + entity.isConnected(graph)) { vertices.push(entity); } } diff --git a/test/spec/osm/node.js b/test/spec/osm/node.js index 5465f4268..5e91dad95 100644 --- a/test/spec/osm/node.js +++ b/test/spec/osm/node.js @@ -67,6 +67,41 @@ describe('iD.osmNode', function () { }); }); + describe('#isConnected', function () { + it('returns true for a node with more than one parent way', function () { + var node = iD.Node(), + w1 = iD.Way({nodes: [node.id]}), + w2 = iD.Way({nodes: [node.id]}), + graph = iD.Graph([node, w1, w2]); + expect(node.isConnected(graph)).to.equal(true); + }); + + it('returns false for a standalone node on a single parent way', function () { + var node = iD.Node(), + way = iD.Way({nodes: [node.id]}), + graph = iD.Graph([node, way]); + expect(node.isConnected(graph)).to.equal(false); + }); + + it('returns true for a self-intersecting node on a single parent way', function () { + var a = iD.Node({id: 'a'}), + b = iD.Node({id: 'b'}), + c = iD.Node({id: 'c'}), + w = iD.Way({nodes: ['a', 'b', 'c', 'b']}), + graph = iD.Graph([a, b, c, w]); + expect(b.isConnected(graph)).to.equal(true); + }); + + it('returns false for the connecting node of a closed way', function () { + var a = iD.Node({id: 'a'}), + b = iD.Node({id: 'b'}), + c = iD.Node({id: 'c'}), + w = iD.Way({nodes: ['a', 'b', 'c', 'a']}), + graph = iD.Graph([a, b, c, w]); + expect(a.isConnected(graph)).to.equal(false); + }); + }); + describe('#isIntersection', function () { it('returns true for a node shared by more than one highway', function () { var node = iD.Node(),