UNPKG

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
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) } }