Allow using the Reverse operation on directional nodes (close #6850)

This commit is contained in:
Quincy Morgan
2019-09-17 10:57:55 -04:00
parent 191d0b9434
commit c229326aad
5 changed files with 78 additions and 11 deletions

View File

@@ -309,6 +309,11 @@ en:
description: Make this line go in the opposite direction.
key: V
annotation: Reversed a line.
node:
description:
single: Flip the direction of this point.
annotation:
single: Reversed a point.
split:
title: Split
description:
@@ -1898,7 +1903,7 @@ en:
disconnect: "Disconnect features at the selected node"
extract: "Extract a point from a feature"
split: "Split a line into two at the selected node"
reverse: "Reverse a line"
reverse: "Reverse selected features"
move: "Move selected features"
rotate: "Rotate selected features"
orthogonalize: "Square corners of a line or area"

12
dist/locales/en.json vendored
View File

@@ -398,7 +398,15 @@
"title": "Reverse",
"description": "Make this line go in the opposite direction.",
"key": "V",
"annotation": "Reversed a line."
"annotation": "Reversed a line.",
"node": {
"description": {
"single": "Flip the direction of this point."
},
"annotation": {
"single": "Reversed a point."
}
}
},
"split": {
"title": "Split",
@@ -2321,7 +2329,7 @@
"disconnect": "Disconnect features at the selected node",
"extract": "Extract a point from a feature",
"split": "Split a line into two at the selected node",
"reverse": "Reverse a line",
"reverse": "Reverse selected features",
"move": "Move selected features",
"rotate": "Rotate selected features",
"orthogonalize": "Square corners of a line or area",

View File

@@ -17,7 +17,7 @@ References:
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) {
export function actionReverse(entityID, options) {
var ignoreKey = /^.*(_|:)?(description|name|note|website|ref|source|comment|watch|attribution)(_|:)?/;
var numeric = /^([+\-]?)(?=[\d.])/;
var turn_lanes = /^turn:lanes:?/;
@@ -97,8 +97,7 @@ export function actionReverse(wayID, options) {
}
return function(graph) {
var way = graph.entity(wayID);
function reverseWay(graph, way) {
var nodes = way.nodes.slice().reverse();
var tags = {};
var role;
@@ -120,5 +119,29 @@ export function actionReverse(wayID, options) {
// the way itself with the reversed node ids and updated way tags
return reverseNodeTags(graph, nodes)
.replace(way.update({nodes: nodes, tags: tags}));
}
var action = function(graph) {
var entity = graph.entity(entityID);
if (entity.type === 'way') {
return reverseWay(graph, entity);
}
return reverseNodeTags(graph, [entityID]);
};
action.disabled = function(graph) {
var entity = graph.hasEntity(entityID);
if (!entity || entity.type === 'way') return false;
for (var key in entity.tags) {
var value = entity.tags[key];
if (reverseKey(key) !== key || reverseValue(key, value) !== value) {
return false;
}
}
return 'nondirectional_node';
};
return action;
}

View File

@@ -7,13 +7,36 @@ export function operationReverse(selectedIDs, context) {
var entityID = selectedIDs[0];
var operation = function() {
context.perform(actionReverse(entityID), operation.annotation());
context.perform(action(), operation.annotation());
context.validator().validate();
};
function action() {
return actionReverse(entityID);
}
operation.available = function() {
return selectedIDs.length === 1 && context.geometry(entityID) === 'line';
function isNode() {
var entity = context.hasEntity(entityID);
return entity && entity.type === 'node';
}
operation.available = function(situation) {
if (situation === 'toolbar') {
if (!selectedIDs.some(function(id) {
var entity = context.hasEntity(id);
return entity && entity.type === 'way' && (entity.isOneWay() || entity.isSided());
})) {
return false;
}
}
if (selectedIDs.length !== 1) return false;
var geometry = context.geometry(entityID);
if (geometry !== 'line' && geometry !== 'vertex' && geometry !== 'point') {
return false;
}
return action().disabled(context.graph()) === false;
};
@@ -23,12 +46,14 @@ export function operationReverse(selectedIDs, context) {
operation.tooltip = function() {
return t('operations.reverse.description');
var id = isNode() ? 'node.description.single' : 'description';
return t('operations.reverse.' + id);
};
operation.annotation = function() {
return t('operations.reverse.annotation');
var id = isNode() ? 'node.annotation.single' : 'annotation';
return t('operations.reverse.' + id);
};

View File

@@ -511,4 +511,10 @@ describe('iD.actionReverse', function () {
});
});
it('reverses directional values on nodes', function () {
var node1 = iD.osmNode({ tags: { 'direction': 'forward' } });
var graph = iD.actionReverse(node1.id)(iD.coreGraph([node1]));
expect(graph.entity(node1.id).tags).to.eql({ 'direction': 'backward' });
});
});