LengthIndexOfPoint.js 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import LinearIterator from './LinearIterator'
  2. import Double from '../../../../java/lang/Double'
  3. import LineSegment from '../geom/LineSegment'
  4. import Assert from '../util/Assert'
  5. export default class LengthIndexOfPoint {
  6. constructor() {
  7. LengthIndexOfPoint.constructor_.apply(this, arguments)
  8. }
  9. static constructor_() {
  10. this._linearGeom = null
  11. const linearGeom = arguments[0]
  12. this._linearGeom = linearGeom
  13. }
  14. static indexOf(linearGeom, inputPt) {
  15. const locater = new LengthIndexOfPoint(linearGeom)
  16. return locater.indexOf(inputPt)
  17. }
  18. static indexOfAfter(linearGeom, inputPt, minIndex) {
  19. const locater = new LengthIndexOfPoint(linearGeom)
  20. return locater.indexOfAfter(inputPt, minIndex)
  21. }
  22. indexOf(inputPt) {
  23. return this.indexOfFromStart(inputPt, -1.0)
  24. }
  25. indexOfFromStart(inputPt, minIndex) {
  26. let minDistance = Double.MAX_VALUE
  27. let ptMeasure = minIndex
  28. let segmentStartMeasure = 0.0
  29. const seg = new LineSegment()
  30. const it = new LinearIterator(this._linearGeom)
  31. while (it.hasNext()) {
  32. if (!it.isEndOfLine()) {
  33. seg.p0 = it.getSegmentStart()
  34. seg.p1 = it.getSegmentEnd()
  35. const segDistance = seg.distance(inputPt)
  36. const segMeasureToPt = this.segmentNearestMeasure(seg, inputPt, segmentStartMeasure)
  37. if (segDistance < minDistance && segMeasureToPt > minIndex) {
  38. ptMeasure = segMeasureToPt
  39. minDistance = segDistance
  40. }
  41. segmentStartMeasure += seg.getLength()
  42. }
  43. it.next()
  44. }
  45. return ptMeasure
  46. }
  47. indexOfAfter(inputPt, minIndex) {
  48. if (minIndex < 0.0) return this.indexOf(inputPt)
  49. const endIndex = this._linearGeom.getLength()
  50. if (endIndex < minIndex) return endIndex
  51. const closestAfter = this.indexOfFromStart(inputPt, minIndex)
  52. Assert.isTrue(closestAfter >= minIndex, 'computed index is before specified minimum index')
  53. return closestAfter
  54. }
  55. segmentNearestMeasure(seg, inputPt, segmentStartMeasure) {
  56. const projFactor = seg.projectionFactor(inputPt)
  57. if (projFactor <= 0.0) return segmentStartMeasure
  58. if (projFactor <= 1.0) return segmentStartMeasure + projFactor * seg.getLength()
  59. return segmentStartMeasure + seg.getLength()
  60. }
  61. }