BoundaryOp.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import LineString from '../geom/LineString'
  2. import BoundaryNodeRule from '../algorithm/BoundaryNodeRule'
  3. import CoordinateArrays from '../geom/CoordinateArrays'
  4. import ArrayList from '../../../../java/util/ArrayList'
  5. import TreeMap from '../../../../java/util/TreeMap'
  6. import MultiLineString from '../geom/MultiLineString'
  7. export default class BoundaryOp {
  8. constructor() {
  9. BoundaryOp.constructor_.apply(this, arguments)
  10. }
  11. static constructor_() {
  12. this._geom = null
  13. this._geomFact = null
  14. this._bnRule = null
  15. this._endpointMap = null
  16. if (arguments.length === 1) {
  17. const geom = arguments[0]
  18. BoundaryOp.constructor_.call(this, geom, BoundaryNodeRule.MOD2_BOUNDARY_RULE)
  19. } else if (arguments.length === 2) {
  20. const geom = arguments[0], bnRule = arguments[1]
  21. this._geom = geom
  22. this._geomFact = geom.getFactory()
  23. this._bnRule = bnRule
  24. }
  25. }
  26. static getBoundary() {
  27. if (arguments.length === 1) {
  28. const g = arguments[0]
  29. const bop = new BoundaryOp(g)
  30. return bop.getBoundary()
  31. } else if (arguments.length === 2) {
  32. const g = arguments[0], bnRule = arguments[1]
  33. const bop = new BoundaryOp(g, bnRule)
  34. return bop.getBoundary()
  35. }
  36. }
  37. boundaryMultiLineString(mLine) {
  38. if (this._geom.isEmpty())
  39. return this.getEmptyMultiPoint()
  40. const bdyPts = this.computeBoundaryCoordinates(mLine)
  41. if (bdyPts.length === 1)
  42. return this._geomFact.createPoint(bdyPts[0])
  43. return this._geomFact.createMultiPointFromCoords(bdyPts)
  44. }
  45. getBoundary() {
  46. if (this._geom instanceof LineString) return this.boundaryLineString(this._geom)
  47. if (this._geom instanceof MultiLineString) return this.boundaryMultiLineString(this._geom)
  48. return this._geom.getBoundary()
  49. }
  50. boundaryLineString(line) {
  51. if (this._geom.isEmpty())
  52. return this.getEmptyMultiPoint()
  53. if (line.isClosed()) {
  54. const closedEndpointOnBoundary = this._bnRule.isInBoundary(2)
  55. if (closedEndpointOnBoundary)
  56. return line.getStartPoint()
  57. else
  58. return this._geomFact.createMultiPoint()
  59. }
  60. return this._geomFact.createMultiPoint([line.getStartPoint(), line.getEndPoint()])
  61. }
  62. getEmptyMultiPoint() {
  63. return this._geomFact.createMultiPoint()
  64. }
  65. computeBoundaryCoordinates(mLine) {
  66. const bdyPts = new ArrayList()
  67. this._endpointMap = new TreeMap()
  68. for (let i = 0; i < mLine.getNumGeometries(); i++) {
  69. const line = mLine.getGeometryN(i)
  70. if (line.getNumPoints() === 0) continue
  71. this.addEndpoint(line.getCoordinateN(0))
  72. this.addEndpoint(line.getCoordinateN(line.getNumPoints() - 1))
  73. }
  74. for (let it = this._endpointMap.entrySet().iterator(); it.hasNext(); ) {
  75. const entry = it.next()
  76. const counter = entry.getValue()
  77. const valence = counter.count
  78. if (this._bnRule.isInBoundary(valence))
  79. bdyPts.add(entry.getKey())
  80. }
  81. return CoordinateArrays.toCoordinateArray(bdyPts)
  82. }
  83. addEndpoint(pt) {
  84. let counter = this._endpointMap.get(pt)
  85. if (counter === null) {
  86. counter = new Counter()
  87. this._endpointMap.put(pt, counter)
  88. }
  89. counter.count++
  90. }
  91. }
  92. class Counter {
  93. constructor() {
  94. Counter.constructor_.apply(this, arguments)
  95. }
  96. static constructor_() {
  97. this.count = null
  98. }
  99. }