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
138 lines (135 loc) • 4.23 kB
JavaScript
import Geometry from '../geom/Geometry'
import Coordinate from '../geom/Coordinate'
import Polygon from '../geom/Polygon'
import SnapIfNeededOverlayOp from '../operation/overlay/snap/SnapIfNeededOverlayOp'
import Double from '../../../../java/lang/Double'
import GeometryCollection from '../geom/GeometryCollection'
import OverlayOp from '../operation/overlay/OverlayOp'
export default class InteriorPointArea {
constructor () {
this._factory = null
this._interiorPoint = null
this._maxWidth = 0.0
let g = arguments[0]
this._factory = g.getFactory()
this.add(g)
}
addPolygon (geometry) {
if (geometry.isEmpty()) return null
var intPt = null
var width = 0
var bisector = this.horizontalBisector(geometry)
if (bisector.getLength() === 0.0) {
width = 0
intPt = bisector.getCoordinate()
} else {
var intersections = SnapIfNeededOverlayOp.overlayOp(bisector, geometry, OverlayOp.INTERSECTION)
var widestIntersection = this.widestGeometry(intersections)
width = widestIntersection.getEnvelopeInternal().getWidth()
intPt = InteriorPointArea.centre(widestIntersection.getEnvelopeInternal())
}
if (this._interiorPoint === null || width > this._maxWidth) {
this._interiorPoint = intPt
this._maxWidth = width
}
}
getInteriorPoint () {
return this._interiorPoint
}
widestGeometry () {
if (arguments[0] instanceof GeometryCollection) {
let gc = arguments[0]
if (gc.isEmpty()) {
return gc
}
var widestGeometry = gc.getGeometryN(0)
for (var i = 1; i < gc.getNumGeometries(); i++) {
if (gc.getGeometryN(i).getEnvelopeInternal().getWidth() > widestGeometry.getEnvelopeInternal().getWidth()) {
widestGeometry = gc.getGeometryN(i)
}
}
return widestGeometry
} else if (arguments[0] instanceof Geometry) {
let geometry = arguments[0]
if (!(geometry instanceof GeometryCollection)) {
return geometry
}
return this.widestGeometry(geometry)
}
}
horizontalBisector (geometry) {
var envelope = geometry.getEnvelopeInternal()
var bisectY = SafeBisectorFinder.getBisectorY(geometry)
return this._factory.createLineString([new Coordinate(envelope.getMinX(), bisectY), new Coordinate(envelope.getMaxX(), bisectY)])
}
add (geom) {
if (geom instanceof Polygon) {
this.addPolygon(geom)
} else if (geom instanceof GeometryCollection) {
var gc = geom
for (var i = 0; i < gc.getNumGeometries(); i++) {
this.add(gc.getGeometryN(i))
}
}
}
interfaces_ () {
return []
}
getClass () {
return InteriorPointArea
}
static centre (envelope) {
return new Coordinate(InteriorPointArea.avg(envelope.getMinX(), envelope.getMaxX()), InteriorPointArea.avg(envelope.getMinY(), envelope.getMaxY()))
}
static avg (a, b) {
return (a + b) / 2.0
}
static get SafeBisectorFinder () { return SafeBisectorFinder }
}
class SafeBisectorFinder {
constructor () {
this._poly = null
this._centreY = null
this._hiY = Double.MAX_VALUE
this._loY = -Double.MAX_VALUE
let poly = arguments[0]
this._poly = poly
this._hiY = poly.getEnvelopeInternal().getMaxY()
this._loY = poly.getEnvelopeInternal().getMinY()
this._centreY = InteriorPointArea.avg(this._loY, this._hiY)
}
updateInterval (y) {
if (y <= this._centreY) {
if (y > this._loY) this._loY = y
} else if (y > this._centreY) {
if (y < this._hiY) {
this._hiY = y
}
}
}
getBisectorY () {
this.process(this._poly.getExteriorRing())
for (var i = 0; i < this._poly.getNumInteriorRing(); i++) {
this.process(this._poly.getInteriorRingN(i))
}
var bisectY = InteriorPointArea.avg(this._hiY, this._loY)
return bisectY
}
process (line) {
var seq = line.getCoordinateSequence()
for (var i = 0; i < seq.size(); i++) {
var y = seq.getY(i)
this.updateInterval(y)
}
}
interfaces_ () {
return []
}
getClass () {
return SafeBisectorFinder
}
static getBisectorY (poly) {
var finder = new SafeBisectorFinder(poly)
return finder.getBisectorY()
}
}