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
256 lines (254 loc) • 9.44 kB
JavaScript
import PointLocator from '../algorithm/PointLocator'
import Location from '../geom/Location'
import LineString from '../geom/LineString'
import HashMap from '../../../../java/util/HashMap'
import CGAlgorithms from '../algorithm/CGAlgorithms'
import hasInterface from '../../../../hasInterface'
import Position from './Position'
import Coordinate from '../geom/Coordinate'
import Point from '../geom/Point'
import Polygon from '../geom/Polygon'
import MultiPoint from '../geom/MultiPoint'
import SimpleMCSweepLineIntersector from './index/SimpleMCSweepLineIntersector'
import LinearRing from '../geom/LinearRing'
import BoundaryNodeRule from '../algorithm/BoundaryNodeRule'
import SegmentIntersector from './index/SegmentIntersector'
import MultiPolygon from '../geom/MultiPolygon'
import Label from './Label'
import GeometryCollection from '../geom/GeometryCollection'
import CoordinateArrays from '../geom/CoordinateArrays'
import Polygonal from '../geom/Polygonal'
import IndexedPointInAreaLocator from '../algorithm/locate/IndexedPointInAreaLocator'
import Assert from '../util/Assert'
import Edge from './Edge'
import MultiLineString from '../geom/MultiLineString'
import PlanarGraph from './PlanarGraph'
export default class GeometryGraph extends PlanarGraph {
constructor () {
super()
this._parentGeom = null
this._lineEdgeMap = new HashMap()
this._boundaryNodeRule = null
this._useBoundaryDeterminationRule = true
this._argIndex = null
this._boundaryNodes = null
this._hasTooFewPoints = false
this._invalidPoint = null
this._areaPtLocator = null
this._ptLocator = new PointLocator()
if (arguments.length === 2) {
const argIndex = arguments[0]
const parentGeom = arguments[1]
const boundaryNodeRule = BoundaryNodeRule.OGC_SFS_BOUNDARY_RULE
this._argIndex = argIndex
this._parentGeom = parentGeom
this._boundaryNodeRule = boundaryNodeRule
if (parentGeom !== null) {
this.add(parentGeom)
}
} else if (arguments.length === 3) {
const argIndex = arguments[0]
const parentGeom = arguments[1]
const boundaryNodeRule = arguments[2]
this._argIndex = argIndex
this._parentGeom = parentGeom
this._boundaryNodeRule = boundaryNodeRule
if (parentGeom !== null) {
this.add(parentGeom)
}
}
}
insertBoundaryPoint (argIndex, coord) {
const n = this._nodes.addNode(coord)
const lbl = n.getLabel()
let boundaryCount = 1
let loc = Location.NONE
loc = lbl.getLocation(argIndex, Position.ON)
if (loc === Location.BOUNDARY) boundaryCount++
const newLoc = GeometryGraph.determineBoundary(this._boundaryNodeRule, boundaryCount)
lbl.setLocation(argIndex, newLoc)
}
computeSelfNodes () {
if (arguments.length === 2) {
const li = arguments[0]
const computeRingSelfNodes = arguments[1]
return this.computeSelfNodes(li, computeRingSelfNodes, false)
} else if (arguments.length === 3) {
const li = arguments[0]
const computeRingSelfNodes = arguments[1]
const isDoneIfProperInt = arguments[2]
const si = new SegmentIntersector(li, true, false)
si.setIsDoneIfProperInt(isDoneIfProperInt)
const esi = this.createEdgeSetIntersector()
const isRings = this._parentGeom instanceof LinearRing || this._parentGeom instanceof Polygon || this._parentGeom instanceof MultiPolygon
const computeAllSegments = computeRingSelfNodes || !isRings
esi.computeIntersections(this._edges, si, computeAllSegments)
this.addSelfIntersectionNodes(this._argIndex)
return si
}
}
computeSplitEdges (edgelist) {
for (const i = this._edges.iterator(); i.hasNext();) {
const e = i.next()
e.eiList.addSplitEdges(edgelist)
}
}
computeEdgeIntersections (g, li, includeProper) {
const si = new SegmentIntersector(li, includeProper, true)
si.setBoundaryNodes(this.getBoundaryNodes(), g.getBoundaryNodes())
const esi = this.createEdgeSetIntersector()
esi.computeIntersections(this._edges, g._edges, si)
return si
}
getGeometry () {
return this._parentGeom
}
getBoundaryNodeRule () {
return this._boundaryNodeRule
}
hasTooFewPoints () {
return this._hasTooFewPoints
}
addPoint () {
if (arguments[0] instanceof Point) {
let p = arguments[0]
const coord = p.getCoordinate()
this.insertPoint(this._argIndex, coord, Location.INTERIOR)
} else if (arguments[0] instanceof Coordinate) {
let pt = arguments[0]
this.insertPoint(this._argIndex, pt, Location.INTERIOR)
}
}
addPolygon (p) {
this.addPolygonRing(p.getExteriorRing(), Location.EXTERIOR, Location.INTERIOR)
for (let i = 0; i < p.getNumInteriorRing(); i++) {
const hole = p.getInteriorRingN(i)
this.addPolygonRing(hole, Location.INTERIOR, Location.EXTERIOR)
}
}
addEdge (e) {
this.insertEdge(e)
const coord = e.getCoordinates()
this.insertPoint(this._argIndex, coord[0], Location.BOUNDARY)
this.insertPoint(this._argIndex, coord[coord.length - 1], Location.BOUNDARY)
}
addLineString (line) {
const coord = CoordinateArrays.removeRepeatedPoints(line.getCoordinates())
if (coord.length < 2) {
this._hasTooFewPoints = true
this._invalidPoint = coord[0]
return null
}
const e = new Edge(coord, new Label(this._argIndex, Location.INTERIOR))
this._lineEdgeMap.put(line, e)
this.insertEdge(e)
Assert.isTrue(coord.length >= 2, 'found LineString with single point')
this.insertBoundaryPoint(this._argIndex, coord[0])
this.insertBoundaryPoint(this._argIndex, coord[coord.length - 1])
}
getInvalidPoint () {
return this._invalidPoint
}
getBoundaryPoints () {
const coll = this.getBoundaryNodes()
const pts = new Array(coll.size()).fill(null)
let i = 0
for (const it = coll.iterator(); it.hasNext();) {
const node = it.next()
pts[i++] = node.getCoordinate().copy()
}
return pts
}
getBoundaryNodes () {
if (this._boundaryNodes === null) this._boundaryNodes = this._nodes.getBoundaryNodes(this._argIndex)
return this._boundaryNodes
}
addSelfIntersectionNode (argIndex, coord, loc) {
if (this.isBoundaryNode(argIndex, coord)) return null
if (loc === Location.BOUNDARY && this._useBoundaryDeterminationRule) this.insertBoundaryPoint(argIndex, coord); else this.insertPoint(argIndex, coord, loc)
}
addPolygonRing (lr, cwLeft, cwRight) {
if (lr.isEmpty()) return null
const coord = CoordinateArrays.removeRepeatedPoints(lr.getCoordinates())
if (coord.length < 4) {
this._hasTooFewPoints = true
this._invalidPoint = coord[0]
return null
}
let left = cwLeft
let right = cwRight
if (CGAlgorithms.isCCW(coord)) {
left = cwRight
right = cwLeft
}
const e = new Edge(coord, new Label(this._argIndex, Location.BOUNDARY, left, right))
this._lineEdgeMap.put(lr, e)
this.insertEdge(e)
this.insertPoint(this._argIndex, coord[0], Location.BOUNDARY)
}
insertPoint (argIndex, coord, onLocation) {
const n = this._nodes.addNode(coord)
const lbl = n.getLabel()
if (lbl === null) {
n._label = new Label(argIndex, onLocation)
} else lbl.setLocation(argIndex, onLocation)
}
createEdgeSetIntersector () {
return new SimpleMCSweepLineIntersector()
}
addSelfIntersectionNodes (argIndex) {
for (const i = this._edges.iterator(); i.hasNext();) {
const e = i.next()
const eLoc = e.getLabel().getLocation(argIndex)
for (const eiIt = e.eiList.iterator(); eiIt.hasNext();) {
const ei = eiIt.next()
this.addSelfIntersectionNode(argIndex, ei.coord, eLoc)
}
}
}
add () {
if (arguments.length === 1) {
let g = arguments[0]
if (g.isEmpty()) return null
if (g instanceof MultiPolygon) this._useBoundaryDeterminationRule = false
if (g instanceof Polygon) this.addPolygon(g)
else if (g instanceof LineString) this.addLineString(g)
else if (g instanceof Point) this.addPoint(g)
else if (g instanceof MultiPoint) this.addCollection(g)
else if (g instanceof MultiLineString) this.addCollection(g)
else if (g instanceof MultiPolygon) this.addCollection(g)
else if (g instanceof GeometryCollection) this.addCollection(g)
else throw new Error(g.getClass().getName())
} else return PlanarGraph.prototype.add.apply(this, arguments)
}
addCollection (gc) {
for (let i = 0; i < gc.getNumGeometries(); i++) {
const g = gc.getGeometryN(i)
this.add(g)
}
}
locate (pt) {
if (hasInterface(this._parentGeom, Polygonal) && this._parentGeom.getNumGeometries() > 50) {
if (this._areaPtLocator === null) {
this._areaPtLocator = new IndexedPointInAreaLocator(this._parentGeom)
}
return this._areaPtLocator.locate(pt)
}
return this._ptLocator.locate(pt, this._parentGeom)
}
findEdge () {
if (arguments.length === 1) {
let line = arguments[0]
return this._lineEdgeMap.get(line)
} else return PlanarGraph.prototype.findEdge.apply(this, arguments)
}
interfaces_ () {
return []
}
getClass () {
return GeometryGraph
}
static determineBoundary (boundaryNodeRule, boundaryCount) {
return boundaryNodeRule.isInBoundary(boundaryCount) ? Location.BOUNDARY : Location.INTERIOR
}
}