isoxml
Version:
JavaScript library to parse and generate ISOXML (ISO11783-10) files
80 lines (79 loc) • 3.98 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.intersectionBasedGridGenerator = void 0;
const turf_1 = require("@turf/turf");
const polygon_clipping_1 = __importDefault(require("polygon-clipping"));
const rbush_1 = __importDefault(require("rbush"));
function intersectionBasedGridGenerator(geoJSON, propertyNames, gridParams) {
var _a;
const { minX, minY, numCols, numRows, cellWidth, cellHeight } = gridParams;
const filelength = numCols * numRows * 4 * propertyNames.length;
const buffer = new ArrayBuffer(filelength);
const int32array = new Int32Array(buffer);
const tree = new rbush_1.default();
tree.load(geoJSON.features.map(f => {
const [bboxMinX, bboxMinY, bboxMaxX, bboxMaxY] = (0, turf_1.bbox)(f);
return { minX: bboxMinX, minY: bboxMinY, maxX: bboxMaxX, maxY: bboxMaxY, feature: f };
}));
let index = 0;
for (let y = 0; y < numRows; y++) {
const subTree = new rbush_1.default();
// TODO: check that it gives performance boost (test case: many small polygons)
subTree.load(tree.search({
minX: minX,
minY: minY + y * cellHeight,
maxX: minX + (numCols) * cellWidth,
maxY: minY + (y + 1) * cellHeight
}));
for (let x = 0; x < numCols; x++) {
// Simplified algorithm: just check the center of cell
// const lng = minX + (x + 0.5) * cellWidth
// const lat = minY + (y + 0.5) * cellHeight
// const searchResults = tree.search({minX: lng, minY: lat, maxX: lng, maxY: lat})
// const feature = searchResults.find(res => booleanPointInPolygon([lng, lat], res.feature))?.feature
const searchResults = subTree.search({
minX: minX + x * cellWidth,
minY: minY + y * cellHeight,
maxX: minX + (x + 1) * cellWidth,
maxY: minY + (y + 1) * cellHeight
});
let feature = null;
let maxArea = 0;
let uncoveredArea = cellWidth * cellHeight;
if (searchResults.length > 0) {
const cell = [[
[minX + x * cellWidth, minY + y * cellHeight],
[minX + x * cellWidth, minY + (y + 1) * cellHeight],
[minX + (x + 1) * cellWidth, minY + (y + 1) * cellHeight],
[minX + (x + 1) * cellWidth, minY + y * cellHeight],
[minX + x * cellWidth, minY + y * cellHeight]
]];
searchResults.some(res => {
const intersectionRes = polygon_clipping_1.default.intersection(res.feature.geometry.coordinates, cell);
if (intersectionRes.length) {
if (searchResults.length === 1) {
feature = res.feature;
return true;
}
const intersectionArea = (0, turf_1.area)({ type: 'MultiPolygon', coordinates: intersectionRes });
uncoveredArea -= intersectionArea;
if (intersectionArea > maxArea) {
feature = res.feature;
maxArea = intersectionArea;
}
return maxArea > uncoveredArea;
}
});
}
for (const propertyName of propertyNames) {
const value = Math.round((_a = feature === null || feature === void 0 ? void 0 : feature.properties[propertyName]) !== null && _a !== void 0 ? _a : 0);
int32array[index++] = value;
}
}
}
return buffer;
}
exports.intersectionBasedGridGenerator = intersectionBasedGridGenerator;