Check if Point Is Inside A Polygon – Even if we have a good project plan and a logical concept, we will spend the majority of our time correcting errors abaout javascript and polygon. Furthermore, our application can run without obvious errors with JavaScript, we must use various ways to ensure that everything is operating properly. In general, there are two types of errors that you’ll encounter while doing something wrong in code: Syntax Errors and Logic Errors. To make bug fixing easier, every JavaScript error is captured with a full stack trace and the specific line of source code marked. To assist you in resolving the JavaScript error, look at the discuss below to fix problem about Check if Point Is Inside A Polygon.
Problem :
I want to check if a point lies within a specific polygon. The polygon is:
polygon= [ [-73.89632720118, 40.8515320489962],
[-73.8964878416508, 40.8512476593594],
[-73.8968799791431, 40.851375925454],
[-73.8967188588015, 40.851660158514],
[-73.89632720118, 40.8515320489962] ]
The points I want to check are:
1 = [40.8515320489962,-73.89632720118]
2 = [40.8512476593594,-73.8964878416508]
3 = [40.851375925454,-73.8968799791431]
4 = [40.851660158514,-73.8967188588015]
5 = [40.8515320489962,-73.89632720118]
How can I tell if each of these points lies within this polygon?
The algorithm below does not work. I don’t know why.
pt[lat,long]
function isPointInPoly(poly, pt){
for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1] < poly[i][1]))
&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
&& (c = !c);
return c;
}
I don’t want to use a third party solution such as google maps API or this one https://github.com/mattwilliamson/Google-Maps-Point-in-Polygon.
My attempt is here:
http://jsfiddle.net/nvNNF/2/
Solution :
There is a project on Github with code: https://github.com/substack/point-in-polygon (MIT license):
function inside(point, vs) {
// ray-casting algorithm based on
// https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html/pnpoly.html
var x = point[0], y = point[1];
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0], yi = vs[i][1];
var xj = vs[j][0], yj = vs[j][1];
var intersect = ((yi > y) != (yj > y))
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
Usage:
// array of coordinates of each vertex of the polygon
var polygon = [ [ 1, 1 ], [ 1, 2 ], [ 2, 2 ], [ 2, 1 ] ];
inside([ 1.5, 1.5 ], polygon); // true
The test function is here: https://github.com/substack/point-in-polygon/blob/master/index.js
Note: This code doesn’t work reliably when the point is a corner of the polygon or on an edge. There is an improved version here: https://github.com/mikolalysenko/robust-point-in-polygon
Your polygon array looks like coordinates
array in GeoJSON polygon structure (read more at https://macwright.org/2015/03/23/geojson-second-bite.html and http://geojson.org).
So maybe you can use libraries which are working with geoJSON data? Look at answer and comments to OP in Is it possible to determine if a GeoJSON point is inside a GeoJSON polygon using JavasScript?
In short, my day was saved by turf
(https://github.com/turfjs/turf)
There is also d3
(https://github.com/d3/d3-geo#geoContains) but i had issues with it.
UPD:
I noticed turf
is giving inconsistent results when point is on ‘edge’ of polygon. I created issue and i am waiting for answer from developers.
UPD2:
‘Boundary points’ issue is resolved by using latest version of turf
(i used 3.0.14 instead of 4.6.1). It’s all right now.
Here is the function I finally got working. I got it by adopting C code to javascript from here (with explanation).
function checkcheck (x, y, cornersX, cornersY) {
var i, j=cornersX.length-1 ;
var odd = false;
var pX = cornersX;
var pY = cornersY;
for (i=0; i<cornersX.length; i++) {
if ((pY[i]< y && pY[j]>=y || pY[j]< y && pY[i]>=y)
&& (pX[i]<=x || pX[j]<=x)) {
odd ^= (pX[i] + (y-pY[i])*(pX[j]-pX[i])/(pY[j]-pY[i])) < x;
}
j=i;
}
return odd;
}
Where cornersX
= array with x or latitude vertices array, cornersY
= array with y or longitude array. X, Y – latitude and longitude of tested point.
In my case i did following thing it’s working fine for me
function isLatLngInZone(latLngs,lat,lng){
// latlngs = [{"lat":22.281610498720003,"lng":70.77577162868579},{"lat":22.28065743343672,"lng":70.77624369747241},{"lat":22.280860953131217,"lng":70.77672113067706},{"lat":22.281863655593973,"lng":70.7762061465462}];
vertices_y = new Array();
vertices_x = new Array();
longitude_x = lng;
latitude_y = lat;
latLngs = JSON.parse(latLngs);
var r = 0;
var i = 0;
var j = 0;
var c = 0;
var point = 0;
for(r=0; r<latLngs.length; r++){
vertices_y.push(latLngs[r].lat);
vertices_x.push(latLngs[r].lng);
}
points_polygon = vertices_x.length;
for(i = 0, j = points_polygon; i < points_polygon; j = i++){
point = i;
if(point == points_polygon)
point = 0;
if ( ((vertices_y[point] > latitude_y != (vertices_y[j] > latitude_y)) && (longitude_x < (vertices_x[j] - vertices_x[point]) * (latitude_y - vertices_y[point]) / (vertices_y[j] - vertices_y[point]) + vertices_x[point]) ) )
c = !c;
}
return c;
}
I modernised the function from Aaron’s answer:
const getIsPointInsidePolygon = (point: number[], vertices: number[][]) => {
const x = point[0]
const y = point[1]
let inside = false
for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
const xi = vertices[i][0],
yi = vertices[i][1]
const xj = vertices[j][0],
yj = vertices[j][1]
const intersect = yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi
if (intersect) inside = !inside
}
return inside
}