LinearLocation.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import Coordinate from '../geom/Coordinate'
  2. import LineSegment from '../geom/LineSegment'
  3. import Comparable from '../../../../java/lang/Comparable'
  4. export default class LinearLocation {
  5. constructor() {
  6. LinearLocation.constructor_.apply(this, arguments)
  7. }
  8. static constructor_() {
  9. this._componentIndex = 0
  10. this._segmentIndex = 0
  11. this._segmentFraction = 0.0
  12. if (arguments.length === 0) {} else if (arguments.length === 1) {
  13. const loc = arguments[0]
  14. this._componentIndex = loc._componentIndex
  15. this._segmentIndex = loc._segmentIndex
  16. this._segmentFraction = loc._segmentFraction
  17. } else if (arguments.length === 2) {
  18. const segmentIndex = arguments[0], segmentFraction = arguments[1]
  19. LinearLocation.constructor_.call(this, 0, segmentIndex, segmentFraction)
  20. } else if (arguments.length === 3) {
  21. const componentIndex = arguments[0], segmentIndex = arguments[1], segmentFraction = arguments[2]
  22. this._componentIndex = componentIndex
  23. this._segmentIndex = segmentIndex
  24. this._segmentFraction = segmentFraction
  25. this.normalize()
  26. } else if (arguments.length === 4) {
  27. const componentIndex = arguments[0], segmentIndex = arguments[1], segmentFraction = arguments[2], doNormalize = arguments[3]
  28. this._componentIndex = componentIndex
  29. this._segmentIndex = segmentIndex
  30. this._segmentFraction = segmentFraction
  31. if (doNormalize) this.normalize()
  32. }
  33. }
  34. static getEndLocation(linear) {
  35. const loc = new LinearLocation()
  36. loc.setToEnd(linear)
  37. return loc
  38. }
  39. static pointAlongSegmentByFraction(p0, p1, frac) {
  40. if (frac <= 0.0) return p0
  41. if (frac >= 1.0) return p1
  42. const x = (p1.x - p0.x) * frac + p0.x
  43. const y = (p1.y - p0.y) * frac + p0.y
  44. const z = (p1.getZ() - p0.getZ()) * frac + p0.getZ()
  45. return new Coordinate(x, y, z)
  46. }
  47. static compareLocationValues(componentIndex0, segmentIndex0, segmentFraction0, componentIndex1, segmentIndex1, segmentFraction1) {
  48. if (componentIndex0 < componentIndex1) return -1
  49. if (componentIndex0 > componentIndex1) return 1
  50. if (segmentIndex0 < segmentIndex1) return -1
  51. if (segmentIndex0 > segmentIndex1) return 1
  52. if (segmentFraction0 < segmentFraction1) return -1
  53. if (segmentFraction0 > segmentFraction1) return 1
  54. return 0
  55. }
  56. static numSegments(line) {
  57. const npts = line.getNumPoints()
  58. if (npts <= 1) return 0
  59. return npts - 1
  60. }
  61. getSegmentIndex() {
  62. return this._segmentIndex
  63. }
  64. getComponentIndex() {
  65. return this._componentIndex
  66. }
  67. isEndpoint(linearGeom) {
  68. const lineComp = linearGeom.getGeometryN(this._componentIndex)
  69. const nseg = LinearLocation.numSegments(lineComp)
  70. return this._segmentIndex >= nseg || this._segmentIndex === nseg - 1 && this._segmentFraction >= 1.0
  71. }
  72. isValid(linearGeom) {
  73. if (this._componentIndex < 0 || this._componentIndex >= linearGeom.getNumGeometries()) return false
  74. const lineComp = linearGeom.getGeometryN(this._componentIndex)
  75. if (this._segmentIndex < 0 || this._segmentIndex > lineComp.getNumPoints()) return false
  76. if (this._segmentIndex === lineComp.getNumPoints() && this._segmentFraction !== 0.0) return false
  77. if (this._segmentFraction < 0.0 || this._segmentFraction > 1.0) return false
  78. return true
  79. }
  80. normalize() {
  81. if (this._segmentFraction < 0.0)
  82. this._segmentFraction = 0.0
  83. if (this._segmentFraction > 1.0)
  84. this._segmentFraction = 1.0
  85. if (this._componentIndex < 0) {
  86. this._componentIndex = 0
  87. this._segmentIndex = 0
  88. this._segmentFraction = 0.0
  89. }
  90. if (this._segmentIndex < 0) {
  91. this._segmentIndex = 0
  92. this._segmentFraction = 0.0
  93. }
  94. if (this._segmentFraction === 1.0) {
  95. this._segmentFraction = 0.0
  96. this._segmentIndex += 1
  97. }
  98. }
  99. toLowest(linearGeom) {
  100. const lineComp = linearGeom.getGeometryN(this._componentIndex)
  101. const nseg = LinearLocation.numSegments(lineComp)
  102. if (this._segmentIndex < nseg) return this
  103. return new LinearLocation(this._componentIndex, nseg - 1, 1.0, false)
  104. }
  105. getCoordinate(linearGeom) {
  106. const lineComp = linearGeom.getGeometryN(this._componentIndex)
  107. const p0 = lineComp.getCoordinateN(this._segmentIndex)
  108. if (this._segmentIndex >= LinearLocation.numSegments(lineComp)) return p0
  109. const p1 = lineComp.getCoordinateN(this._segmentIndex + 1)
  110. return LinearLocation.pointAlongSegmentByFraction(p0, p1, this._segmentFraction)
  111. }
  112. getSegmentFraction() {
  113. return this._segmentFraction
  114. }
  115. getSegment(linearGeom) {
  116. const lineComp = linearGeom.getGeometryN(this._componentIndex)
  117. const p0 = lineComp.getCoordinateN(this._segmentIndex)
  118. if (this._segmentIndex >= LinearLocation.numSegments(lineComp)) {
  119. const prev = lineComp.getCoordinateN(lineComp.getNumPoints() - 2)
  120. return new LineSegment(prev, p0)
  121. }
  122. const p1 = lineComp.getCoordinateN(this._segmentIndex + 1)
  123. return new LineSegment(p0, p1)
  124. }
  125. clamp(linear) {
  126. if (this._componentIndex >= linear.getNumGeometries()) {
  127. this.setToEnd(linear)
  128. return null
  129. }
  130. if (this._segmentIndex >= linear.getNumPoints()) {
  131. const line = linear.getGeometryN(this._componentIndex)
  132. this._segmentIndex = LinearLocation.numSegments(line)
  133. this._segmentFraction = 1.0
  134. }
  135. }
  136. setToEnd(linear) {
  137. this._componentIndex = linear.getNumGeometries() - 1
  138. const lastLine = linear.getGeometryN(this._componentIndex)
  139. this._segmentIndex = LinearLocation.numSegments(lastLine)
  140. this._segmentFraction = 0.0
  141. }
  142. compareTo(o) {
  143. const other = o
  144. if (this._componentIndex < other._componentIndex) return -1
  145. if (this._componentIndex > other._componentIndex) return 1
  146. if (this._segmentIndex < other._segmentIndex) return -1
  147. if (this._segmentIndex > other._segmentIndex) return 1
  148. if (this._segmentFraction < other._segmentFraction) return -1
  149. if (this._segmentFraction > other._segmentFraction) return 1
  150. return 0
  151. }
  152. copy() {
  153. return new LinearLocation(this._componentIndex, this._segmentIndex, this._segmentFraction)
  154. }
  155. toString() {
  156. return 'LinearLoc[' + this._componentIndex + ', ' + this._segmentIndex + ', ' + this._segmentFraction + ']'
  157. }
  158. isOnSameSegment(loc) {
  159. if (this._componentIndex !== loc._componentIndex) return false
  160. if (this._segmentIndex === loc._segmentIndex) return true
  161. if (loc._segmentIndex - this._segmentIndex === 1 && loc._segmentFraction === 0.0) return true
  162. if (this._segmentIndex - loc._segmentIndex === 1 && this._segmentFraction === 0.0) return true
  163. return false
  164. }
  165. snapToVertex(linearGeom, minDistance) {
  166. if (this._segmentFraction <= 0.0 || this._segmentFraction >= 1.0) return null
  167. const segLen = this.getSegmentLength(linearGeom)
  168. const lenToStart = this._segmentFraction * segLen
  169. const lenToEnd = segLen - lenToStart
  170. if (lenToStart <= lenToEnd && lenToStart < minDistance)
  171. this._segmentFraction = 0.0
  172. else if (lenToEnd <= lenToStart && lenToEnd < minDistance)
  173. this._segmentFraction = 1.0
  174. }
  175. compareLocationValues(componentIndex1, segmentIndex1, segmentFraction1) {
  176. if (this._componentIndex < componentIndex1) return -1
  177. if (this._componentIndex > componentIndex1) return 1
  178. if (this._segmentIndex < segmentIndex1) return -1
  179. if (this._segmentIndex > segmentIndex1) return 1
  180. if (this._segmentFraction < segmentFraction1) return -1
  181. if (this._segmentFraction > segmentFraction1) return 1
  182. return 0
  183. }
  184. getSegmentLength(linearGeom) {
  185. const lineComp = linearGeom.getGeometryN(this._componentIndex)
  186. let segIndex = this._segmentIndex
  187. if (this._segmentIndex >= LinearLocation.numSegments(lineComp)) segIndex = lineComp.getNumPoints() - 2
  188. const p0 = lineComp.getCoordinateN(segIndex)
  189. const p1 = lineComp.getCoordinateN(segIndex + 1)
  190. return p0.distance(p1)
  191. }
  192. isVertex() {
  193. return this._segmentFraction <= 0.0 || this._segmentFraction >= 1.0
  194. }
  195. get interfaces_() {
  196. return [Comparable]
  197. }
  198. }