From 1670b311428095d8f9527f060f47cd3c9dd8a105 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Mon, 4 Nov 2013 19:19:54 +0100 Subject: [PATCH] Moving squaredDistanceToSegment to the coordinate package --- src/ol/coordinate.js | 51 +++++++++++++++++++++++++++++++++++++++ src/ol/geom/base.js | 31 ------------------------ src/ol/geom/linestring.js | 3 ++- 3 files changed, 53 insertions(+), 32 deletions(-) delete mode 100644 src/ol/geom/base.js diff --git a/src/ol/coordinate.js b/src/ol/coordinate.js index 85f0b5318e..8616c6ba06 100644 --- a/src/ol/coordinate.js +++ b/src/ol/coordinate.js @@ -42,6 +42,45 @@ ol.coordinate.add = function(coordinate, delta) { }; +/** + * @param {ol.Coordinate} coordinate The coordinate. + * @param {Array.} segment The two coordinates of the segment. + * @return {Array} An array compatible with ol.Coordinate, but with 4 vaules: + * [0] x-coordinate of the point closest to the given point on the segment; + * [1] y-coordinate of the point closest to the given point on the segment; + * [2] squared distance between given point and segment; + * [3] describes how far between the two segment points the given point is. + */ +ol.coordinate.closestOnSegment = function(coordinate, segment) { + var x0 = coordinate[0]; + var y0 = coordinate[1]; + var start = segment[0]; + var end = segment[1]; + var x1 = start[0]; + var y1 = start[1]; + var x2 = end[0]; + var y2 = end[1]; + var dx = x2 - x1; + var dy = y2 - y1; + var along = (dx == 0 && dy == 0) ? 0 : + ((dx * (x0 - x1)) + (dy * (y0 - y1))) / ((dx * dx + dy * dy) || 0); + var x, y; + if (along <= 0) { + x = x1; + y = y1; + } else if (along >= 1) { + x = x2; + y = y2; + } else { + x = x1 + along * dx; + y = y1 + along * dy; + } + var xDist = x - x0; + var yDist = y - y0; + return [x, y, xDist * xDist + yDist * yDist, along]; +}; + + /** * @param {number=} opt_fractionDigits The number of digits to include * after the decimal point. Default is `0`. @@ -136,6 +175,18 @@ ol.coordinate.squaredDistance = function(coord1, coord2) { }; +/** + * Calculate the squared distance from a coordinate to a line segment. + * + * @param {ol.Coordinate} coordinate Coordinate of the point. + * @param {Array.} segment Line segment (2 coordinates). + * @return {number} Squared distance from the point to the line segment. + */ +ol.coordinate.squaredDistanceToSegment = function(coordinate, segment) { + return ol.coordinate.closestOnSegment(coordinate, segment)[2]; +}; + + /** * @param {ol.Coordinate|undefined} coordinate Coordinate. * @return {string} Hemisphere, degrees, minutes and seconds. diff --git a/src/ol/geom/base.js b/src/ol/geom/base.js deleted file mode 100644 index 9950aab807..0000000000 --- a/src/ol/geom/base.js +++ /dev/null @@ -1,31 +0,0 @@ -goog.provide('ol.geom'); - -goog.require('ol.coordinate'); - - -/** - * Calculate the squared distance from a point to a line segment. - * - * @param {ol.Coordinate} coordinate Coordinate of the point. - * @param {Array.} segment Line segment (2 coordinates). - * @return {number} Squared distance from the point to the line segment. - */ -ol.geom.squaredDistanceToSegment = function(coordinate, segment) { - // http://de.softuses.com/103478, Kommentar #1 - var v = segment[0]; - var w = segment[1]; - var l2 = ol.coordinate.squaredDistance(v, w); - if (l2 === 0) { - return ol.coordinate.squaredDistance(coordinate, v); - } - var t = ((coordinate[0] - v[0]) * (w[0] - v[0]) + - (coordinate[1] - v[1]) * (w[1] - v[1])) / l2; - if (t < 0) { - return ol.coordinate.squaredDistance(coordinate, v); - } - if (t > 1) { - return ol.coordinate.squaredDistance(coordinate, w); - } - return ol.coordinate.squaredDistance(coordinate, - [v[0] + t * (w[0] - v[0]), v[1] + t * (w[1] - v[1])]); -}; diff --git a/src/ol/geom/linestring.js b/src/ol/geom/linestring.js index 11b2fd3e05..a4f8d261dc 100644 --- a/src/ol/geom/linestring.js +++ b/src/ol/geom/linestring.js @@ -3,6 +3,7 @@ goog.provide('ol.geom.LineString'); goog.require('goog.asserts'); goog.require('goog.events.EventType'); goog.require('ol.CoordinateArray'); +goog.require('ol.coordinate'); goog.require('ol.extent'); goog.require('ol.geom'); goog.require('ol.geom.Geometry'); @@ -104,7 +105,7 @@ ol.geom.LineString.prototype.distanceFromCoordinate = function(coordinate) { var coordinates = this.getCoordinates(); var dist2 = Infinity; for (var i = 0, j = 1, len = coordinates.length; j < len; i = j++) { - dist2 = Math.min(dist2, ol.geom.squaredDistanceToSegment(coordinate, + dist2 = Math.min(dist2, ol.coordinate.squaredDistanceToSegment(coordinate, [coordinates[i], coordinates[j]])); } return Math.sqrt(dist2);