node-red-contrib-tak-registration
Version:
A Node-RED node to register to TAK and to help wrap files as datapackages to send to TAK
161 lines (156 loc) • 4.82 kB
JavaScript
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
}
}