import Geometry from 'ol/geom/Geometry'
import {
point as turfPoint,
lineString as turfLineString,
polygon as turfPolygon,
multiPoint as turfMultiPoint,
multiLineString as turfMultiLineString,
multiPolygon as turfMultiPolygon,
geometryCollection as turfGeometryCollection,
} from '@turf/helpers'
import turfBooleanCrosses from '@turf/boolean-crosses'
import turfBooleanContains from '@turf/boolean-contains'
import turfIntersect from '@turf/intersect'
function getGeometryType (geometry) {
return geometry instanceof Geometry
? geometry.getType()
: geometry.type || 'Polygon'
}
function getGeometryCoordinates (geometry) {
return geometry instanceof Geometry
? geometry.getCoordinates()
: geometry.coordinates || geometry
}
const TURF_CONSTRUCTORS = {
Point: turfPoint,
LineString: turfLineString,
Polygon: turfPolygon,
MultiPoint: turfMultiPoint,
MultiLineString: turfMultiLineString,
MultiPolygon: turfMultiPolygon,
GeometryCollection: turfGeometryCollection,
}
function toTurfGeometry (geometry) {
const geometryType = getGeometryType(geometry)
const coordinates = getGeometryCoordinates(geometry)
const turfConstructor = TURF_CONSTRUCTORS[geometryType]
return turfConstructor(coordinates)
}
function getGeometries (geometry) {
const type = getGeometryType(geometry)
const isOlGeom = geometry instanceof Geometry
switch (type) {
case 'GeometryCollection':
return isOlGeom ? geometry.getGeometries() : geometry.geometries
case 'MultiPolygon':
return isOlGeom ? geometry.getPolygons() : geometry.coordinates
case 'MultiLineString':
return isOlGeom ? geometry.getLineStrings() : geometry.coordinates
default:
throw new Error(type + ' geometry not supported')
}
}
/**
* Permet de savoir si une géométrie est partiellement
* ou totalement inclue dans une autre
*
* @param {Geometry} container Géométrie contenante
* @param {Geometry} geometry Géométrie contenue
* @param {Object} options Options
* @param {boolean} options.fullyInside Doit être intégralement dans le conteneur
*/
export function intersectsGeometry (container, geometry, { fullyInside } = {}) {
const geometryType = getGeometryType(geometry)
// Cas des groupements de géométries
if (['GeometryCollection', 'MultiPolygon', 'MultiLineString'].includes(geometryType)) {
const geometries = getGeometries(geometry)
const recursiveCall = item => intersectsGeometry(container, item, { fullyInside })
return fullyInside
? geometries.every(recursiveCall)
: geometries.some(recursiveCall)
}
if (geometryType === 'Point') {
return container.intersectsCoordinate(getGeometryCoordinates(geometry))
}
const turfContainer = toTurfGeometry(container)
const turfGeometry = toTurfGeometry(geometry)
const contained = turfBooleanContains(turfContainer, turfGeometry)
// Si la géométrie doit-être ou est totalement dedans
if (fullyInside || contained) {
return contained
}
// Cas particulier de croisement de polygon (non compatible turfBooleanCrosses)
if (geometryType === 'Polygon') {
return !!turfIntersect(turfContainer, turfGeometry)
}
// Cas d'un croisement de géométries simple
return turfBooleanCrosses(turfContainer, turfGeometry)
}