| 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); |
| } |
|
|