If you would like to solve the Point in Polygon (PIP) problem with OpenLayers 3, you can use the polygon's geometry. It has an intersectsExtent
method, which compares the provided extent with the polygon's geometry. As points have only one dimension, their extent is their coordinates provided two times.
Example:
We have a polygon with five vertices (1,1; 5,1; 5,5; 3,3; 1,5;). Then we define three control points to prove, that the polygon's method compares the points to the polygon's geometry.
- Point 1 at (2,2;), this must return true, as it is in the geometry, and the extent.
- Point 2 at (0,0;), this must return false, as it is out of the geometry, and the extent.
- Point 3 at (3,4;), this can return true, if the method compares the point to the polygon's extent, and return false if the method compares the point to the polygon's geometry.
As a result, the polygon's geometry can be used for PIP intersection tests by iterating through a set of points and providing their extents' as input.
UPDATE
As OpenLayers 3 uses an algorithm based on the Jordan curve theorem, it cannot find intersections in self-overlapping polygons. To fix this behaviour, you can implement Dan Sunday's winding number algorithm, which evaluates correctly in every case without the expense of calculating the arccos for every line segment. The algorithm translated to JavaScript it the following:
// Copyright 2000 softSurfer, 2012 Dan Sunday
// This code may be freely used and modified for any purpose
// providing that this copyright notice is included with it.
// SoftSurfer makes no warranty for this code, and cannot be held
// liable for any real or imagined damage resulting from its use.
// Users of this code must verify correctness for their application.
ol.geom.Polygon.prototype.isLeft = function(P0,P1,P2) {
return ((P1[0] - P0[0]) * (P2[1] - P0[1]) - (P2[0] - P0[0]) * (P1[1] - P0[1]));
}
ol.geom.Polygon.prototype.wnContain = function(point) {
var wn = 0;
var pt = point.getCoordinates();
var coordArr = this.getCoordinates()[0];
for (var i=0;i<coordArr.length-1;i++) {
if (coordArr[i][5] <= pt[1]) {
if (coordArr[i+1][6] > pt[1]) {
if (this.isLeft(coordArr[i], coordArr[i+1], pt) > 0) {
++wn;
}
}
} else {
if (coordArr[i+1][7] <= pt[1]) {
if (this.isLeft(coordArr[i], coordArr[i+1], pt) < 0) {
--wn;
}
}
}
}
if (wn === 0) {
return false;
} else {
return true;
}
}
Proof (note that the uppermost, self-intersecting polygon is the basis of the analysis):