|
import {default as polygonContains} from "./polygonContains.js"; |
|
import {default as distance} from "./distance.js"; |
|
import {epsilon2, radians} from "./math.js"; |
|
|
|
var containsObjectType = { |
|
Feature: function(object, point) { |
|
return containsGeometry(object.geometry, point); |
|
}, |
|
FeatureCollection: function(object, point) { |
|
var features = object.features, i = -1, n = features.length; |
|
while (++i < n) if (containsGeometry(features[i].geometry, point)) return true; |
|
return false; |
|
} |
|
}; |
|
|
|
var containsGeometryType = { |
|
Sphere: function() { |
|
return true; |
|
}, |
|
Point: function(object, point) { |
|
return containsPoint(object.coordinates, point); |
|
}, |
|
MultiPoint: function(object, point) { |
|
var coordinates = object.coordinates, i = -1, n = coordinates.length; |
|
while (++i < n) if (containsPoint(coordinates[i], point)) return true; |
|
return false; |
|
}, |
|
LineString: function(object, point) { |
|
return containsLine(object.coordinates, point); |
|
}, |
|
MultiLineString: function(object, point) { |
|
var coordinates = object.coordinates, i = -1, n = coordinates.length; |
|
while (++i < n) if (containsLine(coordinates[i], point)) return true; |
|
return false; |
|
}, |
|
Polygon: function(object, point) { |
|
return containsPolygon(object.coordinates, point); |
|
}, |
|
MultiPolygon: function(object, point) { |
|
var coordinates = object.coordinates, i = -1, n = coordinates.length; |
|
while (++i < n) if (containsPolygon(coordinates[i], point)) return true; |
|
return false; |
|
}, |
|
GeometryCollection: function(object, point) { |
|
var geometries = object.geometries, i = -1, n = geometries.length; |
|
while (++i < n) if (containsGeometry(geometries[i], point)) return true; |
|
return false; |
|
} |
|
}; |
|
|
|
function containsGeometry(geometry, point) { |
|
return geometry && containsGeometryType.hasOwnProperty(geometry.type) |
|
? containsGeometryType[geometry.type](geometry, point) |
|
: false; |
|
} |
|
|
|
function containsPoint(coordinates, point) { |
|
return distance(coordinates, point) === 0; |
|
} |
|
|
|
function containsLine(coordinates, point) { |
|
var ao, bo, ab; |
|
for (var i = 0, n = coordinates.length; i < n; i++) { |
|
bo = distance(coordinates[i], point); |
|
if (bo === 0) return true; |
|
if (i > 0) { |
|
ab = distance(coordinates[i], coordinates[i - 1]); |
|
if ( |
|
ab > 0 && |
|
ao <= ab && |
|
bo <= ab && |
|
(ao + bo - ab) * (1 - Math.pow((ao - bo) / ab, 2)) < epsilon2 * ab |
|
) |
|
return true; |
|
} |
|
ao = bo; |
|
} |
|
return false; |
|
} |
|
|
|
function containsPolygon(coordinates, point) { |
|
return !!polygonContains(coordinates.map(ringRadians), pointRadians(point)); |
|
} |
|
|
|
function ringRadians(ring) { |
|
return ring = ring.map(pointRadians), ring.pop(), ring; |
|
} |
|
|
|
function pointRadians(point) { |
|
return [point[0] * radians, point[1] * radians]; |
|
} |
|
|
|
export default function(object, point) { |
|
return (object && containsObjectType.hasOwnProperty(object.type) |
|
? containsObjectType[object.type] |
|
: containsGeometry)(object, point); |
|
} |
|
|