-
Notifications
You must be signed in to change notification settings - Fork 9
/
index.js
104 lines (100 loc) · 2.89 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
var invariant = require('turf-invariant');
// http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule
// modified from: https://github.com/substack/point-in-polygon/blob/master/index.js
// which was modified from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
/**
* Takes a {@link Point} and a {@link Polygon} or {@link MultiPolygon} and determines if the point resides inside the polygon. The polygon can
* be convex or concave. The function accounts for holes.
*
* @module turf/inside
* @category joins
* @param {Feature<Point>} point input point
* @param {Feature<(Polygon|MultiPolygon)>} polygon input polygon or multipolygon
* @return {Boolean} `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon
* @example
* var pt1 = {
* "type": "Feature",
* "properties": {
* "marker-color": "#f00"
* },
* "geometry": {
* "type": "Point",
* "coordinates": [-111.467285, 40.75766]
* }
* };
* var pt2 = {
* "type": "Feature",
* "properties": {
* "marker-color": "#0f0"
* },
* "geometry": {
* "type": "Point",
* "coordinates": [-111.873779, 40.647303]
* }
* };
* var poly = {
* "type": "Feature",
* "properties": {},
* "geometry": {
* "type": "Polygon",
* "coordinates": [[
* [-112.074279, 40.52215],
* [-112.074279, 40.853293],
* [-111.610107, 40.853293],
* [-111.610107, 40.52215],
* [-112.074279, 40.52215]
* ]]
* }
* };
*
* var features = {
* "type": "FeatureCollection",
* "features": [pt1, pt2, poly]
* };
*
* //=features
*
* var isInside1 = turf.inside(pt1, poly);
* //=isInside1
*
* var isInside2 = turf.inside(pt2, poly);
* //=isInside2
*/
module.exports = function(point, polygon) {
invariant.featureOf(point, 'Point', 'inside');
var polys = polygon.geometry.coordinates;
var pt = [point.geometry.coordinates[0], point.geometry.coordinates[1]];
// normalize to multipolygon
if (polygon.geometry.type === 'Polygon') polys = [polys];
var insidePoly = false;
var i = 0;
while (i < polys.length && !insidePoly) {
// check if it is in the outer ring first
if(inRing(pt, polys[i][0])) {
var inHole = false;
var k = 1;
// check for the point in any of the holes
while(k < polys[i].length && !inHole) {
if(inRing(pt, polys[i][k])) {
inHole = true;
}
k++;
}
if(!inHole) insidePoly = true;
}
i++;
}
return insidePoly;
};
// pt is [x,y] and ring is [[x,y], [x,y],..]
function inRing (pt, ring) {
var isInside = false;
for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) {
var xi = ring[i][0], yi = ring[i][1];
var xj = ring[j][0], yj = ring[j][1];
var intersect = ((yi > pt[1]) !== (yj > pt[1])) &&
(pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi);
if (intersect) isInside = !isInside;
}
return isInside;
}