Densifier.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import LineString from '../geom/LineString'
  2. import CoordinateList from '../geom/CoordinateList'
  3. import GeometryTransformer from '../geom/util/GeometryTransformer'
  4. import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
  5. import MultiPolygon from '../geom/MultiPolygon'
  6. import LineSegment from '../geom/LineSegment'
  7. export default class Densifier {
  8. constructor() {
  9. Densifier.constructor_.apply(this, arguments)
  10. }
  11. static constructor_() {
  12. this._inputGeom = null
  13. this._distanceTolerance = null
  14. const inputGeom = arguments[0]
  15. this._inputGeom = inputGeom
  16. }
  17. static densifyPoints(pts, distanceTolerance, precModel) {
  18. const seg = new LineSegment()
  19. const coordList = new CoordinateList()
  20. for (let i = 0; i < pts.length - 1; i++) {
  21. seg.p0 = pts[i]
  22. seg.p1 = pts[i + 1]
  23. coordList.add(seg.p0, false)
  24. const len = seg.getLength()
  25. const densifiedSegCount = Math.trunc(len / distanceTolerance) + 1
  26. if (densifiedSegCount > 1) {
  27. const densifiedSegLen = len / densifiedSegCount
  28. for (let j = 1; j < densifiedSegCount; j++) {
  29. const segFract = j * densifiedSegLen / len
  30. const p = seg.pointAlong(segFract)
  31. precModel.makePrecise(p)
  32. coordList.add(p, false)
  33. }
  34. }
  35. }
  36. coordList.add(pts[pts.length - 1], false)
  37. return coordList.toCoordinateArray()
  38. }
  39. static densify(geom, distanceTolerance) {
  40. const densifier = new Densifier(geom)
  41. densifier.setDistanceTolerance(distanceTolerance)
  42. return densifier.getResultGeometry()
  43. }
  44. getResultGeometry() {
  45. return new DensifyTransformer(this._distanceTolerance).transform(this._inputGeom)
  46. }
  47. setDistanceTolerance(distanceTolerance) {
  48. if (distanceTolerance <= 0.0) throw new IllegalArgumentException('Tolerance must be positive')
  49. this._distanceTolerance = distanceTolerance
  50. }
  51. }
  52. class DensifyTransformer extends GeometryTransformer {
  53. constructor() {
  54. super()
  55. DensifyTransformer.constructor_.apply(this, arguments)
  56. }
  57. static constructor_() {
  58. this.distanceTolerance = null
  59. const distanceTolerance = arguments[0]
  60. this.distanceTolerance = distanceTolerance
  61. }
  62. transformMultiPolygon(geom, parent) {
  63. const roughGeom = super.transformMultiPolygon.call(this, geom, parent)
  64. return this.createValidArea(roughGeom)
  65. }
  66. transformPolygon(geom, parent) {
  67. const roughGeom = super.transformPolygon.call(this, geom, parent)
  68. if (parent instanceof MultiPolygon)
  69. return roughGeom
  70. return this.createValidArea(roughGeom)
  71. }
  72. transformCoordinates(coords, parent) {
  73. const inputPts = coords.toCoordinateArray()
  74. let newPts = Densifier.densifyPoints(inputPts, this.distanceTolerance, parent.getPrecisionModel())
  75. if (parent instanceof LineString && newPts.length === 1)
  76. newPts = new Array(0).fill(null)
  77. return this._factory.getCoordinateSequenceFactory().create(newPts)
  78. }
  79. createValidArea(roughAreaGeom) {
  80. return roughAreaGeom.buffer(0.0)
  81. }
  82. }
  83. Densifier.DensifyTransformer = DensifyTransformer