Orthogonalize three-node ways (addresses #1077)

This commit is contained in:
Ian B
2013-03-23 15:56:38 +01:00
parent 1c3b817b89
commit c56aa25930
2 changed files with 42 additions and 17 deletions

View File

@@ -6,29 +6,46 @@ iD.actions.Orthogonalize = function(wayId, projection) {
var action = function(graph) {
var way = graph.entity(wayId),
nodes = graph.childNodes(way),
points = nodes.map(function(n) { return projection(n.loc); }),
best, i, j;
points, best, i, j, score, corner;
corner = {i: 0, dotp: 1}; //corner closest to 90
if(nodes.length == 4) {
points = _.uniq(nodes).map(function(n) { return projection(n.loc); });
} else {
points = nodes.map(function(n) { return projection(n.loc); });
score = squareness();
}
var score = squareness();
for (i = 0; i < 1000; i++) {
var motions = points.map(stepMap);
for (j = 0; j < motions.length; j++) {
points[j] = addPoints(points[j],motions[j]);
}
var newScore = squareness();
if (newScore < score) {
best = _.clone(points);
score = newScore;
if(nodes.length == 4) {
points[corner.i] = addPoints(points[corner.i],motions[corner.i]);
score = corner.dotp;
} else {
for (j = 0; j < motions.length; j++) {
points[j] = addPoints(points[j],motions[j]);
}
var newScore = squareness();
if (newScore < score) {
best = _.clone(points);
score = newScore;
}
}
if (score < 1.0e-8) {
break;
}
}
points = best;
for (i = 0; i < points.length - 1; i++) {
graph = graph.replace(graph.entity(nodes[i].id)
if(nodes.length == 4) {
graph = graph.replace(graph.entity(nodes[corner.i].id)
.move(projection.invert(points[corner.i])));
} else {
points = best;
for (i = 0; i < points.length - 1; i++) {
graph = graph.replace(graph.entity(nodes[i].id)
.move(projection.invert(points[i])));
}
}
return graph;
@@ -44,9 +61,17 @@ iD.actions.Orthogonalize = function(wayId, projection) {
q = normalizePoint(q, 1.0);
var dotp = p[0] * q[0] + p[1] * q[1];
// nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
if (dotp < -0.707106781186547) {
dotp += 1.0;
if(nodes.length == 4) {
if( Math.abs(dotp) < corner.dotp){
corner.i = i;
corner.dotp = Math.abs(dotp);
}
} else {
// nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
if (dotp < -0.707106781186547) {
dotp += 1.0;
}
}
return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);

View File

@@ -10,7 +10,7 @@ iD.operations.Orthogonalize = function(selection, context) {
operation.available = function() {
return selection.length === 1 &&
context.entity(entityId).type === 'way' &&
_.uniq(context.entity(entityId).nodes).length > 3;
_.uniq(context.entity(entityId).nodes).length > 2;
};
operation.enabled = function() {