3

ol3 supplies the method forEachFeatureIntersectingExtent which only good for boxes.

I have user drawn polygons (or multipolygons) for selecting features from a vector layer.

I'm relatively new to openlayers and chose to start developing a new project with ol3.

I know openlayers 2 had intersect functions for geometries not just for extents.

How do I achieve this with ol3?

3 Answers 3

4

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:

enter image description here

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.

enter image description here

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):

WN

1
  • great, i'll first collect the points in the polygons extent and then check the polygons geometry in each point extent. problem solved (and yet it would be nice to have ol3 simplified it). many thanks
    – Yoav
    Commented Mar 23, 2015 at 13:14
0

When you want to select a polygon from a user interaction (e.g. user clicks point on the map), you can use ol.Map#forEachFeatureAtPixel(). If you want to programmatically filter polygons that contain a given coordinate, you'll want to use ol.layer.Vector#getSource().getFeaturesAtCoordinate().

1
  • thanks, although i want to select the points and not the polygon your answer led me to think backwards and look for the polygon in each point extent, and then gabor's answer confirmed it. much appreciated
    – Yoav
    Commented Mar 23, 2015 at 13:08
-1

use getFeaturesInExtent or forEachFeatureIntersectingExtent.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.