Search code examples
google-mapspolygonpolyline

Does this polyline pass through this polygon?


I’m trying to test whether a Google Maps polyline passes through a Google Maps polygon. Sounds simple. But I’ve searched and searched... and found no real answers.

Closest I got was this function. It works but, frustratingly, returns the occasional false positive.

//nvert = the number of points in the polygon
//vertx = an array of all the polygon's latitudes
//verty = an array of all the polygon's longitudes
//elat = the current point's latitude
//elng = the current point's longitude

function pnpoly( nvert, vertx, verty, elat, elng) {
        var i, j, c = false;
        for( i = 0, j = nvert-1; i < nvert; j = i++ ) {
            if( ( ( verty[i] > elng ) != ( verty[j] > elng ) ) &&
                ( elat < ( vertx[j] - vertx[i] ) * ( elng - verty[i] ) / ( verty[j] - verty[i] ) + vertx[i] ) ) {
                    c = !c;
            }
          }
          return c;
    }

Before I try a whole new method (a crazy math idea that brings me back to Grade 12 calculus), I’m wondering anyone knows how to accomplish this.


Solution

  • I've come across a working solution.

    https://github.com/albertsun/JavaScript-Geometry

    This geometry package includes a function called findIntersections().

    I ran an $.each loop on each polygon on my map, then pushed each point in the polygon into an array, then each point in the polyline into an array. Finally, I ran two loops and pushed the lat/lon coordinates into variables for the function. It returns empty when it doesn't find anything and returns the coordinates of intersection when it finds something.

    function processPath(polyline, polygons){
    $.each(polygons, function(i,polygon){
        var polygonArr = [] // array for storing each point in polygon
    
        polygon.getPaths().forEach(function(k,g){
            $.each(k.b, function(l,m){
                polygonArr.push({'lat':m.lat(),'lng':m.lng()});
            });
        });
    
        //Get the number of points in the polyLINE
        var numStops = polyline.getPath().b.length -1;
    
        //Get the path and coordinates of the polyLINE
        var polylineArr = [];
    
        polyline.getPath().forEach(function(z,y){
            polylineArr.push({'lat':z.lat(),'lng':z.lng()});
        });
        $.each(polygonArr, function(j, polygon){
            $.each(polylineArr, function(k, polyline){
                if(k+1 != polylineArr.length){
                    var lineCoor1x = polylineArr[k].lat;
                    var lineCoor1y = polylineArr[k].lng;
                    var lineCoor2x = polylineArr[k+1].lat;
                    var lineCoor2y = polylineArr[k+1].lng;
                    var polyCoorx = polygonArr[j].lat;
                    var polyCoory = polygonArr[j].lng;
                    if(j+1 == polygonArr.length){
                        // We've reached the end, go back to the start
                        var polyCoorNextx = polygonArr[0].lat
                        var polyCoorNexty = polygonArr[0].lng
                    } else {
                        // Go to the next point
                        var polyCoorNextx = polygonArr[j+1].lat
                        var polyCoorNexty = polygonArr[j+1].lng
                    }
                    if(findIntersections([[[lineCoor1x,lineCoor1y], [lineCoor2x,lineCoor2y]], [[polyCoorx,polyCoory],[polyCoorNextx,polyCoorNexty]] ]).length != 0){
                        whereInside[i] = i;
                        return;
                    }
                }
            })
        })
    

    It's probably a bit messy but it works.