Disable the straighten operation for selections that are already straight (close #7658)

This commit is contained in:
Quincy Morgan
2020-06-08 11:58:10 -04:00
parent 61b3aaafd2
commit 2e5e3791c5
4 changed files with 71 additions and 22 deletions
+3
View File
@@ -183,6 +183,9 @@ en:
not_downloaded:
single: This can't be straightened because parts of it have not yet been downloaded.
multiple: These can't be straightened because parts of them have not yet been downloaded.
straight_enough:
single: This can't be made straighter than it already is.
multiple: These can't be made straighter than they already are.
too_large:
single: This can't be straightened because not enough of it is currently visible.
multiple: These can't be straightened because not enough of them are currently visible.
+4
View File
@@ -241,6 +241,10 @@
"single": "This can't be straightened because parts of it have not yet been downloaded.",
"multiple": "These can't be straightened because parts of them have not yet been downloaded."
},
"straight_enough": {
"single": "This can't be made straighter than it already is.",
"multiple": "These can't be made straighter than they already are."
},
"too_large": {
"single": "This can't be straightened because not enough of it is currently visible.",
"multiple": "These can't be straightened because not enough of them are currently visible."
+43 -18
View File
@@ -8,13 +8,8 @@ export function actionStraightenNodes(nodeIDs, projection) {
return geoVecDot(a, b, o) / geoVecDot(b, b, o);
}
var action = function(graph, t) {
if (t === null || !isFinite(t)) t = 1;
t = Math.min(Math.max(+t, 0), 1);
var nodes = nodeIDs.map(function(id) { return graph.entity(id); });
var points = nodes.map(function(n) { return projection(n.loc); });
// returns the endpoints of the long axis of symmetry of the `points` bounding rect
function getEndpoints(points) {
var ssr = geoGetSmallestSurroundingRectangle(points);
// Choose line pq = axis of symmetry.
@@ -24,23 +19,31 @@ export function actionStraightenNodes(nodeIDs, projection) {
var q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ];
var p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ];
var q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ];
var p, q;
var isLong = (geoVecLength(p1, q1) > geoVecLength(p2, q2));
if (isLong) {
p = p1;
q = q1;
} else {
p = p2;
q = q2;
return [p1, q1];
}
return [p2, q2];
}
// Move points onto line pq
var action = function(graph, t) {
if (t === null || !isFinite(t)) t = 1;
t = Math.min(Math.max(+t, 0), 1);
var nodes = nodeIDs.map(function(id) { return graph.entity(id); });
var points = nodes.map(function(n) { return projection(n.loc); });
var endpoints = getEndpoints(points);
var startPoint = endpoints[0];
var endPoint = endpoints[1];
// Move points onto the line connecting the endpoints
for (var i = 0; i < points.length; i++) {
var node = nodes[i];
var point = points[i];
var u = positionAlongWay(point, p, q);
var point2 = geoVecInterp(p, q, u);
var u = positionAlongWay(point, startPoint, endPoint);
var point2 = geoVecInterp(startPoint, endPoint, u);
var loc2 = projection.invert(point2);
graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t)));
}
@@ -49,8 +52,30 @@ export function actionStraightenNodes(nodeIDs, projection) {
};
action.disabled = function() {
return false;
action.disabled = function(graph) {
var nodes = nodeIDs.map(function(id) { return graph.entity(id); });
var points = nodes.map(function(n) { return projection(n.loc); });
var endpoints = getEndpoints(points);
var startPoint = endpoints[0];
var endPoint = endpoints[1];
var maxDistance = 0;
for (var i = 0; i < points.length; i++) {
var point = points[i];
var u = positionAlongWay(point, startPoint, endPoint);
var p = geoVecInterp(startPoint, endPoint, u);
var dist = geoVecLength(p, point);
if (!isNaN(dist) && dist > maxDistance) {
maxDistance = dist;
}
}
if (maxDistance < 0.0001) {
return 'straight_enough';
}
};
+21 -4
View File
@@ -81,6 +81,12 @@ export function actionStraightenWay(selectedIDs, projection) {
return nodes.map(function(n) { return graph.entity(n); });
}
function shouldKeepNode(node, graph) {
return graph.parentWays(node).length > 1 ||
graph.parentRelations(node).length ||
node.hasInterestingTags();
}
var action = function(graph, t) {
if (t === null || !isFinite(t)) t = 1;
@@ -97,10 +103,7 @@ export function actionStraightenWay(selectedIDs, projection) {
var node = nodes[i];
var point = points[i];
if (t < 1 || graph.parentWays(node).length > 1 ||
graph.parentRelations(node).length ||
node.hasInterestingTags()
) {
if (t < 1 || shouldKeepNode(node, graph)) {
var u = positionAlongWay(point, startPoint, endPoint);
var p = geoVecInterp(startPoint, endPoint, u);
var loc2 = projection.invert(p);
@@ -135,6 +138,8 @@ export function actionStraightenWay(selectedIDs, projection) {
return 'too_bendy';
}
var maxDistance = 0;
for (i = 1; i < points.length - 1; i++) {
var point = points[i];
var u = positionAlongWay(point, startPoint, endPoint);
@@ -144,8 +149,20 @@ export function actionStraightenWay(selectedIDs, projection) {
// to bendy if point is off by 20% of total start/end distance in projected space
if (isNaN(dist) || dist > threshold) {
return 'too_bendy';
} else if (dist > maxDistance) {
maxDistance = dist;
}
}
var keepingAllNodes = nodes.every(function(node, i) {
return i === 0 || i === nodes.length - 1 || shouldKeepNode(node, graph);
});
if (maxDistance < 0.0001 &&
// Allow straightening even if already straight in order to remove extraneous nodes
keepingAllNodes) {
return 'straight_enough';
}
};
action.transitionable = true;