mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-14 21:28:11 +02:00
Support more direction tags for reversal in Reverse action
(closes #5121) This commit also refactors some of the logic to make it simpler and more efficient (removes lodash _transform too) and updates the comment that was out of date.
This commit is contained in:
+75
-94
@@ -1,67 +1,61 @@
|
||||
import _transform from 'lodash-es/transform';
|
||||
|
||||
|
||||
/*
|
||||
Order the nodes of a way in reverse order and reverse any direction dependent tags
|
||||
other than `oneway`. (We assume that correcting a backwards oneway is the primary
|
||||
reason for reversing a way.)
|
||||
Order the nodes of a way in reverse order and reverse any direction dependent tags
|
||||
other than `oneway`. (We assume that correcting a backwards oneway is the primary
|
||||
reason for reversing a way.)
|
||||
|
||||
The following transforms are performed:
|
||||
In addition, numeric-valued `incline` tags are negated.
|
||||
|
||||
Keys:
|
||||
*:right=* ⟺ *:left=*
|
||||
*:forward=* ⟺ *:backward=*
|
||||
direction=up ⟺ direction=down
|
||||
incline=up ⟺ incline=down
|
||||
*=right ⟺ *=left
|
||||
The JOSM implementation was used as a guide, but transformations that were of unclear benefit
|
||||
or adjusted tags that don't seem to be used in practice were omitted.
|
||||
|
||||
Relation members:
|
||||
role=forward ⟺ role=backward
|
||||
role=north ⟺ role=south
|
||||
role=east ⟺ role=west
|
||||
|
||||
In addition, numeric-valued `incline` tags are negated.
|
||||
|
||||
The JOSM implementation was used as a guide, but transformations that were of unclear benefit
|
||||
or adjusted tags that don't seem to be used in practice were omitted.
|
||||
|
||||
Also, each node on the way is examined for its own tags and the following transformations are performed
|
||||
in order to ensure associated nodes (eg a Stop Sign) is also reversed
|
||||
|
||||
Node Keys:
|
||||
*direction=forward ⟺ *direction=backward
|
||||
*direction=left ⟺ *direction=right
|
||||
*:forward=* ⟺ *:backward=*
|
||||
*:left=* ⟺ *:right=*
|
||||
|
||||
References:
|
||||
http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
|
||||
http://wiki.openstreetmap.org/wiki/Key:direction#Steps
|
||||
http://wiki.openstreetmap.org/wiki/Key:incline
|
||||
http://wiki.openstreetmap.org/wiki/Route#Members
|
||||
http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
|
||||
http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
|
||||
http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
|
||||
*/
|
||||
export function actionReverse(wayId, options) {
|
||||
var replacements = [
|
||||
[/:right$/, ':left'], [/:left$/, ':right'],
|
||||
[/:forward$/, ':backward'], [/:backward$/, ':forward']
|
||||
],
|
||||
numeric = /^([+\-]?)(?=[\d.])/,
|
||||
roleReversals = {
|
||||
forward: 'backward',
|
||||
backward: 'forward',
|
||||
north: 'south',
|
||||
south: 'north',
|
||||
east: 'west',
|
||||
west: 'east'
|
||||
};
|
||||
References:
|
||||
http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
|
||||
http://wiki.openstreetmap.org/wiki/Key:direction#Steps
|
||||
http://wiki.openstreetmap.org/wiki/Key:incline
|
||||
http://wiki.openstreetmap.org/wiki/Route#Members
|
||||
http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
|
||||
http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
|
||||
http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
|
||||
*/
|
||||
export function actionReverse(wayID, options) {
|
||||
var ignoreKey = /^.*(_|:)?(description|name|note|website|ref|source|comment|watch|attribution)(_|:)?/;
|
||||
var numeric = /^([+\-]?)(?=[\d.])/;
|
||||
var keyReplacements = [
|
||||
[/:right$/, ':left'],
|
||||
[/:left$/, ':right'],
|
||||
[/:forward$/, ':backward'],
|
||||
[/:backward$/, ':forward']
|
||||
];
|
||||
var valueReplacements = {
|
||||
left: 'right',
|
||||
right: 'left',
|
||||
up: 'down',
|
||||
down: 'up',
|
||||
forward: 'backward',
|
||||
backward: 'forward',
|
||||
forwards: 'backward',
|
||||
backwards: 'forward',
|
||||
};
|
||||
var roleReplacements = {
|
||||
forward: 'backward',
|
||||
backward: 'forward',
|
||||
forwards: 'backward',
|
||||
backwards: 'forward',
|
||||
north: 'south',
|
||||
south: 'north',
|
||||
east: 'west',
|
||||
west: 'east'
|
||||
};
|
||||
var onewayReplacements = {
|
||||
yes: '-1',
|
||||
'1': '-1',
|
||||
'-1': 'yes'
|
||||
};
|
||||
|
||||
|
||||
function reverseKey(key) {
|
||||
for (var i = 0; i < replacements.length; ++i) {
|
||||
var replacement = replacements[i];
|
||||
for (var i = 0; i < keyReplacements.length; ++i) {
|
||||
var replacement = keyReplacements[i];
|
||||
if (replacement[0].test(key)) {
|
||||
return key.replace(replacement[0], replacement[1]);
|
||||
}
|
||||
@@ -71,61 +65,47 @@ export function actionReverse(wayId, options) {
|
||||
|
||||
|
||||
function reverseValue(key, value) {
|
||||
if (ignoreKey.test(key)) return value;
|
||||
|
||||
if (key === 'incline' && numeric.test(value)) {
|
||||
return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
|
||||
} else if (key === 'incline' || key === 'direction') {
|
||||
return {up: 'down', down: 'up'}[value] || value;
|
||||
} else if (options && options.reverseOneway && key === 'oneway') {
|
||||
return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
|
||||
return onewayReplacements[value] || value;
|
||||
} else {
|
||||
return {left: 'right', right: 'left'}[value] || value;
|
||||
return valueReplacements[value] || value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function reverseDirectionTags(node) {
|
||||
// Update the direction based tags as appropriate then return an updated node
|
||||
return node.update({tags: _transform(node.tags, function(acc, tagValue, tagKey) {
|
||||
// See if this is a direction tag and reverse (or use existing value if not recognised)
|
||||
var re = /direction$/;
|
||||
if (re.test(tagKey)) {
|
||||
acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
|
||||
} else {
|
||||
// Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
|
||||
// This will pass through other tags unchanged
|
||||
acc[reverseKey(tagKey)] = tagValue;
|
||||
// Reverse the direction of tags attached to the nodes - #3076
|
||||
function reverseNodeTags(graph, nodeIDs) {
|
||||
for (var i = 0; i < nodeIDs.length; i++) {
|
||||
var node = graph.hasEntity(nodeIDs[i]);
|
||||
if (!node || !Object.keys(node.tags).length) continue;
|
||||
|
||||
var tags = {};
|
||||
for (var key in node.tags) {
|
||||
tags[reverseKey(key)] = reverseValue(key, node.tags[key]);
|
||||
}
|
||||
return acc;
|
||||
}, {})});
|
||||
}
|
||||
|
||||
|
||||
function reverseTagsOnNodes(graph, nodeIds) {
|
||||
// Reverse the direction of appropriate tags attached to the nodes (#3076)
|
||||
return nodeIds
|
||||
// Get each node from the graph
|
||||
.map(function(nodeId) { return graph.entity(nodeId);})
|
||||
// Check tags on the node, if there aren't any, we can skip
|
||||
.filter(function(existingNode) { return existingNode.tags !== undefined;})
|
||||
// Get a new version of each node with the appropriate tags reversed
|
||||
.map(function(existingNode) { return reverseDirectionTags(existingNode);})
|
||||
// Chain together consecutive updates to the graph for each updated node and return
|
||||
.reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
|
||||
graph = graph.replace(node.update({tags: tags}));
|
||||
}
|
||||
return graph;
|
||||
}
|
||||
|
||||
|
||||
return function(graph) {
|
||||
var way = graph.entity(wayId),
|
||||
nodes = way.nodes.slice().reverse(),
|
||||
tags = {}, key, role;
|
||||
var way = graph.entity(wayID);
|
||||
var nodes = way.nodes.slice().reverse();
|
||||
var tags = {};
|
||||
var role;
|
||||
|
||||
for (key in way.tags) {
|
||||
for (var key in way.tags) {
|
||||
tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
|
||||
}
|
||||
|
||||
graph.parentRelations(way).forEach(function(relation) {
|
||||
relation.members.forEach(function(member, index) {
|
||||
if (member.id === way.id && (role = roleReversals[member.role])) {
|
||||
if (member.id === way.id && (role = roleReplacements[member.role])) {
|
||||
relation = relation.updateMember({role: role}, index);
|
||||
graph = graph.replace(relation);
|
||||
}
|
||||
@@ -134,6 +114,7 @@ export function actionReverse(wayId, options) {
|
||||
|
||||
// Reverse any associated directions on nodes on the way and then replace
|
||||
// the way itself with the reversed node ids and updated way tags
|
||||
return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
|
||||
return reverseNodeTags(graph, nodes)
|
||||
.replace(way.update({nodes: nodes, tags: tags}));
|
||||
};
|
||||
}
|
||||
|
||||
+459
-331
@@ -1,375 +1,503 @@
|
||||
describe('iD.actionReverse', function () {
|
||||
it('reverses the order of nodes in the way', function () {
|
||||
var node1 = iD.Node(),
|
||||
node2 = iD.Node(),
|
||||
way = iD.Way({nodes: [node1.id, node2.id]}),
|
||||
graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, way]));
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, way]));
|
||||
expect(graph.entity(way.id).nodes).to.eql([node2.id, node1.id]);
|
||||
});
|
||||
|
||||
it('preserves non-directional tags', function () {
|
||||
var way = iD.Way({tags: {'highway': 'residential'}}),
|
||||
graph = iD.Graph([way]);
|
||||
var way = iD.osmWay({tags: {'highway': 'residential'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'highway': 'residential'});
|
||||
});
|
||||
|
||||
it('preserves oneway tags', function () {
|
||||
var way = iD.Way({tags: {'oneway': 'yes'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'oneway': 'yes'});
|
||||
});
|
||||
describe('reverses oneway', function () {
|
||||
it('preserves oneway tags', function () {
|
||||
var way = iD.osmWay({tags: {'oneway': 'yes'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
it('reverses oneway tags if reverseOneway: true is provided', function () {
|
||||
var graph = iD.Graph([
|
||||
iD.Way({id: 'yes', tags: {oneway: 'yes'}}),
|
||||
iD.Way({id: 'no', tags: {oneway: 'no'}}),
|
||||
iD.Way({id: '1', tags: {oneway: '1'}}),
|
||||
iD.Way({id: '-1', tags: {oneway: '-1'}})
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'oneway': 'yes'});
|
||||
});
|
||||
|
||||
it('reverses oneway tags if reverseOneway: true is provided', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'yes', tags: {oneway: 'yes'}}),
|
||||
iD.osmWay({id: 'no', tags: {oneway: 'no'}}),
|
||||
iD.osmWay({id: '1', tags: {oneway: '1'}}),
|
||||
iD.osmWay({id: '-1', tags: {oneway: '-1'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('yes', {reverseOneway: true})(graph)
|
||||
.entity('yes').tags).to.eql({oneway: '-1'});
|
||||
expect(iD.actionReverse('no', {reverseOneway: true})(graph)
|
||||
.entity('no').tags).to.eql({oneway: 'no'});
|
||||
expect(iD.actionReverse('1', {reverseOneway: true})(graph)
|
||||
.entity('1').tags).to.eql({oneway: '-1'});
|
||||
expect(iD.actionReverse('-1', {reverseOneway: true})(graph)
|
||||
.entity('-1').tags).to.eql({oneway: 'yes'});
|
||||
expect(iD.actionReverse('yes', {reverseOneway: true})(graph)
|
||||
.entity('yes').tags).to.eql({oneway: '-1'}, 'yes');
|
||||
expect(iD.actionReverse('no', {reverseOneway: true})(graph)
|
||||
.entity('no').tags).to.eql({oneway: 'no'}, 'no');
|
||||
expect(iD.actionReverse('1', {reverseOneway: true})(graph)
|
||||
.entity('1').tags).to.eql({oneway: '-1'}, '1');
|
||||
expect(iD.actionReverse('-1', {reverseOneway: true})(graph)
|
||||
.entity('-1').tags).to.eql({oneway: 'yes'}, '-1');
|
||||
});
|
||||
|
||||
it('ignores other oneway tags', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'alternating', tags: {oneway: 'alternating'}}),
|
||||
iD.osmWay({id: 'reversible', tags: {oneway: 'reversible'}}),
|
||||
iD.osmWay({id: 'dummy', tags: {oneway: 'dummy'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('alternating', {reverseOneway: true})(graph)
|
||||
.entity('alternating').tags).to.eql({oneway: 'alternating'}, 'alternating');
|
||||
expect(iD.actionReverse('reversible', {reverseOneway: true})(graph)
|
||||
.entity('reversible').tags).to.eql({oneway: 'reversible'}, 'reversible');
|
||||
expect(iD.actionReverse('dummy', {reverseOneway: true})(graph)
|
||||
.entity('dummy').tags).to.eql({oneway: 'dummy'}, 'dummy');
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms *:right=* ⟺ *:left=*', function () {
|
||||
var way = iD.Way({tags: {'cycleway:right': 'lane'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'cycleway:left': 'lane'});
|
||||
describe('reverses incline', function () {
|
||||
it('transforms incline=up ⟺ incline=down', function () {
|
||||
var way = iD.osmWay({tags: {'incline': 'up'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'cycleway:right': 'lane'});
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': 'down'});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': 'up'});
|
||||
});
|
||||
|
||||
it('negates numeric-valued incline tags', function () {
|
||||
var way = iD.osmWay({tags: {'incline': '5%'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': '-5%'});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': '5%'});
|
||||
|
||||
way = iD.osmWay({tags: {'incline': '.8°'}});
|
||||
graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': '-.8°'});
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms *:forward=* ⟺ *:backward=*', function () {
|
||||
var way = iD.Way({tags: {'maxspeed:forward': '25'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'maxspeed:backward': '25'});
|
||||
describe('reverses directional keys on ways', function () {
|
||||
it('transforms *:right=* ⟺ *:left=*', function () {
|
||||
var way = iD.osmWay({tags: {'cycleway:right': 'lane'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'maxspeed:forward': '25'});
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'cycleway:left': 'lane'});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'cycleway:right': 'lane'});
|
||||
});
|
||||
|
||||
it('transforms *:forward=* ⟺ *:backward=*', function () {
|
||||
var way = iD.osmWay({tags: {'maxspeed:forward': '25'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'maxspeed:backward': '25'});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'maxspeed:forward': '25'});
|
||||
});
|
||||
|
||||
it('transforms multiple directional tags', function () {
|
||||
var way = iD.osmWay({tags: {'maxspeed:forward': '25', 'maxspeed:backward': '30'}});
|
||||
var graph = iD.coreGraph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'maxspeed:backward': '25', 'maxspeed:forward': '30'});
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms direction=up ⟺ direction=down', function () {
|
||||
var way = iD.Way({tags: {'incline': 'up'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': 'down'});
|
||||
describe('reverses directional values on ways', function () {
|
||||
it('transforms *=up ⟺ *=down', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'inclineU', tags: {incline: 'up'}}),
|
||||
iD.osmWay({id: 'directionU', tags: {direction: 'up'}}),
|
||||
iD.osmWay({id: 'inclineD', tags: {incline: 'down'}}),
|
||||
iD.osmWay({id: 'directionD', tags: {direction: 'down'}})
|
||||
]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': 'up'});
|
||||
expect(iD.actionReverse('inclineU')(graph)
|
||||
.entity('inclineU').tags).to.eql({incline: 'down'}, 'inclineU');
|
||||
expect(iD.actionReverse('directionU')(graph)
|
||||
.entity('directionU').tags).to.eql({direction: 'down'}, 'directionU');
|
||||
|
||||
expect(iD.actionReverse('inclineD')(graph)
|
||||
.entity('inclineD').tags).to.eql({incline: 'up'}, 'inclineD');
|
||||
expect(iD.actionReverse('directionD')(graph)
|
||||
.entity('directionD').tags).to.eql({direction: 'up'}, 'directionD');
|
||||
});
|
||||
|
||||
it('skips *=up ⟺ *=down for ignored tags', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'name', tags: {name: 'up'}}),
|
||||
iD.osmWay({id: 'note', tags: {note: 'up'}}),
|
||||
iD.osmWay({id: 'ref', tags: {ref: 'down'}}),
|
||||
iD.osmWay({id: 'description', tags: {description: 'down'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('name')(graph)
|
||||
.entity('name').tags).to.eql({name: 'up'}, 'name');
|
||||
expect(iD.actionReverse('note')(graph)
|
||||
.entity('note').tags).to.eql({note: 'up'}, 'note');
|
||||
expect(iD.actionReverse('ref')(graph)
|
||||
.entity('ref').tags).to.eql({ref: 'down'}, 'ref');
|
||||
expect(iD.actionReverse('description')(graph)
|
||||
.entity('description').tags).to.eql({description: 'down'}, 'description');
|
||||
});
|
||||
|
||||
it('transforms *=forward ⟺ *=backward', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'conveyingF', tags: {conveying: 'forward'}}),
|
||||
iD.osmWay({id: 'directionF', tags: {direction: 'forward'}}),
|
||||
iD.osmWay({id: 'priorityF', tags: {priority: 'forward'}}),
|
||||
iD.osmWay({id: 'trolley_wireF', tags: {trolley_wire: 'forward'}}),
|
||||
iD.osmWay({id: 'conveyingB', tags: {conveying: 'backward'}}),
|
||||
iD.osmWay({id: 'directionB', tags: {direction: 'backward'}}),
|
||||
iD.osmWay({id: 'priorityB', tags: {priority: 'backward'}}),
|
||||
iD.osmWay({id: 'trolley_wireB', tags: {trolley_wire: 'backward'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('conveyingF')(graph)
|
||||
.entity('conveyingF').tags).to.eql({conveying: 'backward'}, 'conveyingF');
|
||||
expect(iD.actionReverse('directionF')(graph)
|
||||
.entity('directionF').tags).to.eql({direction: 'backward'}, 'directionF');
|
||||
expect(iD.actionReverse('priorityF')(graph)
|
||||
.entity('priorityF').tags).to.eql({priority: 'backward'}, 'priorityF');
|
||||
expect(iD.actionReverse('trolley_wireF')(graph)
|
||||
.entity('trolley_wireF').tags).to.eql({trolley_wire: 'backward'}, 'trolley_wireF');
|
||||
|
||||
expect(iD.actionReverse('conveyingB')(graph)
|
||||
.entity('conveyingB').tags).to.eql({conveying: 'forward'}, 'conveyingB');
|
||||
expect(iD.actionReverse('directionB')(graph)
|
||||
.entity('directionB').tags).to.eql({direction: 'forward'}, 'directionB');
|
||||
expect(iD.actionReverse('priorityB')(graph)
|
||||
.entity('priorityB').tags).to.eql({priority: 'forward'}, 'priorityB');
|
||||
expect(iD.actionReverse('trolley_wireB')(graph)
|
||||
.entity('trolley_wireB').tags).to.eql({trolley_wire: 'forward'}, 'trolley_wireB');
|
||||
});
|
||||
|
||||
it('drops "s" from forwards/backwards when reversing', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'conveyingF', tags: {conveying: 'forwards'}}),
|
||||
iD.osmWay({id: 'conveyingB', tags: {conveying: 'backwards'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('conveyingF')(graph)
|
||||
.entity('conveyingF').tags).to.eql({conveying: 'backward'}, 'conveyingF');
|
||||
expect(iD.actionReverse('conveyingB')(graph)
|
||||
.entity('conveyingB').tags).to.eql({conveying: 'forward'}, 'conveyingB');
|
||||
});
|
||||
|
||||
it('skips *=forward ⟺ *=backward for ignored tags', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'name', tags: {name: 'forward'}}),
|
||||
iD.osmWay({id: 'note', tags: {note: 'forwards'}}),
|
||||
iD.osmWay({id: 'ref', tags: {ref: 'backward'}}),
|
||||
iD.osmWay({id: 'description', tags: {description: 'backwards'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('name')(graph)
|
||||
.entity('name').tags).to.eql({name: 'forward'}, 'name');
|
||||
expect(iD.actionReverse('note')(graph)
|
||||
.entity('note').tags).to.eql({note: 'forwards'}, 'note');
|
||||
expect(iD.actionReverse('ref')(graph)
|
||||
.entity('ref').tags).to.eql({ref: 'backward'}, 'ref');
|
||||
expect(iD.actionReverse('description')(graph)
|
||||
.entity('description').tags).to.eql({description: 'backwards'}, 'description');
|
||||
});
|
||||
|
||||
it('transforms *=right ⟺ *=left', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'sidewalkR', tags: {sidewalk: 'right'}}),
|
||||
iD.osmWay({id: 'sidewalkL', tags: {sidewalk: 'left'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('sidewalkR')(graph)
|
||||
.entity('sidewalkR').tags).to.eql({sidewalk: 'left'}, 'sidewalkR');
|
||||
expect(iD.actionReverse('sidewalkL')(graph)
|
||||
.entity('sidewalkL').tags).to.eql({sidewalk: 'right'}, 'sidewalkL');
|
||||
});
|
||||
|
||||
it('skips *=right ⟺ *=left for ignored tags', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmWay({id: 'name', tags: {name: 'right'}}),
|
||||
iD.osmWay({id: 'note', tags: {note: 'right'}}),
|
||||
iD.osmWay({id: 'ref', tags: {ref: 'left'}}),
|
||||
iD.osmWay({id: 'description', tags: {description: 'left'}})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('name')(graph)
|
||||
.entity('name').tags).to.eql({name: 'right'}, 'name');
|
||||
expect(iD.actionReverse('note')(graph)
|
||||
.entity('note').tags).to.eql({note: 'right'}, 'note');
|
||||
expect(iD.actionReverse('ref')(graph)
|
||||
.entity('ref').tags).to.eql({ref: 'left'}, 'ref');
|
||||
expect(iD.actionReverse('description')(graph)
|
||||
.entity('description').tags).to.eql({description: 'left'}, 'description');
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms incline=up ⟺ incline=down', function () {
|
||||
var way = iD.Way({tags: {'incline': 'up'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': 'down'});
|
||||
describe('reverses relation roles', function () {
|
||||
it('transforms role=forward ⟺ role=backward in member relations', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'n1'}),
|
||||
iD.osmNode({id: 'n2'}),
|
||||
iD.osmWay({id: 'w1', nodes: ['n1', 'n2'], tags: {highway: 'residential'}}),
|
||||
iD.osmRelation({id: 'forward', members: [{type: 'way', id: 'w1', role: 'forward'}]}),
|
||||
iD.osmRelation({id: 'backward', members: [{type: 'way', id: 'w1', role: 'backward'}]})
|
||||
]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': 'up'});
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('forward').members[0].role).to.eql('backward', 'forward');
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('backward').members[0].role).to.eql('forward', 'backward');
|
||||
});
|
||||
|
||||
it('drops "s" from forwards/backwards when reversing', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'n1'}),
|
||||
iD.osmNode({id: 'n2'}),
|
||||
iD.osmWay({id: 'w1', nodes: ['n1', 'n2'], tags: {highway: 'residential'}}),
|
||||
iD.osmRelation({id: 'forwards', members: [{type: 'way', id: 'w1', role: 'forwards'}]}),
|
||||
iD.osmRelation({id: 'backwards', members: [{type: 'way', id: 'w1', role: 'backwards'}]})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('forwards').members[0].role).to.eql('backward', 'forwards');
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('backwards').members[0].role).to.eql('forward', 'backwards');
|
||||
});
|
||||
|
||||
it('transforms role=north ⟺ role=south in member relations', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'n1'}),
|
||||
iD.osmNode({id: 'n2'}),
|
||||
iD.osmWay({id: 'w1', nodes: ['n1', 'n2'], tags: {highway: 'residential'}}),
|
||||
iD.osmRelation({id: 'north', members: [{type: 'way', id: 'w1', role: 'north'}]}),
|
||||
iD.osmRelation({id: 'south', members: [{type: 'way', id: 'w1', role: 'south'}]})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('north').members[0].role).to.eql('south', 'north');
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('south').members[0].role).to.eql('north', 'south');
|
||||
});
|
||||
|
||||
it('transforms role=east ⟺ role=west in member relations', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'n1'}),
|
||||
iD.osmNode({id: 'n2'}),
|
||||
iD.osmWay({id: 'w1', nodes: ['n1', 'n2'], tags: {highway: 'residential'}}),
|
||||
iD.osmRelation({id: 'east', members: [{type: 'way', id: 'w1', role: 'east'}]}),
|
||||
iD.osmRelation({id: 'west', members: [{type: 'way', id: 'w1', role: 'west'}]})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('east').members[0].role).to.eql('west', 'east');
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('west').members[0].role).to.eql('east', 'west');
|
||||
});
|
||||
|
||||
it('ignores directionless roles in member relations', function () {
|
||||
var graph = iD.coreGraph([
|
||||
iD.osmNode({id: 'n1'}),
|
||||
iD.osmNode({id: 'n2'}),
|
||||
iD.osmWay({id: 'w1', nodes: ['n1', 'n2'], tags: {highway: 'residential'}}),
|
||||
iD.osmRelation({id: 'ignore', members: [{type: 'way', id: 'w1', role: 'ignore'}]}),
|
||||
iD.osmRelation({id: 'empty', members: [{type: 'way', id: 'w1', role: ''}]})
|
||||
]);
|
||||
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('ignore').members[0].role).to.eql('ignore', 'ignore');
|
||||
expect(iD.actionReverse('w1')(graph)
|
||||
.entity('empty').members[0].role).to.eql('', 'empty');
|
||||
});
|
||||
});
|
||||
|
||||
it('negates numeric-valued incline tags', function () {
|
||||
var way = iD.Way({tags: {'incline': '5%'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': '-5%'});
|
||||
describe('reverses directional values on childnodes', function () {
|
||||
// For issue #3076
|
||||
it('reverses the direction of a forward facing stop sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'direction': 'forward', 'highway': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('backward');
|
||||
});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': '5%'});
|
||||
it('reverses the direction of a backward facing stop sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'direction': 'backward', 'highway': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('forward');
|
||||
});
|
||||
|
||||
way = iD.Way({tags: {'incline': '.8°'}});
|
||||
graph = iD.Graph([way]);
|
||||
it('reverses the direction of a left facing stop sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'direction': 'left', 'highway': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('right');
|
||||
});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'incline': '-.8°'});
|
||||
it('reverses the direction of a right facing stop sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'direction': 'right', 'highway': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('left');
|
||||
});
|
||||
|
||||
it('does not assign a direction to a directionless stop sign on the way during a reverse', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'highway': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.be.undefined;
|
||||
});
|
||||
|
||||
it('ignores directions other than forward or backward on attached stop sign during a reverse', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'direction': 'empty', 'highway': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('empty');
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms *=right ⟺ *=left', function () {
|
||||
var way = iD.Way({tags: {'sidewalk': 'right'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'sidewalk': 'left'});
|
||||
describe('reverses directional keys on childnodes', function () {
|
||||
it('reverses the direction of a forward facing traffic sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'traffic_sign:forward': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:backward']).to.eql('stop');
|
||||
});
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'sidewalk': 'right'});
|
||||
it('reverses the direction of a backward facing stop sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'traffic_sign:backward': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:forward']).to.eql('stop');
|
||||
});
|
||||
|
||||
it('reverses the direction of a left facing traffic sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'traffic_sign:left': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:right']).to.eql('stop');
|
||||
});
|
||||
|
||||
it('reverses the direction of a right facing stop sign on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: {'traffic_sign:right': 'stop'}});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:left']).to.eql('stop');
|
||||
});
|
||||
|
||||
// For issue #4595
|
||||
it('reverses the direction of a forward facing traffic_signals on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: { 'traffic_signals:direction': 'forward', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('backward');
|
||||
});
|
||||
|
||||
it('reverses the direction of a backward facing traffic_signals on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: { 'traffic_signals:direction': 'backward', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('forward');
|
||||
});
|
||||
|
||||
it('reverses the direction of a left facing traffic_signals on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: { 'traffic_signals:direction': 'left', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('right');
|
||||
});
|
||||
|
||||
it('reverses the direction of a right facing traffic_signals on the way', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: { 'traffic_signals:direction': 'right', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('left');
|
||||
});
|
||||
|
||||
it('does not assign a direction to a directionless traffic_signals on the way during a reverse', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: { 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.be.undefined;
|
||||
});
|
||||
|
||||
it('ignores directions other than forward or backward on attached traffic_signals during a reverse', function () {
|
||||
var node1 = iD.osmNode();
|
||||
var node2 = iD.osmNode({tags: { 'traffic_signals:direction': 'empty', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.osmNode();
|
||||
var way = iD.osmWay({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.coreGraph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('empty');
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms multiple directional tags', function () {
|
||||
var way = iD.Way({tags: {'maxspeed:forward': '25', 'maxspeed:backward': '30'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(way.id).tags).to.eql({'maxspeed:backward': '25', 'maxspeed:forward': '30'});
|
||||
});
|
||||
|
||||
it('transforms role=forward ⟺ role=backward in member relations', function () {
|
||||
var way = iD.Way({tags: {highway: 'residential'}}),
|
||||
relation = iD.Relation({members: [{type: 'way', id: way.id, role: 'forward'}]}),
|
||||
graph = iD.Graph([way, relation]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(relation.id).members[0].role).to.eql('backward');
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(relation.id).members[0].role).to.eql('forward');
|
||||
});
|
||||
|
||||
it('transforms role=north ⟺ role=south in member relations', function () {
|
||||
var way = iD.Way({tags: {highway: 'residential'}}),
|
||||
relation = iD.Relation({members: [{type: 'way', id: way.id, role: 'north'}]}),
|
||||
graph = iD.Graph([way, relation]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(relation.id).members[0].role).to.eql('south');
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(relation.id).members[0].role).to.eql('north');
|
||||
});
|
||||
|
||||
it('transforms role=east ⟺ role=west in member relations', function () {
|
||||
var way = iD.Way({tags: {highway: 'residential'}}),
|
||||
relation = iD.Relation({members: [{type: 'way', id: way.id, role: 'east'}]}),
|
||||
graph = iD.Graph([way, relation]);
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(relation.id).members[0].role).to.eql('west');
|
||||
|
||||
graph = iD.actionReverse(way.id)(graph);
|
||||
expect(graph.entity(relation.id).members[0].role).to.eql('east');
|
||||
});
|
||||
|
||||
// For issue #3076
|
||||
it('reverses the direction of a forward facing stop sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a forward facing stop sign to node 2
|
||||
node2.tags = { 'direction': 'forward', 'highway': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('backward');
|
||||
});
|
||||
|
||||
it('reverses the direction of a backward facing stop sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a backward facing stop sign to node 2
|
||||
node2.tags = { 'direction': 'backward', 'highway': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('forward');
|
||||
});
|
||||
|
||||
it('reverses the direction of a left facing stop sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a left facing stop sign to node 2 (not sure this is a real situation,
|
||||
// but allows us to test)
|
||||
node2.tags = { 'direction': 'left', 'highway': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('right');
|
||||
});
|
||||
|
||||
it('reverses the direction of a right facing stop sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a right facing stop sign to node 2 (not sure this is a real situation,
|
||||
// but allows us to test)
|
||||
node2.tags = { 'direction': 'right', 'highway': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('left');
|
||||
});
|
||||
|
||||
it('does not assign a direction to a directionless stop sign on the way during a reverse', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a stop sign to node 2 with no direction specified
|
||||
node2.tags = { 'highway': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has not gained a direction tag
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.be.undefined;
|
||||
});
|
||||
|
||||
it('ignores directions other than forward or backward on attached stop sign during a reverse', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a stop sign to node 2 with a non-standard direction
|
||||
node2.tags = { 'direction': 'empty', 'highway': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has not had its direction tag altered
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags.direction).to.eql('empty');
|
||||
});
|
||||
|
||||
it('reverses the direction of a forward facing traffic sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a forward facing stop sign to node 2 using the traffic_sign approach
|
||||
node2.tags = { 'traffic_sign:forward': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:backward']).to.eql('stop');
|
||||
});
|
||||
|
||||
it('reverses the direction of a backward facing stop sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a backward facing stop sign to node 2 using the traffic_sign approach
|
||||
node2.tags = { 'traffic_sign:backward': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:forward']).to.eql('stop');
|
||||
});
|
||||
|
||||
it('reverses the direction of a left facing traffic sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a left facing stop sign to node 2 using the traffic_sign approach
|
||||
node2.tags = { 'traffic_sign:left': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:right']).to.eql('stop');
|
||||
});
|
||||
|
||||
it('reverses the direction of a right facing stop sign on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node();
|
||||
var node3 = iD.Node();
|
||||
// Attach a right facing stop sign to node 2 using the traffic_sign approach
|
||||
node2.tags = { 'traffic_sign:right': 'stop' };
|
||||
// Create our way
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
// Act - reverse the way
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
// Assert - confirm that the stop sign on node 2 has changed direction
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_sign:left']).to.eql('stop');
|
||||
});
|
||||
|
||||
// For issue #4595
|
||||
it('reverses the direction of a forward facing traffic_signals on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node({tags: { 'traffic_signals:direction': 'forward', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.Node();
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('backward');
|
||||
});
|
||||
|
||||
it('reverses the direction of a backward facing traffic_signals on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node({tags: { 'traffic_signals:direction': 'backward', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.Node();
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('forward');
|
||||
});
|
||||
|
||||
it('reverses the direction of a left facing traffic_signals on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node({tags: { 'traffic_signals:direction': 'left', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.Node();
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('right');
|
||||
});
|
||||
|
||||
it('reverses the direction of a right facing traffic_signals on the way', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node({tags: { 'traffic_signals:direction': 'right', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.Node();
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('left');
|
||||
});
|
||||
|
||||
it('does not assign a direction to a directionless traffic_signals on the way during a reverse', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node({tags: { 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.Node();
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.be.undefined;
|
||||
});
|
||||
|
||||
it('ignores directions other than forward or backward on attached traffic_signals during a reverse', function () {
|
||||
var node1 = iD.Node();
|
||||
var node2 = iD.Node({tags: { 'traffic_signals:direction': 'empty', 'highway': 'traffic_signals' }});
|
||||
var node3 = iD.Node();
|
||||
var way = iD.Way({nodes: [node1.id, node2.id, node3.id]});
|
||||
var graph = iD.actionReverse(way.id)(iD.Graph([node1, node2, node3, way]));
|
||||
var target = graph.entity(node2.id);
|
||||
expect(target.tags['traffic_signals:direction']).to.eql('empty');
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user