ConsistentPolygonRingChecker.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import Position from '../../geomgraph/Position'
  2. import TopologyException from '../../geom/TopologyException'
  3. import ArrayList from '../../../../../java/util/ArrayList'
  4. import OverlayOp from './OverlayOp'
  5. export default class ConsistentPolygonRingChecker {
  6. constructor() {
  7. ConsistentPolygonRingChecker.constructor_.apply(this, arguments)
  8. }
  9. static constructor_() {
  10. this._graph = null
  11. this._SCANNING_FOR_INCOMING = 1
  12. this._LINKING_TO_OUTGOING = 2
  13. const graph = arguments[0]
  14. this._graph = graph
  15. }
  16. testLinkResultDirectedEdges(deStar, opCode) {
  17. const ringEdges = this.getPotentialResultAreaEdges(deStar, opCode)
  18. let firstOut = null
  19. let incoming = null
  20. let state = this._SCANNING_FOR_INCOMING
  21. for (let i = 0; i < ringEdges.size(); i++) {
  22. const nextOut = ringEdges.get(i)
  23. const nextIn = nextOut.getSym()
  24. if (!nextOut.getLabel().isArea()) continue
  25. if (firstOut === null && this.isPotentialResultAreaEdge(nextOut, opCode)) firstOut = nextOut
  26. switch (state) {
  27. case this._SCANNING_FOR_INCOMING:
  28. if (!this.isPotentialResultAreaEdge(nextIn, opCode)) continue
  29. incoming = nextIn
  30. state = this._LINKING_TO_OUTGOING
  31. break
  32. case this._LINKING_TO_OUTGOING:
  33. if (!this.isPotentialResultAreaEdge(nextOut, opCode)) continue
  34. state = this._SCANNING_FOR_INCOMING
  35. break
  36. }
  37. }
  38. if (state === this._LINKING_TO_OUTGOING)
  39. if (firstOut === null) throw new TopologyException('no outgoing dirEdge found', deStar.getCoordinate())
  40. }
  41. getPotentialResultAreaEdges(deStar, opCode) {
  42. const resultAreaEdgeList = new ArrayList()
  43. for (let it = deStar.iterator(); it.hasNext(); ) {
  44. const de = it.next()
  45. if (this.isPotentialResultAreaEdge(de, opCode) || this.isPotentialResultAreaEdge(de.getSym(), opCode)) resultAreaEdgeList.add(de)
  46. }
  47. return resultAreaEdgeList
  48. }
  49. checkAll() {
  50. this.check(OverlayOp.INTERSECTION)
  51. this.check(OverlayOp.DIFFERENCE)
  52. this.check(OverlayOp.UNION)
  53. this.check(OverlayOp.SYMDIFFERENCE)
  54. }
  55. check(opCode) {
  56. for (let nodeit = this._graph.getNodeIterator(); nodeit.hasNext(); ) {
  57. const node = nodeit.next()
  58. this.testLinkResultDirectedEdges(node.getEdges(), opCode)
  59. }
  60. }
  61. isPotentialResultAreaEdge(de, opCode) {
  62. const label = de.getLabel()
  63. if (label.isArea() && !de.isInteriorAreaEdge() && OverlayOp.isResultOfOp(label.getLocation(0, Position.RIGHT), label.getLocation(1, Position.RIGHT), opCode))
  64. return true
  65. return false
  66. }
  67. }