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
153 lines (151 loc) • 4.95 kB
JavaScript
import CGAlgorithms from '../../algorithm/CGAlgorithms'
import TopologyException from '../../geom/TopologyException'
import MaximalEdgeRing from './MaximalEdgeRing'
import ArrayList from '../../../../../java/util/ArrayList'
import Assert from '../../util/Assert'
import PlanarGraph from '../../geomgraph/PlanarGraph'
export default class PolygonBuilder {
constructor () {
this._geometryFactory = null
this._shellList = new ArrayList()
let geometryFactory = arguments[0]
this._geometryFactory = geometryFactory
}
sortShellsAndHoles (edgeRings, shellList, freeHoleList) {
for (const it = edgeRings.iterator(); it.hasNext();) {
const er = it.next()
if (er.isHole()) {
freeHoleList.add(er)
} else {
shellList.add(er)
}
}
}
computePolygons (shellList) {
const resultPolyList = new ArrayList()
for (const it = shellList.iterator(); it.hasNext();) {
const er = it.next()
const poly = er.toPolygon(this._geometryFactory)
resultPolyList.add(poly)
}
return resultPolyList
}
placeFreeHoles (shellList, freeHoleList) {
for (const it = freeHoleList.iterator(); it.hasNext();) {
const hole = it.next()
if (hole.getShell() === null) {
const shell = this.findEdgeRingContaining(hole, shellList)
if (shell === null) throw new TopologyException('unable to assign hole to a shell', hole.getCoordinate(0))
hole.setShell(shell)
}
}
}
buildMinimalEdgeRings (maxEdgeRings, shellList, freeHoleList) {
const edgeRings = new ArrayList()
for (const it = maxEdgeRings.iterator(); it.hasNext();) {
const er = it.next()
if (er.getMaxNodeDegree() > 2) {
er.linkDirectedEdgesForMinimalEdgeRings()
const minEdgeRings = er.buildMinimalRings()
const shell = this.findShell(minEdgeRings)
if (shell !== null) {
this.placePolygonHoles(shell, minEdgeRings)
shellList.add(shell)
} else {
freeHoleList.addAll(minEdgeRings)
}
} else {
edgeRings.add(er)
}
}
return edgeRings
}
containsPoint (p) {
for (const it = this._shellList.iterator(); it.hasNext();) {
const er = it.next()
if (er.containsPoint(p)) return true
}
return false
}
buildMaximalEdgeRings (dirEdges) {
const maxEdgeRings = new ArrayList()
for (const it = dirEdges.iterator(); it.hasNext();) {
const de = it.next()
if (de.isInResult() && de.getLabel().isArea()) {
if (de.getEdgeRing() === null) {
const er = new MaximalEdgeRing(de, this._geometryFactory)
maxEdgeRings.add(er)
er.setInResult()
}
}
}
return maxEdgeRings
}
placePolygonHoles (shell, minEdgeRings) {
for (const it = minEdgeRings.iterator(); it.hasNext();) {
const er = it.next()
if (er.isHole()) {
er.setShell(shell)
}
}
}
getPolygons () {
const resultPolyList = this.computePolygons(this._shellList)
return resultPolyList
}
findEdgeRingContaining (testEr, shellList) {
const testRing = testEr.getLinearRing()
const testEnv = testRing.getEnvelopeInternal()
const testPt = testRing.getCoordinateN(0)
let minShell = null
let minEnv = null
for (const it = shellList.iterator(); it.hasNext();) {
const tryShell = it.next()
const tryRing = tryShell.getLinearRing()
const tryEnv = tryRing.getEnvelopeInternal()
if (minShell !== null) minEnv = minShell.getLinearRing().getEnvelopeInternal()
let isContained = false
if (tryEnv.contains(testEnv) && CGAlgorithms.isPointInRing(testPt, tryRing.getCoordinates())) isContained = true
if (isContained) {
if (minShell === null || minEnv.contains(tryEnv)) {
minShell = tryShell
}
}
}
return minShell
}
findShell (minEdgeRings) {
let shellCount = 0
let shell = null
for (const it = minEdgeRings.iterator(); it.hasNext();) {
const er = it.next()
if (!er.isHole()) {
shell = er
shellCount++
}
}
Assert.isTrue(shellCount <= 1, 'found two shells in MinimalEdgeRing list')
return shell
}
add () {
if (arguments.length === 1) {
const graph = arguments[0]
this.add(graph.getEdgeEnds(), graph.getNodes())
} else if (arguments.length === 2) {
const dirEdges = arguments[0]
const nodes = arguments[1]
PlanarGraph.linkResultDirectedEdges(nodes)
const maxEdgeRings = this.buildMaximalEdgeRings(dirEdges)
const freeHoleList = new ArrayList()
const edgeRings = this.buildMinimalEdgeRings(maxEdgeRings, this._shellList, freeHoleList)
this.sortShellsAndHoles(edgeRings, this._shellList, freeHoleList)
this.placeFreeHoles(this._shellList, freeHoleList)
}
}
interfaces_ () {
return []
}
getClass () {
return PolygonBuilder
}
}