geography-markup-language
Version:
Parse OGC Geography Markup Language in Pure JavaScript
833 lines (770 loc) • 24.2 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// node_modules/.pnpm/bbox-fns@0.6.0/node_modules/bbox-fns/polygon.js
var require_polygon = __commonJS({
"node_modules/.pnpm/bbox-fns@0.6.0/node_modules/bbox-fns/polygon.js"(exports, module2) {
function polygon([x0, y0, x1, y1]) {
return [
[
[x0, y1],
// top-left
[x0, y0],
// bottom-left
[x1, y0],
// bottom-right
[x1, y1],
// top-right
[x0, y1]
// top-left
]
];
}
module2.exports = polygon;
module2.exports.default = polygon;
}
});
// node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/get-attribute.js
var require_get_attribute = __commonJS({
"node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/get-attribute.js"(exports, module2) {
function getAttribute8(tag, attributeName, options) {
const debug = options && options.debug || false;
if (debug)
console.log("getting " + attributeName + " in " + tag);
const xml = typeof tag === "object" ? tag.outer : tag;
const pattern = `${attributeName}\\="([^"]*)"`;
if (debug)
console.log("pattern:", pattern);
const re = new RegExp(pattern);
const match = re.exec(xml);
if (debug)
console.log("match:", match);
if (match)
return match[1];
}
module2.exports = getAttribute8;
module2.exports.default = getAttribute8;
}
});
// node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/index-of-match.js
var require_index_of_match = __commonJS({
"node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/index-of-match.js"(exports, module2) {
function indexOfMatch(xml, pattern, startIndex) {
const re = new RegExp(pattern);
const match = re.exec(xml.slice(startIndex));
if (match)
return startIndex + match.index;
else
return -1;
}
module2.exports = indexOfMatch;
module2.exports.default = indexOfMatch;
}
});
// node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/index-of-match-end.js
var require_index_of_match_end = __commonJS({
"node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/index-of-match-end.js"(exports, module2) {
function indexOfMatchEnd(xml, pattern, startIndex) {
const re = new RegExp(pattern);
const match = re.exec(xml.slice(startIndex));
if (match)
return startIndex + match.index + match[0].length - 1;
else
return -1;
}
module2.exports = indexOfMatchEnd;
module2.exports.default = indexOfMatchEnd;
}
});
// node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/count-substring.js
var require_count_substring = __commonJS({
"node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/count-substring.js"(exports, module2) {
function countSubstring(string, substring) {
const pattern = new RegExp(substring, "g");
const match = string.match(pattern);
return match ? match.length : 0;
}
module2.exports = countSubstring;
module2.exports.default = countSubstring;
}
});
// node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/find-tag-by-name.js
var require_find_tag_by_name = __commonJS({
"node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/find-tag-by-name.js"(exports, module2) {
var indexOfMatch = require_index_of_match();
var indexOfMatchEnd = require_index_of_match_end();
var countSubstring = require_count_substring();
function findTagByName4(xml, tagName, options) {
const debug = options && options.debug || false;
const nested = !(options && typeof options.nested === false);
const startIndex = options && options.startIndex || 0;
if (debug)
console.log("[xml-utils] starting findTagByName with", tagName, " and ", options);
const start = indexOfMatch(xml, `<${tagName}[ >/]`, startIndex);
if (debug)
console.log("[xml-utils] start:", start);
if (start === -1)
return void 0;
const afterStart = xml.slice(start + tagName.length);
let relativeEnd = indexOfMatchEnd(afterStart, "^[^<]*[ /]>", 0);
const selfClosing = relativeEnd !== -1 && afterStart[relativeEnd - 1] === "/";
if (debug)
console.log("[xml-utils] selfClosing:", selfClosing);
if (selfClosing === false) {
if (nested) {
let startIndex2 = 0;
let openings = 1;
let closings = 0;
while ((relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", startIndex2)) !== -1) {
const clip = afterStart.substring(startIndex2, relativeEnd + 1);
openings += countSubstring(clip, "<" + tagName);
closings += countSubstring(clip, "/" + tagName + ">");
if (closings >= openings)
break;
startIndex2 = relativeEnd;
}
} else {
relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", 0);
}
}
const end = start + tagName.length + relativeEnd + 1;
if (debug)
console.log("[xml-utils] end:", end);
if (end === -1)
return void 0;
const outer = xml.slice(start, end);
let inner;
if (selfClosing) {
inner = null;
} else {
inner = outer.slice(outer.indexOf(">") + 1, outer.lastIndexOf("<"));
}
return { inner, outer, start, end };
}
module2.exports = findTagByName4;
module2.exports.default = findTagByName4;
}
});
// node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/find-tags-by-name.js
var require_find_tags_by_name = __commonJS({
"node_modules/.pnpm/xml-utils@1.3.0/node_modules/xml-utils/find-tags-by-name.js"(exports, module2) {
var findTagByName4 = require_find_tag_by_name();
function findTagsByName3(xml, tagName, options) {
const tags = [];
const debug = options && options.debug || false;
const nested = options && typeof options.nested === "boolean" ? options.nested : true;
let startIndex = options && options.startIndex || 0;
let tag;
while (tag = findTagByName4(xml, tagName, { debug, startIndex })) {
if (nested) {
startIndex = tag.start + 1 + tagName.length;
} else {
startIndex = tag.end;
}
tags.push(tag);
}
if (debug)
console.log("findTagsByName found", tags.length, "tags");
return tags;
}
module2.exports = findTagsByName3;
module2.exports.default = findTagsByName3;
}
});
// index.js
var geography_markup_language_exports = {};
__export(geography_markup_language_exports, {
Envelope: () => Envelope,
Geometry: () => Geometry,
LineString: () => LineString3,
Point: () => Point3,
Polygon: () => Polygon4,
findGeometries: () => geometries
});
module.exports = __toCommonJS(geography_markup_language_exports);
// geometry/Envelope.js
var import_polygon = __toESM(require_polygon(), 1);
// parse/envelope.js
var import_get_attribute = __toESM(require_get_attribute(), 1);
// utils/find.js
var import_find_tags_by_name = __toESM(require_find_tags_by_name(), 1);
function find(xml, names) {
for (let i = 0; i < names.length; i++) {
const name = names[i];
const tags = (0, import_find_tags_by_name.default)(xml, name);
if (tags.length >= 1) {
return tags;
}
}
return [];
}
// enums/Envelope.js
var Envelope_default = ["gml:envelope", "envelope", "gml:Envelope", "Envelope"];
// find/Envelope.js
function envelope(xml) {
return find(xml, Envelope_default)[0];
}
// parse/lowerCorner.js
var import_find_tag_by_name = __toESM(require_find_tag_by_name(), 1);
// utils/reorder.js
function reorder(point) {
const y = point[0];
const x = point[1];
const rest = point.slice(2);
return [x, y].concat(rest);
}
// parse/lowerCorner.js
function lowerCorner(xml, { order = "default", raw = false } = {}) {
const tag = (0, import_find_tag_by_name.default)(xml, "gml:lowerCorner") || (0, import_find_tag_by_name.default)("lowerCorner");
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
let point = inner.trim().split(/[ ,]+/g);
if (!raw)
point = point.map((n) => Number(n));
if (order === "geojson")
point = reorder(point);
return point;
}
// parse/upperCorner.js
var import_find_tag_by_name2 = __toESM(require_find_tag_by_name(), 1);
function upperCorner(xml, { order = "default", raw = false } = {}) {
const tag = (0, import_find_tag_by_name2.default)(xml, "gml:upperCorner") || (0, import_find_tag_by_name2.default)("upperCorner");
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
let point = inner.trim().split(/[ ,]+/g);
if (!raw)
point = point.map((n) => Number(n));
if (order === "geojson")
point = reorder(point);
return point;
}
// parse/envelope.js
function envelope2(xml, { raw = false } = {}) {
const tag = envelope(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
const lowerCorner2 = lowerCorner(inner, { raw });
if (!lowerCorner2)
return;
const upperCorner2 = upperCorner(inner, { raw });
if (!upperCorner2)
return;
if (lowerCorner2.length !== upperCorner2.length) {
throw new Error("[geography-markup-language/parse/envelope] inconsistent number of dimensions");
}
const srs2 = (0, import_get_attribute.default)(tag.outer, "srsName") || null;
return { srs: srs2, corners: [lowerCorner2, upperCorner2] };
}
// geometry/Envelope.js
function Envelope(xml, { format = "default" } = {}) {
let order = "default";
let raw = false;
if (format === "geojson") {
order = "geojson";
}
const obj = envelope2(xml, { order, raw });
if (!obj)
return;
if (!format || format === "default")
return obj;
const { srs: srs2, corners } = obj;
const [lowerCorner2, upperCorner2] = corners;
if (format === "bbox" || format === "geojson") {
const [ymin, xmin, ...lowerCornerRest] = lowerCorner2;
const [ymax, xmax, ...upperCornerRest] = upperCorner2;
if (format === "bbox") {
return [xmin, ymin, ...lowerCornerRest, xmax, ymax, ...upperCornerRest];
} else if (format === "geojson") {
const bbox = [xmin, ymin, xmax, ymax];
const feature = {
type: "Feature",
bbox,
properties: {},
geometry: {
type: "Polygon",
coordinates: (0, import_polygon.default)(bbox)
}
};
if (srs2) {
feature.properties.srsName = srs2;
feature.crs = {
type: "name",
properties: {
name: srs2
}
};
}
return feature;
}
}
}
// parse/LineString.js
var import_get_attribute4 = __toESM(require_get_attribute(), 1);
// enums/LineString.js
var LineString_default = ["gml:LineString", "LineString", "gml:lineString", "lineString", "gml:linestring", "linestring"];
// find/LineString.js
function LineString(xml) {
return find(xml, LineString_default)[0];
}
// parse/coordinates.js
var import_get_attribute2 = __toESM(require_get_attribute(), 1);
// find/coordinates.js
function coordinates(xml) {
return find(xml, ["gml:coordinates", "coordinates", "gml:Coordinates", "Coordinates"])[0];
}
// utils/chunk.js
function chunk(arr, chunkSize = 2) {
const result = [];
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk2 = [];
for (let c = 0; c < chunkSize; c++) {
chunk2.push(arr[i + c]);
}
result.push(chunk2);
}
return result;
}
// parse/coordinates.js
function coordinates2(xml, { debug = false, order = "default", raw = false } = {}) {
const tag = coordinates(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
let nums = inner.trim().split(/[ ,\t\n]+/g);
if (!raw) {
if (debug)
console.log("[geography-markup-language] converting to numbers");
nums = nums.map((n) => Number(n));
}
const srsDimension = (0, import_get_attribute2.default)(tag, "srsDimension");
const chunkSize = srsDimension ? Number(srsDimension) : 2;
let points = chunk(nums, chunkSize);
if (order === "geojson") {
points = points.map((pt) => reorder(pt));
}
if (points.length === 1) {
return points[0];
} else {
return points;
}
}
// parse/posList.js
var import_get_attribute3 = __toESM(require_get_attribute(), 1);
// find/posLists.js
function posLists(xml) {
return find(xml, ["gml:posList", "posList", "gml:PosList", "PosList", "gml:poslist", "poslist"]);
}
// find/posList.js
function posList(xml) {
return posLists(xml)[0];
}
// parse/posList.js
function posList2(xml, { debug = false, order = "default", raw = false } = {}) {
const tag = posList(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
let nums = inner.trim().split(/[ ,\t\n]+/g);
if (!raw) {
if (debug)
console.log("[geography-markup-language] converting to numbers");
nums = nums.map((n) => Number(n));
}
const srsDimension = (0, import_get_attribute3.default)(tag, "srsDimension");
const chunkSize = srsDimension ? Number(srsDimension) : 2;
let points = chunk(nums, chunkSize);
if (order === "geojson") {
points = points.map((pt) => reorder(pt));
}
return points;
}
// parse/LineString.js
function LineString2(xml, { debug, order, raw } = {}) {
const tag = LineString(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
const coords = posList2(inner, { debug, order, raw }) || coordinates2(inner, { debug, order, raw });
const result = {
type: "LineString",
coords
};
const srsName = (0, import_get_attribute4.default)(tag.outer, "srsName");
if (debug)
console.log("[geography-markup-language] srsName:", srs);
if (srsName) {
result.srs = srsName;
}
return result;
}
// geometry/LineString.js
function LineString3(xml, { format = "default" } = { format: "default " }) {
if (format === "geojson") {
const { coords, srs: srs2 } = LineString2(xml, { order: "geojson" });
const feature = {
type: "Feature",
properties: {},
geometry: {
type: "LineString",
coordinates: coords
}
};
if (srs2) {
feature.properties.srsName = srs2;
feature.crs = {
type: "name",
properties: {
name: srs2
}
};
}
return feature;
} else {
const obj = LineString2(xml);
return obj;
}
}
// parse/Point.js
var import_get_attribute5 = __toESM(require_get_attribute(), 1);
// enums/Point.js
var Point_default = ["gml:Point", "Point", "gml:point", "point"];
// find/Points.js
function Points(xml) {
return find(xml, Point_default);
}
// find/Point.js
function Point(xml) {
return Points(xml)[0];
}
// parse/pos.js
var import_find_tag_by_name3 = __toESM(require_find_tag_by_name(), 1);
function pos(xml, { order = "default", raw = false } = {}) {
const tag = (0, import_find_tag_by_name3.default)(xml, "gml:pos") || (0, import_find_tag_by_name3.default)("pos");
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
let point = inner.trim().split(/[ ,]+/g);
if (!raw)
point = point.map((n) => Number(n));
if (order === "geojson")
point = reorder(point);
return point;
}
// parse/Point.js
function Point2(xml, { debug, raw } = {}) {
const tag = Point(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
const point = pos(inner, { debug, raw }) || (posList2(inner, { debug, raw }) || [])[0] || coordinates2(inner, { debug, raw });
if (!point || point.length === 0)
return;
const [y, x, z = null] = point;
return {
type: "Point",
srs: (0, import_get_attribute5.default)(tag.outer, "srsName") || null,
coord: point,
x,
y,
z
};
}
// geometry/Point.js
function Point3(xml, { format = "default" } = { format: "default" }) {
const obj = Point2(xml);
if (!format || format === "default")
return obj;
const { x, y, srs: srs2 } = obj;
if (format === "geojson") {
const feature = {
type: "Feature",
properties: {},
geometry: {
type: "Point",
coordinates: [x, y]
}
};
if (srs2) {
feature.properties.srsName = srs2;
feature.crs = {
type: "name",
properties: {
name: srs2
}
};
}
return feature;
}
}
// parse/Polygon.js
var import_get_attribute7 = __toESM(require_get_attribute(), 1);
// find/innerBoundaries.js
function innerBoundaries(xml) {
return find(xml, ["gml:innerBoundaryIs", "innerBoundaryIs", "gml:InnerBoundaryIs", "InnerBoundaryIs", "gml:innerboundaryis", "innerboundaryis"]);
}
// find/interiors.js
function interiors(xml) {
return find(xml, ["gml:interior", "interior", "gml:Interior", "Interior"]);
}
// enums/Polygon.js
var Polygon_default = ["gml:Polygon", "polygon", "gml:polygon", "polygon"];
// find/Polygons.js
function Polygon(xml) {
return find(xml, Polygon_default);
}
// find/Polygon.js
function Polygon2(xml) {
return Polygon(xml)[0];
}
// find/exteriors.js
function exteriors(xml) {
return find(xml, ["gml:exterior", "exterior", "gml:Exterior", "Exterior"]);
}
// find/exterior.js
function exterior(xml) {
return exteriors(xml)[0];
}
// parse/LinearRing.js
var import_get_attribute6 = __toESM(require_get_attribute(), 1);
// find/LinearRing.js
function LinearRing(xml) {
return find(xml, ["gml:LinearRing", "LinearRing", "gml:linearRing", "linearRing", "gml:linearring", "linearring"])[0];
}
// parse/LinearRing.js
function LinearRing2(xml, { debug, order = "default", raw } = {}) {
const tag = LinearRing(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
const coordinatesTag = coordinates(inner);
if (coordinatesTag) {
return coordinates2(coordinatesTag.outer, { debug, order, raw });
}
const posListTag = posList(xml);
if (posListTag) {
return posList2(posListTag.outer, { debug, order, raw });
}
let nums = inner.trim().split(/[ ,\t\n]+/g);
if (!raw) {
if (debug)
console.log("[geography-markup-language] converting to numbers");
nums = nums.map((n) => Number(n));
}
const srsDimension = (0, import_get_attribute6.default)(tag, "srsDimension");
const chunkSize = srsDimension ? Number(srsDimension) : 2;
let points = chunk(nums, chunkSize);
if (order === "geojson") {
points = points.map((pt) => reorder(pt));
}
return points;
}
// parse/exterior.js
function exterior2(xml, { debug, order, raw } = {}) {
const tag = exterior(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
return LinearRing2(inner, { debug, order, raw });
}
// find/innerBoundaryIs.js
function innerBoundaries2(xml) {
return innerBoundaries(xml)[0];
}
// parse/innerBoundaryIs.js
function innerBoundaryIs(xml, { debug, order, raw } = {}) {
const tag = innerBoundaries2(xml.outer);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
return LinearRing2(inner, { debug, order, raw });
}
// find/interior.js
function interior(xml) {
return interiors(xml)[0];
}
// parse/interior.js
function interior2(xml, { debug, order, raw } = {}) {
const tag = interior(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
return LinearRing2(inner, { debug, order, raw });
}
// find/outerBoundaryIs.js
function outerBoundaryIs(xml) {
return find(xml, ["gml:outerBoundaryIs", "outerBoundaryIs", "gml:OuterBoundaryIs", "OuterBoundaryIs", "gml:outerboundaryis", "outerboundaryis"])[0];
}
// parse/outerBoundaryIs.js
function outerBoundaryIs2(xml, { debug, order, raw } = {}) {
const tag = outerBoundaryIs(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
return LinearRing2(inner, { debug, order, raw });
}
// parse/Polygon.js
function Polygon3(xml, { debug, order, raw } = {}) {
const tag = Polygon2(xml);
if (!tag)
return;
const { inner } = tag;
if (!inner)
return;
const exterior3 = exterior2(xml, { debug, order, raw }) || outerBoundaryIs2(xml, { debug, order, raw });
let holes = interiors(xml).map((interior3) => interior2(interior3, { debug, order, raw }));
if (holes.length === 0) {
holes = innerBoundaries(xml).map((boundary) => innerBoundaryIs(boundary, { debug, order, raw }));
}
const rings = [exterior3].concat(holes);
const result = {
type: "Polygon",
rings
};
const srsName = (0, import_get_attribute7.default)(tag.outer, "srsName");
if (debug)
console.log("[geography-markup-language] srsName:", srs);
if (srsName) {
result.srs = srsName;
}
return result;
}
// geometry/Polygon.js
function Polygon4(xml, { format = "default" } = {}) {
if (format === "geojson") {
const { rings, srs: srs2 } = Polygon3(xml, { order: "geojson" });
const feature = {
type: "Feature",
properties: {},
geometry: {
type: "Polygon",
coordinates: rings
}
};
if (srs2) {
feature.properties.srsName = srs2;
feature.crs = {
type: "name",
properties: {
name: srs2
}
};
}
return feature;
} else {
const obj = Polygon3(xml);
return obj;
}
}
// geometry/Geometry.js
function Geometry(xml, { format = "default" } = { format: "default" }) {
const envelope3 = envelope(xml);
if (envelope3) {
const result = Envelope(envelope3.outer, { format });
if (result) {
return result;
}
}
const lineString = LineString(xml);
if (lineString) {
const result = LineString3(lineString.outer, { format });
if (result) {
return result;
}
}
const point = Point(xml);
if (point) {
const result = Point3(point.outer, { format });
if (result) {
return result;
}
}
const polygon = Polygon2(xml);
if (polygon) {
const result = Polygon4(polygon.outer, { format });
if (result) {
return result;
}
}
}
// utils/findAll.js
var import_find_tags_by_name2 = __toESM(require_find_tags_by_name(), 1);
function find2(xml, names) {
let tags = [];
for (let i = 0; i < names.length; i++) {
const name = names[i];
tags = tags.concat((0, import_find_tags_by_name2.default)(xml, name));
}
return tags;
}
// find/geometries.js
var GEOMETRY_TAG_NAMES;
function geometries(xml) {
if (!GEOMETRY_TAG_NAMES)
GEOMETRY_TAG_NAMES = Envelope_default.concat(LineString_default).concat(Point_default).concat(Polygon_default);
return find2(xml, GEOMETRY_TAG_NAMES).map((tag) => tag.outer);
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
Envelope,
Geometry,
LineString,
Point,
Polygon,
findGeometries
});