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

256 lines (254 loc) 9.44 kB
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 } }