From 7a1800fd6866f7aac7ac27c9785f96bf1740a490 Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Wed, 27 Feb 2013 16:32:52 -0800 Subject: [PATCH] Delete orphaned relation members --- js/id/actions/delete_relation.js | 15 +++++++ test/spec/actions/delete_relation.js | 59 ++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/js/id/actions/delete_relation.js b/js/id/actions/delete_relation.js index 48c62f1e1..783f1533c 100644 --- a/js/id/actions/delete_relation.js +++ b/js/id/actions/delete_relation.js @@ -1,5 +1,11 @@ // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as iD.actions.DeleteRelation = function(relationId) { + function deleteEntity(entity, graph) { + return !graph.parentWays(entity).length && + !graph.parentRelations(entity).length && + !entity.hasInterestingTags(); + } + return function(graph) { var relation = graph.entity(relationId); @@ -8,6 +14,15 @@ iD.actions.DeleteRelation = function(relationId) { graph = graph.replace(parent.removeMember(relationId)); }); + _.uniq(_.pluck(relation.members, 'id')).forEach(function(memberId) { + graph = graph.replace(relation.removeMember(memberId)); + + var entity = graph.entity(memberId); + if (deleteEntity(entity, graph)) { + graph = iD.actions.DeleteMultiple([memberId])(graph); + } + }); + return graph.remove(relation); }; }; diff --git a/test/spec/actions/delete_relation.js b/test/spec/actions/delete_relation.js index c96909f3f..28219601a 100644 --- a/test/spec/actions/delete_relation.js +++ b/test/spec/actions/delete_relation.js @@ -14,4 +14,63 @@ describe("iD.actions.DeleteRelation", function () { graph = action(iD.Graph([a, b, parent])); expect(graph.entity(parent.id).members).to.eql([{ id: b.id }]); }); + + it("deletes member nodes not referenced by another parent", function() { + var node = iD.Node(), + relation = iD.Relation({members: [{id: node.id}]}), + action = iD.actions.DeleteRelation(relation.id), + graph = action(iD.Graph([node, relation])); + expect(graph.entity(node.id)).to.be.undefined; + }); + + it("does not delete member nodes referenced by another parent", function() { + var node = iD.Node(), + way = iD.Way({nodes: [node.id]}), + relation = iD.Relation({members: [{id: node.id}]}), + action = iD.actions.DeleteRelation(relation.id), + graph = action(iD.Graph([node, way, relation])); + expect(graph.entity(node.id)).not.to.be.undefined; + }); + + it("does not delete member nodes with interesting tags", function() { + var node = iD.Node({tags: {highway: 'traffic_signals'}}), + relation = iD.Relation({members: [{id: node.id}]}), + action = iD.actions.DeleteRelation(relation.id), + graph = action(iD.Graph([node, relation])); + expect(graph.entity(node.id)).not.to.be.undefined; + }); + + it("deletes member ways not referenced by another parent", function() { + var way = iD.Way(), + relation = iD.Relation({members: [{id: way.id}]}), + action = iD.actions.DeleteRelation(relation.id), + graph = action(iD.Graph([way, relation])); + expect(graph.entity(way.id)).to.be.undefined; + }); + + it("does not delete member ways referenced by another parent", function() { + var way = iD.Way(), + relation1 = iD.Relation({members: [{id: way.id}]}), + relation2 = iD.Relation({members: [{id: way.id}]}), + action = iD.actions.DeleteRelation(relation1.id), + graph = action(iD.Graph([way, relation1, relation2])); + expect(graph.entity(way.id)).not.to.be.undefined; + }); + + it("does not delete member ways with interesting tags", function() { + var way = iD.Node({tags: {highway: 'residential'}}), + relation = iD.Relation({members: [{id: way.id}]}), + action = iD.actions.DeleteRelation(relation.id), + graph = action(iD.Graph([way, relation])); + expect(graph.entity(way.id)).not.to.be.undefined; + }); + + it("deletes nodes of deleted member ways", function() { + var node = iD.Node(), + way = iD.Way({nodes: [node.id]}), + relation = iD.Relation({members: [{id: way.id}]}), + action = iD.actions.DeleteRelation(relation.id), + graph = action(iD.Graph([node, way, relation])); + expect(graph.entity(node.id)).to.be.undefined; + }); });