CascadedPolygonUnion.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import PolygonExtracter from '../../geom/util/PolygonExtracter'
  2. import OverlapUnion from './OverlapUnion'
  3. import STRtree from '../../index/strtree/STRtree'
  4. import Geometry from '../../geom/Geometry'
  5. import hasInterface from '../../../../../hasInterface'
  6. import GeometryFactory from '../../geom/GeometryFactory'
  7. import Polygonal from '../../geom/Polygonal'
  8. import ArrayList from '../../../../../java/util/ArrayList'
  9. import List from '../../../../../java/util/List'
  10. export default class CascadedPolygonUnion {
  11. constructor() {
  12. CascadedPolygonUnion.constructor_.apply(this, arguments)
  13. }
  14. static constructor_() {
  15. this._inputPolys = null
  16. this._geomFactory = null
  17. const polys = arguments[0]
  18. this._inputPolys = polys
  19. if (this._inputPolys === null) this._inputPolys = new ArrayList()
  20. }
  21. static restrictToPolygons(g) {
  22. if (hasInterface(g, Polygonal))
  23. return g
  24. const polygons = PolygonExtracter.getPolygons(g)
  25. if (polygons.size() === 1) return polygons.get(0)
  26. return g.getFactory().createMultiPolygon(GeometryFactory.toPolygonArray(polygons))
  27. }
  28. static getGeometry(list, index) {
  29. if (index >= list.size()) return null
  30. return list.get(index)
  31. }
  32. static union(polys) {
  33. const op = new CascadedPolygonUnion(polys)
  34. return op.union()
  35. }
  36. reduceToGeometries(geomTree) {
  37. const geoms = new ArrayList()
  38. for (let i = geomTree.iterator(); i.hasNext(); ) {
  39. const o = i.next()
  40. let geom = null
  41. if (hasInterface(o, List))
  42. geom = this.unionTree(o)
  43. else if (o instanceof Geometry)
  44. geom = o
  45. geoms.add(geom)
  46. }
  47. return geoms
  48. }
  49. union() {
  50. if (this._inputPolys === null) throw new IllegalStateException('union() method cannot be called twice')
  51. if (this._inputPolys.isEmpty()) return null
  52. this._geomFactory = this._inputPolys.iterator().next().getFactory()
  53. const index = new STRtree(CascadedPolygonUnion.STRTREE_NODE_CAPACITY)
  54. for (let i = this._inputPolys.iterator(); i.hasNext(); ) {
  55. const item = i.next()
  56. index.insert(item.getEnvelopeInternal(), item)
  57. }
  58. this._inputPolys = null
  59. const itemTree = index.itemsTree()
  60. const unionAll = this.unionTree(itemTree)
  61. return unionAll
  62. }
  63. binaryUnion() {
  64. if (arguments.length === 1) {
  65. const geoms = arguments[0]
  66. return this.binaryUnion(geoms, 0, geoms.size())
  67. } else if (arguments.length === 3) {
  68. const geoms = arguments[0], start = arguments[1], end = arguments[2]
  69. if (end - start <= 1) {
  70. const g0 = CascadedPolygonUnion.getGeometry(geoms, start)
  71. return this.unionSafe(g0, null)
  72. } else if (end - start === 2) {
  73. return this.unionSafe(CascadedPolygonUnion.getGeometry(geoms, start), CascadedPolygonUnion.getGeometry(geoms, start + 1))
  74. } else {
  75. const mid = Math.trunc((end + start) / 2)
  76. const g0 = this.binaryUnion(geoms, start, mid)
  77. const g1 = this.binaryUnion(geoms, mid, end)
  78. return this.unionSafe(g0, g1)
  79. }
  80. }
  81. }
  82. repeatedUnion(geoms) {
  83. let union = null
  84. for (let i = geoms.iterator(); i.hasNext(); ) {
  85. const g = i.next()
  86. if (union === null) union = g.copy(); else union = union.union(g)
  87. }
  88. return union
  89. }
  90. unionSafe(g0, g1) {
  91. if (g0 === null && g1 === null) return null
  92. if (g0 === null) return g1.copy()
  93. if (g1 === null) return g0.copy()
  94. return this.unionActual(g0, g1)
  95. }
  96. unionActual(g0, g1) {
  97. const union = OverlapUnion.union(g0, g1)
  98. return CascadedPolygonUnion.restrictToPolygons(union)
  99. }
  100. unionTree(geomTree) {
  101. const geoms = this.reduceToGeometries(geomTree)
  102. const union = this.binaryUnion(geoms)
  103. return union
  104. }
  105. bufferUnion() {
  106. if (arguments.length === 1) {
  107. const geoms = arguments[0]
  108. const factory = geoms.get(0).getFactory()
  109. const gColl = factory.buildGeometry(geoms)
  110. const unionAll = gColl.buffer(0.0)
  111. return unionAll
  112. } else if (arguments.length === 2) {
  113. const g0 = arguments[0], g1 = arguments[1]
  114. const factory = g0.getFactory()
  115. const gColl = factory.createGeometryCollection([g0, g1])
  116. const unionAll = gColl.buffer(0.0)
  117. return unionAll
  118. }
  119. }
  120. }
  121. CascadedPolygonUnion.STRTREE_NODE_CAPACITY = 4