FacetSequence.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. import StringBuffer from '../../../../../java/lang/StringBuffer'
  2. import Coordinate from '../../geom/Coordinate'
  3. import GeometryLocation from './GeometryLocation'
  4. import Double from '../../../../../java/lang/Double'
  5. import LineSegment from '../../geom/LineSegment'
  6. import Envelope from '../../geom/Envelope'
  7. import Distance from '../../algorithm/Distance'
  8. export default class FacetSequence {
  9. constructor() {
  10. FacetSequence.constructor_.apply(this, arguments)
  11. }
  12. static constructor_() {
  13. this._geom = null
  14. this._pts = null
  15. this._start = null
  16. this._end = null
  17. if (arguments.length === 2) {
  18. const pts = arguments[0], start = arguments[1]
  19. this._pts = pts
  20. this._start = start
  21. this._end = start + 1
  22. } else if (arguments.length === 3) {
  23. const pts = arguments[0], start = arguments[1], end = arguments[2]
  24. this._pts = pts
  25. this._start = start
  26. this._end = end
  27. } else if (arguments.length === 4) {
  28. const geom = arguments[0], pts = arguments[1], start = arguments[2], end = arguments[3]
  29. this._geom = geom
  30. this._pts = pts
  31. this._start = start
  32. this._end = end
  33. }
  34. }
  35. computeDistanceLineLine(facetSeq, locs) {
  36. let minDistance = Double.MAX_VALUE
  37. for (let i = this._start; i < this._end - 1; i++) {
  38. const p0 = this._pts.getCoordinate(i)
  39. const p1 = this._pts.getCoordinate(i + 1)
  40. for (let j = facetSeq._start; j < facetSeq._end - 1; j++) {
  41. const q0 = facetSeq._pts.getCoordinate(j)
  42. const q1 = facetSeq._pts.getCoordinate(j + 1)
  43. const dist = Distance.segmentToSegment(p0, p1, q0, q1)
  44. if (dist < minDistance) {
  45. minDistance = dist
  46. if (locs !== null) this.updateNearestLocationsLineLine(i, p0, p1, facetSeq, j, q0, q1, locs)
  47. if (minDistance <= 0.0) return minDistance
  48. }
  49. }
  50. }
  51. return minDistance
  52. }
  53. updateNearestLocationsPointLine(pt, facetSeq, i, q0, q1, locs) {
  54. locs[0] = new GeometryLocation(this._geom, this._start, new Coordinate(pt))
  55. const seg = new LineSegment(q0, q1)
  56. const segClosestPoint = seg.closestPoint(pt)
  57. locs[1] = new GeometryLocation(facetSeq._geom, i, new Coordinate(segClosestPoint))
  58. }
  59. size() {
  60. return this._end - this._start
  61. }
  62. getCoordinate(index) {
  63. return this._pts.getCoordinate(this._start + index)
  64. }
  65. nearestLocations(facetSeq) {
  66. const isPoint = this.isPoint()
  67. const isPointOther = facetSeq.isPoint()
  68. const locs = new Array(2).fill(null)
  69. if (isPoint && isPointOther) {
  70. const pt = this._pts.getCoordinate(this._start)
  71. const seqPt = facetSeq._pts.getCoordinate(facetSeq._start)
  72. locs[0] = new GeometryLocation(this._geom, this._start, new Coordinate(pt))
  73. locs[1] = new GeometryLocation(facetSeq._geom, facetSeq._start, new Coordinate(seqPt))
  74. } else if (isPoint) {
  75. const pt = this._pts.getCoordinate(this._start)
  76. this.computeDistancePointLine(pt, facetSeq, locs)
  77. } else if (isPointOther) {
  78. const seqPt = facetSeq._pts.getCoordinate(facetSeq._start)
  79. this.computeDistancePointLine(seqPt, this, locs)
  80. const tmp = locs[0]
  81. locs[0] = locs[1]
  82. locs[1] = tmp
  83. } else {
  84. this.computeDistanceLineLine(facetSeq, locs)
  85. }
  86. return locs
  87. }
  88. getEnvelope() {
  89. const env = new Envelope()
  90. for (let i = this._start; i < this._end; i++)
  91. env.expandToInclude(this._pts.getX(i), this._pts.getY(i))
  92. return env
  93. }
  94. updateNearestLocationsLineLine(i, p0, p1, facetSeq, j, q0, q1, locs) {
  95. const seg0 = new LineSegment(p0, p1)
  96. const seg1 = new LineSegment(q0, q1)
  97. const closestPt = seg0.closestPoints(seg1)
  98. locs[0] = new GeometryLocation(this._geom, i, new Coordinate(closestPt[0]))
  99. locs[1] = new GeometryLocation(facetSeq._geom, j, new Coordinate(closestPt[1]))
  100. }
  101. toString() {
  102. const buf = new StringBuffer()
  103. buf.append('LINESTRING ( ')
  104. const p = new Coordinate()
  105. for (let i = this._start; i < this._end; i++) {
  106. if (i > this._start) buf.append(', ')
  107. this._pts.getCoordinate(i, p)
  108. buf.append(p.x + ' ' + p.y)
  109. }
  110. buf.append(' )')
  111. return buf.toString()
  112. }
  113. computeDistancePointLine(pt, facetSeq, locs) {
  114. let minDistance = Double.MAX_VALUE
  115. for (let i = facetSeq._start; i < facetSeq._end - 1; i++) {
  116. const q0 = facetSeq._pts.getCoordinate(i)
  117. const q1 = facetSeq._pts.getCoordinate(i + 1)
  118. const dist = Distance.pointToSegment(pt, q0, q1)
  119. if (dist < minDistance) {
  120. minDistance = dist
  121. if (locs !== null) this.updateNearestLocationsPointLine(pt, facetSeq, i, q0, q1, locs)
  122. if (minDistance <= 0.0) return minDistance
  123. }
  124. }
  125. return minDistance
  126. }
  127. isPoint() {
  128. return this._end - this._start === 1
  129. }
  130. distance(facetSeq) {
  131. const isPoint = this.isPoint()
  132. const isPointOther = facetSeq.isPoint()
  133. let distance = null
  134. if (isPoint && isPointOther) {
  135. const pt = this._pts.getCoordinate(this._start)
  136. const seqPt = facetSeq._pts.getCoordinate(facetSeq._start)
  137. distance = pt.distance(seqPt)
  138. } else if (isPoint) {
  139. const pt = this._pts.getCoordinate(this._start)
  140. distance = this.computeDistancePointLine(pt, facetSeq, null)
  141. } else if (isPointOther) {
  142. const seqPt = facetSeq._pts.getCoordinate(facetSeq._start)
  143. distance = this.computeDistancePointLine(seqPt, this, null)
  144. } else {
  145. distance = this.computeDistanceLineLine(facetSeq, null)
  146. }
  147. return distance
  148. }
  149. }