Skip to content Skip to sidebar Skip to footer

Check If A Polygon Point Is Inside Another In Leaflet

I'm having two sets of polygon coordinates selected from leaflet geoJSON map. The parent and child coordinates are coordinates are: var parentCoordinates=[ [ 32.0589822

Solution 1:

I've had good experience with Turf. It works well, is well documented and the examples are already shown with leaflet.

For your problem, you could use turf.within with parentCoordinates as turf.polygon and childCoordinates as an array of turf.point :

var parentPolygon = turf.polygon([parentCoordinates]);

var inside = true;
childCoordinates.forEach(function(coordinates) {
    point = turf.point(coordinates);
    if (!turf.inside(point, parentPolygon)){
      alert("Oh no! "+ coordinates + " isn't in polygon");
      inside = false;
    }
});

alert("Child polygon inside parent polygon ? " + inside);

Here's a Fiddle example.

Solution 2:

I tried with your algorithm and another found here https://rosettacode.org/wiki/Ray-casting_algorithm and both return the right value.

Maybe this fiddle can help you in the implementation :

https://jsfiddle.net/4psL2hoo/1/

Your algo

// Datavar parentCoordinates=[
    [
        32.05898221582174,
        -28.31004731142091
    ],
    [
        32.05898221582174,
        -28.308044824292978
    ],
    [
        32.06134255975485,
        -28.308044824292978
    ],
    [
        32.06134255975485,
        -28.31004731142091
    ],
    [
        32.05898221582174,
        -28.31004731142091
    ]
]
var childCoordinates=[
  [
    32.059904895722866,
    -28.30970726909422
  ],
  [
    32.059904895722866,
    -28.308743809931784
  ],
  [
    32.06089194864035,
    -28.308743809931784
  ],
  [
    32.06089194864035,
    -28.30970726909422
  ],
  [
    32.059904895722866,
    -28.30970726909422
  ]
]

// Other algo
function test(point, vs) {
    // ray-casting algorithm based on// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.htmlvarx= point[0], y = point[1];

    varinside=false;
    for (vari=0, j = vs.length - 1; i < vs.length; j = i++) {
        varxi= vs[i][0], yi = vs[i][1];
        varxj= vs[j][0], yj = vs[j][1];

        varintersect= ((yi > y) != (yj > y))
            && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
        if (intersect) inside = !inside;
    }

    return inside;
};

for (vari=0; i < childCoordinates.length; i++) {
     vartestPoint= childCoordinates[i];
     console.log(JSON.stringify(testPoint) + '\tin parentCoordinate\t' + test(testPoint, parentCoordinates));
}

Rosetta code algo

//https://rosettacode.org/wiki/Ray-casting_algorithm
function contains(bounds, lat, lng) {
    //https://rosettacode.org/wiki/Ray-casting_algorithmvarcount=0;
    for (varb=0; b < bounds.length; b++) {
        varvertex1= bounds[b];
        varvertex2= bounds[(b + 1) % bounds.length];
        if (west(vertex1, vertex2, lng, lat))
            ++count;
    }
    return count % 2;

    /**
     * @return {boolean} true if (x,y) is west of the line segment connecting A and B
     */
    function west(A, B, x, y) {
        if (A.y <= B.y) {
            if (y <= A.y || y > B.y ||
                x >= A.x && x >= B.x) {
                returnfalse;
            } elseif (x < A.x && x < B.x) {
                returntrue;
            } else {
                return (y - A.y) / (x - A.x) > (B.y - A.y) / (B.x - A.x);
            }
        } else {
            return west(B, A, x, y);
        }
    }
}

varsquare= {name: 'square', bounds: [{x: 32.05898221582174, y: -28.31004731142091}, {x: 32.05898221582174, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.308044824292978}, {x: 32.06134255975485, y: -28.31004731142091}]};

varshapes= [square];
vartestPoints= [{lng: 32.059904895722866, lat: -28.30970726909422}, {lng: 32.059904895722866, lat: -28.308743809931784}, {lng: 32.06089194864035, lat: -28.308743809931784},
    {lng: 32.06089194864035, lat: -28.30970726909422}];

for (vars=0; s < shapes.length; s++) {
    varshape= shapes[s];
    for (vartp=0; tp < testPoints.length; tp++) {
        vartestPoint= testPoints[tp];
        console.log(JSON.stringify(testPoint) + '\tin ' + shape.name + '\t' + contains(shape.bounds, testPoint.lat, testPoint.lng));
    }
}

Solution 3:

You can try Leaflet's api for that - contains . You create a parent polygon with LatLngBounds and then child too.

parentPolygon.contains(childPolygon)

Post a Comment for "Check If A Polygon Point Is Inside Another In Leaflet"