LineMerger.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import LineString from '../../geom/LineString'
  2. import Geometry from '../../geom/Geometry'
  3. import hasInterface from '../../../../../hasInterface'
  4. import Collection from '../../../../../java/util/Collection'
  5. import EdgeString from './EdgeString'
  6. import LineMergeGraph from './LineMergeGraph'
  7. import ArrayList from '../../../../../java/util/ArrayList'
  8. import Assert from '../../util/Assert'
  9. import GraphComponent from '../../planargraph/GraphComponent'
  10. export default class LineMerger {
  11. constructor() {
  12. LineMerger.constructor_.apply(this, arguments)
  13. }
  14. static constructor_() {
  15. this._graph = new LineMergeGraph()
  16. this._mergedLineStrings = null
  17. this._factory = null
  18. this._edgeStrings = null
  19. }
  20. buildEdgeStringsForUnprocessedNodes() {
  21. for (let i = this._graph.getNodes().iterator(); i.hasNext(); ) {
  22. const node = i.next()
  23. if (!node.isMarked()) {
  24. Assert.isTrue(node.getDegree() === 2)
  25. this.buildEdgeStringsStartingAt(node)
  26. node.setMarked(true)
  27. }
  28. }
  29. }
  30. buildEdgeStringsForNonDegree2Nodes() {
  31. for (let i = this._graph.getNodes().iterator(); i.hasNext(); ) {
  32. const node = i.next()
  33. if (node.getDegree() !== 2) {
  34. this.buildEdgeStringsStartingAt(node)
  35. node.setMarked(true)
  36. }
  37. }
  38. }
  39. buildEdgeStringsForObviousStartNodes() {
  40. this.buildEdgeStringsForNonDegree2Nodes()
  41. }
  42. getMergedLineStrings() {
  43. this.merge()
  44. return this._mergedLineStrings
  45. }
  46. buildEdgeStringsStartingAt(node) {
  47. for (let i = node.getOutEdges().iterator(); i.hasNext(); ) {
  48. const directedEdge = i.next()
  49. if (directedEdge.getEdge().isMarked())
  50. continue
  51. this._edgeStrings.add(this.buildEdgeStringStartingWith(directedEdge))
  52. }
  53. }
  54. merge() {
  55. if (this._mergedLineStrings !== null)
  56. return null
  57. GraphComponent.setMarked(this._graph.nodeIterator(), false)
  58. GraphComponent.setMarked(this._graph.edgeIterator(), false)
  59. this._edgeStrings = new ArrayList()
  60. this.buildEdgeStringsForObviousStartNodes()
  61. this.buildEdgeStringsForIsolatedLoops()
  62. this._mergedLineStrings = new ArrayList()
  63. for (let i = this._edgeStrings.iterator(); i.hasNext(); ) {
  64. const edgeString = i.next()
  65. this._mergedLineStrings.add(edgeString.toLineString())
  66. }
  67. }
  68. addLineString(lineString) {
  69. if (this._factory === null)
  70. this._factory = lineString.getFactory()
  71. this._graph.addEdge(lineString)
  72. }
  73. buildEdgeStringStartingWith(start) {
  74. const edgeString = new EdgeString(this._factory)
  75. let current = start
  76. do {
  77. edgeString.add(current)
  78. current.getEdge().setMarked(true)
  79. current = current.getNext()
  80. } while (current !== null && current !== start)
  81. return edgeString
  82. }
  83. add() {
  84. if (arguments[0] instanceof Geometry) {
  85. const geometry = arguments[0]
  86. for (let i = 0; i < geometry.getNumGeometries(); i++) {
  87. const component = geometry.getGeometryN(i)
  88. if (component instanceof LineString)
  89. this.addLineString(component)
  90. }
  91. } else if (hasInterface(arguments[0], Collection)) {
  92. const geometries = arguments[0]
  93. this._mergedLineStrings = null
  94. for (let i = geometries.iterator(); i.hasNext(); ) {
  95. const geometry = i.next()
  96. this.add(geometry)
  97. }
  98. }
  99. }
  100. buildEdgeStringsForIsolatedLoops() {
  101. this.buildEdgeStringsForUnprocessedNodes()
  102. }
  103. }