Skip to content

布尔谓词

目的和范围

布尔谓词是一类 Turf.js 模块,用于测试几何体之间的空间关系,根据是否满足特定几何条件返回 truefalse。这些模块实现了 DE-9IM(维度扩展九交模型)空间谓词规范,使 GeoJSON features 之间能够进行精确的几何关系查询。

本页面介绍 Turf.js 中 13+ 个布尔谓词模块的实现、架构和使用模式。对于几何变换操作(buffer、union、difference),请参见 多边形操作。对于测量计算,请参见 距离和方位角

模块清单

Turf.js 提供 13 个布尔谓词模块,用于测试不同的空间关系:

ModulePurposePrimary Geometry Support
@turf/boolean-intersectsTests if geometries have any overlapAll types
@turf/boolean-disjointTests if geometries have no overlapAll types
@turf/boolean-containsTests if first geometry contains secondPoint, Line, Polygon
@turf/boolean-withinTests if first geometry is within secondPoint, Line, Polygon
@turf/boolean-crossesTests if geometries cross each otherLine/Polygon combinations
@turf/boolean-overlapTests if geometries partially overlapLine, Polygon
@turf/boolean-equalTests if geometries have identical coordinatesAll types
@turf/boolean-touchesTests if boundaries touch but interiors don'tAll types
@turf/boolean-point-in-polygonTests if point is inside polygonPoint, Polygon
@turf/boolean-point-on-lineTests if point lies on linePoint, LineString
@turf/boolean-parallelTests if lines are parallelLineString
@turf/boolean-clockwiseTests if ring is clockwiseLinearRing
@turf/boolean-concaveTests if polygon is concavePolygon

模块架构

依赖结构

布尔谓词模块遵循分层依赖模式,基于基础模块构建,通常组合其他布尔谓词:

SVG
100%

核心实现模式

大多数布尔谓词遵循通用的实现模式,使用 flattenEach 处理多重几何体和几何集合:

SVG
100%

实现示例booleanIntersects 函数演示了这种模式:

packages/turf-boolean-intersects/index.ts30-51

该函数使用 flattenEach 迭代可能复杂输入中的所有简单几何体,然后委托给 booleanDisjoint 并反转结果。

关键布尔操作

booleanDisjoint

测试两个几何体是否没有空间重叠。如果交集为空集,则返回 true

模块@turf/boolean-disjoint

实现方法

  • Point vs Point:坐标比较
  • Point vs LineString:点在线段上的测试
  • Point vs Polygon:点在多边形内的测试
  • LineString vs LineString:线交点检测
  • LineString vs Polygon:坐标包含 + 边界交点
  • Polygon vs Polygon:顶点包含 + 边界交点

packages/turf-boolean-disjoint/index.ts64-99

选项

  • ignoreSelfIntersections(默认:true):测试时忽略自相交几何体

booleanIntersects

测试两个几何体是否有任何空间重叠。这是 booleanDisjoint 的逻辑反运算。

模块@turf/boolean-intersects

实现:委托给 booleanDisjoint 并反转结果:

packages/turf-boolean-intersects/index.ts39-50

选项

  • ignoreSelfIntersections(默认:true):忽略输入 features 上的自相交

booleanContains 和 booleanWithin

这些是相反的操作:

  • booleanContains:如果第二个几何体完全在第一个几何体内,则返回 true
  • booleanWithin:如果第一个几何体完全在第二个几何体内,则返回 true

Key Dependencies:

  • @turf/bbox for bounding box checks
  • @turf/boolean-point-in-polygon for point containment
  • @turf/boolean-point-on-line for line containment

两个模块都支持 MultiPolygon 几何体,并处理点恰好位于边界上的边界情况。

booleanOverlap

测试几何体是否有重叠区域但不完全包含。使用线交点和坐标相等性测试。

Dependencies:

  • @turf/line-intersect for detecting edge intersections
  • @turf/line-overlap for detecting overlapping segments
  • geojson-equality-ts for coordinate comparison

性能说明:在 v6.2.0 中针对 MultiPoint 几何体进行了优化。

booleanEqual

确定两个几何体是否具有相同的 X,Y 坐标值。

实现变更:7.0.0 版本使用 geojson-equality-ts 的自定义实现替换了 geojson-equality 库。

关键特性:支持 precision 选项以控制坐标比较容差。

Dependencies:

  • @turf/clean-coords to normalize geometries before comparison
  • geojson-equality-ts for deep equality testing

booleanCrosses

根据 OpenGIS Simple Feature Specification 测试几何体是否相交。仅对以下情况返回 true

  • MultiPoint/Polygon
  • MultiPoint/LineString
  • LineString/LineString
  • LineString/Polygon
  • LineString/MultiPolygon

Key Dependencies:

  • @turf/boolean-point-in-polygon
  • @turf/line-intersect
  • @turf/polygon-to-line for converting polygons to boundary lines

booleanClockwise

确定线性环的缠绕顺序。如果是顺时针则返回 true,如果是逆时针则返回 false

用例:对于多边形验证和规范化多边形缠绕的 @turf/rewind 模块至关重要。

实现细节

几何类型分发模式

布尔谓词使用 switch-case 分发模式处理不同的几何类型组合:

SVG
100%

该模式在 packages/turf-boolean-disjoint/index.ts64-99 中实现

自相交处理

几个布尔谓词支持 ignoreSelfIntersections 选项以控制自相交几何体的行为:

默认行为ignoreSelfIntersections: true):

  • 单个 feature 内的自相交被忽略
  • 仅检测不同 features 之间的交点

严格模式ignoreSelfIntersections: false):

  • 自相交几何体被视为与自身相交
  • 用于几何体验证

测试示例packages/turf-boolean-disjoint/test.ts47-212 演示了两种模式:

// 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)

外部库集成

SVG
100%

测试策略

测试装置组织

布尔谓词测试使用标准化的目录结构:

packages/turf-boolean-{operation}/test/
  ├── true/               # Cases that should return true
  │   ├── Point/
  │   │   └── Point/
  │   ├── LineString/
  │   │   ├── Point/
  │   │   ├── LineString/
  │   │   └── Polygon/
  │   └── Polygon/
  │       └── ...
  └── false/              # Cases that should return false
      └── ...

每个测试文件是一个 GeoJSON FeatureCollection,包含两个表示输入几何体的 features。

packages/turf-boolean-intersects/test.ts11-45

参考实现验证

测试可以选择使用 SHAPELY 环境变量与 Shapely 几何库(Python)进行验证:

packages/turf-boolean-disjoint/test.ts22-25

这提供了与成熟的 GIS 库的交叉验证以确保正确性。

常见使用模式

组合布尔谓词

布尔谓词可以组合以创建复杂的空间查询:

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

该模式在 packages/turf-boolean-intersects/index.ts40-49 中内部使用

性能考虑

空间索引

布尔谓词不包括内置的空间索引。对于大数据集,考虑使用:

  1. @turf/geojson-rbush: R-tree spatial index wrapper
  2. 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
  }
});

优化历史

从变更日志中,值得注意的性能改进:

  • v6.2.0: @turf/boolean-overlap optimized for MultiPoint geometries
  • v4.7.0: @turf/inside (now @turf/boolean-point-in-polygon) performance increase
  • v7.0.0: @turf/boolean-point-in-polygon moved to point-in-polygon-hao library for better performance
  • v7.0.0: @turf/line-intersect moved to sweepline-intersections library (used by multiple boolean predicates)

版本历史和重大变更

7.0.0 版本

  • @turf/boolean-equal:用新实现替换了 geojson-equality,添加了 precision 选项
  • @turf/boolean-overlap:用新实现替换了 geojson-equality
  • @turf/boolean-point-in-polygon:移至 point-in-polygon-hao

6.5.0 版本

  • @turf/boolean-contains:添加了 MultiPolygon 支持

5.0.0 版本

为了一致性的模块重命名:

  • @turf/inside@turf/boolean-point-in-polygon
  • @turf/within@turf/points-within-polygon