Boolean Predicates
Purpose and Scope
Boolean Predicates are a category of Turf.js modules that test spatial relationships between geometries, returning true or false based on whether specific geometric conditions are met. These modules implement the DE-9IM (Dimensionally Extended nine-Intersection Model) spatial predicate specifications, enabling precise geometric relationship queries between GeoJSON features.
This page covers the implementation, architecture, and usage patterns of the 13+ boolean predicate modules in Turf.js. For geometric transformation operations (buffer, union, difference), see Polygon Operations. For measurement calculations, see Distance and Bearing.
Module Inventory
Turf.js provides 13 boolean predicate modules that test different spatial relationships:
| Module | Purpose | Primary Geometry Support |
|---|---|---|
@turf/boolean-intersects | Tests if geometries have any overlap | All types |
@turf/boolean-disjoint | Tests if geometries have no overlap | All types |
@turf/boolean-contains | Tests if first geometry contains second | Point, Line, Polygon |
@turf/boolean-within | Tests if first geometry is within second | Point, Line, Polygon |
@turf/boolean-crosses | Tests if geometries cross each other | Line/Polygon combinations |
@turf/boolean-overlap | Tests if geometries partially overlap | Line, Polygon |
@turf/boolean-equal | Tests if geometries have identical coordinates | All types |
@turf/boolean-touches | Tests if boundaries touch but interiors don't | All types |
@turf/boolean-point-in-polygon | Tests if point is inside polygon | Point, Polygon |
@turf/boolean-point-on-line | Tests if point lies on line | Point, LineString |
@turf/boolean-parallel | Tests if lines are parallel | LineString |
@turf/boolean-clockwise | Tests if ring is clockwise | LinearRing |
@turf/boolean-concave | Tests if polygon is concave | Polygon |
Module Architecture
Dependency Structure
Boolean predicate modules follow a layered dependency pattern, building on foundation modules and often composing other boolean predicates:
Core Implementation Pattern
Most boolean predicates follow a common implementation pattern using flattenEach to handle multi-geometries and geometry collections:
Implementation Example: The booleanIntersects function demonstrates this pattern:
packages/turf-boolean-intersects/index.ts30-51
The function uses flattenEach to iterate over all simple geometries in potentially complex inputs, then delegates to booleanDisjoint and inverts the result.
Key Boolean Operations
booleanDisjoint
Tests if two geometries have no spatial overlap. Returns true if the intersection is an empty set.
Module: @turf/boolean-disjoint
Implementation Approach:
- Point vs Point: coordinate comparison
- Point vs LineString: point-on-line segment tests
- Point vs Polygon: point-in-polygon test
- LineString vs LineString: line intersection detection
- LineString vs Polygon: coordinate containment + boundary intersection
- Polygon vs Polygon: vertex containment + boundary intersection
packages/turf-boolean-disjoint/index.ts64-99
Options:
ignoreSelfIntersections(default:true): Ignores self-intersecting geometries when testing
booleanIntersects
Tests if two geometries have any spatial overlap. This is the logical inverse of booleanDisjoint.
Module: @turf/boolean-intersects
Implementation: Delegates to booleanDisjoint and inverts the result:
packages/turf-boolean-intersects/index.ts39-50
Options:
ignoreSelfIntersections(default:true): Ignores self-intersections on input features
booleanContains and booleanWithin
These are inverse operations:
booleanContains: Returnstrueif the second geometry is completely within the firstbooleanWithin: Returnstrueif the first geometry is completely within the second
Key Dependencies:
@turf/bboxfor bounding box checks@turf/boolean-point-in-polygonfor point containment@turf/boolean-point-on-linefor line containment
Both modules support MultiPolygon geometries and handle edge cases where points lie exactly on boundaries.
booleanOverlap
Tests if geometries have overlapping areas without complete containment. Uses line intersection and coordinate equality tests.
Dependencies:
@turf/line-intersectfor detecting edge intersections@turf/line-overlapfor detecting overlapping segmentsgeojson-equality-tsfor coordinate comparison
Performance Note: Optimized for MultiPoint geometries in v6.2.0.
booleanEqual
Determines if two geometries have identical X,Y coordinate values.
Implementation Change: Version 7.0.0 replaced the geojson-equality library with a custom implementation using geojson-equality-ts.
Key Feature: Supports a precision option to control coordinate comparison tolerance.
Dependencies:
@turf/clean-coordsto normalize geometries before comparisongeojson-equality-tsfor deep equality testing
booleanCrosses
Tests if geometries cross each other according to the OpenGIS Simple Feature Specification. Returns true only for:
- MultiPoint/Polygon
- MultiPoint/LineString
- LineString/LineString
- LineString/Polygon
- LineString/MultiPolygon
Key Dependencies:
@turf/boolean-point-in-polygon@turf/line-intersect@turf/polygon-to-linefor converting polygons to boundary lines
booleanClockwise
Determines the winding order of a linear ring. Returns true if clockwise, false if counter-clockwise.
Use Case: Critical for polygon validation and for the @turf/rewind module which normalizes polygon winding.
Implementation Details
Geometry Type Dispatch Pattern
Boolean predicates use a switch-case dispatch pattern to handle different geometry type combinations:
This pattern is implemented in packages/turf-boolean-disjoint/index.ts64-99
Self-Intersection Handling
Several boolean predicates support an ignoreSelfIntersections option to control behavior with self-intersecting geometries:
Default Behavior (ignoreSelfIntersections: true):
- Self-intersections within a single feature are ignored
- Only intersections between different features are detected
Strict Mode (ignoreSelfIntersections: false):
- Self-intersecting geometries are treated as intersecting themselves
- Useful for geometry validation
Testing Example: packages/turf-boolean-disjoint/test.ts47-212 demonstrates both modes:
// Self-intersecting LineString
LineString: [[1,1], [2,2], [1,2], [2,1]]
With ignoreSelfIntersections=true:
- disjoint(selfIntersecting, nonIntersecting) = true
With ignoreSelfIntersections=false:
- disjoint(selfIntersecting, nonIntersecting) = false (self-intersection detected)External Library Integration
Testing Strategy
Test Fixture Organization
Boolean predicate tests use a standardized directory structure:
packages/turf-boolean-{operation}/test/
├── true/ # Cases that should return true
│ ├── Point/
│ │ └── Point/
│ ├── LineString/
│ │ ├── Point/
│ │ ├── LineString/
│ │ └── Polygon/
│ └── Polygon/
│ └── ...
└── false/ # Cases that should return false
└── ...Each test file is a GeoJSON FeatureCollection with two features representing the input geometries.
packages/turf-boolean-intersects/test.ts11-45
Validation Against Reference Implementations
Tests can optionally validate against the Shapely geometry library (Python) using the SHAPELY environment variable:
packages/turf-boolean-disjoint/test.ts22-25
This provides cross-validation against a well-established GIS library to ensure correctness.
Common Usage Patterns
Composing Boolean Predicates
Boolean predicates can be composed to create complex spatial queries:
// Check if polygon completely surrounds another without touching
const surrounds = booleanContains(outer, inner) &&
!booleanTouches(outer, inner);
// Check if features share a boundary
const sharesBoundary = booleanTouches(feat1, feat2) &&
!booleanOverlap(feat1, feat2);
// Check if geometries are separate
const areSeparate = booleanDisjoint(feat1, feat2);Feature Collection Processing
Using flattenEach from @turf/meta to test multiple features:
import { flattenEach } from '@turf/meta';
import { booleanIntersects } from '@turf/boolean-intersects';
const intersectingFeatures = [];
flattenEach(featureCollection1, (feature1) => {
flattenEach(featureCollection2, (feature2) => {
if (booleanIntersects(feature1, feature2)) {
intersectingFeatures.push([feature1, feature2]);
}
});
});This pattern is used internally in packages/turf-boolean-intersects/index.ts40-49
Performance Considerations
Spatial Indexing
Boolean predicates do not include built-in spatial indexing. For large datasets, consider using:
- @turf/geojson-rbush: R-tree spatial index wrapper
- rbush: Direct R-tree implementation (used by clustering modules)
Example pattern:
import geojsonRbush from '@turf/geojson-rbush';
const tree = geojsonRbush();
tree.load(featureCollection);
// Only test features within bounding box
const candidates = tree.search(testFeature);
candidates.forEach(candidate => {
if (booleanIntersects(testFeature, candidate)) {
// Process intersection
}
});Optimization History
From the changelog, notable performance improvements:
- v6.2.0:
@turf/boolean-overlapoptimized for MultiPoint geometries - v4.7.0:
@turf/inside(now@turf/boolean-point-in-polygon) performance increase - v7.0.0:
@turf/boolean-point-in-polygonmoved topoint-in-polygon-haolibrary for better performance - v7.0.0:
@turf/line-intersectmoved tosweepline-intersectionslibrary (used by multiple boolean predicates)
Version History and Breaking Changes
Version 7.0.0
@turf/boolean-equal: Replacedgeojson-equalitywith new implementation, addedprecisionoption@turf/boolean-overlap: Replacedgeojson-equalitywith new implementation@turf/boolean-point-in-polygon: Moved topoint-in-polygon-haolibrary
Version 6.5.0
@turf/boolean-contains: Added MultiPolygon support
Version 5.0.0
Module renames for consistency:
@turf/inside→@turf/boolean-point-in-polygon@turf/within→@turf/points-within-polygon