Get hit candidates from RTree, then refine result

Now we get exact hits also for lines and polygons.
This commit is contained in:
ahocevar
2013-04-30 13:34:12 +02:00
parent cc1b70c74b
commit 58c8b07ab5
9 changed files with 208 additions and 21 deletions

View File

@@ -1,6 +1,8 @@
goog.provide('ol.geom.Vertex');
goog.provide('ol.geom.VertexArray');
goog.require('ol.coordinate');
/**
* @typedef {Array.<number>}
@@ -12,3 +14,59 @@ ol.geom.Vertex;
* @typedef {Array.<ol.geom.Vertex>}
*/
ol.geom.VertexArray;
/**
* Calculate the squared distance from a point to a line segment.
*
* @param {ol.Coordinate} coordinate Coordinate of the point.
* @param {Array.<ol.Coordinate>} 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])]);
};
/**
* Calculate whether a point falls inside a polygon.
*
* @param {ol.Coordinate} coordinate Coordinate of the point.
* @param {Array.<ol.Coordinate>} vertices Vertices of the polygon.
* @return {boolean} Whether the point falls inside the polygon.
*/
ol.geom.pointInPolygon = function(coordinate, vertices) {
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = coordinate[0], y = coordinate[1];
var inside = false;
var xi, yi, xj, yj, intersect;
var numVertices = vertices.length;
for (var i = 0, j = numVertices - 1; i < numVertices; j = i++) {
xi = vertices[i][0];
yi = vertices[i][1];
xj = vertices[j][0];
yj = vertices[j][1];
intersect = ((yi > y) != (yj > y)) &&
(x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) {
inside = !inside;
}
}
return inside;
};