import { Feature, Geometry } from "../types/index.js"; import { isFeature } from "../helpers/geo.js"; import { booleanOverlap as turfBoolOverlap } from "@turf/turf"; import deepEqual from "fast-deep-equal"; /** * Returns all B items that overlap with a A items * Not all Feature types are supported, see typedoc * A and B must have the same geometry dimension (single or multi). Builds on @turf/boolean-overlap. * @param {Geometry|Feature} featuresA - single or array * @param {Geometry|Feature} featuresB - single or array * @param idProperty - property in Feature B to track if overlap already found. * Useful if multiple features have same property value and you only want the first match. */ export async function booleanOverlap>( featureAInput: Feature | Feature[], featureBInput: B | B[], idProperty?: string, ): Promise; export async function booleanOverlap>( featureAInput: Geometry[], featureBInput: B | B[], idProperty?: string, ): Promise; export async function booleanOverlap( featureAInput: Feature | Feature[], featureBInput: B | B[], idProperty?: string, ): Promise; export async function booleanOverlap( featureAInput: Geometry | Geometry[], featureBInput: B | B[], idProperty?: string, ): Promise; export async function booleanOverlap( featureAInput, featureBInput: B | B[], idProperty?: string, ): Promise { // Normalize input to array const featuresA = Array.isArray(featureAInput) ? featureAInput : [featureAInput]; const featuresB = Array.isArray(featureBInput) ? featureBInput : [featureBInput]; const overlapFeatures: B[] = []; const overlapIds: string[] = []; for (const featureA of featuresA) { for (const featureB of featuresB) { // Don't test overlap if we already know it does if (isFeature(featureB) && idProperty) { const fb = featureB as Feature; const idB = fb.properties ? fb.properties[idProperty] : null; if (!overlapIds.includes(idB) && turfBoolOverlap(featureA, featureB)) { overlapFeatures.push(featureB); overlapIds.push(idB); } } else { if ( !overlapFeatures.some((of) => deepEqual(featureB, of)) && turfBoolOverlap(featureA, featureB) ) { overlapFeatures.push(featureB); } } } } return overlapFeatures; }