| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- import Location from '../geom/Location'
- import Position from './Position'
- import TopologyException from '../geom/TopologyException'
- import EdgeEndStar from './EdgeEndStar'
- import System from '../../../../java/lang/System'
- import Label from './Label'
- import ArrayList from '../../../../java/util/ArrayList'
- import Quadrant from './Quadrant'
- import Assert from '../util/Assert'
- export default class DirectedEdgeStar extends EdgeEndStar {
- constructor() {
- super()
- DirectedEdgeStar.constructor_.apply(this, arguments)
- }
- static constructor_() {
- this._resultAreaEdgeList = null
- this._label = null
- this._SCANNING_FOR_INCOMING = 1
- this._LINKING_TO_OUTGOING = 2
- }
- linkResultDirectedEdges() {
- this.getResultAreaEdges()
- let firstOut = null
- let incoming = null
- let state = this._SCANNING_FOR_INCOMING
- for (let i = 0; i < this._resultAreaEdgeList.size(); i++) {
- const nextOut = this._resultAreaEdgeList.get(i)
- const nextIn = nextOut.getSym()
- if (!nextOut.getLabel().isArea()) continue
- if (firstOut === null && nextOut.isInResult()) firstOut = nextOut
- switch (state) {
- case this._SCANNING_FOR_INCOMING:
- if (!nextIn.isInResult()) continue
- incoming = nextIn
- state = this._LINKING_TO_OUTGOING
- break
- case this._LINKING_TO_OUTGOING:
- if (!nextOut.isInResult()) continue
- incoming.setNext(nextOut)
- state = this._SCANNING_FOR_INCOMING
- break
- }
- }
- if (state === this._LINKING_TO_OUTGOING) {
- if (firstOut === null) throw new TopologyException('no outgoing dirEdge found', this.getCoordinate())
- Assert.isTrue(firstOut.isInResult(), 'unable to link last incoming dirEdge')
- incoming.setNext(firstOut)
- }
- }
- insert(ee) {
- const de = ee
- this.insertEdgeEnd(de, de)
- }
- getRightmostEdge() {
- const edges = this.getEdges()
- const size = edges.size()
- if (size < 1) return null
- const de0 = edges.get(0)
- if (size === 1) return de0
- const deLast = edges.get(size - 1)
- const quad0 = de0.getQuadrant()
- const quad1 = deLast.getQuadrant()
- if (Quadrant.isNorthern(quad0) && Quadrant.isNorthern(quad1)) {
- return de0
- } else if (!Quadrant.isNorthern(quad0) && !Quadrant.isNorthern(quad1)) {
- return deLast
- } else {
- const nonHorizontalEdge = null
- if (de0.getDy() !== 0) return de0; else if (deLast.getDy() !== 0) return deLast
- }
- Assert.shouldNeverReachHere('found two horizontal edges incident on node')
- return null
- }
- print(out) {
- System.out.println('DirectedEdgeStar: ' + this.getCoordinate())
- for (let it = this.iterator(); it.hasNext(); ) {
- const de = it.next()
- out.print('out ')
- de.print(out)
- out.println()
- out.print('in ')
- de.getSym().print(out)
- out.println()
- }
- }
- getResultAreaEdges() {
- if (this._resultAreaEdgeList !== null) return this._resultAreaEdgeList
- this._resultAreaEdgeList = new ArrayList()
- for (let it = this.iterator(); it.hasNext(); ) {
- const de = it.next()
- if (de.isInResult() || de.getSym().isInResult()) this._resultAreaEdgeList.add(de)
- }
- return this._resultAreaEdgeList
- }
- updateLabelling(nodeLabel) {
- for (let it = this.iterator(); it.hasNext(); ) {
- const de = it.next()
- const label = de.getLabel()
- label.setAllLocationsIfNull(0, nodeLabel.getLocation(0))
- label.setAllLocationsIfNull(1, nodeLabel.getLocation(1))
- }
- }
- linkAllDirectedEdges() {
- this.getEdges()
- let prevOut = null
- let firstIn = null
- for (let i = this._edgeList.size() - 1; i >= 0; i--) {
- const nextOut = this._edgeList.get(i)
- const nextIn = nextOut.getSym()
- if (firstIn === null) firstIn = nextIn
- if (prevOut !== null) nextIn.setNext(prevOut)
- prevOut = nextOut
- }
- firstIn.setNext(prevOut)
- }
- computeDepths() {
- if (arguments.length === 1) {
- const de = arguments[0]
- const edgeIndex = this.findIndex(de)
- const startDepth = de.getDepth(Position.LEFT)
- const targetLastDepth = de.getDepth(Position.RIGHT)
- const nextDepth = this.computeDepths(edgeIndex + 1, this._edgeList.size(), startDepth)
- const lastDepth = this.computeDepths(0, edgeIndex, nextDepth)
- if (lastDepth !== targetLastDepth) throw new TopologyException('depth mismatch at ' + de.getCoordinate())
- } else if (arguments.length === 3) {
- const startIndex = arguments[0], endIndex = arguments[1], startDepth = arguments[2]
- let currDepth = startDepth
- for (let i = startIndex; i < endIndex; i++) {
- const nextDe = this._edgeList.get(i)
- nextDe.setEdgeDepths(Position.RIGHT, currDepth)
- currDepth = nextDe.getDepth(Position.LEFT)
- }
- return currDepth
- }
- }
- mergeSymLabels() {
- for (let it = this.iterator(); it.hasNext(); ) {
- const de = it.next()
- const label = de.getLabel()
- label.merge(de.getSym().getLabel())
- }
- }
- linkMinimalDirectedEdges(er) {
- let firstOut = null
- let incoming = null
- let state = this._SCANNING_FOR_INCOMING
- for (let i = this._resultAreaEdgeList.size() - 1; i >= 0; i--) {
- const nextOut = this._resultAreaEdgeList.get(i)
- const nextIn = nextOut.getSym()
- if (firstOut === null && nextOut.getEdgeRing() === er) firstOut = nextOut
- switch (state) {
- case this._SCANNING_FOR_INCOMING:
- if (nextIn.getEdgeRing() !== er) continue
- incoming = nextIn
- state = this._LINKING_TO_OUTGOING
- break
- case this._LINKING_TO_OUTGOING:
- if (nextOut.getEdgeRing() !== er) continue
- incoming.setNextMin(nextOut)
- state = this._SCANNING_FOR_INCOMING
- break
- }
- }
- if (state === this._LINKING_TO_OUTGOING) {
- Assert.isTrue(firstOut !== null, 'found null for first outgoing dirEdge')
- Assert.isTrue(firstOut.getEdgeRing() === er, 'unable to link last incoming dirEdge')
- incoming.setNextMin(firstOut)
- }
- }
- getOutgoingDegree() {
- if (arguments.length === 0) {
- let degree = 0
- for (let it = this.iterator(); it.hasNext(); ) {
- const de = it.next()
- if (de.isInResult()) degree++
- }
- return degree
- } else if (arguments.length === 1) {
- const er = arguments[0]
- let degree = 0
- for (let it = this.iterator(); it.hasNext(); ) {
- const de = it.next()
- if (de.getEdgeRing() === er) degree++
- }
- return degree
- }
- }
- getLabel() {
- return this._label
- }
- findCoveredLineEdges() {
- let startLoc = Location.NONE
- for (let it = this.iterator(); it.hasNext(); ) {
- const nextOut = it.next()
- const nextIn = nextOut.getSym()
- if (!nextOut.isLineEdge()) {
- if (nextOut.isInResult()) {
- startLoc = Location.INTERIOR
- break
- }
- if (nextIn.isInResult()) {
- startLoc = Location.EXTERIOR
- break
- }
- }
- }
- if (startLoc === Location.NONE) return null
- let currLoc = startLoc
- for (let it = this.iterator(); it.hasNext(); ) {
- const nextOut = it.next()
- const nextIn = nextOut.getSym()
- if (nextOut.isLineEdge()) {
- nextOut.getEdge().setCovered(currLoc === Location.INTERIOR)
- } else {
- if (nextOut.isInResult()) currLoc = Location.EXTERIOR
- if (nextIn.isInResult()) currLoc = Location.INTERIOR
- }
- }
- }
- computeLabelling(geom) {
- super.computeLabelling.call(this, geom)
- this._label = new Label(Location.NONE)
- for (let it = this.iterator(); it.hasNext(); ) {
- const ee = it.next()
- const e = ee.getEdge()
- const eLabel = e.getLabel()
- for (let i = 0; i < 2; i++) {
- const eLoc = eLabel.getLocation(i)
- if (eLoc === Location.INTERIOR || eLoc === Location.BOUNDARY) this._label.setLocation(i, Location.INTERIOR)
- }
- }
- }
- }
|