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
151 lines (149 loc) • 5.74 kB
JavaScript
import Location from '../../geom/Location'
import BufferSubgraph from './BufferSubgraph'
import PolygonBuilder from '../overlay/PolygonBuilder'
import GeometryFactory from '../../geom/GeometryFactory'
import Position from '../../geomgraph/Position'
import MCIndexNoder from '../../noding/MCIndexNoder'
import OffsetCurveBuilder from './OffsetCurveBuilder'
import Collections from '../../../../../java/util/Collections'
import SubgraphDepthLocater from './SubgraphDepthLocater'
import OffsetCurveSetBuilder from './OffsetCurveSetBuilder'
import Label from '../../geomgraph/Label'
import OverlayNodeFactory from '../overlay/OverlayNodeFactory'
import EdgeList from '../../geomgraph/EdgeList'
import ArrayList from '../../../../../java/util/ArrayList'
import RobustLineIntersector from '../../algorithm/RobustLineIntersector'
import IntersectionAdder from '../../noding/IntersectionAdder'
import Edge from '../../geomgraph/Edge'
import PlanarGraph from '../../geomgraph/PlanarGraph'
export default class BufferBuilder {
constructor (bufParams) {
this._workingPrecisionModel = null
this._workingNoder = null
this._geomFact = null
this._graph = null
this._edgeList = new EdgeList()
this._bufParams = bufParams || null
}
setWorkingPrecisionModel (pm) {
this._workingPrecisionModel = pm
}
insertUniqueEdge (e) {
const existingEdge = this._edgeList.findEqualEdge(e)
if (existingEdge !== null) {
const existingLabel = existingEdge.getLabel()
let labelToMerge = e.getLabel()
if (!existingEdge.isPointwiseEqual(e)) {
labelToMerge = new Label(e.getLabel())
labelToMerge.flip()
}
existingLabel.merge(labelToMerge)
const mergeDelta = BufferBuilder.depthDelta(labelToMerge)
const existingDelta = existingEdge.getDepthDelta()
const newDelta = existingDelta + mergeDelta
existingEdge.setDepthDelta(newDelta)
} else {
this._edgeList.add(e)
e.setDepthDelta(BufferBuilder.depthDelta(e.getLabel()))
}
}
buildSubgraphs (subgraphList, polyBuilder) {
const processedGraphs = new ArrayList()
for (const i = subgraphList.iterator(); i.hasNext();) {
const subgraph = i.next()
const p = subgraph.getRightmostCoordinate()
const locater = new SubgraphDepthLocater(processedGraphs)
const outsideDepth = locater.getDepth(p)
subgraph.computeDepth(outsideDepth)
subgraph.findResultEdges()
processedGraphs.add(subgraph)
polyBuilder.add(subgraph.getDirectedEdges(), subgraph.getNodes())
}
}
createSubgraphs (graph) {
const subgraphList = new ArrayList()
for (const i = graph.getNodes().iterator(); i.hasNext();) {
const node = i.next()
if (!node.isVisited()) {
const subgraph = new BufferSubgraph()
subgraph.create(node)
subgraphList.add(subgraph)
}
}
Collections.sort(subgraphList, Collections.reverseOrder())
return subgraphList
}
createEmptyResultGeometry () {
const emptyGeom = this._geomFact.createPolygon()
return emptyGeom
}
getNoder (precisionModel) {
if (this._workingNoder !== null) return this._workingNoder
const noder = new MCIndexNoder()
const li = new RobustLineIntersector()
li.setPrecisionModel(precisionModel)
noder.setSegmentIntersector(new IntersectionAdder(li))
return noder
}
buffer (g, distance) {
let precisionModel = this._workingPrecisionModel
if (precisionModel === null) precisionModel = g.getPrecisionModel()
this._geomFact = g.getFactory()
const curveBuilder = new OffsetCurveBuilder(precisionModel, this._bufParams)
const curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder)
const bufferSegStrList = curveSetBuilder.getCurves()
if (bufferSegStrList.size() <= 0) {
return this.createEmptyResultGeometry()
}
this.computeNodedEdges(bufferSegStrList, precisionModel)
this._graph = new PlanarGraph(new OverlayNodeFactory())
this._graph.addEdges(this._edgeList.getEdges())
const subgraphList = this.createSubgraphs(this._graph)
const polyBuilder = new PolygonBuilder(this._geomFact)
this.buildSubgraphs(subgraphList, polyBuilder)
const resultPolyList = polyBuilder.getPolygons()
if (resultPolyList.size() <= 0) {
return this.createEmptyResultGeometry()
}
const resultGeom = this._geomFact.buildGeometry(resultPolyList)
return resultGeom
}
computeNodedEdges (bufferSegStrList, precisionModel) {
const noder = this.getNoder(precisionModel)
noder.computeNodes(bufferSegStrList)
const nodedSegStrings = noder.getNodedSubstrings()
for (const i = nodedSegStrings.iterator(); i.hasNext();) {
const segStr = i.next()
const pts = segStr.getCoordinates()
if (pts.length === 2 && pts[0].equals2D(pts[1])) continue
const oldLabel = segStr.getData()
const edge = new Edge(segStr.getCoordinates(), new Label(oldLabel))
this.insertUniqueEdge(edge)
}
}
setNoder (noder) {
this._workingNoder = noder
}
interfaces_ () {
return []
}
getClass () {
return BufferBuilder
}
static depthDelta (label) {
const lLoc = label.getLocation(0, Position.LEFT)
const rLoc = label.getLocation(0, Position.RIGHT)
if (lLoc === Location.INTERIOR && rLoc === Location.EXTERIOR) return 1; else if (lLoc === Location.EXTERIOR && rLoc === Location.INTERIOR) return -1
return 0
}
static convertSegStrings (it) {
const fact = new GeometryFactory()
const lines = new ArrayList()
while (it.hasNext()) {
const ss = it.next()
const line = fact.createLineString(ss.getCoordinates())
lines.add(line)
}
return fact.buildGeometry(lines)
}
}