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
232 lines (230 loc) • 7.98 kB
JavaScript
import NotRepresentableException from './NotRepresentableException'
import CGAlgorithms from './CGAlgorithms'
import Coordinate from '../geom/Coordinate'
import CGAlgorithmsDD from './CGAlgorithmsDD'
import System from '../../../../java/lang/System'
import HCoordinate from './HCoordinate'
import Envelope from '../geom/Envelope'
import LineIntersector from './LineIntersector'
export default class RobustLineIntersector extends LineIntersector {
isInSegmentEnvelopes (intPt) {
const env0 = new Envelope(this._inputLines[0][0], this._inputLines[0][1])
const env1 = new Envelope(this._inputLines[1][0], this._inputLines[1][1])
return env0.contains(intPt) && env1.contains(intPt)
}
computeIntersection () {
if (arguments.length === 3) {
const p = arguments[0]
const p1 = arguments[1]
const p2 = arguments[2]
this._isProper = false
if (Envelope.intersects(p1, p2, p)) {
if (CGAlgorithms.orientationIndex(p1, p2, p) === 0 && CGAlgorithms.orientationIndex(p2, p1, p) === 0) {
this._isProper = true
if (p.equals(p1) || p.equals(p2)) {
this._isProper = false
}
this._result = LineIntersector.POINT_INTERSECTION
return null
}
}
this._result = LineIntersector.NO_INTERSECTION
} else return LineIntersector.prototype.computeIntersection.apply(this, arguments)
}
normalizeToMinimum (n1, n2, n3, n4, normPt) {
normPt.x = this.smallestInAbsValue(n1.x, n2.x, n3.x, n4.x)
normPt.y = this.smallestInAbsValue(n1.y, n2.y, n3.y, n4.y)
n1.x -= normPt.x
n1.y -= normPt.y
n2.x -= normPt.x
n2.y -= normPt.y
n3.x -= normPt.x
n3.y -= normPt.y
n4.x -= normPt.x
n4.y -= normPt.y
}
safeHCoordinateIntersection (p1, p2, q1, q2) {
let intPt = null
try {
intPt = HCoordinate.intersection(p1, p2, q1, q2)
} catch (e) {
if (e instanceof NotRepresentableException) {
intPt = RobustLineIntersector.nearestEndpoint(p1, p2, q1, q2)
} else throw e
} finally {}
return intPt
}
intersection (p1, p2, q1, q2) {
let intPt = this.intersectionWithNormalization(p1, p2, q1, q2)
if (!this.isInSegmentEnvelopes(intPt)) {
intPt = new Coordinate(RobustLineIntersector.nearestEndpoint(p1, p2, q1, q2))
}
if (this._precisionModel !== null) {
this._precisionModel.makePrecise(intPt)
}
return intPt
}
smallestInAbsValue (x1, x2, x3, x4) {
let x = x1
let xabs = Math.abs(x)
if (Math.abs(x2) < xabs) {
x = x2
xabs = Math.abs(x2)
}
if (Math.abs(x3) < xabs) {
x = x3
xabs = Math.abs(x3)
}
if (Math.abs(x4) < xabs) {
x = x4
}
return x
}
checkDD (p1, p2, q1, q2, intPt) {
const intPtDD = CGAlgorithmsDD.intersection(p1, p2, q1, q2)
const isIn = this.isInSegmentEnvelopes(intPtDD)
System.out.println('DD in env = ' + isIn + ' --------------------- ' + intPtDD)
if (intPt.distance(intPtDD) > 0.0001) {
System.out.println('Distance = ' + intPt.distance(intPtDD))
}
}
intersectionWithNormalization (p1, p2, q1, q2) {
const n1 = new Coordinate(p1)
const n2 = new Coordinate(p2)
const n3 = new Coordinate(q1)
const n4 = new Coordinate(q2)
const normPt = new Coordinate()
this.normalizeToEnvCentre(n1, n2, n3, n4, normPt)
const intPt = this.safeHCoordinateIntersection(n1, n2, n3, n4)
intPt.x += normPt.x
intPt.y += normPt.y
return intPt
}
computeCollinearIntersection (p1, p2, q1, q2) {
const p1q1p2 = Envelope.intersects(p1, p2, q1)
const p1q2p2 = Envelope.intersects(p1, p2, q2)
const q1p1q2 = Envelope.intersects(q1, q2, p1)
const q1p2q2 = Envelope.intersects(q1, q2, p2)
if (p1q1p2 && p1q2p2) {
this._intPt[0] = q1
this._intPt[1] = q2
return LineIntersector.COLLINEAR_INTERSECTION
}
if (q1p1q2 && q1p2q2) {
this._intPt[0] = p1
this._intPt[1] = p2
return LineIntersector.COLLINEAR_INTERSECTION
}
if (p1q1p2 && q1p1q2) {
this._intPt[0] = q1
this._intPt[1] = p1
return q1.equals(p1) && !p1q2p2 && !q1p2q2 ? LineIntersector.POINT_INTERSECTION : LineIntersector.COLLINEAR_INTERSECTION
}
if (p1q1p2 && q1p2q2) {
this._intPt[0] = q1
this._intPt[1] = p2
return q1.equals(p2) && !p1q2p2 && !q1p1q2 ? LineIntersector.POINT_INTERSECTION : LineIntersector.COLLINEAR_INTERSECTION
}
if (p1q2p2 && q1p1q2) {
this._intPt[0] = q2
this._intPt[1] = p1
return q2.equals(p1) && !p1q1p2 && !q1p2q2 ? LineIntersector.POINT_INTERSECTION : LineIntersector.COLLINEAR_INTERSECTION
}
if (p1q2p2 && q1p2q2) {
this._intPt[0] = q2
this._intPt[1] = p2
return q2.equals(p2) && !p1q1p2 && !q1p1q2 ? LineIntersector.POINT_INTERSECTION : LineIntersector.COLLINEAR_INTERSECTION
}
return LineIntersector.NO_INTERSECTION
}
normalizeToEnvCentre (n00, n01, n10, n11, normPt) {
const minX0 = n00.x < n01.x ? n00.x : n01.x
const minY0 = n00.y < n01.y ? n00.y : n01.y
const maxX0 = n00.x > n01.x ? n00.x : n01.x
const maxY0 = n00.y > n01.y ? n00.y : n01.y
const minX1 = n10.x < n11.x ? n10.x : n11.x
const minY1 = n10.y < n11.y ? n10.y : n11.y
const maxX1 = n10.x > n11.x ? n10.x : n11.x
const maxY1 = n10.y > n11.y ? n10.y : n11.y
const intMinX = minX0 > minX1 ? minX0 : minX1
const intMaxX = maxX0 < maxX1 ? maxX0 : maxX1
const intMinY = minY0 > minY1 ? minY0 : minY1
const intMaxY = maxY0 < maxY1 ? maxY0 : maxY1
const intMidX = (intMinX + intMaxX) / 2.0
const intMidY = (intMinY + intMaxY) / 2.0
normPt.x = intMidX
normPt.y = intMidY
n00.x -= normPt.x
n00.y -= normPt.y
n01.x -= normPt.x
n01.y -= normPt.y
n10.x -= normPt.x
n10.y -= normPt.y
n11.x -= normPt.x
n11.y -= normPt.y
}
computeIntersect (p1, p2, q1, q2) {
this._isProper = false
if (!Envelope.intersects(p1, p2, q1, q2)) return LineIntersector.NO_INTERSECTION
const Pq1 = CGAlgorithms.orientationIndex(p1, p2, q1)
const Pq2 = CGAlgorithms.orientationIndex(p1, p2, q2)
if ((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) {
return LineIntersector.NO_INTERSECTION
}
const Qp1 = CGAlgorithms.orientationIndex(q1, q2, p1)
const Qp2 = CGAlgorithms.orientationIndex(q1, q2, p2)
if ((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) {
return LineIntersector.NO_INTERSECTION
}
const collinear = Pq1 === 0 && Pq2 === 0 && Qp1 === 0 && Qp2 === 0
if (collinear) {
return this.computeCollinearIntersection(p1, p2, q1, q2)
}
if (Pq1 === 0 || Pq2 === 0 || Qp1 === 0 || Qp2 === 0) {
this._isProper = false
if (p1.equals2D(q1) || p1.equals2D(q2)) {
this._intPt[0] = p1
} else if (p2.equals2D(q1) || p2.equals2D(q2)) {
this._intPt[0] = p2
} else if (Pq1 === 0) {
this._intPt[0] = new Coordinate(q1)
} else if (Pq2 === 0) {
this._intPt[0] = new Coordinate(q2)
} else if (Qp1 === 0) {
this._intPt[0] = new Coordinate(p1)
} else if (Qp2 === 0) {
this._intPt[0] = new Coordinate(p2)
}
} else {
this._isProper = true
this._intPt[0] = this.intersection(p1, p2, q1, q2)
}
return LineIntersector.POINT_INTERSECTION
}
interfaces_ () {
return []
}
getClass () {
return RobustLineIntersector
}
static nearestEndpoint (p1, p2, q1, q2) {
let nearestPt = p1
let minDist = CGAlgorithms.distancePointLine(p1, q1, q2)
let dist = CGAlgorithms.distancePointLine(p2, q1, q2)
if (dist < minDist) {
minDist = dist
nearestPt = p2
}
dist = CGAlgorithms.distancePointLine(q1, p1, p2)
if (dist < minDist) {
minDist = dist
nearestPt = q1
}
dist = CGAlgorithms.distancePointLine(q2, p1, p2)
if (dist < minDist) {
minDist = dist
nearestPt = q2
}
return nearestPt
}
}