LineDissolver.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import LineString from '../geom/LineString'
  2. import CoordinateList from '../geom/CoordinateList'
  3. import Geometry from '../geom/Geometry'
  4. import hasInterface from '../../../../hasInterface'
  5. import Collection from '../../../../java/util/Collection'
  6. import Stack from '../../../../java/util/Stack'
  7. import MarkHalfEdge from '../edgegraph/MarkHalfEdge'
  8. import DissolveEdgeGraph from './DissolveEdgeGraph'
  9. import GeometryComponentFilter from '../geom/GeometryComponentFilter'
  10. import ArrayList from '../../../../java/util/ArrayList'
  11. export default class LineDissolver {
  12. constructor() {
  13. LineDissolver.constructor_.apply(this, arguments)
  14. }
  15. static constructor_() {
  16. this._result = null
  17. this._factory = null
  18. this._graph = null
  19. this._lines = new ArrayList()
  20. this._nodeEdgeStack = new Stack()
  21. this._ringStartEdge = null
  22. this._graph = new DissolveEdgeGraph()
  23. }
  24. static dissolve(g) {
  25. const d = new LineDissolver()
  26. d.add(g)
  27. return d.getResult()
  28. }
  29. addLine(line) {
  30. this._lines.add(this._factory.createLineString(line.toCoordinateArray()))
  31. }
  32. updateRingStartEdge(e) {
  33. if (!e.isStart()) {
  34. e = e.sym()
  35. if (!e.isStart()) return null
  36. }
  37. if (this._ringStartEdge === null) {
  38. this._ringStartEdge = e
  39. return null
  40. }
  41. if (e.orig().compareTo(this._ringStartEdge.orig()) < 0)
  42. this._ringStartEdge = e
  43. }
  44. getResult() {
  45. if (this._result === null) this.computeResult()
  46. return this._result
  47. }
  48. process(e) {
  49. let eNode = e.prevNode()
  50. if (eNode === null) eNode = e
  51. this.stackEdges(eNode)
  52. this.buildLines()
  53. }
  54. buildRing(eStartRing) {
  55. const line = new CoordinateList()
  56. let e = eStartRing
  57. line.add(e.orig().copy(), false)
  58. while (e.sym().degree() === 2) {
  59. const eNext = e.next()
  60. if (eNext === eStartRing) break
  61. line.add(eNext.orig().copy(), false)
  62. e = eNext
  63. }
  64. line.add(e.dest().copy(), false)
  65. this.addLine(line)
  66. }
  67. buildLine(eStart) {
  68. const line = new CoordinateList()
  69. let e = eStart
  70. this._ringStartEdge = null
  71. MarkHalfEdge.markBoth(e)
  72. line.add(e.orig().copy(), false)
  73. while (e.sym().degree() === 2) {
  74. this.updateRingStartEdge(e)
  75. const eNext = e.next()
  76. if (eNext === eStart) {
  77. this.buildRing(this._ringStartEdge)
  78. return null
  79. }
  80. line.add(eNext.orig().copy(), false)
  81. e = eNext
  82. MarkHalfEdge.markBoth(e)
  83. }
  84. line.add(e.dest().clone(), false)
  85. this.stackEdges(e.sym())
  86. this.addLine(line)
  87. }
  88. stackEdges(node) {
  89. let e = node
  90. do {
  91. if (!MarkHalfEdge.isMarked(e)) this._nodeEdgeStack.add(e)
  92. e = e.oNext()
  93. } while (e !== node)
  94. }
  95. computeResult() {
  96. const edges = this._graph.getVertexEdges()
  97. for (let i = edges.iterator(); i.hasNext(); ) {
  98. const e = i.next()
  99. if (MarkHalfEdge.isMarked(e)) continue
  100. this.process(e)
  101. }
  102. this._result = this._factory.buildGeometry(this._lines)
  103. }
  104. buildLines() {
  105. while (!this._nodeEdgeStack.empty()) {
  106. const e = this._nodeEdgeStack.pop()
  107. if (MarkHalfEdge.isMarked(e)) continue
  108. this.buildLine(e)
  109. }
  110. }
  111. add() {
  112. if (arguments[0] instanceof Geometry) {
  113. const geometry = arguments[0]
  114. geometry.apply(new (class {
  115. get interfaces_() {
  116. return [GeometryComponentFilter]
  117. }
  118. filter(component) {
  119. if (component instanceof LineString)
  120. this.add(component)
  121. }
  122. })())
  123. } else if (hasInterface(arguments[0], Collection)) {
  124. const geometries = arguments[0]
  125. for (let i = geometries.iterator(); i.hasNext(); ) {
  126. const geometry = i.next()
  127. this.add(geometry)
  128. }
  129. } else if (arguments[0] instanceof LineString) {
  130. const lineString = arguments[0]
  131. if (this._factory === null)
  132. this._factory = lineString.getFactory()
  133. const seq = lineString.getCoordinateSequence()
  134. let doneStart = false
  135. for (let i = 1; i < seq.size(); i++) {
  136. const e = this._graph.addEdge(seq.getCoordinate(i - 1), seq.getCoordinate(i))
  137. if (e === null) continue
  138. if (!doneStart) {
  139. e.setStart()
  140. doneStart = true
  141. }
  142. }
  143. }
  144. }
  145. }