Edge.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import EdgeIntersectionList from './EdgeIntersectionList'
  2. import IntersectionMatrix from '../geom/IntersectionMatrix'
  3. import MonotoneChainEdge from './index/MonotoneChainEdge'
  4. import Position from './Position'
  5. import Coordinate from '../geom/Coordinate'
  6. import Label from './Label'
  7. import Envelope from '../geom/Envelope'
  8. import StringBuilder from '../../../../java/lang/StringBuilder'
  9. import Depth from './Depth'
  10. import GraphComponent from './GraphComponent'
  11. export default class Edge extends GraphComponent {
  12. constructor() {
  13. super()
  14. Edge.constructor_.apply(this, arguments)
  15. }
  16. static constructor_() {
  17. this.pts = null
  18. this._env = null
  19. this.eiList = new EdgeIntersectionList(this)
  20. this._name = null
  21. this._mce = null
  22. this._isIsolated = true
  23. this._depth = new Depth()
  24. this._depthDelta = 0
  25. if (arguments.length === 1) {
  26. const pts = arguments[0]
  27. Edge.constructor_.call(this, pts, null)
  28. } else if (arguments.length === 2) {
  29. const pts = arguments[0], label = arguments[1]
  30. this.pts = pts
  31. this._label = label
  32. }
  33. }
  34. static updateIM() {
  35. if (arguments.length === 2 && (arguments[1] instanceof IntersectionMatrix && arguments[0] instanceof Label)) {
  36. const label = arguments[0], im = arguments[1]
  37. im.setAtLeastIfValid(label.getLocation(0, Position.ON), label.getLocation(1, Position.ON), 1)
  38. if (label.isArea()) {
  39. im.setAtLeastIfValid(label.getLocation(0, Position.LEFT), label.getLocation(1, Position.LEFT), 2)
  40. im.setAtLeastIfValid(label.getLocation(0, Position.RIGHT), label.getLocation(1, Position.RIGHT), 2)
  41. }
  42. } else {
  43. return super.updateIM.apply(this, arguments)
  44. }
  45. }
  46. getDepth() {
  47. return this._depth
  48. }
  49. getCollapsedEdge() {
  50. const newPts = new Array(2).fill(null)
  51. newPts[0] = this.pts[0]
  52. newPts[1] = this.pts[1]
  53. const newe = new Edge(newPts, Label.toLineLabel(this._label))
  54. return newe
  55. }
  56. isIsolated() {
  57. return this._isIsolated
  58. }
  59. getCoordinates() {
  60. return this.pts
  61. }
  62. setIsolated(isIsolated) {
  63. this._isIsolated = isIsolated
  64. }
  65. setName(name) {
  66. this._name = name
  67. }
  68. equals(o) {
  69. if (!(o instanceof Edge)) return false
  70. const e = o
  71. if (this.pts.length !== e.pts.length) return false
  72. let isEqualForward = true
  73. let isEqualReverse = true
  74. let iRev = this.pts.length
  75. for (let i = 0; i < this.pts.length; i++) {
  76. if (!this.pts[i].equals2D(e.pts[i]))
  77. isEqualForward = false
  78. if (!this.pts[i].equals2D(e.pts[-- iRev]))
  79. isEqualReverse = false
  80. if (!isEqualForward && !isEqualReverse) return false
  81. }
  82. return true
  83. }
  84. getCoordinate() {
  85. if (arguments.length === 0) {
  86. if (this.pts.length > 0) return this.pts[0]
  87. return null
  88. } else if (arguments.length === 1) {
  89. const i = arguments[0]
  90. return this.pts[i]
  91. }
  92. }
  93. print(out) {
  94. out.print('edge ' + this._name + ': ')
  95. out.print('LINESTRING (')
  96. for (let i = 0; i < this.pts.length; i++) {
  97. if (i > 0) out.print(',')
  98. out.print(this.pts[i].x + ' ' + this.pts[i].y)
  99. }
  100. out.print(') ' + this._label + ' ' + this._depthDelta)
  101. }
  102. computeIM(im) {
  103. Edge.updateIM(this._label, im)
  104. }
  105. isCollapsed() {
  106. if (!this._label.isArea()) return false
  107. if (this.pts.length !== 3) return false
  108. if (this.pts[0].equals(this.pts[2])) return true
  109. return false
  110. }
  111. isClosed() {
  112. return this.pts[0].equals(this.pts[this.pts.length - 1])
  113. }
  114. getMaximumSegmentIndex() {
  115. return this.pts.length - 1
  116. }
  117. getDepthDelta() {
  118. return this._depthDelta
  119. }
  120. getNumPoints() {
  121. return this.pts.length
  122. }
  123. printReverse(out) {
  124. out.print('edge ' + this._name + ': ')
  125. for (let i = this.pts.length - 1; i >= 0; i--)
  126. out.print(this.pts[i] + ' ')
  127. out.println('')
  128. }
  129. getMonotoneChainEdge() {
  130. if (this._mce === null) this._mce = new MonotoneChainEdge(this)
  131. return this._mce
  132. }
  133. getEnvelope() {
  134. if (this._env === null) {
  135. this._env = new Envelope()
  136. for (let i = 0; i < this.pts.length; i++)
  137. this._env.expandToInclude(this.pts[i])
  138. }
  139. return this._env
  140. }
  141. addIntersection(li, segmentIndex, geomIndex, intIndex) {
  142. const intPt = new Coordinate(li.getIntersection(intIndex))
  143. let normalizedSegmentIndex = segmentIndex
  144. let dist = li.getEdgeDistance(geomIndex, intIndex)
  145. const nextSegIndex = normalizedSegmentIndex + 1
  146. if (nextSegIndex < this.pts.length) {
  147. const nextPt = this.pts[nextSegIndex]
  148. if (intPt.equals2D(nextPt)) {
  149. normalizedSegmentIndex = nextSegIndex
  150. dist = 0.0
  151. }
  152. }
  153. const ei = this.eiList.add(intPt, normalizedSegmentIndex, dist)
  154. }
  155. toString() {
  156. const builder = new StringBuilder()
  157. builder.append('edge ' + this._name + ': ')
  158. builder.append('LINESTRING (')
  159. for (let i = 0; i < this.pts.length; i++) {
  160. if (i > 0) builder.append(',')
  161. builder.append(this.pts[i].x + ' ' + this.pts[i].y)
  162. }
  163. builder.append(') ' + this._label + ' ' + this._depthDelta)
  164. return builder.toString()
  165. }
  166. isPointwiseEqual(e) {
  167. if (this.pts.length !== e.pts.length) return false
  168. for (let i = 0; i < this.pts.length; i++)
  169. if (!this.pts[i].equals2D(e.pts[i]))
  170. return false
  171. return true
  172. }
  173. setDepthDelta(depthDelta) {
  174. this._depthDelta = depthDelta
  175. }
  176. getEdgeIntersectionList() {
  177. return this.eiList
  178. }
  179. addIntersections(li, segmentIndex, geomIndex) {
  180. for (let i = 0; i < li.getIntersectionNum(); i++)
  181. this.addIntersection(li, segmentIndex, geomIndex, i)
  182. }
  183. }