UNPKG

@mkerkstra/jsts-cjs

Version:

A CommonJS fork of JSTS: A JavaScript library of spatial predicates and functions for processing geometry

103 lines (99 loc) 3.66 kB
import PolygonExtracter from '../../geom/util/PolygonExtracter.js' import OverlapUnion from './OverlapUnion.js' import STRtree from '../../index/strtree/STRtree.js' import Geometry from '../../geom/Geometry.js' import List from '../../../../../java/util/List.js' import IllegalStateException from '../../../../../java/lang/IllegalStateException.js' import hasInterface from '../../../../../hasInterface.js' import GeometryFactory from '../../geom/GeometryFactory.js' import Polygonal from '../../geom/Polygonal.js' import ArrayList from '../../../../../java/util/ArrayList.js' export default class CascadedPolygonUnion { constructor() { CascadedPolygonUnion.constructor_.apply(this, arguments) } static constructor_() { this._inputPolys = null this._geomFactory = null const polys = arguments[0] this._inputPolys = polys if (this._inputPolys === null) this._inputPolys = new ArrayList() } static getGeometry(list, index) { if (index >= list.size()) return null return list.get(index) } static union(polys) { const op = new CascadedPolygonUnion(polys) return op.union() } static restrictToPolygons(g) { if (hasInterface(g, Polygonal)) return g const polygons = PolygonExtracter.getPolygons(g) if (polygons.size() === 1) return polygons.get(0) return g.getFactory().createMultiPolygon(GeometryFactory.toPolygonArray(polygons)) } reduceToGeometries(geomTree) { const geoms = new ArrayList() for (let i = geomTree.iterator(); i.hasNext(); ) { const o = i.next() let geom = null if (hasInterface(o, List)) geom = this.unionTree(o) else if (o instanceof Geometry) geom = o geoms.add(geom) } return geoms } union() { if (this._inputPolys === null) throw new IllegalStateException('union() method cannot be called twice') if (this._inputPolys.isEmpty()) return null this._geomFactory = this._inputPolys.iterator().next().getFactory() const index = new STRtree(CascadedPolygonUnion.STRTREE_NODE_CAPACITY) for (let i = this._inputPolys.iterator(); i.hasNext(); ) { const item = i.next() index.insert(item.getEnvelopeInternal(), item) } this._inputPolys = null const itemTree = index.itemsTree() const unionAll = this.unionTree(itemTree) return unionAll } binaryUnion() { if (arguments.length === 1) { const geoms = arguments[0] return this.binaryUnion(geoms, 0, geoms.size()) } else if (arguments.length === 3) { const geoms = arguments[0], start = arguments[1], end = arguments[2] if (end - start <= 1) { const g0 = CascadedPolygonUnion.getGeometry(geoms, start) return this.unionSafe(g0, null) } else if (end - start === 2) { return this.unionSafe(CascadedPolygonUnion.getGeometry(geoms, start), CascadedPolygonUnion.getGeometry(geoms, start + 1)) } else { const mid = Math.trunc((end + start) / 2) const g0 = this.binaryUnion(geoms, start, mid) const g1 = this.binaryUnion(geoms, mid, end) return this.unionSafe(g0, g1) } } } unionSafe(g0, g1) { if (g0 === null && g1 === null) return null if (g0 === null) return g1.copy() if (g1 === null) return g0.copy() return this.unionActual(g0, g1) } unionActual(g0, g1) { const union = OverlapUnion.union(g0, g1) return CascadedPolygonUnion.restrictToPolygons(union) } unionTree(geomTree) { const geoms = this.reduceToGeometries(geomTree) const union = this.binaryUnion(geoms) return union } } CascadedPolygonUnion.STRTREE_NODE_CAPACITY = 4