BufferSubgraph.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import HashSet from '../../../../../java/util/HashSet'
  2. import Position from '../../geomgraph/Position'
  3. import Stack from '../../../../../java/util/Stack'
  4. import RightmostEdgeFinder from './RightmostEdgeFinder'
  5. import TopologyException from '../../geom/TopologyException'
  6. import LinkedList from '../../../../../java/util/LinkedList'
  7. import Comparable from '../../../../../java/lang/Comparable'
  8. import ArrayList from '../../../../../java/util/ArrayList'
  9. import Envelope from '../../geom/Envelope'
  10. export default class BufferSubgraph {
  11. constructor() {
  12. BufferSubgraph.constructor_.apply(this, arguments)
  13. }
  14. static constructor_() {
  15. this._finder = null
  16. this._dirEdgeList = new ArrayList()
  17. this._nodes = new ArrayList()
  18. this._rightMostCoord = null
  19. this._env = null
  20. this._finder = new RightmostEdgeFinder()
  21. }
  22. clearVisitedEdges() {
  23. for (let it = this._dirEdgeList.iterator(); it.hasNext(); ) {
  24. const de = it.next()
  25. de.setVisited(false)
  26. }
  27. }
  28. getRightmostCoordinate() {
  29. return this._rightMostCoord
  30. }
  31. computeNodeDepth(n) {
  32. let startEdge = null
  33. for (let i = n.getEdges().iterator(); i.hasNext(); ) {
  34. const de = i.next()
  35. if (de.isVisited() || de.getSym().isVisited()) {
  36. startEdge = de
  37. break
  38. }
  39. }
  40. if (startEdge === null) throw new TopologyException('unable to find edge to compute depths at ' + n.getCoordinate())
  41. n.getEdges().computeDepths(startEdge)
  42. for (let i = n.getEdges().iterator(); i.hasNext(); ) {
  43. const de = i.next()
  44. de.setVisited(true)
  45. this.copySymDepths(de)
  46. }
  47. }
  48. computeDepth(outsideDepth) {
  49. this.clearVisitedEdges()
  50. const de = this._finder.getEdge()
  51. const n = de.getNode()
  52. const label = de.getLabel()
  53. de.setEdgeDepths(Position.RIGHT, outsideDepth)
  54. this.copySymDepths(de)
  55. this.computeDepths(de)
  56. }
  57. create(node) {
  58. this.addReachable(node)
  59. this._finder.findEdge(this._dirEdgeList)
  60. this._rightMostCoord = this._finder.getCoordinate()
  61. }
  62. findResultEdges() {
  63. for (let it = this._dirEdgeList.iterator(); it.hasNext(); ) {
  64. const de = it.next()
  65. if (de.getDepth(Position.RIGHT) >= 1 && de.getDepth(Position.LEFT) <= 0 && !de.isInteriorAreaEdge())
  66. de.setInResult(true)
  67. }
  68. }
  69. computeDepths(startEdge) {
  70. const nodesVisited = new HashSet()
  71. const nodeQueue = new LinkedList()
  72. const startNode = startEdge.getNode()
  73. nodeQueue.addLast(startNode)
  74. nodesVisited.add(startNode)
  75. startEdge.setVisited(true)
  76. while (!nodeQueue.isEmpty()) {
  77. const n = nodeQueue.removeFirst()
  78. nodesVisited.add(n)
  79. this.computeNodeDepth(n)
  80. for (let i = n.getEdges().iterator(); i.hasNext(); ) {
  81. const de = i.next()
  82. const sym = de.getSym()
  83. if (sym.isVisited()) continue
  84. const adjNode = sym.getNode()
  85. if (!nodesVisited.contains(adjNode)) {
  86. nodeQueue.addLast(adjNode)
  87. nodesVisited.add(adjNode)
  88. }
  89. }
  90. }
  91. }
  92. compareTo(o) {
  93. const graph = o
  94. if (this._rightMostCoord.x < graph._rightMostCoord.x)
  95. return -1
  96. if (this._rightMostCoord.x > graph._rightMostCoord.x)
  97. return 1
  98. return 0
  99. }
  100. getEnvelope() {
  101. if (this._env === null) {
  102. const edgeEnv = new Envelope()
  103. for (let it = this._dirEdgeList.iterator(); it.hasNext(); ) {
  104. const dirEdge = it.next()
  105. const pts = dirEdge.getEdge().getCoordinates()
  106. for (let i = 0; i < pts.length - 1; i++)
  107. edgeEnv.expandToInclude(pts[i])
  108. }
  109. this._env = edgeEnv
  110. }
  111. return this._env
  112. }
  113. addReachable(startNode) {
  114. const nodeStack = new Stack()
  115. nodeStack.add(startNode)
  116. while (!nodeStack.empty()) {
  117. const node = nodeStack.pop()
  118. this.add(node, nodeStack)
  119. }
  120. }
  121. copySymDepths(de) {
  122. const sym = de.getSym()
  123. sym.setDepth(Position.LEFT, de.getDepth(Position.RIGHT))
  124. sym.setDepth(Position.RIGHT, de.getDepth(Position.LEFT))
  125. }
  126. add(node, nodeStack) {
  127. node.setVisited(true)
  128. this._nodes.add(node)
  129. for (let i = node.getEdges().iterator(); i.hasNext(); ) {
  130. const de = i.next()
  131. this._dirEdgeList.add(de)
  132. const sym = de.getSym()
  133. const symNode = sym.getNode()
  134. if (!symNode.isVisited()) nodeStack.push(symNode)
  135. }
  136. }
  137. getNodes() {
  138. return this._nodes
  139. }
  140. getDirectedEdges() {
  141. return this._dirEdgeList
  142. }
  143. get interfaces_() {
  144. return [Comparable]
  145. }
  146. }