ExtractLineByLocation.js 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import CoordinateList from '../geom/CoordinateList'
  2. import hasInterface from '../../../../hasInterface'
  3. import LinearIterator from './LinearIterator'
  4. import Lineal from '../geom/Lineal'
  5. import Assert from '../util/Assert'
  6. import LinearGeometryBuilder from './LinearGeometryBuilder'
  7. export default class ExtractLineByLocation {
  8. constructor() {
  9. ExtractLineByLocation.constructor_.apply(this, arguments)
  10. }
  11. static constructor_() {
  12. this._line = null
  13. const line = arguments[0]
  14. this._line = line
  15. }
  16. static extract(line, start, end) {
  17. const ls = new ExtractLineByLocation(line)
  18. return ls.extract(start, end)
  19. }
  20. computeLinear(start, end) {
  21. const builder = new LinearGeometryBuilder(this._line.getFactory())
  22. builder.setFixInvalidLines(true)
  23. if (!start.isVertex()) builder.add(start.getCoordinate(this._line))
  24. for (let it = new LinearIterator(this._line, start); it.hasNext(); it.next()) {
  25. if (end.compareLocationValues(it.getComponentIndex(), it.getVertexIndex(), 0.0) < 0) break
  26. const pt = it.getSegmentStart()
  27. builder.add(pt)
  28. if (it.isEndOfLine()) builder.endLine()
  29. }
  30. if (!end.isVertex()) builder.add(end.getCoordinate(this._line))
  31. return builder.getGeometry()
  32. }
  33. computeLine(start, end) {
  34. const coordinates = this._line.getCoordinates()
  35. const newCoordinates = new CoordinateList()
  36. let startSegmentIndex = start.getSegmentIndex()
  37. if (start.getSegmentFraction() > 0.0) startSegmentIndex += 1
  38. let lastSegmentIndex = end.getSegmentIndex()
  39. if (end.getSegmentFraction() === 1.0) lastSegmentIndex += 1
  40. if (lastSegmentIndex >= coordinates.length) lastSegmentIndex = coordinates.length - 1
  41. if (!start.isVertex()) newCoordinates.add(start.getCoordinate(this._line))
  42. for (let i = startSegmentIndex; i <= lastSegmentIndex; i++)
  43. newCoordinates.add(coordinates[i])
  44. if (!end.isVertex()) newCoordinates.add(end.getCoordinate(this._line))
  45. if (newCoordinates.size() <= 0) newCoordinates.add(start.getCoordinate(this._line))
  46. let newCoordinateArray = newCoordinates.toCoordinateArray()
  47. if (newCoordinateArray.length <= 1)
  48. newCoordinateArray = [newCoordinateArray[0], newCoordinateArray[0]]
  49. return this._line.getFactory().createLineString(newCoordinateArray)
  50. }
  51. extract(start, end) {
  52. if (end.compareTo(start) < 0)
  53. return this.reverse(this.computeLinear(end, start))
  54. return this.computeLinear(start, end)
  55. }
  56. reverse(linear) {
  57. if (hasInterface(linear, Lineal)) return linear.reverse()
  58. Assert.shouldNeverReachHere('non-linear geometry encountered')
  59. return null
  60. }
  61. }