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
171 lines (169 loc) • 6 kB
JavaScript
import BufferParameters from './BufferParameters'
import Position from '../../geomgraph/Position'
import Coordinate from '../../geom/Coordinate'
import BufferInputLineSimplifier from './BufferInputLineSimplifier'
import CoordinateArrays from '../../geom/CoordinateArrays'
import OffsetSegmentGenerator from './OffsetSegmentGenerator'
export default class OffsetCurveBuilder {
constructor () {
this._distance = 0.0
this._precisionModel = null
this._bufParams = null
const precisionModel = arguments[0]
const bufParams = arguments[1]
this._precisionModel = precisionModel
this._bufParams = bufParams
}
getOffsetCurve (inputPts, distance) {
this._distance = distance
if (distance === 0.0) return null
let isRightSide = distance < 0.0
const posDistance = Math.abs(distance)
const segGen = this.getSegGen(posDistance)
if (inputPts.length <= 1) {
this.computePointCurve(inputPts[0], segGen)
} else {
this.computeOffsetCurve(inputPts, isRightSide, segGen)
}
const curvePts = segGen.getCoordinates()
if (isRightSide) CoordinateArrays.reverse(curvePts)
return curvePts
}
computeSingleSidedBufferCurve (inputPts, isRightSide, segGen) {
const distTol = this.simplifyTolerance(this._distance)
if (isRightSide) {
segGen.addSegments(inputPts, true)
const simp2 = BufferInputLineSimplifier.simplify(inputPts, -distTol)
const n2 = simp2.length - 1
segGen.initSideSegments(simp2[n2], simp2[n2 - 1], Position.LEFT)
segGen.addFirstSegment()
for (let i = n2 - 2; i >= 0; i--) {
segGen.addNextSegment(simp2[i], true)
}
} else {
segGen.addSegments(inputPts, false)
const simp1 = BufferInputLineSimplifier.simplify(inputPts, distTol)
const n1 = simp1.length - 1
segGen.initSideSegments(simp1[0], simp1[1], Position.LEFT)
segGen.addFirstSegment()
for (let i = 2; i <= n1; i++) {
segGen.addNextSegment(simp1[i], true)
}
}
segGen.addLastSegment()
segGen.closeRing()
}
computeRingBufferCurve (inputPts, side, segGen) {
let distTol = this.simplifyTolerance(this._distance)
if (side === Position.RIGHT) distTol = -distTol
const simp = BufferInputLineSimplifier.simplify(inputPts, distTol)
const n = simp.length - 1
segGen.initSideSegments(simp[n - 1], simp[0], side)
for (let i = 1; i <= n; i++) {
const addStartPoint = i !== 1
segGen.addNextSegment(simp[i], addStartPoint)
}
segGen.closeRing()
}
computeLineBufferCurve (inputPts, segGen) {
const distTol = this.simplifyTolerance(this._distance)
const simp1 = BufferInputLineSimplifier.simplify(inputPts, distTol)
const n1 = simp1.length - 1
segGen.initSideSegments(simp1[0], simp1[1], Position.LEFT)
for (let i = 2; i <= n1; i++) {
segGen.addNextSegment(simp1[i], true)
}
segGen.addLastSegment()
segGen.addLineEndCap(simp1[n1 - 1], simp1[n1])
const simp2 = BufferInputLineSimplifier.simplify(inputPts, -distTol)
const n2 = simp2.length - 1
segGen.initSideSegments(simp2[n2], simp2[n2 - 1], Position.LEFT)
for (let i = n2 - 2; i >= 0; i--) {
segGen.addNextSegment(simp2[i], true)
}
segGen.addLastSegment()
segGen.addLineEndCap(simp2[1], simp2[0])
segGen.closeRing()
}
computePointCurve (pt, segGen) {
switch (this._bufParams.getEndCapStyle()) {
case BufferParameters.CAP_ROUND:
segGen.createCircle(pt)
break
case BufferParameters.CAP_SQUARE:
segGen.createSquare(pt)
break
default:
}
}
getLineCurve (inputPts, distance) {
this._distance = distance
if (distance < 0.0 && !this._bufParams.isSingleSided()) return null
if (distance === 0.0) return null
const posDistance = Math.abs(distance)
const segGen = this.getSegGen(posDistance)
if (inputPts.length <= 1) {
this.computePointCurve(inputPts[0], segGen)
} else {
if (this._bufParams.isSingleSided()) {
let isRightSide = distance < 0.0
this.computeSingleSidedBufferCurve(inputPts, isRightSide, segGen)
} else this.computeLineBufferCurve(inputPts, segGen)
}
const lineCoord = segGen.getCoordinates()
return lineCoord
}
getBufferParameters () {
return this._bufParams
}
simplifyTolerance (bufDistance) {
return bufDistance * this._bufParams.getSimplifyFactor()
}
getRingCurve (inputPts, side, distance) {
this._distance = distance
if (inputPts.length <= 2) return this.getLineCurve(inputPts, distance)
if (distance === 0.0) {
return OffsetCurveBuilder.copyCoordinates(inputPts)
}
const segGen = this.getSegGen(distance)
this.computeRingBufferCurve(inputPts, side, segGen)
return segGen.getCoordinates()
}
computeOffsetCurve (inputPts, isRightSide, segGen) {
const distTol = this.simplifyTolerance(this._distance)
if (isRightSide) {
const simp2 = BufferInputLineSimplifier.simplify(inputPts, -distTol)
const n2 = simp2.length - 1
segGen.initSideSegments(simp2[n2], simp2[n2 - 1], Position.LEFT)
segGen.addFirstSegment()
for (let i = n2 - 2; i >= 0; i--) {
segGen.addNextSegment(simp2[i], true)
}
} else {
const simp1 = BufferInputLineSimplifier.simplify(inputPts, distTol)
const n1 = simp1.length - 1
segGen.initSideSegments(simp1[0], simp1[1], Position.LEFT)
segGen.addFirstSegment()
for (let i = 2; i <= n1; i++) {
segGen.addNextSegment(simp1[i], true)
}
}
segGen.addLastSegment()
}
getSegGen (distance) {
return new OffsetSegmentGenerator(this._precisionModel, this._bufParams, distance)
}
interfaces_ () {
return []
}
getClass () {
return OffsetCurveBuilder
}
static copyCoordinates (pts) {
const copy = new Array(pts.length).fill(null)
for (let i = 0; i < copy.length; i++) {
copy[i] = new Coordinate(pts[i])
}
return copy
}
}