mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-17 22:24:49 +02:00
Split ways at intersections (fixes #750)
This commit is contained in:
+11
-6
@@ -9,7 +9,7 @@
|
||||
// Reference:
|
||||
// https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
|
||||
//
|
||||
iD.actions.Split = function(nodeId, newWayId) {
|
||||
iD.actions.Split = function(nodeId, newWayIds) {
|
||||
function candidateWays(graph) {
|
||||
var node = graph.entity(nodeId),
|
||||
parents = graph.parentWays(node);
|
||||
@@ -21,9 +21,8 @@ iD.actions.Split = function(nodeId, newWayId) {
|
||||
});
|
||||
}
|
||||
|
||||
var action = function(graph) {
|
||||
var wayA = candidateWays(graph)[0],
|
||||
wayB = iD.Way({id: newWayId, tags: wayA.tags}),
|
||||
function split(graph, wayA, newWayId) {
|
||||
var wayB = iD.Way({id: newWayId, tags: wayA.tags}),
|
||||
nodesA,
|
||||
nodesB,
|
||||
isArea = wayA.isArea();
|
||||
@@ -91,6 +90,14 @@ iD.actions.Split = function(nodeId, newWayId) {
|
||||
graph = graph.replace(wayB.update({tags: {}}));
|
||||
}
|
||||
|
||||
return graph;
|
||||
}
|
||||
|
||||
var action = function(graph) {
|
||||
var candidates = candidateWays(graph);
|
||||
for (var i = 0; i < candidates.length; i++) {
|
||||
graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
|
||||
}
|
||||
return graph;
|
||||
};
|
||||
|
||||
@@ -98,8 +105,6 @@ iD.actions.Split = function(nodeId, newWayId) {
|
||||
var candidates = candidateWays(graph);
|
||||
if (candidates.length === 0)
|
||||
return 'not_eligible';
|
||||
if (candidates.length > 1)
|
||||
return 'multiple_ways';
|
||||
};
|
||||
|
||||
return action;
|
||||
|
||||
+64
-15
@@ -11,6 +11,20 @@ describe("iD.actions.Split", function () {
|
||||
expect(iD.actions.Split('b').disabled(graph)).not.to.be.ok;
|
||||
});
|
||||
|
||||
it("returns falsy for an intersection of two ways", function () {
|
||||
var graph = iD.Graph({
|
||||
'a': iD.Node({id: 'a'}),
|
||||
'b': iD.Node({id: 'b'}),
|
||||
'c': iD.Node({id: 'c'}),
|
||||
'd': iD.Node({id: 'c'}),
|
||||
'*': iD.Node({id: '*'}),
|
||||
'-': iD.Way({id: '-', nodes: ['a', '*', 'b']}),
|
||||
'|': iD.Way({id: '|', nodes: ['c', '*', 'd']})
|
||||
});
|
||||
|
||||
expect(iD.actions.Split('*').disabled(graph)).not.to.be.ok;
|
||||
});
|
||||
|
||||
it("returns 'not_eligible' for the first node of a single way", function () {
|
||||
var graph = iD.Graph({
|
||||
'a': iD.Node({id: 'a'}),
|
||||
@@ -48,7 +62,7 @@ describe("iD.actions.Split", function () {
|
||||
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c']})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('-').nodes).to.eql(['a', 'b']);
|
||||
expect(graph.entity('=').nodes).to.eql(['b', 'c']);
|
||||
@@ -63,7 +77,7 @@ describe("iD.actions.Split", function () {
|
||||
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c'], tags: tags})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
// Immutable tags => should be shared by identity.
|
||||
expect(graph.entity('-').tags).to.equal(tags);
|
||||
@@ -92,13 +106,48 @@ describe("iD.actions.Split", function () {
|
||||
'|': iD.Way({id: '|', nodes: ['d', 'b']})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('-').nodes).to.eql(['a', 'b']);
|
||||
expect(graph.entity('=').nodes).to.eql(['b', 'c']);
|
||||
expect(graph.entity('|').nodes).to.eql(['d', 'b']);
|
||||
});
|
||||
|
||||
it("splits multiple ways at an intersection", function () {
|
||||
// Situation:
|
||||
// c
|
||||
// |
|
||||
// a ---- * ---- b
|
||||
// ¦
|
||||
// d
|
||||
//
|
||||
// Split at b.
|
||||
//
|
||||
// Expected result:
|
||||
// c
|
||||
// |
|
||||
// a ---- * ==== b
|
||||
// ¦
|
||||
// d
|
||||
//
|
||||
var graph = iD.Graph({
|
||||
'a': iD.Node({id: 'a'}),
|
||||
'b': iD.Node({id: 'b'}),
|
||||
'c': iD.Node({id: 'c'}),
|
||||
'd': iD.Node({id: 'c'}),
|
||||
'*': iD.Node({id: '*'}),
|
||||
'-': iD.Way({id: '-', nodes: ['a', '*', 'b']}),
|
||||
'|': iD.Way({id: '|', nodes: ['c', '*', 'd']})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('*', ['=', '¦'])(graph);
|
||||
|
||||
expect(graph.entity('-').nodes).to.eql(['a', '*']);
|
||||
expect(graph.entity('=').nodes).to.eql(['*', 'b']);
|
||||
expect(graph.entity('|').nodes).to.eql(['c', '*']);
|
||||
expect(graph.entity('¦').nodes).to.eql(['*', 'd']);
|
||||
});
|
||||
|
||||
it("splits a closed way at the given point and its antipode", function () {
|
||||
// Situation:
|
||||
// a ---- b
|
||||
@@ -120,19 +169,19 @@ describe("iD.actions.Split", function () {
|
||||
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'd', 'a']})
|
||||
});
|
||||
|
||||
var g1 = iD.actions.Split('a', '=')(graph);
|
||||
var g1 = iD.actions.Split('a', ['='])(graph);
|
||||
expect(g1.entity('-').nodes).to.eql(['a', 'b', 'c']);
|
||||
expect(g1.entity('=').nodes).to.eql(['c', 'd', 'a']);
|
||||
|
||||
var g2 = iD.actions.Split('b', '=')(graph);
|
||||
var g2 = iD.actions.Split('b', ['='])(graph);
|
||||
expect(g2.entity('-').nodes).to.eql(['b', 'c', 'd']);
|
||||
expect(g2.entity('=').nodes).to.eql(['d', 'a', 'b']);
|
||||
|
||||
var g3 = iD.actions.Split('c', '=')(graph);
|
||||
var g3 = iD.actions.Split('c', ['='])(graph);
|
||||
expect(g3.entity('-').nodes).to.eql(['c', 'd', 'a']);
|
||||
expect(g3.entity('=').nodes).to.eql(['a', 'b', 'c']);
|
||||
|
||||
var g4 = iD.actions.Split('d', '=')(graph);
|
||||
var g4 = iD.actions.Split('d', ['='])(graph);
|
||||
expect(g4.entity('-').nodes).to.eql(['d', 'a', 'b']);
|
||||
expect(g4.entity('=').nodes).to.eql(['b', 'c', 'd']);
|
||||
});
|
||||
@@ -146,7 +195,7 @@ describe("iD.actions.Split", function () {
|
||||
'-': iD.Way({id: '-', tags: {building: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('a', '=')(graph);
|
||||
graph = iD.actions.Split('a', ['='])(graph);
|
||||
expect(graph.entity('-').tags).to.eql({});
|
||||
expect(graph.entity('=').tags).to.eql({});
|
||||
expect(graph.parentRelations(graph.entity('-'))).to.have.length(1);
|
||||
@@ -178,7 +227,7 @@ describe("iD.actions.Split", function () {
|
||||
'r': iD.Relation({id: 'r', members: [{id: '-', type: 'way', role: 'forward'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('r').members).to.eql([
|
||||
{id: '-', type: 'way', role: 'forward'},
|
||||
@@ -207,7 +256,7 @@ describe("iD.actions.Split", function () {
|
||||
'r': iD.Relation({id: 'r', members: [{id: '-', type: 'way'}, {id: '~', type: 'way'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(_.pluck(graph.entity('r').members, 'id')).to.eql(['-', '=', '~']);
|
||||
});
|
||||
@@ -233,7 +282,7 @@ describe("iD.actions.Split", function () {
|
||||
'r': iD.Relation({id: 'r', members: [{id: '~', type: 'way'}, {id: '-', type: 'way'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(_.pluck(graph.entity('r').members, 'id')).to.eql(['~', '=', '-']);
|
||||
});
|
||||
@@ -247,7 +296,7 @@ describe("iD.actions.Split", function () {
|
||||
'r': iD.Relation({id: 'r', members: [{id: '~', type: 'way'}, {id: '-', type: 'way'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(_.pluck(graph.entity('r').members, 'id')).to.eql(['~', '-', '=']);
|
||||
});
|
||||
@@ -277,7 +326,7 @@ describe("iD.actions.Split", function () {
|
||||
{id: 'c', role: 'via'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('r').members).to.eql([
|
||||
{id: '=', role: 'from'},
|
||||
@@ -309,7 +358,7 @@ describe("iD.actions.Split", function () {
|
||||
{id: 'c', role: 'via'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('r').members).to.eql([
|
||||
{id: '~', role: 'from'},
|
||||
@@ -341,7 +390,7 @@ describe("iD.actions.Split", function () {
|
||||
{id: 'c', role: 'via'}]})
|
||||
});
|
||||
|
||||
graph = iD.actions.Split('b', '=')(graph);
|
||||
graph = iD.actions.Split('b', ['='])(graph);
|
||||
|
||||
expect(graph.entity('r').members).to.eql([
|
||||
{id: '-', role: 'from'},
|
||||
|
||||
Reference in New Issue
Block a user