mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-20 23:44:47 +02:00
Cleanup docs and tests for actionRestrictTurn / actionUnrestrictTurn
- actionRestrictTurn will no longer "infer" the turn type - restrictionType *must* be passed in - this is ok because the only code we use this action (restrictions.js) already has inferred the type - this simplifies what the action actually does - moved the tests from restrict_turn.js that were really just testing the restriction type inferrence over to intersection.js (and added a few more tests for iD.osmInferRestriction)
This commit is contained in:
@@ -1,33 +1,23 @@
|
||||
import {
|
||||
osmInferRestriction,
|
||||
osmRelation
|
||||
} from '../osm';
|
||||
import { osmRelation } from '../osm';
|
||||
|
||||
|
||||
// Create a restriction relation for `turn`, which must have the following structure:
|
||||
// `actionRestrictTurn` creates a turn restriction relation.
|
||||
//
|
||||
// {
|
||||
// from: { node: <node ID>, way: <way ID> },
|
||||
// via: { node: <node ID>, ways: [<way ID>,<way ID>,...] },
|
||||
// to: { node: <node ID>, way: <way ID> },
|
||||
// restriction: <'no_right_turn', 'no_left_turn', etc.>
|
||||
// }
|
||||
// `turn` must be an `osmTurn` object
|
||||
// see osm/intersection.js, pathToTurn()
|
||||
//
|
||||
// This specifies a restriction of type `restriction` when traveling from
|
||||
// `from.node` in `from.way` toward `to.node` in `to.way` via `via.node` OR `via.ways`.
|
||||
// `turn.from.way` toward `turn.to.way` via `turn.via.node` OR `turn.via.ways`.
|
||||
// (The action does not check that these entities form a valid intersection.)
|
||||
//
|
||||
// If `restriction` is not provided, it is automatically determined by
|
||||
// osmInferRestriction.
|
||||
//
|
||||
// From, to, and via ways should be split before calling this action.
|
||||
// (old versions of the code would split the ways here, but we no longer do it)
|
||||
//
|
||||
// For testing convenience, accepts an ID to assign to the new relation.
|
||||
// Normally, this will be undefined and the relation will automatically
|
||||
// be assigned a new ID.
|
||||
// For testing convenience, accepts a restrictionID to assign to the new
|
||||
// relation. Normally, this will be undefined and the relation will
|
||||
// automatically be assigned a new ID.
|
||||
//
|
||||
export function actionRestrictTurn(turn, projection, restrictionID) {
|
||||
export function actionRestrictTurn(turn, restrictionType, restrictionID) {
|
||||
|
||||
return function(graph) {
|
||||
var fromWay = graph.entity(turn.from.way);
|
||||
@@ -52,7 +42,7 @@ export function actionRestrictTurn(turn, projection, restrictionID) {
|
||||
id: restrictionID,
|
||||
tags: {
|
||||
type: 'restriction',
|
||||
restriction: turn.restriction || osmInferRestriction(graph, turn, projection)
|
||||
restriction: restrictionType
|
||||
},
|
||||
members: members
|
||||
}));
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
import { actionDeleteRelation } from './delete_relation';
|
||||
|
||||
|
||||
// Remove the effects of `turn.restriction` on `turn`, which must have the
|
||||
// following structure:
|
||||
// `actionUnrestrictTurn` deletes a turn restriction relation.
|
||||
//
|
||||
// {
|
||||
// from: { node: <node ID>, way: <way ID> },
|
||||
// via: { node: <node ID> },
|
||||
// to: { node: <node ID>, way: <way ID> },
|
||||
// restrictionID: <relation ID>
|
||||
// }
|
||||
//
|
||||
// In the simple case, `restrictionID` is a reference to a `no_*` restriction
|
||||
// on the turn itself. In this case, it is simply deleted.
|
||||
//
|
||||
// The more complex case is where `restrictionID` references an `only_*`
|
||||
// restriction on a different turn in the same intersection. In that case,
|
||||
// that restriction is also deleted, but at the same time restrictions on
|
||||
// the turns other than the first two are created.
|
||||
// `turn` must be an `osmTurn` object with a `restrictionID` property.
|
||||
// see osm/intersection.js, pathToTurn()
|
||||
//
|
||||
export function actionUnrestrictTurn(turn) {
|
||||
return function(graph) {
|
||||
|
||||
@@ -339,15 +339,15 @@ export function uiFieldRestrictions(field, context) {
|
||||
|
||||
} else if (datum instanceof osmTurn) {
|
||||
var actions, extraActions, turns, i;
|
||||
datum.restriction = osmInferRestriction(vgraph, datum, projection);
|
||||
var restrictionType = osmInferRestriction(vgraph, datum, projection);
|
||||
|
||||
if (datum.restrictionID && !datum.direct) {
|
||||
return;
|
||||
|
||||
} else if (datum.restrictionID && !datum.only) { // cycle NO -> ONLY
|
||||
} else if (datum.restrictionID && !datum.only) { // NO -> ONLY
|
||||
var datumOnly = _cloneDeep(datum);
|
||||
datumOnly.only = true;
|
||||
datumOnly.restriction = datumOnly.restriction.replace(/^no/, 'only');
|
||||
restrictionType = restrictionType.replace(/^no/, 'only');
|
||||
|
||||
// Adding an ONLY restriction should destroy all other direct restrictions from the FROM.
|
||||
// We will remember them in _oldTurns, and restore them if the user clicks again.
|
||||
@@ -356,17 +356,18 @@ export function uiFieldRestrictions(field, context) {
|
||||
_oldTurns = [];
|
||||
for (i = 0; i < turns.length; i++) {
|
||||
if (turns[i].direct) {
|
||||
turns[i].restrictionType = osmInferRestriction(vgraph, turns[i], projection);
|
||||
_oldTurns.push(turns[i]);
|
||||
extraActions.push(actionUnrestrictTurn(turns[i], projection));
|
||||
extraActions.push(actionUnrestrictTurn(turns[i]));
|
||||
}
|
||||
}
|
||||
|
||||
actions = _intersection.actions.concat(extraActions, [
|
||||
actionRestrictTurn(datumOnly, projection),
|
||||
actionRestrictTurn(datumOnly, restrictionType),
|
||||
t('operations.restriction.annotation.create')
|
||||
]);
|
||||
|
||||
} else if (datum.restrictionID) { // cycle ONLY -> Allowed
|
||||
} else if (datum.restrictionID) { // ONLY -> Allowed
|
||||
// Restore whatever restrictions we might have destroyed by cycling thru the ONLY state.
|
||||
// This relies on the assumption that the intersection was already split up when we
|
||||
// performed the previous action (NO -> ONLY), so the IDs in _oldTurns shouldn't have changed.
|
||||
@@ -374,19 +375,19 @@ export function uiFieldRestrictions(field, context) {
|
||||
extraActions = [];
|
||||
for (i = 0; i < turns.length; i++) {
|
||||
if (turns[i].key !== datum.key) {
|
||||
extraActions.push(actionRestrictTurn(turns[i], projection));
|
||||
extraActions.push(actionRestrictTurn(turns[i], turns[i].restrictionType));
|
||||
}
|
||||
}
|
||||
_oldTurns = null;
|
||||
|
||||
actions = _intersection.actions.concat(extraActions, [
|
||||
actionUnrestrictTurn(datum, projection),
|
||||
actionUnrestrictTurn(datum),
|
||||
t('operations.restriction.annotation.delete')
|
||||
]);
|
||||
|
||||
} else { // cycle Allowed -> NO
|
||||
} else { // Allowed -> NO
|
||||
actions = _intersection.actions.concat([
|
||||
actionRestrictTurn(datum, projection),
|
||||
actionRestrictTurn(datum, restrictionType),
|
||||
t('operations.restriction.annotation.create')
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,288 +1,80 @@
|
||||
describe('iD.actionRestrictTurn', function() {
|
||||
var projection = d3.geoMercator().scale(250 / Math.PI);
|
||||
it('adds a via node restriction to an unrestricted turn', function() {
|
||||
//
|
||||
// u === * --- w
|
||||
//
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u'}),
|
||||
iD.osmNode({id: '*'}),
|
||||
iD.osmNode({id: 'w'}),
|
||||
iD.osmWay({id: '=', nodes: ['u', '*']}),
|
||||
iD.osmWay({id: '-', nodes: ['*', 'w']})
|
||||
]);
|
||||
|
||||
describe('via node', function() {
|
||||
var turn = {
|
||||
from: { node: 'u', way: '=' },
|
||||
via: { node: '*'},
|
||||
to: { node: 'w', way: '-' }
|
||||
};
|
||||
|
||||
it('adds a via node restriction to an unrestricted turn', function() {
|
||||
// u====*--->w
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u'}),
|
||||
iD.osmNode({id: '*'}),
|
||||
iD.osmNode({id: 'w'}),
|
||||
iD.osmWay({id: '=', nodes: ['u', '*']}),
|
||||
iD.osmWay({id: '-', nodes: ['*', 'w']})
|
||||
]);
|
||||
var action = iD.actionRestrictTurn({
|
||||
from: {node: 'u', way: '='},
|
||||
via: {node: '*'},
|
||||
to: {node: 'w', way: '-'},
|
||||
restriction: 'no_right_turn'
|
||||
}, projection, 'r');
|
||||
var action = iD.actionRestrictTurn(turn, 'no_straight_on', 'r');
|
||||
graph = action(graph);
|
||||
|
||||
graph = action(graph);
|
||||
var r = graph.entity('r');
|
||||
expect(r.tags).to.eql({type: 'restriction', restriction: 'no_straight_on'});
|
||||
|
||||
var r = graph.entity('r');
|
||||
expect(r.tags).to.eql({type: 'restriction', restriction: 'no_right_turn'});
|
||||
var f = r.memberByRole('from');
|
||||
expect(f.id).to.eql('=');
|
||||
expect(f.type).to.eql('way');
|
||||
|
||||
var f = r.memberByRole('from');
|
||||
expect(f.id).to.eql('=');
|
||||
expect(f.type).to.eql('way');
|
||||
var v = r.memberByRole('via');
|
||||
expect(v.id).to.eql('*');
|
||||
expect(v.type).to.eql('node');
|
||||
|
||||
var v = r.memberByRole('via');
|
||||
expect(v.id).to.eql('*');
|
||||
expect(v.type).to.eql('node');
|
||||
|
||||
var t = r.memberByRole('to');
|
||||
expect(t.id).to.eql('-');
|
||||
expect(t.type).to.eql('way');
|
||||
});
|
||||
|
||||
//TODO?
|
||||
it.skip('infers the restriction type based on the turn angle', function() {
|
||||
// u====*~~~~w
|
||||
// |
|
||||
// x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u', loc: [-1, 0]}),
|
||||
iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
iD.osmNode({id: 'w', loc: [ 1, 0]}),
|
||||
iD.osmNode({id: 'x', loc: [ 0, -1]}),
|
||||
iD.osmWay({id: '=', nodes: ['u', '*']}),
|
||||
iD.osmWay({id: '-', nodes: ['*', 'x']}),
|
||||
iD.osmWay({id: '~', nodes: ['*', 'w']})
|
||||
]);
|
||||
|
||||
var r1 = iD.actionRestrictTurn({
|
||||
from: {node: 'u', way: '='},
|
||||
via: {node: '*'},
|
||||
to: {node: 'x', way: '-'}
|
||||
}, projection, 'r')(graph);
|
||||
expect(r1.entity('r').tags.restriction).to.equal('no_right_turn');
|
||||
|
||||
var r2 = iD.actionRestrictTurn({
|
||||
from: {node: 'x', way: '-'},
|
||||
via: {node: '*'},
|
||||
to: {node: 'w', way: '~'}
|
||||
}, projection, 'r')(graph);
|
||||
expect(r2.entity('r').tags.restriction).to.equal('no_right_turn');
|
||||
|
||||
var l1 = iD.actionRestrictTurn({
|
||||
from: {node: 'x', way: '-'},
|
||||
via: {node: '*'},
|
||||
to: {node: 'u', way: '='}
|
||||
}, projection, 'r')(graph);
|
||||
expect(l1.entity('r').tags.restriction).to.equal('no_left_turn');
|
||||
|
||||
var l2 = iD.actionRestrictTurn({
|
||||
from: {node: 'w', way: '~'},
|
||||
via: {node: '*'},
|
||||
to: {node: 'x', way: '-'}
|
||||
}, projection, 'r')(graph);
|
||||
expect(l2.entity('r').tags.restriction).to.equal('no_left_turn');
|
||||
|
||||
var s = iD.actionRestrictTurn({
|
||||
from: {node: 'u', way: '='},
|
||||
via: {node: '*'},
|
||||
to: {node: 'w', way: '~'}
|
||||
}, projection, 'r')(graph);
|
||||
expect(s.entity('r').tags.restriction).to.equal('no_straight_on');
|
||||
|
||||
var u = iD.actionRestrictTurn({
|
||||
from: {node: 'u', way: '='},
|
||||
via: {node: '*'},
|
||||
to: {node: 'u', way: '='}
|
||||
}, projection, 'r')(graph);
|
||||
expect(u.entity('r').tags.restriction).to.equal('no_u_turn');
|
||||
});
|
||||
|
||||
//TODO?
|
||||
it.skip('infers no_u_turn from acute angle made by forward oneways', function() {
|
||||
// *
|
||||
// / \
|
||||
// w2/ \w1
|
||||
// / \
|
||||
// u x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u', loc: [-1, -20]}),
|
||||
iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
iD.osmNode({id: 'x', loc: [ 1, -20]}),
|
||||
iD.osmWay({id: 'w1', nodes: ['x', '*'], tags: {oneway: 'yes'}}),
|
||||
iD.osmWay({id: 'w2', nodes: ['*', 'u'], tags: {oneway: 'yes'}})
|
||||
]);
|
||||
|
||||
var r = iD.actionRestrictTurn({
|
||||
from: {node: 'x', way: 'w1'},
|
||||
via: {node: '*'},
|
||||
to: {node: 'u', way: 'w2'}
|
||||
}, projection, 'r')(graph);
|
||||
expect(r.entity('r').tags.restriction).to.equal('no_u_turn');
|
||||
});
|
||||
|
||||
//TODO?
|
||||
it.skip('infers no_u_turn from acute angle made by reverse oneways', function() {
|
||||
// *
|
||||
// / \
|
||||
// w2/ \w1
|
||||
// / \
|
||||
// u x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u', loc: [-1, -20]}),
|
||||
iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
iD.osmNode({id: 'x', loc: [ 1, -20]}),
|
||||
iD.osmWay({id: 'w1', nodes: ['*', 'x'], tags: {oneway: '-1'}}),
|
||||
iD.osmWay({id: 'w2', nodes: ['u', '*'], tags: {oneway: '-1'}})
|
||||
]);
|
||||
|
||||
var r = iD.actionRestrictTurn({
|
||||
from: {node: 'x', way: 'w1'},
|
||||
via: {node: '*'},
|
||||
to: {node: 'u', way: 'w2'}
|
||||
}, projection, 'r')(graph);
|
||||
expect(r.entity('r').tags.restriction).to.equal('no_u_turn');
|
||||
});
|
||||
var t = r.memberByRole('to');
|
||||
expect(t.id).to.eql('-');
|
||||
expect(t.type).to.eql('way');
|
||||
});
|
||||
|
||||
|
||||
describe('via way', function() {
|
||||
it('adds a via way restriction to an unrestricted turn', function() {
|
||||
//
|
||||
// u === v1
|
||||
// |
|
||||
// w --- v2
|
||||
//
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u'}),
|
||||
iD.osmNode({id: 'v1'}),
|
||||
iD.osmNode({id: 'v2'}),
|
||||
iD.osmNode({id: 'w'}),
|
||||
iD.osmWay({id: '=', nodes: ['u', 'v1']}),
|
||||
iD.osmWay({id: '|', nodes: ['v1', 'v2']}),
|
||||
iD.osmWay({id: '-', nodes: ['v2', 'w']})
|
||||
]);
|
||||
|
||||
it('adds a via way restriction to an unrestricted turn', function() {
|
||||
// u ==== VIA ---> w
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u'}),
|
||||
iD.osmNode({id: 'V1'}),
|
||||
iD.osmNode({id: 'V2'}),
|
||||
iD.osmNode({id: 'w'}),
|
||||
iD.osmWay({id: '=', nodes: ['u', 'V1']}),
|
||||
iD.osmWay({id: 'VIA', nodes: ['V1', 'V2']}),
|
||||
iD.osmWay({id: '-', nodes: ['V2', 'w']})
|
||||
]);
|
||||
var action = iD.actionRestrictTurn({
|
||||
from: {node: 'u', way: '='},
|
||||
via: {ways: ['VIA']},
|
||||
to: {node: 'w', way: '-'},
|
||||
restriction: 'no_u_turn'
|
||||
}, projection, 'r');
|
||||
var turn = {
|
||||
from: { node: 'u', way: '=' },
|
||||
via: { ways: ['|'] },
|
||||
to: { node: 'w', way: '-' }
|
||||
};
|
||||
|
||||
graph = action(graph);
|
||||
var action = iD.actionRestrictTurn(turn, 'no_u_turn', 'r');
|
||||
graph = action(graph);
|
||||
|
||||
var r = graph.entity('r');
|
||||
expect(r.tags).to.eql({type: 'restriction', restriction: 'no_u_turn'});
|
||||
var r = graph.entity('r');
|
||||
expect(r.tags).to.eql({type: 'restriction', restriction: 'no_u_turn'});
|
||||
|
||||
var f = r.memberByRole('from');
|
||||
expect(f.id).to.eql('=');
|
||||
expect(f.type).to.eql('way');
|
||||
var f = r.memberByRole('from');
|
||||
expect(f.id).to.eql('=');
|
||||
expect(f.type).to.eql('way');
|
||||
|
||||
var v = r.memberByRole('via');
|
||||
expect(v.id).to.eql('VIA');
|
||||
expect(v.type).to.eql('way');
|
||||
var v = r.memberByRole('via');
|
||||
expect(v.id).to.eql('|');
|
||||
expect(v.type).to.eql('way');
|
||||
|
||||
var t = r.memberByRole('to');
|
||||
expect(t.id).to.eql('-');
|
||||
expect(t.type).to.eql('way');
|
||||
});
|
||||
|
||||
|
||||
// TODO?
|
||||
|
||||
// it('infers the restriction type based on the turn angle', function() {
|
||||
// // u====*~~~~w
|
||||
// // |
|
||||
// // x
|
||||
// var graph = iD.coreGraph([
|
||||
// iD.osmNode({id: 'u', loc: [-1, 0]}),
|
||||
// iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
// iD.osmNode({id: 'w', loc: [ 1, 0]}),
|
||||
// iD.osmNode({id: 'x', loc: [ 0, -1]}),
|
||||
// iD.osmWay({id: '=', nodes: ['u', '*']}),
|
||||
// iD.osmWay({id: '-', nodes: ['*', 'x']}),
|
||||
// iD.osmWay({id: '~', nodes: ['*', 'w']})
|
||||
// ]);
|
||||
|
||||
// var r1 = iD.actionRestrictTurn({
|
||||
// from: {node: 'u', way: '='},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'x', way: '-'}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(r1.entity('r').tags.restriction).to.equal('no_right_turn');
|
||||
|
||||
// var r2 = iD.actionRestrictTurn({
|
||||
// from: {node: 'x', way: '-'},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'w', way: '~'}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(r2.entity('r').tags.restriction).to.equal('no_right_turn');
|
||||
|
||||
// var l1 = iD.actionRestrictTurn({
|
||||
// from: {node: 'x', way: '-'},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'u', way: '='}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(l1.entity('r').tags.restriction).to.equal('no_left_turn');
|
||||
|
||||
// var l2 = iD.actionRestrictTurn({
|
||||
// from: {node: 'w', way: '~'},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'x', way: '-'}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(l2.entity('r').tags.restriction).to.equal('no_left_turn');
|
||||
|
||||
// var s = iD.actionRestrictTurn({
|
||||
// from: {node: 'u', way: '='},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'w', way: '~'}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(s.entity('r').tags.restriction).to.equal('no_straight_on');
|
||||
|
||||
// var u = iD.actionRestrictTurn({
|
||||
// from: {node: 'u', way: '='},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'u', way: '='}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(u.entity('r').tags.restriction).to.equal('no_u_turn');
|
||||
// });
|
||||
|
||||
// it('infers no_u_turn from acute angle made by forward oneways', function() {
|
||||
// // *
|
||||
// // / \
|
||||
// // w2/ \w1
|
||||
// // / \
|
||||
// // u x
|
||||
// var graph = iD.coreGraph([
|
||||
// iD.osmNode({id: 'u', loc: [-1, -20]}),
|
||||
// iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
// iD.osmNode({id: 'x', loc: [ 1, -20]}),
|
||||
// iD.osmWay({id: 'w1', nodes: ['x', '*'], tags: {oneway: 'yes'}}),
|
||||
// iD.osmWay({id: 'w2', nodes: ['*', 'u'], tags: {oneway: 'yes'}})
|
||||
// ]);
|
||||
|
||||
// var r = iD.actionRestrictTurn({
|
||||
// from: {node: 'x', way: 'w1'},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'u', way: 'w2'}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(r.entity('r').tags.restriction).to.equal('no_u_turn');
|
||||
// });
|
||||
|
||||
// it('infers no_u_turn from acute angle made by reverse oneways', function() {
|
||||
// // *
|
||||
// // / \
|
||||
// // w2/ \w1
|
||||
// // / \
|
||||
// // u x
|
||||
// var graph = iD.coreGraph([
|
||||
// iD.osmNode({id: 'u', loc: [-1, -20]}),
|
||||
// iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
// iD.osmNode({id: 'x', loc: [ 1, -20]}),
|
||||
// iD.osmWay({id: 'w1', nodes: ['*', 'x'], tags: {oneway: '-1'}}),
|
||||
// iD.osmWay({id: 'w2', nodes: ['u', '*'], tags: {oneway: '-1'}})
|
||||
// ]);
|
||||
|
||||
// var r = iD.actionRestrictTurn({
|
||||
// from: {node: 'x', way: 'w1'},
|
||||
// via: {node: '*'},
|
||||
// to: {node: 'u', way: 'w2'}
|
||||
// }, projection, 'r')(graph);
|
||||
// expect(r.entity('r').tags.restriction).to.equal('no_u_turn');
|
||||
// });
|
||||
var t = r.memberByRole('to');
|
||||
expect(t.id).to.eql('-');
|
||||
expect(t.type).to.eql('way');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
describe('iD.actionUnrestrictTurn', function() {
|
||||
it('removes a restriction from a restricted turn', function() {
|
||||
// u====*--->w
|
||||
//
|
||||
// u === * --- w
|
||||
//
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({ id: 'u' }),
|
||||
iD.osmNode({ id: '*' }),
|
||||
|
||||
@@ -557,3 +557,153 @@ describe('iD.osmIntersection', function() {
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('iD.osmInferRestriction', function() {
|
||||
var projection = d3.geoMercator().scale(250 / Math.PI);
|
||||
|
||||
it('infers the restriction type based on the turn angle', function() {
|
||||
//
|
||||
// u === * ~~~ w
|
||||
// |
|
||||
// x
|
||||
//
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'u', loc: [-1, 0]}),
|
||||
iD.osmNode({id: '*', loc: [ 0, 0]}),
|
||||
iD.osmNode({id: 'w', loc: [ 1, 0]}),
|
||||
iD.osmNode({id: 'x', loc: [ 0, -1]}),
|
||||
iD.osmWay({id: '=', nodes: ['u', '*']}),
|
||||
iD.osmWay({id: '-', nodes: ['*', 'x']}),
|
||||
iD.osmWay({id: '~', nodes: ['*', 'w']})
|
||||
]);
|
||||
|
||||
var r1 = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'u', way: '=', vertex: '*' },
|
||||
to: { node: 'x', way: '-', vertex: '*' }
|
||||
}, projection);
|
||||
expect(r1).to.equal('no_right_turn');
|
||||
|
||||
var r2 = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'x', way: '-', vertex: '*' },
|
||||
to: { node: 'w', way: '~', vertex: '*' }
|
||||
}, projection);
|
||||
expect(r2).to.equal('no_right_turn');
|
||||
|
||||
var l1 = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'x', way: '-', vertex: '*' },
|
||||
to: { node: 'u', way: '=', vertex: '*' }
|
||||
}, projection);
|
||||
expect(l1).to.equal('no_left_turn');
|
||||
|
||||
var l2 = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'w', way: '~', vertex: '*' },
|
||||
to: { node: 'x', way: '-', vertex: '*' }
|
||||
}, projection);
|
||||
expect(l2).to.equal('no_left_turn');
|
||||
|
||||
var s = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'u', way: '=', vertex: '*' },
|
||||
to: { node: 'w', way: '~', vertex: '*' }
|
||||
}, projection);
|
||||
expect(s).to.equal('no_straight_on');
|
||||
|
||||
var u = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'u', way: '=', vertex: '*' },
|
||||
to: { node: 'u', way: '=', vertex: '*' }
|
||||
}, projection);
|
||||
expect(u).to.equal('no_u_turn');
|
||||
});
|
||||
|
||||
|
||||
it('infers no_u_turn from sharply acute angle made by forward oneways', function() {
|
||||
// *
|
||||
// / \
|
||||
// w2/ \w1 angle ≈22.6°
|
||||
// / \
|
||||
// u x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({ id: 'u', loc: [0, -5] }),
|
||||
iD.osmNode({ id: '*', loc: [1, 0] }),
|
||||
iD.osmNode({ id: 'x', loc: [2, -5] }),
|
||||
iD.osmWay({ id: 'w1', nodes: ['x', '*'], tags: { oneway: 'yes' } }),
|
||||
iD.osmWay({ id: 'w2', nodes: ['*', 'u'], tags: { oneway: 'yes' } })
|
||||
]);
|
||||
|
||||
var r = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'x', way: 'w1', vertex: '*' },
|
||||
to: { node: 'u', way: 'w2', vertex: '*' }
|
||||
}, projection);
|
||||
expect(r).to.equal('no_u_turn');
|
||||
});
|
||||
|
||||
|
||||
it('does not infer no_u_turn from widely acute angle made by forward oneways', function() {
|
||||
// *
|
||||
// / \
|
||||
// w2/ \w1 angle ≈36.9°
|
||||
// / \
|
||||
// u x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({ id: 'u', loc: [0, -3] }),
|
||||
iD.osmNode({ id: '*', loc: [1, 0] }),
|
||||
iD.osmNode({ id: 'x', loc: [2, -3] }),
|
||||
iD.osmWay({ id: 'w1', nodes: ['x', '*'], tags: { oneway: 'yes' } }),
|
||||
iD.osmWay({ id: 'w2', nodes: ['*', 'u'], tags: { oneway: 'yes' } })
|
||||
]);
|
||||
|
||||
var r = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'x', way: 'w1', vertex: '*' },
|
||||
to: { node: 'u', way: 'w2', vertex: '*' }
|
||||
}, projection);
|
||||
expect(r).to.equal('no_left_turn');
|
||||
});
|
||||
|
||||
|
||||
it('infers no_u_turn from sharply acute angle made by forward oneways with a via way', function() {
|
||||
// * -- +
|
||||
// / \
|
||||
// w2/ \w1 angle ≈22.6°
|
||||
// / \
|
||||
// u x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({ id: 'u', loc: [0, -5] }),
|
||||
iD.osmNode({ id: '*', loc: [1, 0] }),
|
||||
iD.osmNode({ id: '+', loc: [2, 0] }),
|
||||
iD.osmNode({ id: 'x', loc: [3, -5] }),
|
||||
iD.osmWay({ id: 'w1', nodes: ['x', '+'], tags: { oneway: 'yes' } }),
|
||||
iD.osmWay({ id: 'w2', nodes: ['*', 'u'], tags: { oneway: 'yes' } }),
|
||||
iD.osmWay({ id: '-', nodes: ['*', '+'] })
|
||||
]);
|
||||
|
||||
var r = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'x', way: 'w1', vertex: '+' },
|
||||
to: { node: 'u', way: 'w2', vertex: '*' }
|
||||
}, projection);
|
||||
expect(r).to.equal('no_u_turn');
|
||||
});
|
||||
|
||||
|
||||
it('infers no_u_turn from widely acute angle made by forward oneways with a via way', function() {
|
||||
// * -- +
|
||||
// / \
|
||||
// w2/ \w1 angle ≈36.9°
|
||||
// / \
|
||||
// u x
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({ id: 'u', loc: [0, -3] }),
|
||||
iD.osmNode({ id: '*', loc: [1, 0] }),
|
||||
iD.osmNode({ id: '+', loc: [2, 0] }),
|
||||
iD.osmNode({ id: 'x', loc: [3, -3] }),
|
||||
iD.osmWay({ id: 'w1', nodes: ['x', '+'], tags: { oneway: 'yes' } }),
|
||||
iD.osmWay({ id: 'w2', nodes: ['*', 'u'], tags: { oneway: 'yes' } }),
|
||||
iD.osmWay({ id: '-', nodes: ['*', '+'] })
|
||||
]);
|
||||
|
||||
var r = iD.osmInferRestriction(graph, {
|
||||
from: { node: 'x', way: 'w1', vertex: '+' },
|
||||
to: { node: 'u', way: 'w2', vertex: '*' }
|
||||
}, projection);
|
||||
expect(r).to.equal('no_u_turn');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user