RectangleIntersects.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import Coordinate from '../../geom/Coordinate'
  2. import Polygon from '../../geom/Polygon'
  3. import RectangleLineIntersector from '../../algorithm/RectangleLineIntersector'
  4. import ShortCircuitedGeometryVisitor from '../../geom/util/ShortCircuitedGeometryVisitor'
  5. import SimplePointInAreaLocator from '../../algorithm/locate/SimplePointInAreaLocator'
  6. import LinearComponentExtracter from '../../geom/util/LinearComponentExtracter'
  7. export default class RectangleIntersects {
  8. constructor() {
  9. RectangleIntersects.constructor_.apply(this, arguments)
  10. }
  11. static constructor_() {
  12. this._rectangle = null
  13. this._rectEnv = null
  14. const rectangle = arguments[0]
  15. this._rectangle = rectangle
  16. this._rectEnv = rectangle.getEnvelopeInternal()
  17. }
  18. static intersects(rectangle, b) {
  19. const rp = new RectangleIntersects(rectangle)
  20. return rp.intersects(b)
  21. }
  22. intersects(geom) {
  23. if (!this._rectEnv.intersects(geom.getEnvelopeInternal())) return false
  24. const visitor = new EnvelopeIntersectsVisitor(this._rectEnv)
  25. visitor.applyTo(geom)
  26. if (visitor.intersects()) return true
  27. const ecpVisitor = new GeometryContainsPointVisitor(this._rectangle)
  28. ecpVisitor.applyTo(geom)
  29. if (ecpVisitor.containsPoint()) return true
  30. const riVisitor = new RectangleIntersectsSegmentVisitor(this._rectangle)
  31. riVisitor.applyTo(geom)
  32. if (riVisitor.intersects()) return true
  33. return false
  34. }
  35. }
  36. class EnvelopeIntersectsVisitor extends ShortCircuitedGeometryVisitor {
  37. constructor() {
  38. super()
  39. EnvelopeIntersectsVisitor.constructor_.apply(this, arguments)
  40. }
  41. static constructor_() {
  42. this._rectEnv = null
  43. this._intersects = false
  44. const rectEnv = arguments[0]
  45. this._rectEnv = rectEnv
  46. }
  47. isDone() {
  48. return this._intersects === true
  49. }
  50. visit(element) {
  51. const elementEnv = element.getEnvelopeInternal()
  52. if (!this._rectEnv.intersects(elementEnv))
  53. return null
  54. if (this._rectEnv.contains(elementEnv)) {
  55. this._intersects = true
  56. return null
  57. }
  58. if (elementEnv.getMinX() >= this._rectEnv.getMinX() && elementEnv.getMaxX() <= this._rectEnv.getMaxX()) {
  59. this._intersects = true
  60. return null
  61. }
  62. if (elementEnv.getMinY() >= this._rectEnv.getMinY() && elementEnv.getMaxY() <= this._rectEnv.getMaxY()) {
  63. this._intersects = true
  64. return null
  65. }
  66. }
  67. intersects() {
  68. return this._intersects
  69. }
  70. }
  71. class GeometryContainsPointVisitor extends ShortCircuitedGeometryVisitor {
  72. constructor() {
  73. super()
  74. GeometryContainsPointVisitor.constructor_.apply(this, arguments)
  75. }
  76. static constructor_() {
  77. this._rectSeq = null
  78. this._rectEnv = null
  79. this._containsPoint = false
  80. const rectangle = arguments[0]
  81. this._rectSeq = rectangle.getExteriorRing().getCoordinateSequence()
  82. this._rectEnv = rectangle.getEnvelopeInternal()
  83. }
  84. isDone() {
  85. return this._containsPoint === true
  86. }
  87. visit(geom) {
  88. if (!(geom instanceof Polygon)) return null
  89. const elementEnv = geom.getEnvelopeInternal()
  90. if (!this._rectEnv.intersects(elementEnv)) return null
  91. const rectPt = new Coordinate()
  92. for (let i = 0; i < 4; i++) {
  93. this._rectSeq.getCoordinate(i, rectPt)
  94. if (!elementEnv.contains(rectPt)) continue
  95. if (SimplePointInAreaLocator.containsPointInPolygon(rectPt, geom)) {
  96. this._containsPoint = true
  97. return null
  98. }
  99. }
  100. }
  101. containsPoint() {
  102. return this._containsPoint
  103. }
  104. }
  105. class RectangleIntersectsSegmentVisitor extends ShortCircuitedGeometryVisitor {
  106. constructor() {
  107. super()
  108. RectangleIntersectsSegmentVisitor.constructor_.apply(this, arguments)
  109. }
  110. static constructor_() {
  111. this._rectEnv = null
  112. this._rectIntersector = null
  113. this._hasIntersection = false
  114. this._p0 = new Coordinate()
  115. this._p1 = new Coordinate()
  116. const rectangle = arguments[0]
  117. this._rectEnv = rectangle.getEnvelopeInternal()
  118. this._rectIntersector = new RectangleLineIntersector(this._rectEnv)
  119. }
  120. intersects() {
  121. return this._hasIntersection
  122. }
  123. isDone() {
  124. return this._hasIntersection === true
  125. }
  126. visit(geom) {
  127. const elementEnv = geom.getEnvelopeInternal()
  128. if (!this._rectEnv.intersects(elementEnv)) return null
  129. const lines = LinearComponentExtracter.getLines(geom)
  130. this.checkIntersectionWithLineStrings(lines)
  131. }
  132. checkIntersectionWithLineStrings(lines) {
  133. for (let i = lines.iterator(); i.hasNext(); ) {
  134. const testLine = i.next()
  135. this.checkIntersectionWithSegments(testLine)
  136. if (this._hasIntersection) return null
  137. }
  138. }
  139. checkIntersectionWithSegments(testLine) {
  140. const seq1 = testLine.getCoordinateSequence()
  141. for (let j = 1; j < seq1.size(); j++) {
  142. seq1.getCoordinate(j - 1, this._p0)
  143. seq1.getCoordinate(j, this._p1)
  144. if (this._rectIntersector.intersects(this._p0, this._p1)) {
  145. this._hasIntersection = true
  146. return null
  147. }
  148. }
  149. }
  150. }