| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- import Location from '../geom/Location'
- import Position from './Position'
- import PointLocation from '../algorithm/PointLocation'
- import TopologyException from '../geom/TopologyException'
- import Orientation from '../algorithm/Orientation'
- import Label from './Label'
- import ArrayList from '../../../../java/util/ArrayList'
- import Assert from '../util/Assert'
- export default class EdgeRing {
- constructor() {
- EdgeRing.constructor_.apply(this, arguments)
- }
- static constructor_() {
- this._startDe = null
- this._maxNodeDegree = -1
- this._edges = new ArrayList()
- this._pts = new ArrayList()
- this._label = new Label(Location.NONE)
- this._ring = null
- this._isHole = null
- this._shell = null
- this._holes = new ArrayList()
- this._geometryFactory = null
- if (arguments.length === 0) {} else if (arguments.length === 2) {
- const start = arguments[0], geometryFactory = arguments[1]
- this._geometryFactory = geometryFactory
- this.computePoints(start)
- this.computeRing()
- }
- }
- computeRing() {
- if (this._ring !== null) return null
- const coord = new Array(this._pts.size()).fill(null)
- for (let i = 0; i < this._pts.size(); i++)
- coord[i] = this._pts.get(i)
-
- this._ring = this._geometryFactory.createLinearRing(coord)
- this._isHole = Orientation.isCCW(this._ring.getCoordinates())
- }
- isIsolated() {
- return this._label.getGeometryCount() === 1
- }
- computePoints(start) {
- this._startDe = start
- let de = start
- let isFirstEdge = true
- do {
- if (de === null) throw new TopologyException('Found null DirectedEdge')
- if (de.getEdgeRing() === this) throw new TopologyException('Directed Edge visited twice during ring-building at ' + de.getCoordinate())
- this._edges.add(de)
- const label = de.getLabel()
- Assert.isTrue(label.isArea())
- this.mergeLabel(label)
- this.addPoints(de.getEdge(), de.isForward(), isFirstEdge)
- isFirstEdge = false
- this.setEdgeRing(de, this)
- de = this.getNext(de)
- } while (de !== this._startDe)
- }
- getLinearRing() {
- return this._ring
- }
- getCoordinate(i) {
- return this._pts.get(i)
- }
- computeMaxNodeDegree() {
- this._maxNodeDegree = 0
- let de = this._startDe
- do {
- const node = de.getNode()
- const degree = node.getEdges().getOutgoingDegree(this)
- if (degree > this._maxNodeDegree) this._maxNodeDegree = degree
- de = this.getNext(de)
- } while (de !== this._startDe)
- this._maxNodeDegree *= 2
- }
- addPoints(edge, isForward, isFirstEdge) {
- const edgePts = edge.getCoordinates()
- if (isForward) {
- let startIndex = 1
- if (isFirstEdge) startIndex = 0
- for (let i = startIndex; i < edgePts.length; i++)
- this._pts.add(edgePts[i])
-
- } else {
- let startIndex = edgePts.length - 2
- if (isFirstEdge) startIndex = edgePts.length - 1
- for (let i = startIndex; i >= 0; i--)
- this._pts.add(edgePts[i])
-
- }
- }
- isHole() {
- return this._isHole
- }
- setInResult() {
- let de = this._startDe
- do {
- de.getEdge().setInResult(true)
- de = de.getNext()
- } while (de !== this._startDe)
- }
- containsPoint(p) {
- const shell = this.getLinearRing()
- const env = shell.getEnvelopeInternal()
- if (!env.contains(p)) return false
- if (!PointLocation.isInRing(p, shell.getCoordinates())) return false
- for (let i = this._holes.iterator(); i.hasNext(); ) {
- const hole = i.next()
- if (hole.containsPoint(p)) return false
- }
- return true
- }
- addHole(ring) {
- this._holes.add(ring)
- }
- isShell() {
- return this._shell === null
- }
- getLabel() {
- return this._label
- }
- getEdges() {
- return this._edges
- }
- getMaxNodeDegree() {
- if (this._maxNodeDegree < 0) this.computeMaxNodeDegree()
- return this._maxNodeDegree
- }
- getShell() {
- return this._shell
- }
- mergeLabel() {
- if (arguments.length === 1) {
- const deLabel = arguments[0]
- this.mergeLabel(deLabel, 0)
- this.mergeLabel(deLabel, 1)
- } else if (arguments.length === 2) {
- const deLabel = arguments[0], geomIndex = arguments[1]
- const loc = deLabel.getLocation(geomIndex, Position.RIGHT)
- if (loc === Location.NONE) return null
- if (this._label.getLocation(geomIndex) === Location.NONE) {
- this._label.setLocation(geomIndex, loc)
- return null
- }
- }
- }
- setShell(shell) {
- this._shell = shell
- if (shell !== null) shell.addHole(this)
- }
- toPolygon(geometryFactory) {
- const holeLR = new Array(this._holes.size()).fill(null)
- for (let i = 0; i < this._holes.size(); i++)
- holeLR[i] = this._holes.get(i).getLinearRing()
-
- const poly = geometryFactory.createPolygon(this.getLinearRing(), holeLR)
- return poly
- }
- }
|