Files
iD/test/spec/actions/split.js
Thomas Petillon 3ff06f9045 Fix relation handling on way split
Depending on which way is the longest, the new way is inserted into the
relation before the existing one. This case must be explicitly handled
for the relation to remain correct.
2021-12-06 21:25:23 +01:00

1772 lines
70 KiB
JavaScript

describe('iD.actionSplit', function () {
describe('#disabled', function () {
it('returns falsy for a non-end node of a single way', function () {
//
// a ---> b ---> c split at 'b' not disabled
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] })
]);
expect(iD.actionSplit('b').disabled(graph)).not.to.be.ok;
});
it('returns falsy for an intersection of two ways', function () {
//
// c
// |
// a ---> * ---> b split at '*' not disabled
// |
// d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [-1, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [0, 1] }),
iD.osmNode({ id: 'd', loc: [0, -1] }),
iD.osmNode({ id: '*', loc: [0, 0] }),
iD.osmWay({ id: '-', nodes: ['a', '*', 'b'] }),
iD.osmWay({ id: '|', nodes: ['c', '*', 'd'] })
]);
expect(iD.actionSplit('*').disabled(graph)).not.to.be.ok;
});
it('returns falsy for an intersection of two ways with parent way specified', function () {
//
// c
// |
// a ---> * ---> b split '-' at '*' not disabled
// |
// d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [-1, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [0, 1] }),
iD.osmNode({ id: 'd', loc: [0, -1] }),
iD.osmNode({ id: '*', loc: [0, 0] }),
iD.osmWay({ id: '-', nodes: ['a', '*', 'b'] }),
iD.osmWay({ id: '|', nodes: ['c', '*', 'd'] })
]);
expect(iD.actionSplit('*').limitWays(['-']).disabled(graph)).not.to.be.ok;
});
it('returns falsy for a self-intersection', function () {
//
// b -- c
// | /
// | / split '-' at 'a' not disabled
// | /
// a -- b
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [0, 2] }),
iD.osmNode({ id: 'c', loc: [1, 2] }),
iD.osmNode({ id: 'd', loc: [1, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'a', 'd'] })
]);
expect(iD.actionSplit('a').disabled(graph)).not.to.be.ok;
});
it('returns \'not_eligible\' for the first node of a single way', function () {
//
// a ---> b split at 'a' disabled - 'not eligible'
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b'] })
]);
expect(iD.actionSplit('a').disabled(graph)).to.equal('not_eligible');
});
it('returns \'not_eligible\' for the last node of a single way', function () {
//
// a ---> b split at 'b' disabled - 'not eligible'
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b'] })
]);
expect(iD.actionSplit('b').disabled(graph)).to.equal('not_eligible');
});
it('returns \'not_eligible\' for an intersection of two ways with non-parent way specified', function () {
//
// c
// |
// a ---> * ---> b split '-' and '=' at '*' disabled - 'not eligible'
// | (there is no '=' here)
// d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [-1, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [0, 1] }),
iD.osmNode({ id: 'd', loc: [0, -1] }),
iD.osmNode({ id: '*', loc: [0, 0] }),
iD.osmWay({ id: '-', nodes: ['a', '*', 'b'] }),
iD.osmWay({ id: '|', nodes: ['c', '*', 'd'] })
]);
expect(iD.actionSplit('*').limitWays(['-', '=']).disabled(graph)).to.equal('not_eligible');
});
});
describe('ways', function () {
it('creates a new way with the appropriate nodes', function () {
//
// Situation:
// a ---> b ---> c split at 'b'
//
// Expected result:
// a ---> b ===> c
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] })
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'b']);
expect(graph.entity('=').nodes).to.eql(['b', 'c']);
});
it('copies tags to the new way', function () {
var tags = { highway: 'residential' };
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'], tags: tags })
]);
graph = iD.actionSplit('b', ['='])(graph);
// Immutable tags => should be shared by identity.
expect(graph.entity('-').tags).to.equal(tags);
expect(graph.entity('=').tags).to.equal(tags);
});
it('gives the previous id to the longest way (first)', function () {
//
// Situation:
// a ---> b ---> c ---> d ---> e ---> f split at 'd'
//
// Expected result:
// a ---> b ---> c ---> d ===> e ===> f
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmNode({ id: 'e', loc: [4, 0] }),
iD.osmNode({ id: 'f', loc: [5, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'd', 'e', 'f'] })
]);
graph = iD.actionSplit('d', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c', 'd']);
expect(graph.entity('=').nodes).to.eql(['d', 'e', 'f']);
});
it('gives the previous id to the longest way (second)', function () {
//
// Situation:
// a ---> b ---> c ---> d ---> e ---> f split at 'c'
//
// Expected result:
// a ===> b ===> c ---> d ---> e ---> f
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmNode({ id: 'e', loc: [4, 0] }),
iD.osmNode({ id: 'f', loc: [5, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'd', 'e', 'f'] })
]);
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['c', 'd', 'e', 'f']);
expect(graph.entity('=').nodes).to.eql(['a', 'b', 'c']);
});
it('gives the previous id to the first way on same length', function () {
//
// Situation:
// a ---> b ---> c ---> d ---> e split at 'c'
//
// Expected result:
// a ---> b ---> c ===> d ===> e
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmNode({ id: 'e', loc: [4, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'd', 'e'] })
]);
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c']);
expect(graph.entity('=').nodes).to.eql(['c', 'd', 'e']);
});
it('gives the previous id to the longest way even with fewer nodes', function () {
//
// Situation:
// a -----------------> d ---> e ---> f split at 'd'
//
// Expected result:
// a -----------------> d ===> e ===> f
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmNode({ id: 'e', loc: [4, 0] }),
iD.osmNode({ id: 'f', loc: [5, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'd', 'e', 'f'] })
]);
graph = iD.actionSplit('d', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'd']);
expect(graph.entity('=').nodes).to.eql(['d', 'e', 'f']);
});
it('splits a way at a T-junction', function () {
//
// Situation:
// a ---- b ---- c split at 'b'
// |
// d
//
// Expected result:
// a ---- b ==== c
// |
// d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [-1, 0] }),
iD.osmNode({ id: 'b', loc: [0, 0] }),
iD.osmNode({ id: 'c', loc: [1, 0] }),
iD.osmNode({ id: 'd', loc: [0, -1] }),
iD.osmWay({id: '-', nodes: ['a', 'b', 'c']}),
iD.osmWay({id: '|', nodes: ['d', 'b']})
]);
graph = iD.actionSplit('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 split at '*'
// |
// d
//
// Expected result:
// c
// |
// a ---- * ==== b
// ¦
// d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [-1, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [0, 1] }),
iD.osmNode({ id: 'd', loc: [0, -1] }),
iD.osmNode({ id: '*', loc: [0, 0] }),
iD.osmWay({ id: '-', nodes: ['a', '*', 'b'] }),
iD.osmWay({ id: '|', nodes: ['c', '*', 'd'] })
]);
graph = iD.actionSplit('*', ['=', '¦'])(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 the specified ways at an intersection', function () {
//
// c
// |
// a ---- * ---- b split at '*'
// |
// d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [-1, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [0, 1] }),
iD.osmNode({ id: 'd', loc: [0, -1] }),
iD.osmNode({ id: '*', loc: [0, 0] }),
iD.osmWay({ id: '-', nodes: ['a', '*', 'b'] }),
iD.osmWay({ id: '|', nodes: ['c', '*', 'd'] })
]);
var g1 = iD.actionSplit('*', ['=']).limitWays(['-'])(graph);
expect(g1.entity('-').nodes).to.eql(['a', '*']);
expect(g1.entity('=').nodes).to.eql(['*', 'b']);
expect(g1.entity('|').nodes).to.eql(['c', '*', 'd']);
var g2 = iD.actionSplit('*', ['¦']).limitWays(['|'])(graph);
expect(g2.entity('-').nodes).to.eql(['a', '*', 'b']);
expect(g2.entity('|').nodes).to.eql(['c', '*']);
expect(g2.entity('¦').nodes).to.eql(['*', 'd']);
var g3 = iD.actionSplit('*', ['=', '¦']).limitWays(['-', '|'])(graph);
expect(g3.entity('-').nodes).to.eql(['a', '*']);
expect(g3.entity('=').nodes).to.eql(['*', 'b']);
expect(g3.entity('|').nodes).to.eql(['c', '*']);
expect(g3.entity('¦').nodes).to.eql(['*', 'd']);
});
it('splits self-intersecting ways', function () {
//
// Situation:
// b
// /|
// / |
// / |
// c - a -- d split at 'a'
//
// Expected result:
// b
// /|
// / |
// / |
// c - a == d
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [0, 2] }),
iD.osmNode({ id: 'c', loc: [-1, 0] }),
iD.osmNode({ id: 'd', loc: [1, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'a', 'd'] })
]);
graph = iD.actionSplit('a', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c', 'a']);
expect(graph.entity('=').nodes).to.eql(['a', 'd']);
});
it('splits a closed way at the given point and its antipode', function () {
//
// Situation:
// a ---- b
// | |
// d ---- c
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 1] }),
iD.osmNode({ id: 'b', loc: [1, 1] }),
iD.osmNode({ id: 'c', loc: [1, 0] }),
iD.osmNode({ id: 'd', loc: [0, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'd', 'a']})
]);
var g1 = iD.actionSplit('a', ['='])(graph);
expect(g1.entity('-').nodes).to.eql(['c', 'd', 'a']);
expect(g1.entity('=').nodes).to.eql(['a', 'b', 'c']);
var g2 = iD.actionSplit('b', ['='])(graph);
expect(g2.entity('-').nodes).to.eql(['b', 'c', 'd']);
expect(g2.entity('=').nodes).to.eql(['d', 'a', 'b']);
var g3 = iD.actionSplit('c', ['='])(graph);
expect(g3.entity('-').nodes).to.eql(['c', 'd', 'a']);
expect(g3.entity('=').nodes).to.eql(['a', 'b', 'c']);
var g4 = iD.actionSplit('d', ['='])(graph);
expect(g4.entity('-').nodes).to.eql(['b', 'c', 'd']);
expect(g4.entity('=').nodes).to.eql(['d', 'a', 'b']);
});
});
describe('relations', function () {
function members(graph) {
return graph.entity('r').members.map(function (m) { return m.id; });
}
it('handles incomplete relations', function () {
//
// Situation:
// a ---> b ---> c split at 'b'
// Relation: ['~', '-']
//
// Expected result:
// a ---> b ===> c
// Relation: ['~', '-', '=']
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] }),
iD.osmRelation({id: 'r', members: [
{ id: '~', type: 'way' },
{ id: '-', type: 'way' }
]})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(members(graph)).to.eql(['~', '-', '=']);
});
describe('member ordering', function () {
it('adds the new way to parent relations (simple)', function () {
//
// Situation:
// a ---> b ---> c split at 'b'
// Relation: ['-']
//
// Expected result:
// a ---> b ===> c
// Relation: ['-', '=']
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] }),
iD.osmRelation({id: 'r', members: [
{ id: '-', type: 'way', role: 'forward' }
]})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{ id: '-', type: 'way', role: 'forward' },
{ id: '=', type: 'way', role: 'forward' }
]);
});
it('adds the new way to parent relations (forward order)', function () {
//
// Situation:
// a ---> b ---> c ~~~> d split at 'b'
// Relation: ['-', '~']
//
// Expected result:
// a ---> b ===> c ~~~> d
// Relation: ['-', '=', '~']
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] }),
iD.osmWay({ id: '~', nodes: ['c', 'd'] }),
iD.osmRelation({id: 'r', members: [
{ id: '-', type: 'way' },
{ id: '~', type: 'way' }
]})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(members(graph)).to.eql(['-', '=', '~']);
});
it('adds the new way to parent relations (reverse order)', function () {
//
// Situation:
// a ---> b ---> c ~~~> d split at 'b'
// Relation: ['~', '-']
//
// Expected result:
// a ---> b ===> c ~~~> d
// Relation: ['~', '=', '-']
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] }),
iD.osmWay({ id: '~', nodes: ['c', 'd'] }),
iD.osmRelation({id: 'r', members: [
{ id: '~', type: 'way' },
{ id: '-', type: 'way' }
]})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(members(graph)).to.eql(['~', '=', '-']);
});
it('adds the new way to parent relations (existing way is first)', function () {
//
// Situation:
// a ---> b ---> c ---> d split at 'c'
// Relation: ['-']
//
// Expected result:
// a ---> b ---> c ===> d
// Relation: ['-', '=']
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'd'] }),
iD.osmRelation({id: 'r', members: [
{ id: '-', type: 'way', role: 'forward' }
]})
]);
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{ id: '-', type: 'way', role: 'forward' },
{ id: '=', type: 'way', role: 'forward' }
]);
});
it('adds the new way to parent relations (existing way is second)', function () {
//
// Situation:
// a ---> b ---> c ---> d split at 'b'
// Relation: ['-']
//
// Expected result:
// a ===> b ---> c ---> d
// Relation: ['=', '-']
//
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmNode({ id: 'd', loc: [3, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c', 'd'] }),
iD.osmRelation({id: 'r', members: [
{ id: '-', type: 'way', role: 'forward' }
]})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{ id: '=', type: 'way', role: 'forward' },
{ id: '-', type: 'way', role: 'forward' }
]);
});
it('reorders members as node, way, relation (for Public Transport routing)', function () {
var graph = iD.coreGraph([
iD.osmNode({ id: 'a', loc: [0, 0] }),
iD.osmNode({ id: 'b', loc: [1, 0] }),
iD.osmNode({ id: 'c', loc: [2, 0] }),
iD.osmWay({ id: '-', nodes: ['a', 'b', 'c'] }),
iD.osmRelation({id: 'r', members: [
{ id: 'n1', type: 'node', role: 'forward' },
{ id: '-', type: 'way', role: 'forward' },
{ id: 'r1', type: 'relation', role: 'forward' },
{ id: 'n2', type: 'node', role: 'forward' }
]})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{ id: 'n1', type: 'node', role: 'forward' },
{ id: 'n2', type: 'node', role: 'forward' },
{ id: '-', type: 'way', role: 'forward' },
{ id: '=', type: 'way', role: 'forward' },
{ id: 'r1', type: 'relation', role: 'forward'}
]);
});
});
describe('splitting out-and-back routes', function () {
var a = iD.osmNode({ id: 'a', loc: [0, 0] });
var b = iD.osmNode({ id: 'b', loc: [0, 1] });
var c = iD.osmNode({ id: 'c', loc: [0, 2] });
var d = iD.osmNode({ id: 'd', loc: [0, 3] });
var e = iD.osmNode({ id: 'e', loc: [0, 4] });
//
// Situation:
// a ---> b ---> c ---> d ~~~> e
// Relation: ['-', '~', '~', '-']
//
var outAndBack1 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'e']}),
iD.osmRelation({id: 'r', members: [
{id: '-', type: 'way'},
{id: '~', type: 'way'},
{id: '~', type: 'way'},
{id: '-', type: 'way'}
]})
]);
//
// Situation:
// a <--- b <--- c <--- d ~~~> e
// Relation: ['-', '~', '~', '-']
//
var outAndBack2 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['d', 'c', 'b', 'a']}),
iD.osmWay({id: '~', nodes: ['d', 'e']}),
iD.osmRelation({id: 'r', members: [
{id: '-', type: 'way'},
{id: '~', type: 'way'},
{id: '~', type: 'way'},
{id: '-', type: 'way'}
]})
]);
//
// Situation:
// a ---> b ---> c ---> d <~~~ e
// Relation: ['-', '~', '~', '-']
//
var outAndBack3 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['e', 'd']}),
iD.osmRelation({id: 'r', members: [
{id: '-', type: 'way'},
{id: '~', type: 'way'},
{id: '~', type: 'way'},
{id: '-', type: 'way'}
]})
]);
//
// Situation:
// a <--- b <--- c <--- d <~~~ e
// Relation: ['-', '~', '~', '-']
//
var outAndBack4 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['d', 'c', 'b', 'a']}),
iD.osmWay({id: '~', nodes: ['e', 'd']}),
iD.osmRelation({id: 'r', members: [
{id: '-', type: 'way'},
{id: '~', type: 'way'},
{id: '~', type: 'way'},
{id: '-', type: 'way'}
]})
]);
it('splits out-and-back1 route at c', function () {
//
// Expected result:
// a ---> b ---> c ===> d ~~~> e
// Relation: ['-', '=', '~', '~', '=', '-']
//
var graph = outAndBack1;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c']);
expect(graph.entity('=').nodes).to.eql(['c', 'd']);
expect(graph.entity('~').nodes).to.eql(['d', 'e']);
expect(members(graph)).to.eql(['-', '=', '~', '~', '=', '-']);
});
it('splits out-and-back1 route at b', function () {
//
// Expected result:
// a ===> b ---> c ---> d ~~~> e
// Relation: ['=', '-', '~', '~', '-', '=']
//
var graph = outAndBack1;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['b', 'c', 'd']);
expect(graph.entity('=').nodes).to.eql(['a', 'b']);
expect(graph.entity('~').nodes).to.eql(['d', 'e']);
expect(members(graph)).to.eql(['=', '-', '~', '~', '-', '=']);
});
it('splits out-and-back2 route at b', function () {
//
// Expected result:
// a <=== b <--- c <--- d ~~~> e
// Relation: ['=', '-', '~', '~', '-', '=']
//
var graph = outAndBack2;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'c', 'b']);
expect(graph.entity('=').nodes).to.eql(['b', 'a']);
expect(graph.entity('~').nodes).to.eql(['d', 'e']);
expect(members(graph)).to.eql(['=', '-', '~', '~', '-', '=']);
});
it('splits out-and-back2 route at c', function () {
//
// Expected result:
// a <--- b <--- c <=== d ~~~> e
// Relation: ['-', '=', '~', '~', '=', '-']
//
var graph = outAndBack2;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['c', 'b', 'a']);
expect(graph.entity('=').nodes).to.eql(['d', 'c']);
expect(graph.entity('~').nodes).to.eql(['d', 'e']);
expect(members(graph)).to.eql(['-', '=', '~', '~', '=', '-']);
});
it('splits out-and-back3 route at c', function () {
//
// Expected result:
// a ---> b ---> c ===> d <~~~ e
// Relation: ['-', '=', '~', '~', '=', '-']
//
var graph = outAndBack3;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['a', 'b', 'c']);
expect(graph.entity('=').nodes).to.eql(['c', 'd']);
expect(graph.entity('~').nodes).to.eql(['e', 'd']);
expect(members(graph)).to.eql(['-', '=', '~', '~', '=', '-']);
});
it('splits out-and-back3 route at b', function () {
//
// Expected result:
// a ===> b ---> c ---> d <~~~ e
// Relation: ['=', '-', '~', '~', '-', '=']
//
var graph = outAndBack3;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['b', 'c', 'd']);
expect(graph.entity('=').nodes).to.eql(['a', 'b']);
expect(graph.entity('~').nodes).to.eql(['e', 'd']);
expect(members(graph)).to.eql(['=', '-', '~', '~', '-', '=']);
});
it('splits out-and-back4 route at b', function () {
//
// Expected result:
// a <=== b <--- c <--- d <~~~ e
// Relation: ['=', '-', '~', '~', '-', '=']
//
var graph = outAndBack4;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'c', 'b']);
expect(graph.entity('=').nodes).to.eql(['b', 'a']);
expect(graph.entity('~').nodes).to.eql(['e', 'd']);
expect(members(graph)).to.eql(['=', '-', '~', '~', '-', '=']);
});
it('splits out-and-back4 route at c', function () {
//
// Expected result:
// a <--- b <--- c <=== d <~~~ e
// Relation: ['-', '=', '~', '~', '=', '-']
//
var graph = outAndBack4;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['c', 'b', 'a']);
expect(graph.entity('=').nodes).to.eql(['d', 'c']);
expect(graph.entity('~').nodes).to.eql(['e', 'd']);
expect(members(graph)).to.eql(['-', '=', '~', '~', '=', '-']);
});
});
describe('splitting hat routes', function () {
var a = iD.osmNode({id: 'a', loc: [0, 0]});
var b = iD.osmNode({id: 'b', loc: [1, 0]});
var c = iD.osmNode({id: 'c', loc: [2, 1]});
var d = iD.osmNode({id: 'd', loc: [3, 0]});
var e = iD.osmNode({id: 'e', loc: [4, 0]});
//
// Situation:
// ###> c >###
// # #
// a --> b ~~~~~~> d ==> e
//
// Relation: ['-', '#', '~', '#', '=']
//
var hat1a = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b']}),
iD.osmWay({id: '#', nodes: ['b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['b', 'd']}),
iD.osmWay({id: '=', nodes: ['d', 'e']}),
iD.osmRelation({
id: 'r', members: [
{id: '-', type: 'way'},
{id: '#', type: 'way'},
{id: '~', type: 'way'},
{id: '#', type: 'way'},
{id: '=', type: 'way'}
]
})
]);
//
// Situation:
// ###> c >###
// # #
// a --> b ~~~~~~> d ==> e
//
// Relation: ['-', '~', '#', '~', '=']
//
var hat1b = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b']}),
iD.osmWay({id: '#', nodes: ['b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['b', 'd']}),
iD.osmWay({id: '=', nodes: ['d', 'e']}),
iD.osmRelation({
id: 'r', members: [
{id: '-', type: 'way'},
{id: '~', type: 'way'},
{id: '#', type: 'way'},
{id: '~', type: 'way'},
{id: '=', type: 'way'}
]
})
]);
//
// Situation:
// ###< c <###
// # #
// a --> b ~~~~~~> d ==> e
//
// Relation: ['-', '#', '~', '#', '=']
//
var hat2 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b']}),
iD.osmWay({id: '#', nodes: ['d', 'c', 'b']}),
iD.osmWay({id: '~', nodes: ['b', 'd']}),
iD.osmWay({id: '=', nodes: ['d', 'e']}),
iD.osmRelation({
id: 'r', members: [
{id: '-', type: 'way'},
{id: '#', type: 'way'},
{id: '~', type: 'way'},
{id: '#', type: 'way'},
{id: '=', type: 'way'}
]
})
]);
//
// Situation:
// ###< c <###
// # #
// a --> b <~~~~~~ d ==> e
//
// Relation: ['-', '#', '~', '#', '=']
//
var hat3 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b']}),
iD.osmWay({id: '#', nodes: ['d', 'c', 'b']}),
iD.osmWay({id: '~', nodes: ['d', 'b']}),
iD.osmWay({id: '=', nodes: ['d', 'e']}),
iD.osmRelation({
id: 'r', members: [
{id: '-', type: 'way'},
{id: '#', type: 'way'},
{id: '~', type: 'way'},
{id: '#', type: 'way'},
{id: '=', type: 'way'}
]
})
]);
//
// Situation:
// ###> c >###
// # #
// a --> b <~~~~~~ d ==> e
//
// Relation: ['-', '#', '~', '#', '=']
//
var hat4 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b']}),
iD.osmWay({id: '#', nodes: ['b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'b']}),
iD.osmWay({id: '=', nodes: ['d', 'e']}),
iD.osmRelation({
id: 'r', members: [
{id: '-', type: 'way'},
{id: '#', type: 'way'},
{id: '~', type: 'way'},
{id: '#', type: 'way'},
{id: '=', type: 'way'}
]
})
]);
//
// Situation:
// ###> c >###
// # #
// a <-- b ~~~~~~> d <== e
//
// Relation: ['-', '#', '~', '#', '=']
//
var hat5 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['b', 'a']}),
iD.osmWay({id: '#', nodes: ['b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['b', 'd']}),
iD.osmWay({id: '=', nodes: ['e', 'd']}),
iD.osmRelation({
id: 'r', members: [
{id: '-', type: 'way'},
{id: '#', type: 'way'},
{id: '~', type: 'way'},
{id: '#', type: 'way'},
{id: '=', type: 'way'}
]
})
]);
it('splits hat1a route at c', function () {
//
// Expected result:
// ###> c >***
// # *
// a --> b ~~~~~~> d ==> e
//
// Relation: ['-', '#', '*', '~', '#', '*', '=']
//
var graph = hat1a;
graph = iD.actionSplit('c', ['*'])(graph);
expect(graph.entity('#').nodes).to.eql(['b', 'c']);
expect(graph.entity('*').nodes).to.eql(['c', 'd']);
expect(members(graph)).to.eql(['-', '#', '*', '~', '#', '*', '=']);
});
it('splits hat1b route at c', function () {
//
// Expected result:
// ###> c >***
// # *
// a --> b ~~~~~~> d ==> e
//
// Relation: ['-', '~', '*', '#', '~', '=']
//
var graph = hat1b;
graph = iD.actionSplit('c', ['*'])(graph);
expect(graph.entity('#').nodes).to.eql(['b', 'c']);
expect(graph.entity('*').nodes).to.eql(['c', 'd']);
expect(members(graph)).to.eql(['-', '~', '*', '#', '~', '=']);
});
it('splits hat2 route at c', function () {
//
// Expected result:
// ***< c <###
// * #
// a --> b ~~~~~~> d ==> e
//
// Relation: ['-', '*', '#', '~', '*', '#', '=']
//
var graph = hat2;
graph = iD.actionSplit('c', ['*'])(graph);
expect(graph.entity('#').nodes).to.eql(['d', 'c']);
expect(graph.entity('*').nodes).to.eql(['c', 'b']);
expect(members(graph)).to.eql(['-', '*', '#', '~', '*', '#', '=']);
});
it('splits hat3 route at c', function () {
//
// Expected result:
// ***< c <###
// * #
// a --> b <~~~~~~ d ==> e
//
// Relation: ['-', '*', '#', '~', '*', '#', '=']
//
var graph = hat3;
graph = iD.actionSplit('c', ['*'])(graph);
expect(graph.entity('#').nodes).to.eql(['d', 'c']);
expect(graph.entity('*').nodes).to.eql(['c', 'b']);
expect(members(graph)).to.eql(['-', '*', '#', '~', '*', '#', '=']);
});
it('splits hat4 route at c', function () {
//
// Expected result:
// ###> c >***
// # *
// a --> b <~~~~~~ d ==> e
//
// Relation: ['-', '*', '#', '~', '*', '#', '=']
//
var graph = hat4;
graph = iD.actionSplit('c', ['*'])(graph);
expect(graph.entity('#').nodes).to.eql(['b', 'c']);
expect(graph.entity('*').nodes).to.eql(['c', 'd']);
expect(members(graph)).to.eql(['-', '#', '*', '~', '#', '*', '=']);
});
it('splits hat5 route at c', function () {
//
// Expected result:
// ###> c >***
// # *
// a <-- b ~~~~~~> d <== e
//
// Relation: ['-', '#', '*', '~', '#', '*', '=']
//
var graph = hat5;
graph = iD.actionSplit('c', ['*'])(graph);
expect(graph.entity('#').nodes).to.eql(['b', 'c']);
expect(graph.entity('*').nodes).to.eql(['c', 'd']);
expect(members(graph)).to.eql(['-', '#', '*', '~', '#', '*', '=']);
});
});
describe('splitting spoon routes', function () {
var a = iD.osmNode({ id: 'a', loc: [0, 0] });
var b = iD.osmNode({ id: 'b', loc: [0, 1] });
var c = iD.osmNode({ id: 'c', loc: [1, 1] });
var d = iD.osmNode({ id: 'd', loc: [1, 0] });
var e = iD.osmNode({ id: 'e', loc: [2, 0] });
var f = iD.osmNode({ id: 'f', loc: [3, 0] });
//
// Situation:
// b --> c
// | |
// a <-- d ~~~> e ~~~> f
//
// Relation: ['~', '-', '~']
//
var spoon1 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['d', 'a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'e', 'f']}),
iD.osmRelation({id: 'r', members: [
{id: '~', type: 'way'},
{id: '-', type: 'way'},
{id: '~', type: 'way'}
]})
]);
//
// Situation:
// b <-- c
// | |
// a --> d ~~~> e ~~~> f
//
// Relation: ['~', '-', '~']
//
var spoon2 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['d', 'c', 'b', 'a', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'e', 'f']}),
iD.osmRelation({id: 'r', members: [
{id: '~', type: 'way'},
{id: '-', type: 'way'},
{id: '~', type: 'way'}
]})
]);
//
// Situation:
// b --> c
// | |
// a <-- d <~~~ e <~~~ f
//
// Relation: ['~', '-', '~']
//
var spoon3 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['d', 'a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['f', 'e', 'd']}),
iD.osmRelation({id: 'r', members: [
{id: '~', type: 'way'},
{id: '-', type: 'way'},
{id: '~', type: 'way'}
]})
]);
//
// Situation:
// b <-- c
// | |
// a --> d <~~~ e <~~~ f
//
// Relation: ['~', '-', '~']
//
var spoon4 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['d', 'c', 'b', 'a', 'd']}),
iD.osmWay({id: '~', nodes: ['f', 'e', 'd']}),
iD.osmRelation({id: 'r', members: [
{id: '~', type: 'way'},
{id: '-', type: 'way'},
{id: '~', type: 'way'}
]})
]);
it('splits spoon1 route at d', function () {
//
// Expected result:
// b ==> c
// | ‖
// a <-- d ~~~> e ~~~> f
//
// Relation: ['~', '-', '=', '~']
//
var graph = spoon1;
graph = iD.actionSplit('d', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'a', 'b']);
expect(graph.entity('=').nodes).to.eql(['b', 'c', 'd']);
expect(graph.entity('~').nodes).to.eql(['d', 'e', 'f']);
expect(members(graph)).to.eql(['~', '-', '=', '~']);
});
it('splits spoon2 route at d', function () {
//
// Expected result:
// b <== c
// | ‖
// a --> d ~~~> e ~~~> f
//
// Relation: ['~', '-', '=', '~']
//
var graph = spoon2;
graph = iD.actionSplit('d', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['b', 'a', 'd']);
expect(graph.entity('=').nodes).to.eql(['d', 'c', 'b']);
expect(graph.entity('~').nodes).to.eql(['d', 'e', 'f']);
expect(members(graph)).to.eql(['~', '-', '=', '~']);
});
it('splits spoon3 route at d', function () {
//
// Expected result:
// b ==> c
// | ‖
// a <-- d <~~~ e <~~~ f
//
// Relation: ['~', '-', '=', '~']
//
var graph = spoon3;
graph = iD.actionSplit('d', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'a', 'b']);
expect(graph.entity('=').nodes).to.eql(['b', 'c', 'd']);
expect(graph.entity('~').nodes).to.eql(['f', 'e', 'd']);
expect(members(graph)).to.eql(['~', '-', '=', '~']);
});
it('splits spoon4 route at d', function () {
//
// Expected result:
// b <== c
// | ‖
// a --> d <~~~ e <~~~ f
//
// Relation: ['~', '-', '=', '~']
//
var graph = spoon4;
graph = iD.actionSplit('d', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['b', 'a', 'd']);
expect(graph.entity('=').nodes).to.eql(['d', 'c', 'b']);
expect(graph.entity('~').nodes).to.eql(['f', 'e', 'd']);
expect(members(graph)).to.eql(['~', '-', '=', '~']);
});
it('splits spoon1 route at e', function () {
//
// Expected result:
// b --> c
// | |
// a <-- d ~~~> e ===> f
//
// Relation: ['=', '~', '-', '~', '=']
//
var graph = spoon1;
graph = iD.actionSplit('e', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'a', 'b', 'c', 'd']);
expect(graph.entity('~').nodes).to.eql(['d', 'e']);
expect(graph.entity('=').nodes).to.eql(['e', 'f']);
expect(members(graph)).to.eql(['=', '~', '-', '~', '=']);
});
it('splits spoon2 route at e', function () {
//
// Expected result:
// b <-- c
// | |
// a --> d ~~~> e ===> f
//
// Relation: ['=', '~', '-', '~', '=']
//
var graph = spoon2;
graph = iD.actionSplit('e', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'c', 'b', 'a', 'd']);
expect(graph.entity('~').nodes).to.eql(['d', 'e']);
expect(graph.entity('=').nodes).to.eql(['e', 'f']);
expect(members(graph)).to.eql(['=', '~', '-', '~', '=']);
});
it('splits spoon3 route at e', function () {
//
// Expected result:
// b --> c
// | |
// a <-- d <=== e <~~~ f
//
// Relation: ['~', '=', '-', '=', '~']
//
var graph = spoon3;
graph = iD.actionSplit('e', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'a', 'b', 'c', 'd']);
expect(graph.entity('~').nodes).to.eql(['f', 'e']);
expect(graph.entity('=').nodes).to.eql(['e', 'd']);
expect(members(graph)).to.eql(['~', '=', '-', '=', '~']);
});
it('splits spoon4 route at e', function () {
//
// Expected result:
// b <-- c
// | |
// a --> d <=== e <~~~ f
//
// Relation: ['~', '=', '-', '=', '~']
//
var graph = spoon4;
graph = iD.actionSplit('e', ['='])(graph);
expect(graph.entity('-').nodes).to.eql(['d', 'c', 'b', 'a', 'd']);
expect(graph.entity('~').nodes).to.eql(['f', 'e']);
expect(graph.entity('=').nodes).to.eql(['e', 'd']);
expect(members(graph)).to.eql(['~', '=', '-', '=', '~']);
});
});
describe('type = multipolygon', function () {
it('splits an area by converting it to a multipolygon', function () {
// Situation:
// a ---- b
// | |
// d ---- c
//
// Split at a.
//
// Expected result:
// a ---- b
// || |
// d ==== c
//
var graph = iD.coreGraph([
iD.osmNode({id: 'a', loc: [0,1]}),
iD.osmNode({id: 'b', loc: [1,1]}),
iD.osmNode({id: 'c', loc: [1,0]}),
iD.osmNode({id: 'd', loc: [0,0]}),
iD.osmWay({id: '-', tags: {area: 'yes'}, nodes: ['a', 'b', 'c', 'd', 'a']})
]);
graph = iD.actionSplit('a', ['='])(graph);
expect(graph.entity('-').tags).to.eql({});
expect(graph.entity('=').tags).to.eql({});
expect(graph.parentRelations(graph.entity('-'))).to.have.length(1);
var relation = graph.parentRelations(graph.entity('-'))[0];
expect(relation.tags).to.eql({type: 'multipolygon', area: 'yes'});
expect(relation.members).to.eql([
{id: '-', role: 'outer', type: 'way'},
{id: '=', role: 'outer', type: 'way'}
]);
});
it('splits only the line of a node shared by a line and an area', function () {
var graph = iD.coreGraph([
iD.osmNode({id: 'a', loc: [0,1]}),
iD.osmNode({id: 'b', loc: [1,1]}),
iD.osmNode({id: 'c', loc: [1,0]}),
iD.osmWay({id: '-', nodes: ['a', 'b', 'c']}),
iD.osmWay({id: '=', nodes: ['a', 'b', 'c', 'a'], tags: {area: 'yes'}})
]);
graph = iD.actionSplit('b', ['~'])(graph);
expect(graph.entity('-').nodes).to.eql(['b', 'c']);
expect(graph.entity('~').nodes).to.eql(['a', 'b']);
expect(graph.entity('=').nodes).to.eql(['a', 'b', 'c', 'a']);
expect(graph.parentRelations(graph.entity('='))).to.have.length(0);
});
it('converts simple multipolygon to a proper multipolygon', function () {
var graph = iD.coreGraph([
iD.osmNode({id: 'a'}),
iD.osmNode({id: 'b'}),
iD.osmNode({id: 'c'}),
iD.osmWay({'id': '-', nodes: ['a', 'b', 'c'], tags: { area: 'yes' }}),
iD.osmRelation({id: 'r', members: [{id: '-', type: 'way', role: 'outer'}], tags: {type: 'multipolygon'}})
]);
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('-').tags).to.eql({});
expect(graph.entity('r').tags).to.eql({type: 'multipolygon', area: 'yes' });
var ids = graph.entity('r').members.map(function(m) { return m.id; });
expect(ids).to.have.ordered.members(['-', '=']);
});
});
['restriction', 'restriction:bus', 'manoeuvre'].forEach(function (type) {
describe('type = ' + type, function () {
var a = iD.osmNode({id: 'a', loc: [0, 0]});
var b = iD.osmNode({id: 'b', loc: [1, 0]});
var c = iD.osmNode({id: 'c', loc: [2, 0]});
var d = iD.osmNode({id: 'd', loc: [3, 0]});
var e = iD.osmNode({id: 'e', loc: [4, 0]});
var f = iD.osmNode({id: 'f', loc: [5, 0]});
//
// Situation:
// a ----> b ----> c ----> d ~~~~ e
// A restriction from ---- to ~~~~ via node d.
//
var restriction1 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'e']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '-', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]})
]);
//
// Situation:
// a ----> b ----> c ----> d ~~~~ e
// A restriction from ~~~~ to ---- via node d.
//
var restriction2 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'e']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '~', role: 'from', type: 'way'},
{id: '-', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]})
]);
//
// Situation:
// a ----> b ----> c ----> d ~~~~ e
// A restriction from ---- to ---- via node d.
//
var restriction3 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '~', nodes: ['d', 'e']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '-', role: 'from', type: 'way'},
{id: '-', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]})
]);
//
// Situation:
// f <~~~~ e
// |
// |
// a ----> b ----> c ----> d
//
// A restriction from ---- to ~~~~ via way |
//
var restriction4 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '|', nodes: ['d', 'e']}),
iD.osmWay({id: '~', nodes: ['e', 'f']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '-', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: '|', role: 'via', type: 'way'}
]})
]);
//
// Situation:
// f <~~~~ e
// |
// |
// a ----> b ----> c ----> d
//
// A restriction from ~~~~ to ---- via way |
//
var restriction5 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '|', nodes: ['d', 'e']}),
iD.osmWay({id: '~', nodes: ['e', 'f']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '~', role: 'from', type: 'way'},
{id: '-', role: 'to', type: 'way'},
{id: '|', role: 'via', type: 'way'}
]})
]);
//
// Situation:
// e f
// | ‖
// | ‖
// a ----> b ----> c ----> d
//
// A restriction from | to ‖ via way ----
//
var restriction6 = iD.coreGraph([
a, b, c, d, e, f,
iD.osmWay({id: '-', nodes: ['a', 'b', 'c', 'd']}),
iD.osmWay({id: '|', nodes: ['e', 'a']}),
iD.osmWay({id: '‖', nodes: ['f', 'd']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '|', role: 'from', type: 'way'},
{id: '-', role: 'via', type: 'way'},
{id: '‖', role: 'to', type: 'way'}
]})
]);
//
// Situation:
// a <---- b <---- c <---- d ~~~~ e
// A restriction from ---- to ~~~~ via d.
//
var restriction7 = iD.coreGraph([
a, b, c, d, e,
iD.osmWay({id: '-', nodes: ['d', 'c', 'b', 'a']}),
iD.osmWay({id: '~', nodes: ['d', 'e']}),
iD.osmRelation({id: 'r', tags: {type: type}, members: [
{id: '-', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]})
]);
it('updates a restriction\'s \'from\' role - via node (1c)', function () {
//
// Expected result:
// a ----> b ----> c ====> d ~~~~ e
// A restriction from ==== to ~~~~ via node d.
//
var graph = restriction1;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '=', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('updates a restriction\'s \'from\' role - via node (1b)', function () {
//
// Expected result:
// a ====> b ----> c ----> d ~~~~ e
// A restriction from ---- to ~~~~ via node d.
//
var graph = restriction1;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '-', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('updates a restriction\'s \'to\' role - via node (2c)', function () {
//
// Expected result:
// a ----> b ----> c ====> d ~~~~ e
// A restriction from ~~~~ to ==== via node d.
//
var graph = restriction2;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '~', role: 'from', type: 'way'},
{id: '=', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('updates a restriction\'s \'to\' role - via node (2b)', function () {
//
// Expected result:
// a ====> b ----> c ----> d ~~~~ e
// A restriction from ~~~~ to ---- via node d.
//
var graph = restriction2;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '~', role: 'from', type: 'way'},
{id: '-', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('updates both \'to\' and \'from\' roles for via-node u-turn restrictions (3c)', function () {
//
// Expected result:
// a ----> b ----> c ====> d ~~~~ e
// A restriction from ==== to ==== via node d.
//
var graph = restriction3;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '=', role: 'from', type: 'way'},
{id: '=', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('updates both \'to\' and \'from\' roles for via-node u-turn restrictions (3b)', function () {
//
// Expected result:
// a ====> b ----> c ----> d ~~~~ e
// A restriction from ---- to ---- via node d.
//
var graph = restriction3;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '-', role: 'from', type: 'way'},
{id: '-', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('updates a restriction\'s \'from\' role - via way (4c)', function () {
//
// Expected result:
// f <~~~~ e
// |
// |
// a ----> b ----> c ====> d
//
// A restriction from ==== to ~~~~ via way |
//
var graph = restriction4;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '=', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: '|', role: 'via', type: 'way'}
]);
});
it('updates a restriction\'s \'from\' role - via way (4b)', function () {
//
// Expected result:
// f <~~~~ e
// |
// |
// a ====> b ----> c ----> d
//
// A restriction from ---- to ~~~~ via way |
//
var graph = restriction4;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '-', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: '|', role: 'via', type: 'way'}
]);
});
it('updates a restriction\'s \'to\' role - via way (5c)', function () {
//
// Expected result:
// f <~~~~ e
// |
// |
// a ----> b ----> c ====> d
//
// A restriction from ~~~~ to ==== via way |
//
var graph = restriction5;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '~', role: 'from', type: 'way'},
{id: '=', role: 'to', type: 'way'},
{id: '|', role: 'via', type: 'way'}
]);
});
it('updates a restriction\'s \'to\' role - via way (5b)', function () {
//
// Expected result:
// f <~~~~ e
// |
// |
// a ====> b ----> c ----> d
//
// A restriction from ~~~~ to ---- via way |
//
var graph = restriction5;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '~', role: 'from', type: 'way'},
{id: '-', role: 'to', type: 'way'},
{id: '|', role: 'via', type: 'way'}
]);
});
it('updates a restriction\'s \'via\' role when splitting via way (6c)', function () {
//
// Expected result:
// e f
// | ‖
// | ‖
// a ----> b ----> c ====> d
//
// A restriction from | to ‖ via ways ----, ====
//
var graph = restriction6;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '|', role: 'from', type: 'way'},
{id: '-', role: 'via', type: 'way'},
{id: '=', role: 'via', type: 'way'},
{id: '‖', role: 'to', type: 'way'}
]);
});
it('updates a restriction\'s \'via\' role when splitting via way (6b)', function () {
//
// Expected result:
// e f
// | ‖
// | ‖
// a ====> b ----> c ----> d
//
// A restriction from | to ‖ via ways ----, ====
//
var graph = restriction6;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '|', role: 'from', type: 'way'},
{id: '-', role: 'via', type: 'way'},
{id: '=', role: 'via', type: 'way'},
{id: '‖', role: 'to', type: 'way'}
]);
});
it('leaves unaffected restrictions unchanged (7b)', function () {
//
// Expected result:
// a <==== b <---- c <---- d ~~~~ e
// A restriction from ---- to ~~~~ via d.
//
var graph = restriction7;
graph = iD.actionSplit('b', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '-', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
it('leaves unaffected restrictions unchanged (7c)', function () {
//
// Expected result:
// a <---- b <---- c <==== d ~~~~ e
// A restriction from ---- to ~~~~ via d.
//
var graph = restriction7;
graph = iD.actionSplit('c', ['='])(graph);
expect(graph.entity('r').members).to.eql([
{id: '=', role: 'from', type: 'way'},
{id: '~', role: 'to', type: 'way'},
{id: 'd', role: 'via', type: 'node'}
]);
});
});
});
});
});