Add iD.geo.sphericalDistance

iD.geo.euclideanDistance should only be used for calculations of 
projected coordinates or display (pixel) coordinates.

iD.geo.sphericalDistance calculates approximate geographical 
distances, accounting for distortions at higher latitudes. This 
can be used for determining the nearest node (operations.Delete,
actions.Circularize) or relative length comparisons (actions.Split).
This commit is contained in:
tyr
2013-09-12 13:55:07 +02:00
committed by John Firebaugh
parent 6afe3adfbe
commit e8d637f2bb
11 changed files with 55 additions and 21 deletions
+3 -3
View File
@@ -48,7 +48,7 @@ describe("iD.actions.Circularize", function () {
graph = iD.actions.Circularize('-', projection)(graph);
expect(iD.geo.dist(graph.entity('d').loc, [2, -2])).to.be.lt(0.5);
expect(iD.geo.euclideanDistance(graph.entity('d').loc, [2, -2])).to.be.lt(0.5);
});
function angle(point1, point2, center) {
@@ -56,10 +56,10 @@ describe("iD.actions.Circularize", function () {
vector2 = [point2[0] - center[0], point2[1] - center[1]],
distance;
distance = iD.geo.dist(vector1, [0, 0]);
distance = iD.geo.euclideanDistance(vector1, [0, 0]);
vector1 = [vector1[0] / distance, vector1[1] / distance];
distance = iD.geo.dist(vector2, [0, 0]);
distance = iD.geo.euclideanDistance(vector2, [0, 0]);
vector2 = [vector2[0] / distance, vector2[1] / distance];
return 180 / Math.PI * Math.acos(vector1[0] * vector2[0] + vector1[1] * vector2[1]);
+2 -2
View File
@@ -97,12 +97,12 @@ describe("iD.actions.Orthogonalize", function () {
'd': iD.Node({id: 'd', loc: tests[i][3]}),
'-': iD.Way({id: '-', nodes: ['a', 'b', 'c', 'd', 'a']})
}),
initialWidth = iD.geo.dist(graph.entity('a').loc, graph.entity('b').loc),
initialWidth = iD.geo.sphericalDistance(graph.entity('a').loc, graph.entity('b').loc),
finalWidth;
graph = iD.actions.Orthogonalize('-', projection)(graph);
finalWidth = iD.geo.dist(graph.entity('a').loc, graph.entity('b').loc);
finalWidth = iD.geo.sphericalDistance(graph.entity('a').loc, graph.entity('b').loc);
expect(finalWidth / initialWidth).within(0.90, 1.10);
}
});
+32 -4
View File
@@ -18,21 +18,49 @@ describe('iD.geo', function() {
});
});
describe('.dist', function() {
describe('.euclideanDistance', function() {
it('distance between two same points is zero', function() {
var a = [0, 0],
b = [0, 0];
expect(iD.geo.dist(a, b)).to.eql(0);
expect(iD.geo.euclideanDistance(a, b)).to.eql(0);
});
it('a straight 10 unit line is 10', function() {
var a = [0, 0],
b = [10, 0];
expect(iD.geo.dist(a, b)).to.eql(10);
expect(iD.geo.euclideanDistance(a, b)).to.eql(10);
});
it('a pythagorean triangle is right', function() {
var a = [0, 0],
b = [4, 3];
expect(iD.geo.dist(a, b)).to.eql(5);
expect(iD.geo.euclideanDistance(a, b)).to.eql(5);
});
});
describe('.sphericalDistance', function() {
it('distance between two same points is zero', function() {
var a = [0, 0],
b = [0, 0];
expect(iD.geo.sphericalDistance(a, b)).to.eql(0);
});
it('a straight 1 degree line at the equator is aproximately 111 km', function() {
var a = [0, 0],
b = [1, 0];
expect(iD.geo.sphericalDistance(a, b)).to.be.within(100E3,120E3);
});
it('a pythagorean triangle is right', function() {
var a = [0, 0],
b = [4, 3];
expect(iD.geo.sphericalDistance(a, b)).to.be.within(500E3,600E3);
});
it('east-west distances at high latitude are shorter', function() {
var a = [0, 60],
b = [1, 60];
expect(iD.geo.sphericalDistance(a, b)).to.be.within(50E3,60E3);
});
it('north-south distances at high latitude are not shorter', function() {
var a = [0, 60],
b = [0, 61];
expect(iD.geo.sphericalDistance(a, b)).to.be.within(100E3,120E3);
});
});