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

240 lines (237 loc) 9.91 kB
import PointLocator from '../../algorithm/PointLocator' import PolygonExtracter from '../../geom/util/PolygonExtracter' import Location from '../../geom/Location' import LineString from '../../geom/LineString' import CGAlgorithms from '../../algorithm/CGAlgorithms' import hasInterface from '../../../../../hasInterface' import IllegalArgumentException from '../../../../../java/lang/IllegalArgumentException' import Point from '../../geom/Point' import Polygon from '../../geom/Polygon' import GeometryLocation from './GeometryLocation' import Double from '../../../../../java/lang/Double' import PointExtracter from '../../geom/util/PointExtracter' import ConnectedElementLocationFilter from './ConnectedElementLocationFilter' import LineSegment from '../../geom/LineSegment' import LinearComponentExtracter from '../../geom/util/LinearComponentExtracter' import List from '../../../../../java/util/List' export default class DistanceOp { constructor () { this._geom = null this._terminateDistance = 0.0 this._ptLocator = new PointLocator() this._minDistanceLocation = null this._minDistance = Double.MAX_VALUE if (arguments.length === 2) { const g0 = arguments[0] const g1 = arguments[1] this._geom = [g0, g1] this._terminateDistance = 0.0 } else if (arguments.length === 3) { const g0 = arguments[0] const g1 = arguments[1] const terminateDistance = arguments[2] this._geom = new Array(2).fill(null) this._geom[0] = g0 this._geom[1] = g1 this._terminateDistance = terminateDistance } } computeContainmentDistance () { if (arguments.length === 0) { const locPtPoly = new Array(2).fill(null) this.computeContainmentDistance(0, locPtPoly) if (this._minDistance <= this._terminateDistance) return null this.computeContainmentDistance(1, locPtPoly) } else if (arguments.length === 2) { const polyGeomIndex = arguments[0] const locPtPoly = arguments[1] const locationsIndex = 1 - polyGeomIndex const polys = PolygonExtracter.getPolygons(this._geom[polyGeomIndex]) if (polys.size() > 0) { const insideLocs = ConnectedElementLocationFilter.getLocations(this._geom[locationsIndex]) this.computeContainmentDistance(insideLocs, polys, locPtPoly) if (this._minDistance <= this._terminateDistance) { this._minDistanceLocation[locationsIndex] = locPtPoly[0] this._minDistanceLocation[polyGeomIndex] = locPtPoly[1] return null } } } else if (arguments.length === 3) { if (arguments[2] instanceof Array && (hasInterface(arguments[0], List) && hasInterface(arguments[1], List))) { const locs = arguments[0] const polys = arguments[1] const locPtPoly = arguments[2] for (let i = 0; i < locs.size(); i++) { const loc = locs.get(i) for (let j = 0; j < polys.size(); j++) { this.computeContainmentDistance(loc, polys.get(j), locPtPoly) if (this._minDistance <= this._terminateDistance) return null } } } else if (arguments[2] instanceof Array && (arguments[0] instanceof GeometryLocation && arguments[1] instanceof Polygon)) { const ptLoc = arguments[0] const poly = arguments[1] const locPtPoly = arguments[2] const pt = ptLoc.getCoordinate() if (Location.EXTERIOR !== this._ptLocator.locate(pt, poly)) { this._minDistance = 0.0 locPtPoly[0] = ptLoc locPtPoly[1] = new GeometryLocation(poly, pt) return null } } } } computeMinDistanceLinesPoints (lines, points, locGeom) { for (let i = 0; i < lines.size(); i++) { const line = lines.get(i) for (let j = 0; j < points.size(); j++) { const pt = points.get(j) this.computeMinDistance(line, pt, locGeom) if (this._minDistance <= this._terminateDistance) return null } } } computeFacetDistance () { const locGeom = new Array(2).fill(null) const lines0 = LinearComponentExtracter.getLines(this._geom[0]) const lines1 = LinearComponentExtracter.getLines(this._geom[1]) const pts0 = PointExtracter.getPoints(this._geom[0]) const pts1 = PointExtracter.getPoints(this._geom[1]) this.computeMinDistanceLines(lines0, lines1, locGeom) this.updateMinDistance(locGeom, false) if (this._minDistance <= this._terminateDistance) return null locGeom[0] = null locGeom[1] = null this.computeMinDistanceLinesPoints(lines0, pts1, locGeom) this.updateMinDistance(locGeom, false) if (this._minDistance <= this._terminateDistance) return null locGeom[0] = null locGeom[1] = null this.computeMinDistanceLinesPoints(lines1, pts0, locGeom) this.updateMinDistance(locGeom, true) if (this._minDistance <= this._terminateDistance) return null locGeom[0] = null locGeom[1] = null this.computeMinDistancePoints(pts0, pts1, locGeom) this.updateMinDistance(locGeom, false) } nearestLocations () { this.computeMinDistance() return this._minDistanceLocation } updateMinDistance (locGeom, flip) { if (locGeom[0] === null) return null if (flip) { this._minDistanceLocation[0] = locGeom[1] this._minDistanceLocation[1] = locGeom[0] } else { this._minDistanceLocation[0] = locGeom[0] this._minDistanceLocation[1] = locGeom[1] } } nearestPoints () { this.computeMinDistance() const nearestPts = [this._minDistanceLocation[0].getCoordinate(), this._minDistanceLocation[1].getCoordinate()] return nearestPts } computeMinDistance () { if (arguments.length === 0) { if (this._minDistanceLocation !== null) return null this._minDistanceLocation = new Array(2).fill(null) this.computeContainmentDistance() if (this._minDistance <= this._terminateDistance) return null this.computeFacetDistance() } else if (arguments.length === 3) { if (arguments[2] instanceof Array && (arguments[0] instanceof LineString && arguments[1] instanceof Point)) { const line = arguments[0] const pt = arguments[1] const locGeom = arguments[2] if (line.getEnvelopeInternal().distance(pt.getEnvelopeInternal()) > this._minDistance) return null const coord0 = line.getCoordinates() const coord = pt.getCoordinate() for (let i = 0; i < coord0.length - 1; i++) { const dist = CGAlgorithms.distancePointLine(coord, coord0[i], coord0[i + 1]) if (dist < this._minDistance) { this._minDistance = dist const seg = new LineSegment(coord0[i], coord0[i + 1]) const segClosestPoint = seg.closestPoint(coord) locGeom[0] = new GeometryLocation(line, i, segClosestPoint) locGeom[1] = new GeometryLocation(pt, 0, coord) } if (this._minDistance <= this._terminateDistance) return null } } else if (arguments[2] instanceof Array && (arguments[0] instanceof LineString && arguments[1] instanceof LineString)) { const line0 = arguments[0] const line1 = arguments[1] const locGeom = arguments[2] if (line0.getEnvelopeInternal().distance(line1.getEnvelopeInternal()) > this._minDistance) return null const coord0 = line0.getCoordinates() const coord1 = line1.getCoordinates() for (let i = 0; i < coord0.length - 1; i++) { for (let j = 0; j < coord1.length - 1; j++) { const dist = CGAlgorithms.distanceLineLine(coord0[i], coord0[i + 1], coord1[j], coord1[j + 1]) if (dist < this._minDistance) { this._minDistance = dist const seg0 = new LineSegment(coord0[i], coord0[i + 1]) const seg1 = new LineSegment(coord1[j], coord1[j + 1]) const closestPt = seg0.closestPoints(seg1) locGeom[0] = new GeometryLocation(line0, i, closestPt[0]) locGeom[1] = new GeometryLocation(line1, j, closestPt[1]) } if (this._minDistance <= this._terminateDistance) return null } } } } } computeMinDistancePoints (points0, points1, locGeom) { for (let i = 0; i < points0.size(); i++) { const pt0 = points0.get(i) for (let j = 0; j < points1.size(); j++) { const pt1 = points1.get(j) const dist = pt0.getCoordinate().distance(pt1.getCoordinate()) if (dist < this._minDistance) { this._minDistance = dist locGeom[0] = new GeometryLocation(pt0, 0, pt0.getCoordinate()) locGeom[1] = new GeometryLocation(pt1, 0, pt1.getCoordinate()) } if (this._minDistance <= this._terminateDistance) return null } } } distance () { if (this._geom[0] === null || this._geom[1] === null) throw new IllegalArgumentException('null geometries are not supported') if (this._geom[0].isEmpty() || this._geom[1].isEmpty()) return 0.0 this.computeMinDistance() return this._minDistance } computeMinDistanceLines (lines0, lines1, locGeom) { for (let i = 0; i < lines0.size(); i++) { const line0 = lines0.get(i) for (let j = 0; j < lines1.size(); j++) { const line1 = lines1.get(j) this.computeMinDistance(line0, line1, locGeom) if (this._minDistance <= this._terminateDistance) return null } } } interfaces_ () { return [] } getClass () { return DistanceOp } static distance (g0, g1) { const distOp = new DistanceOp(g0, g1) return distOp.distance() } static isWithinDistance (g0, g1, distance) { const distOp = new DistanceOp(g0, g1, distance) return distOp.distance() <= distance } static nearestPoints (g0, g1) { const distOp = new DistanceOp(g0, g1) return distOp.nearestPoints() } }