UNPKG

isoxml-angular

Version:

JavaScript library to parse and generate ISOXML (ISO11783-10) files

149 lines (148 loc) 7.19 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ExtendedPolygon = void 0; const turf_1 = require("@turf/turf"); const polygon_clipping_1 = require("polygon-clipping"); const baseEntities_1 = require("../baseEntities"); const classRegistry_1 = require("../classRegistry"); const LineString_1 = require("./LineString"); class ExtendedPolygon extends baseEntities_1.Polygon { constructor(attributes, isoxmlManager) { super(attributes, isoxmlManager); this.tag = "PLN" /* TAGS.Polygon */; } static fromXML(xml, isoxmlManager, internalId) { return baseEntities_1.Polygon.fromXML(xml, isoxmlManager, internalId, ExtendedPolygon); } static fromGeoJSON(geoJSON, polygonType, isoxmlManager) { if (geoJSON.type === 'Polygon') { geoJSON = { type: 'MultiPolygon', coordinates: [geoJSON.coordinates] }; } if (isoxmlManager.options.version === 3) { const lineStrings = [].concat(...geoJSON.coordinates.map(component => component.map((ring, idx) => LineString_1.ExtendedLineString.fromGeoJSONCoordinates(ring, isoxmlManager, idx ? "2" /* LineStringLineStringTypeEnum.PolygonInterior */ : "1" /* LineStringLineStringTypeEnum.PolygonExterior */)))); return [new ExtendedPolygon({ PolygonType: polygonType, LineString: lineStrings }, isoxmlManager)]; } else { return geoJSON.coordinates.map(component => new ExtendedPolygon({ PolygonType: polygonType, LineString: component.map((ring, idx) => LineString_1.ExtendedLineString.fromGeoJSONCoordinates(ring, isoxmlManager, idx ? "2" /* LineStringLineStringTypeEnum.PolygonInterior */ : "1" /* LineStringLineStringTypeEnum.PolygonExterior */)) }, isoxmlManager)); } } // converts polygons to fits format of the target ISOXML version (taken from the first Polygon) static normalizePolygons(polygons) { if (!polygons || polygons.length === 0) { return []; } const isoxmlManager = polygons[0].isoxmlManager; if (isoxmlManager.options.version === 3) { if (polygons.length === 1) { return polygons; } const allLineStrings = [].concat(...polygons.map(poly => poly.attributes.LineString)); const combinedPolygon = new ExtendedPolygon(Object.assign(Object.assign({}, polygons[0].attributes), { LineString: allLineStrings }), isoxmlManager); delete combinedPolygon.attributes.PolygonArea; // area recalculation is not implemented return [combinedPolygon]; } else { const splittedPolygons = []; polygons.forEach(polygon => { const outerRings = polygon.attributes.LineString .filter((ring) => ring.attributes.LineStringType === "1" /* LineStringLineStringTypeEnum.PolygonExterior */); if (outerRings.length <= 1) { splittedPolygons.push(polygon); return; } const innerRings = polygon.attributes.LineString .filter((ring) => ring.attributes.LineStringType === "2" /* LineStringLineStringTypeEnum.PolygonInterior */); const outerRingIdxs = innerRings.map((ring) => { let maxArea = 0; let bestIdx = -1; outerRings.forEach((outerRing, idx) => { const intersectionRes = (0, polygon_clipping_1.intersection)([outerRing.toCoordinatesArray()], [ring.toCoordinatesArray()]); if (intersectionRes) { const areaRes = (0, turf_1.area)({ type: 'MultiPolygon', coordinates: intersectionRes }); if (areaRes > maxArea) { maxArea = areaRes; bestIdx = idx; } } }); return bestIdx; }); outerRings.forEach((outerRing, outerIdx) => { const splittedPolygon = new ExtendedPolygon(Object.assign(Object.assign({}, polygon.attributes), { LineString: [ outerRing, ...innerRings.filter((_, innerIdx) => outerRingIdxs[innerIdx] === outerIdx) ] }), isoxmlManager); delete splittedPolygon.attributes.PolygonArea; // area recalculation is not implemented splittedPolygons.push(splittedPolygon); }); }); return splittedPolygons; } } static toGeoJSON(polygons) { if (!polygons || polygons.length === 0) { return null; } const geoJSONCoordinates = []; polygons.forEach(polygon => { const outerRings = polygon.attributes.LineString .filter((ring) => ring.attributes.LineStringType === "1" /* LineStringLineStringTypeEnum.PolygonExterior */) .map((ring) => ring.toCoordinatesArray()); const innerRings = polygon.attributes.LineString .filter((ring) => ring.attributes.LineStringType === "2" /* LineStringLineStringTypeEnum.PolygonInterior */) .map((ring) => ring.toCoordinatesArray()); if (outerRings.length === 0) { return; } else if (outerRings.length === 1) { geoJSONCoordinates.push([ outerRings[0], ...innerRings ]); return; } const outerRingIdxs = innerRings.map((ring) => { let maxArea = 0; let bestIdx = -1; outerRings.forEach((outerRing, idx) => { const intersectionRes = (0, polygon_clipping_1.intersection)([outerRing], [ring]); if (intersectionRes) { const areaRes = (0, turf_1.area)({ type: 'MultiPolygon', coordinates: intersectionRes }); if (areaRes > maxArea) { maxArea = areaRes; bestIdx = idx; } } }); return bestIdx; }); outerRings.forEach((outerRing, outerIdx) => { geoJSONCoordinates.push([ outerRing, ...innerRings.filter((_, innerIdx) => outerRingIdxs[innerIdx] === outerIdx) ]); }); }); const geoJSON = { type: 'MultiPolygon', coordinates: geoJSONCoordinates }; geoJSON.bbox = (0, turf_1.bbox)(geoJSON); return geoJSON; } } exports.ExtendedPolygon = ExtendedPolygon; (0, classRegistry_1.registerEntityClass)('main', "PLN" /* TAGS.Polygon */, ExtendedPolygon);