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
133 lines (131 loc) • 3.75 kB
JavaScript
// index.ts
import {
lineString,
multiLineString,
multiPolygon,
polygon
} from "@turf/helpers";
import { getGeom } from "@turf/invariant";
// lib/lineclip.ts
function lineclip(points, bbox, result) {
var len = points.length, codeA = bitCode(points[0], bbox), part = [], i, codeB, lastCode;
let a;
let b;
if (!result) result = [];
for (i = 1; i < len; i++) {
a = points[i - 1];
b = points[i];
codeB = lastCode = bitCode(b, bbox);
while (true) {
if (!(codeA | codeB)) {
part.push(a);
if (codeB !== lastCode) {
part.push(b);
if (i < len - 1) {
result.push(part);
part = [];
}
} else if (i === len - 1) {
part.push(b);
}
break;
} else if (codeA & codeB) {
break;
} else if (codeA) {
a = intersect(a, b, codeA, bbox);
codeA = bitCode(a, bbox);
} else {
b = intersect(a, b, codeB, bbox);
codeB = bitCode(b, bbox);
}
}
codeA = lastCode;
}
if (part.length) result.push(part);
return result;
}
function polygonclip(points, bbox) {
var result, edge, prev, prevInside, i, p, inside;
for (edge = 1; edge <= 8; edge *= 2) {
result = [];
prev = points[points.length - 1];
prevInside = !(bitCode(prev, bbox) & edge);
for (i = 0; i < points.length; i++) {
p = points[i];
inside = !(bitCode(p, bbox) & edge);
if (inside !== prevInside) result.push(intersect(prev, p, edge, bbox));
if (inside) result.push(p);
prev = p;
prevInside = inside;
}
points = result;
if (!points.length) break;
}
return result;
}
function intersect(a, b, edge, bbox) {
return edge & 8 ? [a[0] + (b[0] - a[0]) * (bbox[3] - a[1]) / (b[1] - a[1]), bbox[3]] : edge & 4 ? [a[0] + (b[0] - a[0]) * (bbox[1] - a[1]) / (b[1] - a[1]), bbox[1]] : edge & 2 ? [bbox[2], a[1] + (b[1] - a[1]) * (bbox[2] - a[0]) / (b[0] - a[0])] : edge & 1 ? [bbox[0], a[1] + (b[1] - a[1]) * (bbox[0] - a[0]) / (b[0] - a[0])] : null;
}
function bitCode(p, bbox) {
var code = 0;
if (p[0] < bbox[0]) code |= 1;
else if (p[0] > bbox[2]) code |= 2;
if (p[1] < bbox[1]) code |= 4;
else if (p[1] > bbox[3]) code |= 8;
return code;
}
// index.ts
function bboxClip(feature, bbox) {
const geom = getGeom(feature);
const type = geom.type;
const properties = feature.type === "Feature" ? feature.properties : {};
let coords = geom.coordinates;
switch (type) {
case "LineString":
case "MultiLineString": {
const lines = [];
if (type === "LineString") {
coords = [coords];
}
coords.forEach((line) => {
lineclip(line, bbox, lines);
});
if (lines.length === 1) {
return lineString(lines[0], properties);
}
return multiLineString(lines, properties);
}
case "Polygon":
return polygon(clipPolygon(coords, bbox), properties);
case "MultiPolygon":
return multiPolygon(
coords.map((poly) => {
return clipPolygon(poly, bbox);
}),
properties
);
default:
throw new Error("geometry " + type + " not supported");
}
}
function clipPolygon(rings, bbox) {
const outRings = [];
for (const ring of rings) {
const clipped = polygonclip(ring, bbox);
if (clipped.length > 0) {
if (clipped[0][0] !== clipped[clipped.length - 1][0] || clipped[0][1] !== clipped[clipped.length - 1][1]) {
clipped.push(clipped[0]);
}
if (clipped.length >= 4) {
outRings.push(clipped);
}
}
}
return outRings;
}
var turf_bbox_clip_default = bboxClip;
export {
bboxClip,
turf_bbox_clip_default as default
};
//# sourceMappingURL=index.js.map