diff --git a/js/id/actions/orthogonalize.js b/js/id/actions/orthogonalize.js
index 80c6a12c8..830d1a1eb 100644
--- a/js/id/actions/orthogonalize.js
+++ b/js/id/actions/orthogonalize.js
@@ -1,20 +1,18 @@
-iD.actions.Orthogonalize = function(wayId, map) {
+iD.actions.Orthogonalize = function(wayId, projection) {
var action = function(graph) {
var way = graph.entity(wayId),
- nodes = graph.childNodes(way),
- tags = {},key,role;
+ nodes = graph.childNodes(way);
var points = nodes.map(function(n) {
- return map.projection(n.loc);
- }),
- quad_nodes = [];
+ return projection(n.loc);
+ }),
+ quad_nodes = [];
var score = squareness();
- for (var i = 0; i < 1000; ++i) {
+ for (var i = 0; i < 1000; i++) {
var motions = points.map(stepMap);
- //return false;
- for (var j = 0; j < motions.length; ++j) {
+ for (var j = 0; j < motions.length; j++) {
points[j] = addPoints(points[j],motions[j]);
}
var newScore = squareness();
@@ -26,10 +24,9 @@ iD.actions.Orthogonalize = function(wayId, map) {
break;
}
}
- for (var i = 0; i < points.length; i++) {
- quad_nodes.push(iD.Node({ loc: map.projection.invert(points[i]) }));
+ for (i = 0; i < points.length - 1; i++) {
+ quad_nodes.push(iD.Node({ loc: projection.invert(points[i]) }));
}
- quad_nodes.push(quad_nodes[0]);
for (i = 0; i < nodes.length; i++) {
if (graph.parentWays(nodes[i]).length > 1) {
@@ -42,93 +39,89 @@ iD.actions.Orthogonalize = function(wayId, map) {
}
}
quad_nodes.splice(closest, 1, nodes[i]);
- if (closest === 0) quad_nodes.splice(quad_nodes.length - 1, 1, nodes[i]);
- else if (closest === quad_nodes.length - 1) quad_nodes.splice(0, 1, nodes[i]);
- } else {
- graph = graph.remove(nodes[i]);
}
}
- for (var i = 0; i < quad_nodes.length; i++) {
- graph = graph.replace(quad_nodes[i]);
+ for (i = 0; i < quad_nodes.length; i++) {
+ graph = graph.replace(quad_nodes[i]);
}
- return graph.replace(way.update({
- nodes: _.pluck(quad_nodes, 'id')
- }));
+ var ids = _.pluck(quad_nodes, 'id'),
+ difference = _.difference(_.uniq(way.nodes), ids);
+ ids.push(ids[0]);
- function stepMap(b,i,array){
- var a,c,p,q = [];
- a = array[(i-1+array.length) % array.length];
- c = array[(i+1) % array.length];
- p = subtractPoints(a,b);
- q = subtractPoints(c,b);
+ graph = graph.replace(way.update({nodes: ids}));
+ for (i = 0; i < difference.length; i++) {
+ graph = iD.actions.DeleteNode(difference[i])(graph);
+ }
+
+ return graph;
+
+ function stepMap(b, i, array) {
+ var a, c, p, q = [];
+ a = array[(i - 1 + array.length) % array.length];
+ c = array[(i + 1) % array.length];
+ p = subtractPoints(a, b);
+ q = subtractPoints(c, b);
var scale = p.length + q.length;
- p = normalizePoint(p,1.0);
- q = normalizePoint(q,1.0);
- var dotp = p[0]*q[0] + p[1]*q[1];
+ p = normalizePoint(p, 1.0);
+ 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;
}
var v = [];
- v = addPoints(p,q);
- v = normalizePoint(v,0.1 * dotp * scale);
+ v = addPoints(p, q);
+ v = normalizePoint(v, 0.1 * dotp * scale);
return v;
}
- function squareness(){
+ function squareness() {
var g = 0.0;
for (var i = 1; i < points.length - 1; i++) {
- var score = scoreOfPoints(points[i-1], points[i], points[i+1]);
+ var score = scoreOfPoints(points[i - 1], points[i], points[i + 1]);
g += score;
}
- var startScore = scoreOfPoints(points[points.length-1], points[0], points[1]);
- var endScore = scoreOfPoints(points[points.length-2], points[points.length-1], points[0]);
+ var startScore = scoreOfPoints(points[points.length - 1], points[0], points[1]);
+ var endScore = scoreOfPoints(points[points.length - 2], points[points.length - 1], points[0]);
g += startScore;
g += endScore;
return g;
}
function scoreOfPoints(a, b, c) {
- var p,q = [];
- p = subtractPoints(a,b);
- q = subtractPoints(c,b);
+ var p, q = [];
+ p = subtractPoints(a, b);
+ q = subtractPoints(c, b);
+ p = normalizePoint(p, 1.0);
+ q = normalizePoint(q, 1.0);
- p = normalizePoint(p,1.0);
- q = normalizePoint(q,1.0);
-
- var dotp = p[0]*q[0] + p[1]*q[1];
+ var dotp = p[0] * q[0] + p[1] * q[1];
// score is constructed so that +1, -1 and 0 are all scored 0, any other angle
// is scored higher.
- var score = 2.0 * Math.min(Math.abs(dotp-1.0), Math.min(Math.abs(dotp), Math.abs(dotp+1)));
+ var score = 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
return score;
}
- function subtractPoints(a,b){
- var vector = [0,0];
- vector[0] = a[0]-b[0];
- vector[1] = a[1]-b[1];
- return vector;
+ function subtractPoints(a, b) {
+ return [a[0] - b[0], a[1] - b[1]];
}
- function addPoints(a,b){
- var vector = [0,0];
- vector[0] = a[0]+b[0];
- vector[1] = a[1]+b[1];
- return vector;
+ function addPoints(a, b) {
+ return [a[0]+b[0],a[1]+b[1]];
}
- function normalizePoint(point,thickness){
+ function normalizePoint(point, thickness) {
var vector = [0,0];
- var length = Math.sqrt( point[0] * point[0] + point[1] * point[1]);
+ var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
if(length != 0){
- vector[0] = point[0]/length;
- vector[1] = point[1]/length;
+ vector[0] = point[0] / length;
+ vector[1] = point[1] / length;
}
vector[0] *= thickness;
diff --git a/js/id/operations/orthogonalize.js b/js/id/operations/orthogonalize.js
index 888d0015e..c59ed13e4 100644
--- a/js/id/operations/orthogonalize.js
+++ b/js/id/operations/orthogonalize.js
@@ -1,6 +1,6 @@
iD.operations.Orthogonalize = function(selection, context) {
var entityId = selection[0],
- action = iD.actions.Orthogonalize(entityId, context.map());
+ action = iD.actions.Orthogonalize(entityId, context.projection);
var operation = function() {
var annotation = t('operations.orthogonalize.annotation.' + context.geometry(entityId));
diff --git a/test/index.html b/test/index.html
index b6d925923..551a87621 100644
--- a/test/index.html
+++ b/test/index.html
@@ -73,6 +73,7 @@
+
@@ -108,6 +109,7 @@
+