LengthLocationMap.js 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import LinearIterator from './LinearIterator'
  2. import LinearLocation from './LinearLocation'
  3. export default class LengthLocationMap {
  4. constructor() {
  5. LengthLocationMap.constructor_.apply(this, arguments)
  6. }
  7. static constructor_() {
  8. this._linearGeom = null
  9. const linearGeom = arguments[0]
  10. this._linearGeom = linearGeom
  11. }
  12. static getLength(linearGeom, loc) {
  13. const locater = new LengthLocationMap(linearGeom)
  14. return locater.getLength(loc)
  15. }
  16. static getLocation() {
  17. if (arguments.length === 2) {
  18. const linearGeom = arguments[0], length = arguments[1]
  19. const locater = new LengthLocationMap(linearGeom)
  20. return locater.getLocation(length)
  21. } else if (arguments.length === 3) {
  22. const linearGeom = arguments[0], length = arguments[1], resolveLower = arguments[2]
  23. const locater = new LengthLocationMap(linearGeom)
  24. return locater.getLocation(length, resolveLower)
  25. }
  26. }
  27. getLength(loc) {
  28. let totalLength = 0.0
  29. const it = new LinearIterator(this._linearGeom)
  30. while (it.hasNext()) {
  31. if (!it.isEndOfLine()) {
  32. const p0 = it.getSegmentStart()
  33. const p1 = it.getSegmentEnd()
  34. const segLen = p1.distance(p0)
  35. if (loc.getComponentIndex() === it.getComponentIndex() && loc.getSegmentIndex() === it.getVertexIndex())
  36. return totalLength + segLen * loc.getSegmentFraction()
  37. totalLength += segLen
  38. }
  39. it.next()
  40. }
  41. return totalLength
  42. }
  43. resolveHigher(loc) {
  44. if (!loc.isEndpoint(this._linearGeom)) return loc
  45. let compIndex = loc.getComponentIndex()
  46. if (compIndex >= this._linearGeom.getNumGeometries() - 1) return loc
  47. do
  48. compIndex++
  49. while (compIndex < this._linearGeom.getNumGeometries() - 1 && this._linearGeom.getGeometryN(compIndex).getLength() === 0)
  50. return new LinearLocation(compIndex, 0, 0.0)
  51. }
  52. getLocation() {
  53. if (arguments.length === 1) {
  54. const length = arguments[0]
  55. return this.getLocation(length, true)
  56. } else if (arguments.length === 2) {
  57. const length = arguments[0], resolveLower = arguments[1]
  58. let forwardLength = length
  59. if (length < 0.0) {
  60. const lineLen = this._linearGeom.getLength()
  61. forwardLength = lineLen + length
  62. }
  63. const loc = this.getLocationForward(forwardLength)
  64. if (resolveLower)
  65. return loc
  66. return this.resolveHigher(loc)
  67. }
  68. }
  69. getLocationForward(length) {
  70. if (length <= 0.0) return new LinearLocation()
  71. let totalLength = 0.0
  72. const it = new LinearIterator(this._linearGeom)
  73. while (it.hasNext()) {
  74. if (it.isEndOfLine()) {
  75. if (totalLength === length) {
  76. const compIndex = it.getComponentIndex()
  77. const segIndex = it.getVertexIndex()
  78. return new LinearLocation(compIndex, segIndex, 0.0)
  79. }
  80. } else {
  81. const p0 = it.getSegmentStart()
  82. const p1 = it.getSegmentEnd()
  83. const segLen = p1.distance(p0)
  84. if (totalLength + segLen > length) {
  85. const frac = (length - totalLength) / segLen
  86. const compIndex = it.getComponentIndex()
  87. const segIndex = it.getVertexIndex()
  88. return new LinearLocation(compIndex, segIndex, frac)
  89. }
  90. totalLength += segLen
  91. }
  92. it.next()
  93. }
  94. return LinearLocation.getEndLocation(this._linearGeom)
  95. }
  96. }