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
126 lines (122 loc) • 4.16 kB
JavaScript
import ItemBoundable from '../index/strtree/ItemBoundable'
import FacetSequence from '../operation/distance/FacetSequence'
import Coordinate from '../geom/Coordinate'
import Double from '../../../../java/lang/Double'
import LineSegment from '../geom/LineSegment'
import FacetSequenceTreeBuilder from '../operation/distance/FacetSequenceTreeBuilder'
import Distance from '../algorithm/Distance'
import ItemDistance from '../index/strtree/ItemDistance'
export default class MinimumClearance {
constructor() {
MinimumClearance.constructor_.apply(this, arguments)
}
static constructor_() {
this._inputGeom = null
this._minClearance = null
this._minClearancePts = null
const geom = arguments[0]
this._inputGeom = geom
}
static getLine(g) {
const rp = new MinimumClearance(g)
return rp.getLine()
}
static getDistance(g) {
const rp = new MinimumClearance(g)
return rp.getDistance()
}
getLine() {
this.compute()
if (this._minClearancePts === null || this._minClearancePts[0] === null) return this._inputGeom.getFactory().createLineString()
return this._inputGeom.getFactory().createLineString(this._minClearancePts)
}
compute() {
if (this._minClearancePts !== null) return null
this._minClearancePts = new Array(2).fill(null)
this._minClearance = Double.MAX_VALUE
if (this._inputGeom.isEmpty())
return null
const geomTree = FacetSequenceTreeBuilder.build(this._inputGeom)
const nearest = geomTree.nearestNeighbour(new MinClearanceDistance())
const mcd = new MinClearanceDistance()
this._minClearance = mcd.distance(nearest[0], nearest[1])
this._minClearancePts = mcd.getCoordinates()
}
getDistance() {
this.compute()
return this._minClearance
}
}
class MinClearanceDistance {
constructor() {
MinClearanceDistance.constructor_.apply(this, arguments)
}
static constructor_() {
this._minDist = Double.MAX_VALUE
this._minPts = new Array(2).fill(null)
}
vertexDistance(fs1, fs2) {
for (let i1 = 0; i1 < fs1.size(); i1++)
for (let i2 = 0; i2 < fs2.size(); i2++) {
const p1 = fs1.getCoordinate(i1)
const p2 = fs2.getCoordinate(i2)
if (!p1.equals2D(p2)) {
const d = p1.distance(p2)
if (d < this._minDist) {
this._minDist = d
this._minPts[0] = p1
this._minPts[1] = p2
if (d === 0.0) return d
}
}
}
return this._minDist
}
getCoordinates() {
return this._minPts
}
segmentDistance(fs1, fs2) {
for (let i1 = 0; i1 < fs1.size(); i1++)
for (let i2 = 1; i2 < fs2.size(); i2++) {
const p = fs1.getCoordinate(i1)
const seg0 = fs2.getCoordinate(i2 - 1)
const seg1 = fs2.getCoordinate(i2)
if (!(p.equals2D(seg0) || p.equals2D(seg1))) {
const d = Distance.pointToSegment(p, seg0, seg1)
if (d < this._minDist) {
this._minDist = d
this.updatePts(p, seg0, seg1)
if (d === 0.0) return d
}
}
}
return this._minDist
}
distance() {
if (arguments[0] instanceof ItemBoundable && arguments[1] instanceof ItemBoundable) {
const b1 = arguments[0], b2 = arguments[1]
const fs1 = b1.getItem()
const fs2 = b2.getItem()
this._minDist = Double.MAX_VALUE
return this.distance(fs1, fs2)
} else if (arguments[0] instanceof FacetSequence && arguments[1] instanceof FacetSequence) {
const fs1 = arguments[0], fs2 = arguments[1]
this.vertexDistance(fs1, fs2)
if (fs1.size() === 1 && fs2.size() === 1) return this._minDist
if (this._minDist <= 0.0) return this._minDist
this.segmentDistance(fs1, fs2)
if (this._minDist <= 0.0) return this._minDist
this.segmentDistance(fs2, fs1)
return this._minDist
}
}
updatePts(p, seg0, seg1) {
this._minPts[0] = p
const seg = new LineSegment(seg0, seg1)
this._minPts[1] = new Coordinate(seg.closestPoint(p))
}
get interfaces_() {
return [ItemDistance]
}
}
MinimumClearance.MinClearanceDistance = MinClearanceDistance