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.28 kB
JavaScript
import LineString from '../geom/LineString'
import CoordinateList from '../geom/CoordinateList'
import Geometry from '../geom/Geometry'
import hasInterface from '../../../../hasInterface'
import Collection from '../../../../java/util/Collection'
import Stack from '../../../../java/util/Stack'
import MarkHalfEdge from '../edgegraph/MarkHalfEdge'
import DissolveEdgeGraph from './DissolveEdgeGraph'
import GeometryComponentFilter from '../geom/GeometryComponentFilter'
import ArrayList from '../../../../java/util/ArrayList'
export default class LineDissolver {
constructor () {
this._result = null
this._factory = null
this._graph = null
this._lines = new ArrayList()
this._nodeEdgeStack = new Stack()
this._ringStartEdge = null
this._graph = new DissolveEdgeGraph()
}
addLine (line) {
this._lines.add(this._factory.createLineString(line.toCoordinateArray()))
}
updateRingStartEdge (e) {
if (!e.isStart()) {
e = e.sym()
if (!e.isStart()) return null
}
if (this._ringStartEdge === null) {
this._ringStartEdge = e
return null
}
if (e.orig().compareTo(this._ringStartEdge.orig()) < 0) {
this._ringStartEdge = e
}
}
getResult () {
if (this._result === null) this.computeResult()
return this._result
}
process (e) {
let eNode = e.prevNode()
if (eNode === null) eNode = e
this.stackEdges(eNode)
this.buildLines()
}
buildRing (eStartRing) {
const line = new CoordinateList()
let e = eStartRing
line.add(e.orig().copy(), false)
while (e.sym().degree() === 2) {
const eNext = e.next()
if (eNext === eStartRing) break
line.add(eNext.orig().copy(), false)
e = eNext
}
line.add(e.dest().copy(), false)
this.addLine(line)
}
buildLine (eStart) {
const line = new CoordinateList()
let e = eStart
this._ringStartEdge = null
MarkHalfEdge.markBoth(e)
line.add(e.orig().copy(), false)
while (e.sym().degree() === 2) {
this.updateRingStartEdge(e)
const eNext = e.next()
if (eNext === eStart) {
this.buildRing(this._ringStartEdge)
return null
}
line.add(eNext.orig().copy(), false)
e = eNext
MarkHalfEdge.markBoth(e)
}
line.add(e.dest().copy(), false)
this.stackEdges(e.sym())
this.addLine(line)
}
stackEdges (node) {
let e = node
do {
if (!MarkHalfEdge.isMarked(e)) this._nodeEdgeStack.add(e)
e = e.oNext()
} while (e !== node)
}
computeResult () {
const edges = this._graph.getVertexEdges()
for (const i = edges.iterator(); i.hasNext();) {
const e = i.next()
if (MarkHalfEdge.isMarked(e)) continue
this.process(e)
}
this._result = this._factory.buildGeometry(this._lines)
}
buildLines () {
while (!this._nodeEdgeStack.empty()) {
const e = this._nodeEdgeStack.pop()
if (MarkHalfEdge.isMarked(e)) continue
this.buildLine(e)
}
}
add () {
if (arguments[0] instanceof Geometry) {
let geometry = arguments[0]
geometry.appy({
interfaces_: function () {
return [GeometryComponentFilter]
},
filter: function (component) {
if (component instanceof LineString) {
this.add(component)
}
}
})
} else if (hasInterface(arguments[0], Collection)) {
let geometries = arguments[0]
for (const i = geometries.iterator(); i.hasNext();) {
const geometry = i.next()
this.add(geometry)
}
} else if (arguments[0] instanceof LineString) {
let lineString = arguments[0]
if (this._factory === null) {
this._factory = lineString.getFactory()
}
const seq = lineString.getCoordinateSequence()
let doneStart = false
for (let i = 1; i < seq.size(); i++) {
const e = this._graph.addEdge(seq.getCoordinate(i - 1), seq.getCoordinate(i))
if (e === null) continue
if (!doneStart) {
e.setStart()
doneStart = true
}
}
}
}
interfaces_ () {
return []
}
getClass () {
return LineDissolver
}
static dissolve (g) {
const d = new LineDissolver()
d.add(g)
return d.getResult()
}
}