diff --git a/src/ol/geom/circle.js b/src/ol/geom/circle.js index 00ab10d11e..fffb4399c0 100644 --- a/src/ol/geom/circle.js +++ b/src/ol/geom/circle.js @@ -39,21 +39,24 @@ ol.geom.Circle.prototype.clone = function() { ol.geom.Circle.prototype.closestPointXY = function(x, y, closestPoint, minSquaredDistance) { var flatCoordinates = this.flatCoordinates; - var radius = flatCoordinates[this.stride] - flatCoordinates[0]; var dx = x - flatCoordinates[0]; var dy = y - flatCoordinates[1]; - var d = Math.sqrt(dx * dx + dy * dy); - var distance = Math.max(d, 0); - var squaredDistance = distance * distance; + var squaredDistance = dx * dx + dy * dy; if (squaredDistance < minSquaredDistance) { - if (d === 0) { - closestPoint[0] = flatCoordinates[0]; - closestPoint[1] = flatCoordinates[1]; + var i; + if (squaredDistance === 0) { + for (i = 0; i < this.stride; ++i) { + closestPoint[i] = flatCoordinates[i]; + } } else { - var delta = radius / d; + var delta = this.getRadius() / Math.sqrt(squaredDistance); closestPoint[0] = flatCoordinates[0] + delta * dx; closestPoint[1] = flatCoordinates[1] + delta * dy; + for (i = 2; i < this.stride; ++i) { + closestPoint[i] = flatCoordinates[i]; + } } + closestPoint.length = this.stride; return squaredDistance; } else { return minSquaredDistance; diff --git a/test/spec/ol/geom/circle.test.js b/test/spec/ol/geom/circle.test.js index e7e6fa119d..3ae6298440 100644 --- a/test/spec/ol/geom/circle.test.js +++ b/test/spec/ol/geom/circle.test.js @@ -89,6 +89,37 @@ describe('ol.geom.Circle', function() { expect(closestPoint[1]).to.roughlyEqual(-Math.sqrt(0.5), 1e-15); }); + it('maintains Z coordinates', function() { + var circle = new ol.geom.Circle([0, 0, 1], 1); + expect(circle.getLayout()).to.be(ol.geom.GeometryLayout.XYZ); + var closestPoint = circle.getClosestPoint([2, 0]); + expect(closestPoint).to.have.length(3); + expect(closestPoint[0]).to.roughlyEqual(1, 1e-15); + expect(closestPoint[1]).to.roughlyEqual(0, 1e-15); + expect(closestPoint[2]).to.be(1); + }); + + it('maintains M coordinates', function() { + var circle = new ol.geom.Circle([0, 0, 2], 1, + ol.geom.GeometryLayout.XYM); + var closestPoint = circle.getClosestPoint([2, 0]); + expect(closestPoint).to.have.length(3); + expect(closestPoint[0]).to.roughlyEqual(1, 1e-15); + expect(closestPoint[1]).to.roughlyEqual(0, 1e-15); + expect(closestPoint[2]).to.be(2); + }); + + it('maintains Z and M coordinates', function() { + var circle = new ol.geom.Circle([0, 0, 1, 2], 1); + expect(circle.getLayout()).to.be(ol.geom.GeometryLayout.XYZM); + var closestPoint = circle.getClosestPoint([2, 0]); + expect(closestPoint).to.have.length(4); + expect(closestPoint[0]).to.roughlyEqual(1, 1e-15); + expect(closestPoint[1]).to.roughlyEqual(0, 1e-15); + expect(closestPoint[2]).to.be(1); + expect(closestPoint[3]).to.be(2); + }); + }); describe('#getExtent', function() {