はじめに
OpenLayersで矩形内にある図形を抽出する場合、矩形で図形の交差を判定するため、正確にポリゴン同士の交差を判定できません。
JSTS導入前のイメージ
以下のイメージでは、ポリゴン同士の交差を判定できず、範囲外でも選択されています。

残念ながら、OpenLayers 単体では TopologySuite のような正確な図形同士の空間演算はサポートされていません(GeometryEngineがないため)。そのため、高精度を求める場合は Turf.js や JSTS を併用する必要があります。
Turf.js と JSTS の比較
以下は、Turf.js と JSTS の機能や用途に関する詳細な比較です。どちらもJavaScriptで空間解析を行うライブラリですが、目的やアーキテクチャが異なります。
| No | 項目 | Turf.js | JSTS |
| 1 | 起源 | Mapbox製(GeoJSON特化) | JTS(Java Topology Suite)のJS移植 |
| 2 | データ形式 | GeoJSON に最適化 | OpenLayers / JSTS独自形式(OL互換) |
| 3 | APIスタイル | 関数型(turf.booleanIntersects(...)) |
クラスベース(geomA.intersects(geomB)) |
| 4 | 軽量さ | ◎ 軽い | △ やや重い |
| 5 | サポート図形 | ポリゴン/ライン/ポイント中心 | 複雑なMulti/GeometryCollection対応 |
| 6 | トポロジー構築 | ❌ 不可 | ✅ 可能(GeometryPrecisionReducer, BufferOp, UnionOp など) |
| 7 | バッファ・ユニオン等の幾何処理 | △ 限定的 | ◎ 豊富かつ正確 |
c#でNetTopologySuiteを利用していることと、Turf.jsと比べても、正確な空間演算・トポロジー処理を扱いたい開発者向けであることから、OpenLayersでJSTSを導入し、ポリゴン同士の交差を判定してみました。
JSTS使用例
jstsはビルド済みのファイルを利用します。自分でbuildするのは面倒なので、CDNで直接jsts.min.jsを取得します。CDNで直接jsts.min.jsを取得できるURLとしては、以下が一般的です。
|
1 |
https://cdn.jsdelivr.net/npm/jsts@2.11.0/dist/jsts.min.js |
jsts.html
CDNで直接jsts.min.jsを取得したファイルをローカルに保存し、読み込みます。
|
1 2 3 4 5 6 7 8 9 10 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <!-- jsts --> <script src="scripts/jsts-2.12.1/dist/jsts.min.js"></script> <body> </body> </html> |
jsts.js
初期処理でOpenLayersのGeometoryクラスが利用できるようにします。そのあとOpenLayersのGeometoryデータを読込んで、JSTSのGeometoryに変換して空間演算を行います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 初期処理 const parser = new jsts.io.OL3Parser(undefined, undefined); const parser.inject( ol.geom.Point, ol.geom.LineString, ol.geom.LinearRing, ol.geom.Polygon, ol.geom.MultiPoint, ol.geom.MultiLineString, ol.geom.MultiPolygon, ); // 矩形描画後の処理 drawInteraction.on('drawend', (evt) => { const geometry = evt.feature.getGeometry(); targetSource.forEachFeature((feature) => { const geom = feature.getGeometry(); if (geometry.intersectsExtent(geom.getExtent())) { const geomA = this.parser.read(geometry); const geomB = this.parser.read(geom); if (geomA.intersects(geomB)) { const clone = feature.clone(); resultSource.addFeature(clone); } } }); }); |
JSTS導入後のイメージ1
OpenLayers単体の時と、同じ図形の場合は、交差を判定されません。

JSTS導入後のイメージ2
図形同士が交差するは、交差を判定されています。

まとめ
OpenLayersで、正確な図形同士の空間演算はサポートされていないのは意外でした。
ただ、自力で構築するのは大変なので、JSTSが提供されていたのでよかったです。
JSTSがあれば、より高度な空間演算が提供されているので、他の機能も試してみます!