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