diff --git a/modules/actions/circularize.js b/modules/actions/circularize.js
index dc66825ac..908edb349 100644
--- a/modules/actions/circularize.js
+++ b/modules/actions/circularize.js
@@ -10,11 +10,7 @@ import {
polygonCentroid as d3_polygonCentroid
} from 'd3-polygon';
-import {
- geoEuclideanDistance,
- geoInterp
-} from '../geo';
-
+import { geoVecInterp, geoVecLength } from '../geo';
import { osmNode } from '../osm';
@@ -41,8 +37,8 @@ export function actionCircularize(wayId, projection, maxAngle) {
keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
points = nodes.map(function(n) { return projection(n.loc); }),
keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
- centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points),
- radius = d3_median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
+ centroid = (points.length === 2) ? geoVecInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points),
+ radius = d3_median(points, function(p) { return geoVecLength(centroid, p); }),
sign = d3_polygonArea(points) > 0 ? 1 : -1,
ids;
@@ -82,7 +78,7 @@ export function actionCircularize(wayId, projection, maxAngle) {
}
// position this key node
- var distance = geoEuclideanDistance(centroid, keyPoints[i]);
+ var distance = geoVecLength(centroid, keyPoints[i]);
if (distance === 0) { distance = 1e-4; }
keyPoints[i] = [
centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
@@ -91,7 +87,7 @@ export function actionCircularize(wayId, projection, maxAngle) {
loc = projection.invert(keyPoints[i]);
node = keyNodes[i];
origNode = origNodes[node.id];
- node = node.move(geoInterp(origNode.loc, loc, t));
+ node = node.move(geoVecInterp(origNode.loc, loc, t));
graph = graph.replace(node);
// figure out the between delta angle we want to match to
@@ -122,7 +118,7 @@ export function actionCircularize(wayId, projection, maxAngle) {
origNode = origNodes[node.id];
nearNodes[node.id] = angle;
- node = node.move(geoInterp(origNode.loc, loc, t));
+ node = node.move(geoVecInterp(origNode.loc, loc, t));
graph = graph.replace(node);
}
@@ -145,7 +141,7 @@ export function actionCircularize(wayId, projection, maxAngle) {
}
}
- node = osmNode({ loc: geoInterp(origNode.loc, loc, t) });
+ node = osmNode({ loc: geoVecInterp(origNode.loc, loc, t) });
graph = graph.replace(node);
nodes.splice(endNodeIndex + j, 0, node);
@@ -220,7 +216,7 @@ export function actionCircularize(wayId, projection, maxAngle) {
// move interior nodes to the surface of the convex hull..
for (var j = 1; j < indexRange; j++) {
- var point = geoInterp(hull[i], hull[i+1], j / indexRange),
+ var point = geoVecInterp(hull[i], hull[i+1], j / indexRange),
node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
graph = graph.replace(node);
}
diff --git a/modules/actions/move.js b/modules/actions/move.js
index baa75fb32..1f400085c 100644
--- a/modules/actions/move.js
+++ b/modules/actions/move.js
@@ -13,11 +13,11 @@ import { osmNode } from '../osm';
import {
geoAngle,
geoChooseEdge,
- geoInterp,
geoPathIntersections,
geoPathLength,
geoSphericalDistance,
geoVecAdd,
+ geoVecInterp,
geoVecSubtract
} from '../geo';
@@ -206,7 +206,7 @@ export function actionMove(moveIds, tryDelta, projection, cache) {
if (!isEP1 && !isEP2) {
var epsilon = 1e-4, maxIter = 10;
for (var i = 0; i < maxIter; i++) {
- loc = geoInterp(edge1.loc, edge2.loc, 0.5);
+ loc = geoVecInterp(edge1.loc, edge2.loc, 0.5);
edge1 = geoChooseEdge(nodes1, projection(loc), projection);
edge2 = geoChooseEdge(nodes2, projection(loc), projection);
if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
diff --git a/modules/actions/move_node.js b/modules/actions/move_node.js
index 8de29a16a..4288dcbc5 100644
--- a/modules/actions/move_node.js
+++ b/modules/actions/move_node.js
@@ -1,4 +1,4 @@
-import { geoInterp } from '../geo';
+import { geoVecInterp } from '../geo';
export function actionMoveNode(nodeID, toLoc) {
@@ -8,7 +8,7 @@ export function actionMoveNode(nodeID, toLoc) {
var node = graph.entity(nodeID);
return graph.replace(
- node.move(geoInterp(node.loc, toLoc, t))
+ node.move(geoVecInterp(node.loc, toLoc, t))
);
};
diff --git a/modules/actions/orthogonalize.js b/modules/actions/orthogonalize.js
index 33b4a4c61..b9d64b205 100644
--- a/modules/actions/orthogonalize.js
+++ b/modules/actions/orthogonalize.js
@@ -2,10 +2,7 @@ import _clone from 'lodash-es/clone';
import _uniq from 'lodash-es/uniq';
import { actionDeleteNode } from './delete_node';
-import {
- geoEuclideanDistance,
- geoInterp
-} from '../geo';
+import { geoVecInterp, geoVecLength } from '../geo';
/*
@@ -40,7 +37,7 @@ export function actionOrthogonalize(wayId, projection) {
node = graph.entity(nodes[corner.i].id);
loc = projection.invert(points[corner.i]);
- graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
+ graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
} else {
var best,
@@ -69,7 +66,7 @@ export function actionOrthogonalize(wayId, projection) {
if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
loc = projection.invert(points[i]);
node = graph.entity(nodes[i].id);
- graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
+ graph = graph.replace(node.move(geoVecInterp(node.loc, loc, t)));
}
}
@@ -100,7 +97,7 @@ export function actionOrthogonalize(wayId, projection) {
q = subtractPoints(c, b),
scale, dotp;
- scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
+ scale = 2 * Math.min(geoVecLength(p, [0, 0]), geoVecLength(q, [0, 0]));
p = normalizePoint(p, 1.0);
q = normalizePoint(q, 1.0);
diff --git a/modules/actions/reflect.js b/modules/actions/reflect.js
index b27c9eadf..be435c5f9 100644
--- a/modules/actions/reflect.js
+++ b/modules/actions/reflect.js
@@ -4,10 +4,10 @@ import {
} from 'd3-polygon';
import {
- geoEuclideanDistance,
geoExtent,
- geoInterp,
- geoRotate
+ geoRotate,
+ geoVecInterp,
+ geoVecLength
} from '../geo';
import { utilGetAllNodes } from '../util';
@@ -69,7 +69,7 @@ export function actionReflect(reflectIds, projection) {
q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
p, q;
- var isLong = (geoEuclideanDistance(p1, q1) > geoEuclideanDistance(p2, q2));
+ var isLong = (geoVecLength(p1, q1) > geoVecLength(p2, q2));
if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
p = p1;
q = q1;
@@ -92,7 +92,7 @@ export function actionReflect(reflectIds, projection) {
b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
];
var loc2 = projection.invert(c2);
- node = node.move(geoInterp(node.loc, loc2, t));
+ node = node.move(geoVecInterp(node.loc, loc2, t));
graph = graph.replace(node);
}
diff --git a/modules/actions/straighten.js b/modules/actions/straighten.js
index e16bdd613..e9456d220 100644
--- a/modules/actions/straighten.js
+++ b/modules/actions/straighten.js
@@ -1,8 +1,8 @@
import { actionDeleteNode } from './delete_node';
import {
- geoEuclideanDistance,
- geoInterp
+ geoVecInterp,
+ geoVecLength
} from '../geo';
@@ -44,7 +44,7 @@ export function actionStraighten(wayId, projection) {
],
loc2 = projection.invert(p);
- graph = graph.replace(node.move(geoInterp(node.loc, loc2, t)));
+ graph = graph.replace(node.move(geoVecInterp(node.loc, loc2, t)));
} else {
// safe to delete
@@ -69,7 +69,7 @@ export function actionStraighten(wayId, projection) {
points = nodes.map(function(n) { return projection(n.loc); }),
startPoint = points[0],
endPoint = points[points.length-1],
- threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
+ threshold = 0.2 * geoVecLength(startPoint, endPoint),
i;
if (threshold === 0) {
diff --git a/modules/behavior/draw.js b/modules/behavior/draw.js
index 513c0b30c..77315e03b 100644
--- a/modules/behavior/draw.js
+++ b/modules/behavior/draw.js
@@ -14,7 +14,7 @@ import { behaviorTail } from './tail';
import {
geoChooseEdge,
- geoEuclideanDistance,
+ geoVecLength,
geoViewportEdge
} from '../geo';
@@ -81,7 +81,7 @@ export function behaviorDraw(context) {
d3_select(window).on('mouseup.draw', function() {
var t2 = +new Date();
var p2 = point();
- var dist = geoEuclideanDistance(p1, p2);
+ var dist = geoVecLength(p1, p2);
element.on('mousemove.draw', mousemove);
d3_select(window).on('mouseup.draw', null);
@@ -157,7 +157,7 @@ export function behaviorDraw(context) {
var currSpace = context.mouse();
if (_disableSpace && _lastSpace) {
- var dist = geoEuclideanDistance(_lastSpace, currSpace);
+ var dist = geoVecLength(_lastSpace, currSpace);
if (dist > tolerance) {
_disableSpace = false;
}
diff --git a/modules/behavior/select.js b/modules/behavior/select.js
index a77044133..98799e625 100644
--- a/modules/behavior/select.js
+++ b/modules/behavior/select.js
@@ -6,7 +6,7 @@ import {
select as d3_select
} from 'd3-selection';
-import { geoEuclideanDistance } from '../geo';
+import { geoVecLength } from '../geo';
import {
modeBrowse,
@@ -103,7 +103,7 @@ export function behaviorSelect(context) {
if (!p1) return;
var p2 = point();
- var dist = geoEuclideanDistance(p1, p2);
+ var dist = geoVecLength(p1, p2);
p1 = null;
if (dist > tolerance) {
diff --git a/modules/geo/geo.js b/modules/geo/geo.js
index 7a4fe121a..0c5a27778 100644
--- a/modules/geo/geo.js
+++ b/modules/geo/geo.js
@@ -1,6 +1,15 @@
import _every from 'lodash-es/every';
import _some from 'lodash-es/some';
+import {
+ geoVecAngle,
+ geoVecCross,
+ geoVecDot,
+ geoVecInterp,
+ geoVecLength,
+ geoVecSubtract
+} from './vector.js';
+
// constants
var TAU = 2 * Math.PI;
@@ -8,66 +17,6 @@ var EQUATORIAL_RADIUS = 6356752.314245179;
var POLAR_RADIUS = 6378137.0;
-// vector addition
-export function geoVecEquals(a, b) {
- return (a[0] === b[0]) && (a[1] === b[1]);
-}
-
-// vector addition
-export function geoVecAdd(a, b) {
- return [ a[0] + b[0], a[1] + b[1] ];
-}
-
-// vector subtraction
-export function geoVecSubtract(a, b) {
- return [ a[0] - b[0], a[1] - b[1] ];
-}
-
-// vector multiplication
-export function geoVecScale(a, b) {
- return [ a[0] * b, a[1] * b ];
-}
-
-// vector rounding (was: geoRoundCoordinates)
-export function geoVecFloor(a) {
- return [ Math.floor(a[0]), Math.floor(a[1]) ];
-}
-
-// linear interpolation
-export function geoInterp(p1, p2, t) {
- return [
- p1[0] + (p2[0] - p1[0]) * t,
- p1[1] + (p2[1] - p1[1]) * t
- ];
-}
-
-
-// dot product
-export function geoDot(a, b, origin) {
- origin = origin || [0, 0];
- return (a[0] - origin[0]) * (b[0] - origin[0]) +
- (a[1] - origin[1]) * (b[1] - origin[1]);
-}
-
-
-// 2D cross product of OA and OB vectors, returns magnitude of Z vector
-// Returns a positive value, if OAB makes a counter-clockwise turn,
-// negative for clockwise turn, and zero if the points are collinear.
-export function geoCross(a, b, origin) {
- origin = origin || [0, 0];
- return (a[0] - origin[0]) * (b[1] - origin[1]) -
- (a[1] - origin[1]) * (b[0] - origin[0]);
-}
-
-
-// http://jsperf.com/id-dist-optimization
-export function geoEuclideanDistance(a, b) {
- var x = a[0] - b[0];
- var y = a[1] - b[1];
- return Math.sqrt((x * x) + (y * y));
-}
-
-
export function geoLatToMeters(dLat) {
return dLat * (TAU * POLAR_RADIUS / 360);
}
@@ -140,9 +89,7 @@ export function geoEdgeEqual(a, b) {
// Return the counterclockwise angle in the range (-pi, pi)
// between the positive X axis and the line intersecting a and b.
export function geoAngle(a, b, projection) {
- a = projection(a.loc);
- b = projection(b.loc);
- return Math.atan2(b[1] - a[1], b[0] - a[0]);
+ return geoVecAngle(projection(a.loc), projection(b.loc));
}
@@ -163,7 +110,7 @@ export function geoRotate(points, angle, around) {
// the closest vertex on that edge. Returns an object with the `index` of the
// chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
export function geoChooseEdge(nodes, point, projection, skipID) {
- var dist = geoEuclideanDistance;
+ var dist = geoVecLength;
var points = nodes.map(function(n) { return projection(n.loc); });
var ids = nodes.map(function(n) { return n.id; });
var min = Infinity;
@@ -176,7 +123,7 @@ export function geoChooseEdge(nodes, point, projection, skipID) {
var o = points[i];
var s = geoVecSubtract(points[i + 1], o);
var v = geoVecSubtract(point, o);
- var proj = geoDot(v, s) / geoDot(s, s);
+ var proj = geoVecDot(v, s) / geoVecDot(s, s);
var p;
if (proj < 0) {
@@ -214,15 +161,15 @@ export function geoLineIntersection(a, b) {
var q2 = [b[1][0], b[1][1]];
var r = geoVecSubtract(p2, p);
var s = geoVecSubtract(q2, q);
- var uNumerator = geoCross(geoVecSubtract(q, p), r);
- var denominator = geoCross(r, s);
+ var uNumerator = geoVecCross(geoVecSubtract(q, p), r);
+ var denominator = geoVecCross(r, s);
if (uNumerator && denominator) {
var u = uNumerator / denominator;
- var t = geoCross(geoVecSubtract(q, p), s) / denominator;
+ var t = geoVecCross(geoVecSubtract(q, p), s) / denominator;
if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
- return geoInterp(p, p2, t);
+ return geoVecInterp(p, p2, t);
}
}
@@ -284,7 +231,7 @@ export function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
function testSegments(outer, inner) {
for (var i = 0; i < outer.length - 1; i++) {
for (var j = 0; j < inner.length - 1; j++) {
- var a = [ outer[i], outer[i +1 ] ];
+ var a = [ outer[i], outer[i + 1] ];
var b = [ inner[j], inner[j + 1] ];
if (geoLineIntersection(a, b)) return true;
}
@@ -305,7 +252,7 @@ export function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
export function geoPathLength(path) {
var length = 0;
for (var i = 0; i < path.length - 1; i++) {
- length += geoEuclideanDistance(path[i], path[i + 1]);
+ length += geoVecLength(path[i], path[i + 1]);
}
return length;
}
diff --git a/modules/geo/index.js b/modules/geo/index.js
index 95bba82c5..dca2f31dd 100644
--- a/modules/geo/index.js
+++ b/modules/geo/index.js
@@ -1,11 +1,7 @@
export { geoAngle } from './geo.js';
export { geoChooseEdge } from './geo.js';
-export { geoCross } from './geo.js';
-export { geoDot } from './geo.js';
export { geoEdgeEqual } from './geo.js';
-export { geoEuclideanDistance } from './geo.js';
export { geoExtent } from './extent.js';
-export { geoInterp } from './geo.js';
export { geoRawMercator } from './raw_mercator.js';
export { geoRotate } from './geo.js';
export { geoLatToMeters } from './geo.js';
@@ -22,10 +18,15 @@ export { geoPolygonContainsPolygon } from './geo.js';
export { geoPolygonIntersectsPolygon } from './geo.js';
export { geoScaleToZoom } from './geo.js';
export { geoSphericalDistance } from './geo.js';
-export { geoVecAdd } from './geo.js';
-export { geoVecEquals } from './geo.js';
-export { geoVecFloor } from './geo.js';
-export { geoVecSubtract } from './geo.js';
-export { geoVecScale } from './geo.js';
+export { geoVecAdd } from './vector.js';
+export { geoVecAngle } from './vector.js';
+export { geoVecCross } from './vector.js';
+export { geoVecDot } from './vector.js';
+export { geoVecEqual } from './vector.js';
+export { geoVecFloor } from './vector.js';
+export { geoVecInterp } from './vector.js';
+export { geoVecLength } from './vector.js';
+export { geoVecSubtract } from './vector.js';
+export { geoVecScale } from './vector.js';
export { geoZoomToScale } from './geo.js';
export { geoViewportEdge } from './geo.js';
diff --git a/modules/geo/vector.js b/modules/geo/vector.js
new file mode 100644
index 000000000..0e7929b3b
--- /dev/null
+++ b/modules/geo/vector.js
@@ -0,0 +1,62 @@
+// vector equals
+export function geoVecEqual(a, b) {
+ return (a[0] === b[0]) && (a[1] === b[1]);
+}
+
+// vector addition
+export function geoVecAdd(a, b) {
+ return [ a[0] + b[0], a[1] + b[1] ];
+}
+
+// vector subtraction
+export function geoVecSubtract(a, b) {
+ return [ a[0] - b[0], a[1] - b[1] ];
+}
+
+// vector multiplication
+export function geoVecScale(a, b) {
+ return [ a[0] * b, a[1] * b ];
+}
+
+// vector rounding (was: geoRoundCoordinates)
+export function geoVecFloor(a) {
+ return [ Math.floor(a[0]), Math.floor(a[1]) ];
+}
+
+// linear interpolation
+export function geoVecInterp(a, b, t) {
+ return [
+ a[0] + (b[0] - a[0]) * t,
+ a[1] + (b[1] - a[1]) * t
+ ];
+}
+
+// http://jsperf.com/id-dist-optimization
+export function geoVecLength(a, b) {
+ var x = a[0] - b[0];
+ var y = a[1] - b[1];
+ return Math.sqrt((x * x) + (y * y));
+}
+
+// Return the counterclockwise angle in the range (-pi, pi)
+// between the positive X axis and the line intersecting a and b.
+export function geoVecAngle(a, b) {
+ return Math.atan2(b[1] - a[1], b[0] - a[0]);
+}
+
+// dot product
+export function geoVecDot(a, b, origin) {
+ origin = origin || [0, 0];
+ return (a[0] - origin[0]) * (b[0] - origin[0]) +
+ (a[1] - origin[1]) * (b[1] - origin[1]);
+}
+
+// 2D cross product of OA and OB vectors, returns magnitude of Z vector
+// Returns a positive value, if OAB makes a counter-clockwise turn,
+// negative for clockwise turn, and zero if the points are collinear.
+export function geoVecCross(a, b, origin) {
+ origin = origin || [0, 0];
+ return (a[0] - origin[0]) * (b[1] - origin[1]) -
+ (a[1] - origin[1]) * (b[0] - origin[0]);
+}
+
diff --git a/modules/index.js b/modules/index.js
index 981a047db..dcd7f276e 100644
--- a/modules/index.js
+++ b/modules/index.js
@@ -29,6 +29,10 @@ export { coreDifference as Difference } from './core/difference';
export { coreGraph as Graph } from './core/graph';
export { coreHistory as History } from './core/history';
export { coreTree as Tree } from './core/tree';
+export { geoVecCross as geoCross } from './geo/vector';
+export { geoVecInterp as geoInterp } from './geo/vector';
+export { geoVecFloor as geoRoundCoordinates } from './geo/vector';
+export { geoVecLength as geoEuclideanDistance } from './geo/vector';
export { osmEntity as Entity } from './osm/entity';
export { osmNode as Node } from './osm/node';
export { osmRelation as Relation } from './osm/relation';
diff --git a/modules/modes/drag_node.js b/modules/modes/drag_node.js
index d165949d5..3809a352f 100644
--- a/modules/modes/drag_node.js
+++ b/modules/modes/drag_node.js
@@ -21,7 +21,7 @@ import {
import {
geoChooseEdge,
geoLineIntersection,
- geoVecEquals,
+ geoVecEqual,
geoVecSubtract,
geoViewportEdge
} from '../geo';
@@ -203,8 +203,8 @@ export function modeDragNode(context) {
var p = actives[j];
var q = inactives[k];
// skip if segments share an endpoint
- if (geoVecEquals(p[1], q[0]) || geoVecEquals(p[0], q[1]) ||
- geoVecEquals(p[0], q[0]) || geoVecEquals(p[1], q[1]) ) {
+ if (geoVecEqual(p[1], q[0]) || geoVecEqual(p[0], q[1]) ||
+ geoVecEqual(p[0], q[0]) || geoVecEqual(p[1], q[1]) ) {
continue;
} else if (geoLineIntersection(p, q)) {
return true;
diff --git a/modules/modes/rotate.js b/modules/modes/rotate.js
index d889a174b..4addaed88 100644
--- a/modules/modes/rotate.js
+++ b/modules/modes/rotate.js
@@ -13,7 +13,7 @@ import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';
import { t } from '../util/locale';
import { actionRotate } from '../actions';
import { behaviorEdit } from '../behavior';
-import { geoInterp } from '../geo';
+import { geoVecInterp } from '../geo';
import {
modeBrowse,
@@ -80,7 +80,7 @@ export function modeRotate(context, entityIDs) {
if (points.length === 1) { // degenerate case
_pivot = points[0];
} else if (points.length === 2) {
- _pivot = geoInterp(points[0], points[1], 0.5);
+ _pivot = geoVecInterp(points[0], points[1], 0.5);
} else {
_pivot = d3_polygonCentroid(d3_polygonHull(points));
}
diff --git a/modules/osm/way.js b/modules/osm/way.js
index c93224146..14e4e410c 100644
--- a/modules/osm/way.js
+++ b/modules/osm/way.js
@@ -4,7 +4,7 @@ import _uniq from 'lodash-es/uniq';
import { geoArea as d3_geoArea } from 'd3-geo';
-import { geoExtent, geoCross } from '../geo';
+import { geoExtent, geoVecCross } from '../geo';
import { osmEntity } from './entity';
import { osmLanes } from './lanes';
import { osmOneWayTags } from './tags';
@@ -142,7 +142,7 @@ _extend(osmWay.prototype, {
var o = coords[(i+1) % coords.length];
var a = coords[i];
var b = coords[(i+2) % coords.length];
- var res = geoCross(a, b, o);
+ var res = geoVecCross(a, b, o);
curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
if (curr === 0) {
diff --git a/modules/renderer/tile_layer.js b/modules/renderer/tile_layer.js
index 9d143f045..b0fb42aa3 100644
--- a/modules/renderer/tile_layer.js
+++ b/modules/renderer/tile_layer.js
@@ -2,7 +2,7 @@ import { select as d3_select } from 'd3-selection';
import { t } from '../util/locale';
import { d3geoTile as d3_geoTile } from '../lib/d3.geo.tile';
-import { geoEuclideanDistance, geoScaleToZoom } from '../geo';
+import { geoScaleToZoom, geoVecLength } from '../geo';
import { utilPrefixCSSProperty } from '../util';
@@ -187,7 +187,7 @@ export function rendererTileLayer(context) {
requests.forEach(function(d) {
var c = tileCenter(d);
- var dist = geoEuclideanDistance(c, mapCenter);
+ var dist = geoVecLength(c, mapCenter);
if (dist < minDist) {
minDist = dist;
nearCenter = d;
diff --git a/modules/svg/helpers.js b/modules/svg/helpers.js
index b4d00264e..40f28d0a6 100644
--- a/modules/svg/helpers.js
+++ b/modules/svg/helpers.js
@@ -6,7 +6,7 @@ import {
geoStream as d3_geoStream
} from 'd3-geo';
-import { geoEuclideanDistance } from '../geo';
+import { geoVecLength } from '../geo';
// Touch targets control which other vertices we can drag a vertex onto.
@@ -82,7 +82,7 @@ export function svgOneWaySegments(projection, graph, dt) {
b = [x, y];
if (a) {
- var span = geoEuclideanDistance(a, b) - offset;
+ var span = geoVecLength(a, b) - offset;
if (span >= 0) {
var angle = Math.atan2(b[1] - a[1], b[0] - a[0]);
diff --git a/modules/svg/labels.js b/modules/svg/labels.js
index 15c3d2b08..c79448d75 100644
--- a/modules/svg/labels.js
+++ b/modules/svg/labels.js
@@ -10,11 +10,11 @@ import { textDirection } from '../util/locale';
import {
geoExtent,
- geoEuclideanDistance,
- geoInterp,
geoPolygonIntersectsPolygon,
geoPathLength,
- geoScaleToZoom
+ geoScaleToZoom,
+ geoVecInterp,
+ geoVecLength
} from '../geo';
import { osmEntity } from '../osm';
@@ -489,10 +489,10 @@ export function svgLabels(projection, context) {
var b = sub[j + 1];
// split up the text into small collision boxes
- var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
+ var num = Math.max(1, Math.floor(geoVecLength(a, b) / boxsize / 2));
for (var box = 0; box < num; box++) {
- var p = geoInterp(a, b, box / num);
+ var p = geoVecInterp(a, b, box / num);
var x0 = p[0] - boxsize - padding;
var y0 = p[1] - boxsize - padding;
var x1 = p[0] + boxsize + padding;
@@ -532,7 +532,7 @@ export function svgLabels(projection, context) {
for (var i = 0; i < points.length - 1; i++) {
var a = points[i];
var b = points[i + 1];
- var current = geoEuclideanDistance(a, b);
+ var current = geoVecLength(a, b);
var portion;
if (!start && sofar + current >= from) {
portion = (from - sofar) / current;
diff --git a/modules/svg/midpoints.js b/modules/svg/midpoints.js
index ed629c6c6..bcf9495b2 100644
--- a/modules/svg/midpoints.js
+++ b/modules/svg/midpoints.js
@@ -7,9 +7,9 @@ import {
import {
geoAngle,
- geoEuclideanDistance,
- geoInterp,
- geoLineIntersection
+ geoLineIntersection,
+ geoVecInterp,
+ geoVecLength
} from '../geo';
@@ -73,8 +73,8 @@ export function svgMidpoints(projection, context) {
if (midpoints[id]) {
midpoints[id].parents.push(entity);
} else {
- if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
- var point = geoInterp(a.loc, b.loc, 0.5);
+ if (geoVecLength(projection(a.loc), projection(b.loc)) > 40) {
+ var point = geoVecInterp(a.loc, b.loc, 0.5);
var loc = null;
if (extent.intersects(point)) {
@@ -83,8 +83,8 @@ export function svgMidpoints(projection, context) {
for (var k = 0; k < 4; k++) {
point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
if (point &&
- geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
- geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
+ geoVecLength(projection(a.loc), projection(point)) > 20 &&
+ geoVecLength(projection(b.loc), projection(point)) > 20)
{
loc = point;
break;
diff --git a/test/index.html b/test/index.html
index 18092851b..ed2cb0c54 100644
--- a/test/index.html
+++ b/test/index.html
@@ -74,6 +74,7 @@
+
diff --git a/test/spec/actions/circularize.js b/test/spec/actions/circularize.js
index fb54bbd05..5d7e4c73c 100644
--- a/test/spec/actions/circularize.js
+++ b/test/spec/actions/circularize.js
@@ -5,7 +5,7 @@ describe('iD.actionCircularize', function () {
var points = graph.childNodes(graph.entity(id))
.map(function (n) { return projection(n.loc); }),
centroid = d3.polygonCentroid(points),
- radius = iD.geoEuclideanDistance(centroid, points[0]),
+ radius = iD.geoVecLength(centroid, points[0]),
estArea = Math.PI * radius * radius,
trueArea = Math.abs(d3.polygonArea(points)),
pctDiff = (estArea - trueArea) / estArea;
@@ -31,10 +31,10 @@ describe('iD.actionCircularize', function () {
vector2 = [point2[0] - center[0], point2[1] - center[1]],
distance;
- distance = iD.geoEuclideanDistance(vector1, [0, 0]);
+ distance = iD.geoVecLength(vector1, [0, 0]);
vector1 = [vector1[0] / distance, vector1[1] / distance];
- distance = iD.geoEuclideanDistance(vector2, [0, 0]);
+ distance = iD.geoVecLength(vector2, [0, 0]);
vector2 = [vector2[0] / distance, vector2[1] / distance];
return 180 / Math.PI * Math.acos(vector1[0] * vector2[0] + vector1[1] * vector2[1]);
@@ -106,7 +106,7 @@ describe('iD.actionCircularize', function () {
graph = iD.actionCircularize('-', projection)(graph);
expect(isCircular('-', graph)).to.be.ok;
- expect(iD.geoEuclideanDistance(graph.entity('d').loc, [2, -2])).to.be.lt(0.5);
+ expect(iD.geoVecLength(graph.entity('d').loc, [2, -2])).to.be.lt(0.5);
});
it('creates circle respecting min-angle limit', function() {
diff --git a/test/spec/geo/geo.js b/test/spec/geo/geo.js
index 585e7a2e7..9f31f1d27 100644
--- a/test/spec/geo/geo.js
+++ b/test/spec/geo/geo.js
@@ -1,108 +1,5 @@
describe('iD.geo', function() {
- describe('geoVecEquals', function() {
- it('tests vectors for equality', function() {
- expect(iD.geoVecEquals([1, 2], [1, 2])).to.be.true;
- expect(iD.geoVecEquals([1, 2], [1, 0])).to.be.false;
- expect(iD.geoVecEquals([1, 2], [2, 1])).to.be.false;
- });
- });
-
- describe('geoVecAdd', function() {
- it('adds vectors', function() {
- expect(iD.geoVecAdd([1, 2], [3, 4])).to.eql([4, 6]);
- expect(iD.geoVecAdd([1, 2], [0, 0])).to.eql([1, 2]);
- expect(iD.geoVecAdd([1, 2], [-3, -4])).to.eql([-2, -2]);
- });
- });
-
- describe('geoVecSubtract', function() {
- it('subtracts vectors', function() {
- expect(iD.geoVecSubtract([1, 2], [3, 4])).to.eql([-2, -2]);
- expect(iD.geoVecSubtract([1, 2], [0, 0])).to.eql([1, 2]);
- expect(iD.geoVecSubtract([1, 2], [-3, -4])).to.eql([4, 6]);
- });
- });
-
- describe('geoVecScale', function() {
- it('multiplies vectors', function() {
- expect(iD.geoVecScale([1, 2], 0)).to.eql([0, 0]);
- expect(iD.geoVecScale([1, 2], 1)).to.eql([1, 2]);
- expect(iD.geoVecScale([1, 2], 2)).to.eql([2, 4]);
- expect(iD.geoVecScale([1, 2], 0.5)).to.eql([0.5, 1]);
- });
- });
-
- describe('geoVecFloor (was: geoRoundCoordinates)', function() {
- it('rounds vectors', function() {
- expect(iD.geoVecFloor([0.1, 1])).to.eql([0, 1]);
- expect(iD.geoVecFloor([0, 1])).to.eql([0, 1]);
- expect(iD.geoVecFloor([0, 1.1])).to.eql([0, 1]);
- });
- });
-
- describe('geoInterp', function() {
- it('interpolates halfway', function() {
- var a = [0, 0];
- var b = [10, 10];
- expect(iD.geoInterp(a, b, 0.5)).to.eql([5, 5]);
- });
- it('interpolates to one side', function() {
- var a = [0, 0];
- var b = [10, 10];
- expect(iD.geoInterp(a, b, 0)).to.eql([0, 0]);
- });
- });
-
- describe('geoDot', function() {
- it('dot product of right angle is zero', function() {
- var a = [1, 0];
- var b = [0, 1];
- expect(iD.geoDot(a, b)).to.eql(0);
- });
- it('dot product of same vector multiplies', function() {
- var a = [2, 0];
- var b = [2, 0];
- expect(iD.geoDot(a, b)).to.eql(4);
- });
- });
-
- describe('geoCross', function() {
- it('2D cross product of right hand turn is positive', function() {
- var a = [2, 0];
- var b = [0, 2];
- expect(iD.geoCross(a, b)).to.eql(4);
- });
- it('2D cross product of left hand turn is negative', function() {
- var a = [2, 0];
- var b = [0, -2];
- expect(iD.geoCross(a, b)).to.eql(-4);
- });
- it('2D cross product of colinear points is zero', function() {
- var a = [-2, 0];
- var b = [2, 0];
- expect(iD.geoCross(a, b)).to.equal(0);
- });
- });
-
- describe('geoEuclideanDistance', function() {
- it('distance between two same points is zero', function() {
- var a = [0, 0];
- var b = [0, 0];
- expect(iD.geoEuclideanDistance(a, b)).to.eql(0);
- });
- it('a straight 10 unit line is 10', function() {
- var a = [0, 0];
- var b = [10, 0];
- expect(iD.geoEuclideanDistance(a, b)).to.eql(10);
- });
- it('a pythagorean triangle is right', function() {
- var a = [0, 0];
- var b = [4, 3];
- expect(iD.geoEuclideanDistance(a, b)).to.eql(5);
- });
- });
-
describe('geoLatToMeters', function() {
it('0 degrees latitude is 0 meters', function() {
expect(iD.geoLatToMeters(0)).to.eql(0);
diff --git a/test/spec/geo/vector.js b/test/spec/geo/vector.js
new file mode 100644
index 000000000..21968bb5a
--- /dev/null
+++ b/test/spec/geo/vector.js
@@ -0,0 +1,115 @@
+describe('iD.geo vector', function() {
+
+ describe('geoVecEqual', function() {
+ it('tests vectors for equality', function() {
+ expect(iD.geoVecEqual([1, 2], [1, 2])).to.be.true;
+ expect(iD.geoVecEqual([1, 2], [1, 0])).to.be.false;
+ expect(iD.geoVecEqual([1, 2], [2, 1])).to.be.false;
+ });
+ });
+
+ describe('geoVecAdd', function() {
+ it('adds vectors', function() {
+ expect(iD.geoVecAdd([1, 2], [3, 4])).to.eql([4, 6]);
+ expect(iD.geoVecAdd([1, 2], [0, 0])).to.eql([1, 2]);
+ expect(iD.geoVecAdd([1, 2], [-3, -4])).to.eql([-2, -2]);
+ });
+ });
+
+ describe('geoVecSubtract', function() {
+ it('subtracts vectors', function() {
+ expect(iD.geoVecSubtract([1, 2], [3, 4])).to.eql([-2, -2]);
+ expect(iD.geoVecSubtract([1, 2], [0, 0])).to.eql([1, 2]);
+ expect(iD.geoVecSubtract([1, 2], [-3, -4])).to.eql([4, 6]);
+ });
+ });
+
+ describe('geoVecScale', function() {
+ it('multiplies vectors', function() {
+ expect(iD.geoVecScale([1, 2], 0)).to.eql([0, 0]);
+ expect(iD.geoVecScale([1, 2], 1)).to.eql([1, 2]);
+ expect(iD.geoVecScale([1, 2], 2)).to.eql([2, 4]);
+ expect(iD.geoVecScale([1, 2], 0.5)).to.eql([0.5, 1]);
+ });
+ });
+
+ describe('geoVecFloor (was: geoRoundCoordinates)', function() {
+ it('rounds vectors', function() {
+ expect(iD.geoVecFloor([0.1, 1])).to.eql([0, 1]);
+ expect(iD.geoVecFloor([0, 1])).to.eql([0, 1]);
+ expect(iD.geoVecFloor([0, 1.1])).to.eql([0, 1]);
+ });
+ });
+
+ describe('geoVecInterp', function() {
+ it('interpolates halfway', function() {
+ var a = [0, 0];
+ var b = [10, 10];
+ expect(iD.geoVecInterp(a, b, 0.5)).to.eql([5, 5]);
+ });
+ it('interpolates to one side', function() {
+ var a = [0, 0];
+ var b = [10, 10];
+ expect(iD.geoVecInterp(a, b, 0)).to.eql([0, 0]);
+ });
+ });
+
+ describe('geoVecLength (was: geoEuclideanDistance)', function() {
+ it('distance between two same points is zero', function() {
+ var a = [0, 0];
+ var b = [0, 0];
+ expect(iD.geoVecLength(a, b)).to.eql(0);
+ });
+ it('a straight 10 unit line is 10', function() {
+ var a = [0, 0];
+ var b = [10, 0];
+ expect(iD.geoVecLength(a, b)).to.eql(10);
+ });
+ it('a pythagorean triangle is right', function() {
+ var a = [0, 0];
+ var b = [4, 3];
+ expect(iD.geoVecLength(a, b)).to.eql(5);
+ });
+ });
+
+ describe('geoVecAngle', function() {
+ it('returns angle between a and b', function() {
+ expect(iD.geoVecAngle([0, 0], [1, 0])).to.be.closeTo(0, 1e-6);
+ expect(iD.geoVecAngle([0, 0], [0, 1])).to.be.closeTo(Math.PI / 2, 1e-6);
+ expect(iD.geoVecAngle([0, 0], [-1, 0])).to.be.closeTo(Math.PI, 1e-6);
+ expect(iD.geoVecAngle([0, 0], [0, -1])).to.be.closeTo(-Math.PI / 2, 1e-6);
+ });
+ });
+
+ describe('geoVecDot', function() {
+ it('dot product of right angle is zero', function() {
+ var a = [1, 0];
+ var b = [0, 1];
+ expect(iD.geoVecDot(a, b)).to.eql(0);
+ });
+ it('dot product of same vector multiplies', function() {
+ var a = [2, 0];
+ var b = [2, 0];
+ expect(iD.geoVecDot(a, b)).to.eql(4);
+ });
+ });
+
+ describe('geoVecCross', function() {
+ it('2D cross product of right hand turn is positive', function() {
+ var a = [2, 0];
+ var b = [0, 2];
+ expect(iD.geoVecCross(a, b)).to.eql(4);
+ });
+ it('2D cross product of left hand turn is negative', function() {
+ var a = [2, 0];
+ var b = [0, -2];
+ expect(iD.geoVecCross(a, b)).to.eql(-4);
+ });
+ it('2D cross product of colinear points is zero', function() {
+ var a = [-2, 0];
+ var b = [2, 0];
+ expect(iD.geoVecCross(a, b)).to.equal(0);
+ });
+ });
+
+});