LineString.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. import Geometry from './Geometry'
  2. import CoordinateFilter from './CoordinateFilter'
  3. import hasInterface from '../../../../hasInterface'
  4. import Length from '../algorithm/Length'
  5. import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
  6. import Lineal from './Lineal'
  7. import CoordinateSequences from './CoordinateSequences'
  8. import GeometryComponentFilter from './GeometryComponentFilter'
  9. import UnsupportedOperationException from '../../../../java/lang/UnsupportedOperationException'
  10. import Dimension from './Dimension'
  11. import GeometryFilter from './GeometryFilter'
  12. import CoordinateSequenceFilter from './CoordinateSequenceFilter'
  13. import Envelope from './Envelope'
  14. export default class LineString extends Geometry {
  15. constructor() {
  16. super()
  17. LineString.constructor_.apply(this, arguments)
  18. }
  19. static constructor_() {
  20. this._points = null
  21. if (arguments.length === 0) {} else if (arguments.length === 2) {
  22. const points = arguments[0], factory = arguments[1]
  23. Geometry.constructor_.call(this, factory)
  24. this.init(points)
  25. }
  26. }
  27. computeEnvelopeInternal() {
  28. if (this.isEmpty())
  29. return new Envelope()
  30. return this._points.expandEnvelope(new Envelope())
  31. }
  32. isRing() {
  33. return this.isClosed() && this.isSimple()
  34. }
  35. getCoordinates() {
  36. return this._points.toCoordinateArray()
  37. }
  38. copyInternal() {
  39. return new LineString(this._points.copy(), this._factory)
  40. }
  41. equalsExact() {
  42. if (arguments.length === 2 && (typeof arguments[1] === 'number' && arguments[0] instanceof Geometry)) {
  43. const other = arguments[0], tolerance = arguments[1]
  44. if (!this.isEquivalentClass(other))
  45. return false
  46. const otherLineString = other
  47. if (this._points.size() !== otherLineString._points.size())
  48. return false
  49. for (let i = 0; i < this._points.size(); i++)
  50. if (!this.equal(this._points.getCoordinate(i), otherLineString._points.getCoordinate(i), tolerance))
  51. return false
  52. return true
  53. } else {
  54. return super.equalsExact.apply(this, arguments)
  55. }
  56. }
  57. normalize() {
  58. for (let i = 0; i < Math.trunc(this._points.size() / 2); i++) {
  59. const j = this._points.size() - 1 - i
  60. if (!this._points.getCoordinate(i).equals(this._points.getCoordinate(j))) {
  61. if (this._points.getCoordinate(i).compareTo(this._points.getCoordinate(j)) > 0) {
  62. const copy = this._points.copy()
  63. CoordinateSequences.reverse(copy)
  64. this._points = copy
  65. }
  66. return null
  67. }
  68. }
  69. }
  70. getCoordinate() {
  71. if (this.isEmpty()) return null
  72. return this._points.getCoordinate(0)
  73. }
  74. getBoundaryDimension() {
  75. if (this.isClosed())
  76. return Dimension.FALSE
  77. return 0
  78. }
  79. isClosed() {
  80. if (this.isEmpty())
  81. return false
  82. return this.getCoordinateN(0).equals2D(this.getCoordinateN(this.getNumPoints() - 1))
  83. }
  84. reverseInternal() {
  85. const seq = this._points.copy()
  86. CoordinateSequences.reverse(seq)
  87. return this.getFactory().createLineString(seq)
  88. }
  89. getEndPoint() {
  90. if (this.isEmpty())
  91. return null
  92. return this.getPointN(this.getNumPoints() - 1)
  93. }
  94. getTypeCode() {
  95. return Geometry.TYPECODE_LINESTRING
  96. }
  97. getDimension() {
  98. return 1
  99. }
  100. getLength() {
  101. return Length.ofLine(this._points)
  102. }
  103. getNumPoints() {
  104. return this._points.size()
  105. }
  106. compareToSameClass() {
  107. if (arguments.length === 1) {
  108. const o = arguments[0]
  109. const line = o
  110. let i = 0
  111. let j = 0
  112. while (i < this._points.size() && j < line._points.size()) {
  113. const comparison = this._points.getCoordinate(i).compareTo(line._points.getCoordinate(j))
  114. if (comparison !== 0)
  115. return comparison
  116. i++
  117. j++
  118. }
  119. if (i < this._points.size())
  120. return 1
  121. if (j < line._points.size())
  122. return -1
  123. return 0
  124. } else if (arguments.length === 2) {
  125. const o = arguments[0], comp = arguments[1]
  126. const line = o
  127. return comp.compare(this._points, line._points)
  128. }
  129. }
  130. apply() {
  131. if (hasInterface(arguments[0], CoordinateFilter)) {
  132. const filter = arguments[0]
  133. for (let i = 0; i < this._points.size(); i++)
  134. filter.filter(this._points.getCoordinate(i))
  135. } else if (hasInterface(arguments[0], CoordinateSequenceFilter)) {
  136. const filter = arguments[0]
  137. if (this._points.size() === 0) return null
  138. for (let i = 0; i < this._points.size(); i++) {
  139. filter.filter(this._points, i)
  140. if (filter.isDone()) break
  141. }
  142. if (filter.isGeometryChanged()) this.geometryChanged()
  143. } else if (hasInterface(arguments[0], GeometryFilter)) {
  144. const filter = arguments[0]
  145. filter.filter(this)
  146. } else if (hasInterface(arguments[0], GeometryComponentFilter)) {
  147. const filter = arguments[0]
  148. filter.filter(this)
  149. }
  150. }
  151. getBoundary() {
  152. throw new UnsupportedOperationException()
  153. }
  154. isEquivalentClass(other) {
  155. return other instanceof LineString
  156. }
  157. getCoordinateN(n) {
  158. return this._points.getCoordinate(n)
  159. }
  160. getGeometryType() {
  161. return Geometry.TYPENAME_LINESTRING
  162. }
  163. getCoordinateSequence() {
  164. return this._points
  165. }
  166. isEmpty() {
  167. return this._points.size() === 0
  168. }
  169. init(points) {
  170. if (points === null)
  171. points = this.getFactory().getCoordinateSequenceFactory().create([])
  172. if (points.size() === 1)
  173. throw new IllegalArgumentException('Invalid number of points in LineString (found ' + points.size() + ' - must be 0 or >= 2)')
  174. this._points = points
  175. }
  176. isCoordinate(pt) {
  177. for (let i = 0; i < this._points.size(); i++)
  178. if (this._points.getCoordinate(i).equals(pt))
  179. return true
  180. return false
  181. }
  182. getStartPoint() {
  183. if (this.isEmpty())
  184. return null
  185. return this.getPointN(0)
  186. }
  187. getPointN(n) {
  188. return this.getFactory().createPoint(this._points.getCoordinate(n))
  189. }
  190. get interfaces_() {
  191. return [Lineal]
  192. }
  193. }