diff --git a/src/ol/geom/closestgeom.js b/src/ol/geom/flat/closestflatgeom.js similarity index 76% rename from src/ol/geom/closestgeom.js rename to src/ol/geom/flat/closestflatgeom.js index 0084a0d6f6..12691ab88f 100644 --- a/src/ol/geom/closestgeom.js +++ b/src/ol/geom/flat/closestflatgeom.js @@ -1,11 +1,53 @@ -// FIXME find better names for these functions - -goog.provide('ol.geom.closest'); +goog.provide('ol.geom.flat.closest'); goog.require('goog.asserts'); +goog.require('goog.math'); goog.require('ol.geom.flat'); +/** + * Returns the point on the 2D line segment flatCoordinates[offset1] to + * flatCoordinates[offset2] that is closest to the point (x, y). Extra + * dimensions are linearly interpolated. + * @param {Array.} flatCoordinates Flat coordinates. + * @param {number} offset1 Offset 1. + * @param {number} offset2 Offset 2. + * @param {number} stride Stride. + * @param {number} x X. + * @param {number} y Y. + * @param {Array.} closestPoint Closest point. + */ +ol.geom.flat.closest.point = + function(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) { + var x1 = flatCoordinates[offset1]; + var y1 = flatCoordinates[offset1 + 1]; + var dx = flatCoordinates[offset2] - x1; + var dy = flatCoordinates[offset2 + 1] - y1; + var i, offset; + if (dx === 0 && dy === 0) { + offset = offset1; + } else { + var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy); + if (t > 1) { + offset = offset2; + } else if (t > 0) { + for (i = 0; i < stride; ++i) { + closestPoint[i] = goog.math.lerp(flatCoordinates[offset1 + i], + flatCoordinates[offset2 + i], t); + } + closestPoint.length = stride; + return; + } else { + offset = offset1; + } + } + for (i = 0; i < stride; ++i) { + closestPoint[i] = flatCoordinates[offset + i]; + } + closestPoint.length = stride; +}; + + /** * Return the squared of the largest distance between any pair of consecutive * coordinates. @@ -16,7 +58,7 @@ goog.require('ol.geom.flat'); * @param {number} maxSquaredDelta Max squared delta. * @return {number} Max squared delta. */ -ol.geom.closest.getMaxSquaredDelta = +ol.geom.flat.closest.getMaxSquaredDelta = function(flatCoordinates, offset, end, stride, maxSquaredDelta) { var x1 = flatCoordinates[offset]; var y1 = flatCoordinates[offset + 1]; @@ -42,12 +84,12 @@ ol.geom.closest.getMaxSquaredDelta = * @param {number} maxSquaredDelta Max squared delta. * @return {number} Max squared delta. */ -ol.geom.closest.getsMaxSquaredDelta = +ol.geom.flat.closest.getsMaxSquaredDelta = function(flatCoordinates, offset, ends, stride, maxSquaredDelta) { var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { var end = ends[i]; - maxSquaredDelta = ol.geom.closest.getMaxSquaredDelta( + maxSquaredDelta = ol.geom.flat.closest.getMaxSquaredDelta( flatCoordinates, offset, end, stride, maxSquaredDelta); offset = end; } @@ -63,12 +105,12 @@ ol.geom.closest.getsMaxSquaredDelta = * @param {number} maxSquaredDelta Max squared delta. * @return {number} Max squared delta. */ -ol.geom.closest.getssMaxSquaredDelta = +ol.geom.flat.closest.getssMaxSquaredDelta = function(flatCoordinates, offset, endss, stride, maxSquaredDelta) { var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { var ends = endss[i]; - maxSquaredDelta = ol.geom.closest.getsMaxSquaredDelta( + maxSquaredDelta = ol.geom.flat.closest.getsMaxSquaredDelta( flatCoordinates, offset, ends, stride, maxSquaredDelta); offset = ends[ends.length - 1]; } @@ -90,8 +132,9 @@ ol.geom.closest.getssMaxSquaredDelta = * @param {Array.=} opt_tmpPoint Temporary point object. * @return {number} Minimum squared distance. */ -ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride, - maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) { +ol.geom.flat.closest.getClosestPoint = function(flatCoordinates, offset, end, + stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, + opt_tmpPoint) { if (offset == end) { return minSquaredDistance; } @@ -114,7 +157,7 @@ ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride, var tmpPoint = goog.isDef(opt_tmpPoint) ? opt_tmpPoint : [NaN, NaN]; var index = offset + stride; while (index < end) { - ol.geom.flat.closestPoint( + ol.geom.flat.closest.point( flatCoordinates, index - stride, index, stride, x, y, tmpPoint); squaredDistance = ol.geom.flat.squaredDistance( x, y, tmpPoint[0], tmpPoint[1]); @@ -143,7 +186,7 @@ ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride, } if (isRing) { // Check the closing segment. - ol.geom.flat.closestPoint( + ol.geom.flat.closest.point( flatCoordinates, end - stride, offset, stride, x, y, tmpPoint); squaredDistance = ol.geom.flat.squaredDistance( x, y, tmpPoint[0], tmpPoint[1]); @@ -173,14 +216,14 @@ ol.geom.closest.getClosestPoint = function(flatCoordinates, offset, end, stride, * @param {Array.=} opt_tmpPoint Temporary point object. * @return {number} Minimum squared distance. */ -ol.geom.closest.getsClosestPoint = function(flatCoordinates, offset, ends, +ol.geom.flat.closest.getsClosestPoint = function(flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) { var tmpPoint = goog.isDef(opt_tmpPoint) ? opt_tmpPoint : [NaN, NaN]; var i, ii; for (i = 0, ii = ends.length; i < ii; ++i) { var end = ends[i]; - minSquaredDistance = ol.geom.closest.getClosestPoint( + minSquaredDistance = ol.geom.flat.closest.getClosestPoint( flatCoordinates, offset, end, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint); offset = end; @@ -203,14 +246,14 @@ ol.geom.closest.getsClosestPoint = function(flatCoordinates, offset, ends, * @param {Array.=} opt_tmpPoint Temporary point object. * @return {number} Minimum squared distance. */ -ol.geom.closest.getssClosestPoint = function(flatCoordinates, offset, endss, - stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, +ol.geom.flat.closest.getssClosestPoint = function(flatCoordinates, offset, + endss, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, opt_tmpPoint) { var tmpPoint = goog.isDef(opt_tmpPoint) ? opt_tmpPoint : [NaN, NaN]; var i, ii; for (i = 0, ii = endss.length; i < ii; ++i) { var ends = endss[i]; - minSquaredDistance = ol.geom.closest.getsClosestPoint( + minSquaredDistance = ol.geom.flat.closest.getsClosestPoint( flatCoordinates, offset, ends, stride, maxDelta, isRing, x, y, closestPoint, minSquaredDistance, tmpPoint); offset = ends[ends.length - 1]; diff --git a/src/ol/geom/flatgeom.js b/src/ol/geom/flatgeom.js index 5041bdf223..9ba82972fd 100644 --- a/src/ol/geom/flatgeom.js +++ b/src/ol/geom/flatgeom.js @@ -7,49 +7,6 @@ goog.require('goog.vec.Mat4'); goog.require('ol.extent'); -/** - * Returns the point on the 2D line segment flatCoordinates[offset1] to - * flatCoordinates[offset2] that is closest to the point (x, y). Extra - * dimensions are linearly interpolated. - * @param {Array.} flatCoordinates Flat coordinates. - * @param {number} offset1 Offset 1. - * @param {number} offset2 Offset 2. - * @param {number} stride Stride. - * @param {number} x X. - * @param {number} y Y. - * @param {Array.} closestPoint Closest point. - */ -ol.geom.flat.closestPoint = - function(flatCoordinates, offset1, offset2, stride, x, y, closestPoint) { - var x1 = flatCoordinates[offset1]; - var y1 = flatCoordinates[offset1 + 1]; - var dx = flatCoordinates[offset2] - x1; - var dy = flatCoordinates[offset2 + 1] - y1; - var i, offset; - if (dx === 0 && dy === 0) { - offset = offset1; - } else { - var t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy); - if (t > 1) { - offset = offset2; - } else if (t > 0) { - for (i = 0; i < stride; ++i) { - closestPoint[i] = goog.math.lerp(flatCoordinates[offset1 + i], - flatCoordinates[offset2 + i], t); - } - closestPoint.length = stride; - return; - } else { - offset = offset1; - } - } - for (i = 0; i < stride; ++i) { - closestPoint[i] = flatCoordinates[offset + i]; - } - closestPoint.length = stride; -}; - - /** * @param {Array.} flatCoordinates Flat coordinates. * @param {number} offset Offset. diff --git a/src/ol/geom/linearring.js b/src/ol/geom/linearring.js index 92d1ec19e1..71bde3380a 100644 --- a/src/ol/geom/linearring.js +++ b/src/ol/geom/linearring.js @@ -3,8 +3,8 @@ goog.provide('ol.geom.LinearRing'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.SimpleGeometry'); -goog.require('ol.geom.closest'); goog.require('ol.geom.flat'); +goog.require('ol.geom.flat.closest'); goog.require('ol.geom.simplify'); @@ -58,11 +58,11 @@ ol.geom.LinearRing.prototype.closestPointXY = return minSquaredDistance; } if (this.maxDeltaRevision_ != this.getRevision()) { - this.maxDelta_ = Math.sqrt(ol.geom.closest.getMaxSquaredDelta( + this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0)); this.maxDeltaRevision_ = this.getRevision(); } - return ol.geom.closest.getClosestPoint( + return ol.geom.flat.closest.getClosestPoint( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance); }; diff --git a/src/ol/geom/linestring.js b/src/ol/geom/linestring.js index 8ac6ec912e..ab3b55dfb0 100644 --- a/src/ol/geom/linestring.js +++ b/src/ol/geom/linestring.js @@ -5,8 +5,8 @@ goog.require('goog.asserts'); goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.SimpleGeometry'); -goog.require('ol.geom.closest'); goog.require('ol.geom.flat'); +goog.require('ol.geom.flat.closest'); goog.require('ol.geom.simplify'); @@ -86,11 +86,11 @@ ol.geom.LineString.prototype.closestPointXY = return minSquaredDistance; } if (this.maxDeltaRevision_ != this.getRevision()) { - this.maxDelta_ = Math.sqrt(ol.geom.closest.getMaxSquaredDelta( + this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, 0)); this.maxDeltaRevision_ = this.getRevision(); } - return ol.geom.closest.getClosestPoint( + return ol.geom.flat.closest.getClosestPoint( this.flatCoordinates, 0, this.flatCoordinates.length, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance); }; diff --git a/src/ol/geom/multilinestring.js b/src/ol/geom/multilinestring.js index 816abef889..d859c34bae 100644 --- a/src/ol/geom/multilinestring.js +++ b/src/ol/geom/multilinestring.js @@ -6,8 +6,8 @@ goog.require('ol.extent'); goog.require('ol.geom.GeometryType'); goog.require('ol.geom.LineString'); goog.require('ol.geom.SimpleGeometry'); -goog.require('ol.geom.closest'); goog.require('ol.geom.flat'); +goog.require('ol.geom.flat.closest'); goog.require('ol.geom.simplify'); @@ -84,11 +84,11 @@ ol.geom.MultiLineString.prototype.closestPointXY = return minSquaredDistance; } if (this.maxDeltaRevision_ != this.getRevision()) { - this.maxDelta_ = Math.sqrt(ol.geom.closest.getsMaxSquaredDelta( + this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getsMaxSquaredDelta( this.flatCoordinates, 0, this.ends_, this.stride, 0)); this.maxDeltaRevision_ = this.getRevision(); } - return ol.geom.closest.getsClosestPoint( + return ol.geom.flat.closest.getsClosestPoint( this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, false, x, y, closestPoint, minSquaredDistance); }; diff --git a/src/ol/geom/multipolygon.js b/src/ol/geom/multipolygon.js index acd04669da..0e14f3798e 100644 --- a/src/ol/geom/multipolygon.js +++ b/src/ol/geom/multipolygon.js @@ -7,8 +7,8 @@ goog.require('ol.geom.GeometryType'); goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.Polygon'); goog.require('ol.geom.SimpleGeometry'); -goog.require('ol.geom.closest'); goog.require('ol.geom.flat'); +goog.require('ol.geom.flat.closest'); goog.require('ol.geom.simplify'); @@ -118,11 +118,11 @@ ol.geom.MultiPolygon.prototype.closestPointXY = return minSquaredDistance; } if (this.maxDeltaRevision_ != this.getRevision()) { - this.maxDelta_ = Math.sqrt(ol.geom.closest.getssMaxSquaredDelta( + this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getssMaxSquaredDelta( this.flatCoordinates, 0, this.endss_, this.stride, 0)); this.maxDeltaRevision_ = this.getRevision(); } - return ol.geom.closest.getssClosestPoint( + return ol.geom.flat.closest.getssClosestPoint( this.getOrientedFlatCoordinates(), 0, this.endss_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance); }; diff --git a/src/ol/geom/polygon.js b/src/ol/geom/polygon.js index 1cd2d1fd4e..2fa6eebae5 100644 --- a/src/ol/geom/polygon.js +++ b/src/ol/geom/polygon.js @@ -7,8 +7,8 @@ goog.require('ol.geom.GeometryType'); goog.require('ol.geom.LinearRing'); goog.require('ol.geom.Point'); goog.require('ol.geom.SimpleGeometry'); -goog.require('ol.geom.closest'); goog.require('ol.geom.flat'); +goog.require('ol.geom.flat.closest'); goog.require('ol.geom.simplify'); @@ -108,11 +108,11 @@ ol.geom.Polygon.prototype.closestPointXY = return minSquaredDistance; } if (this.maxDeltaRevision_ != this.getRevision()) { - this.maxDelta_ = Math.sqrt(ol.geom.closest.getsMaxSquaredDelta( + this.maxDelta_ = Math.sqrt(ol.geom.flat.closest.getsMaxSquaredDelta( this.flatCoordinates, 0, this.ends_, this.stride, 0)); this.maxDeltaRevision_ = this.getRevision(); } - return ol.geom.closest.getsClosestPoint( + return ol.geom.flat.closest.getsClosestPoint( this.flatCoordinates, 0, this.ends_, this.stride, this.maxDelta_, true, x, y, closestPoint, minSquaredDistance); }; diff --git a/test/spec/ol/geom/closestgeom.test.js b/test/spec/ol/geom/flat/closestflatgeom.test.js similarity index 80% rename from test/spec/ol/geom/closestgeom.test.js rename to test/spec/ol/geom/flat/closestflatgeom.test.js index 124b5afde6..d9b972b180 100644 --- a/test/spec/ol/geom/closestgeom.test.js +++ b/test/spec/ol/geom/flat/closestflatgeom.test.js @@ -1,41 +1,41 @@ -goog.provide('ol.test.geom.closest'); +goog.provide('ol.test.geom.flat.closest'); -describe('ol.geom.closest', function() { +describe('ol.geom.flat.closest', function() { describe('with simple data', function() { var flatCoordinates = [0, 0, 1, 0, 3, 0, 5, 0, 6, 0, 8, 0, 11, 0]; - describe('ol.geom.closest.getMaxSquaredDelta', function() { + describe('ol.geom.flat.closest.getMaxSquaredDelta', function() { it('returns the expected value in simple cases', function() { - expect(ol.geom.closest.getMaxSquaredDelta( + expect(ol.geom.flat.closest.getMaxSquaredDelta( flatCoordinates, 0, flatCoordinates.length, 2, 0)).to.be(9); }); }); - describe('ol.geom.closest.getClosestPoint', function() { + describe('ol.geom.flat.closest.getClosestPoint', function() { it('returns the expected value', function() { - var maxDelta = Math.sqrt(ol.geom.closest.getMaxSquaredDelta( + var maxDelta = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta( flatCoordinates, 0, flatCoordinates.length, 2, 0)); expect(maxDelta).to.be(3); var closestPoint = [NaN, NaN]; - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 0, 0, closestPoint, Infinity)).to.be(0); expect(closestPoint).to.eql([0, 0]); - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 4, 1, closestPoint, Infinity)).to.be(1); expect(closestPoint).to.eql([4, 0]); - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 5, 2, closestPoint, Infinity)).to.be(4); expect(closestPoint).to.eql([5, 0]); - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 10, 100, closestPoint, Infinity)).to.be(10000); expect(closestPoint).to.eql([10, 0]); @@ -78,31 +78,31 @@ describe('ol.geom.closest', function() { describe('ol.geom.closet.maSquaredDelta', function() { it('returns the expected value', function() { - expect(ol.geom.closest.getMaxSquaredDelta( + expect(ol.geom.flat.closest.getMaxSquaredDelta( flatCoordinates, 0, flatCoordinates.length, 2, 0)). to.roughlyEqual(1389.1058, 1e-9); }); }); - describe('ol.geom.closest.getClosestPoint', function() { + describe('ol.geom.flat.closest.getClosestPoint', function() { it('returns the expected value', function() { - var maxDelta = Math.sqrt(ol.geom.closest.getMaxSquaredDelta( + var maxDelta = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta( flatCoordinates, 0, flatCoordinates.length, 2, 0)); expect(maxDelta).to.roughlyEqual(Math.sqrt(1389.1058), 1e-9); var closestPoint = [NaN, NaN]; - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 0, 0, closestPoint, Infinity)). to.roughlyEqual(110902.405, 1e-9); expect(closestPoint).to.eql([292.41, 159.37]); - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 500, 500, closestPoint, Infinity)). to.roughlyEqual(106407.905, 1e-9); expect(closestPoint).to.eql([671.55, 222.55]); - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, 2, maxDelta, false, 1000, 500, closestPoint, Infinity)). to.roughlyEqual(18229.4425, 1e-9); @@ -118,14 +118,14 @@ describe('ol.geom.closest', function() { var flatCoordinates = [0, 0, 10, -10, 2, 2, 30, -20]; var stride = 4; - describe('ol.geom.closest.getClosestPoint', function() { + describe('ol.geom.flat.closest.getClosestPoint', function() { it('interpolates M coordinates', function() { - var maxDelta = Math.sqrt(ol.geom.closest.getMaxSquaredDelta( + var maxDelta = Math.sqrt(ol.geom.flat.closest.getMaxSquaredDelta( flatCoordinates, 0, flatCoordinates.length, stride, 0)); expect(maxDelta).to.roughlyEqual(Math.sqrt(8), 1e-9); var closestPoint = [NaN, NaN]; - expect(ol.geom.closest.getClosestPoint( + expect(ol.geom.flat.closest.getClosestPoint( flatCoordinates, 0, flatCoordinates.length, stride, maxDelta, false, 1, 1, closestPoint, Infinity)). to.roughlyEqual(0, 1e-9); @@ -143,4 +143,5 @@ describe('ol.geom.closest', function() { }); -goog.require('ol.geom.closest'); +goog.require('ol.geom.flat'); +goog.require('ol.geom.flat.closest');