"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; 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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // dist/index.js var dist_exports = {}; __export(dist_exports, { HexWKBLoader: () => HexWKBLoader, TWKBLoader: () => TWKBLoader, TWKBWriter: () => TWKBWriter, WKBLoader: () => WKBLoader, WKBWorkerLoader: () => WKBWorkerLoader, WKBWriter: () => WKBWriter, WKTCRSLoader: () => WKTCRSLoader, WKTCRSWriter: () => WKTCRSWriter, WKTLoader: () => WKTLoader, WKTWorkerLoader: () => WKTWorkerLoader, WKTWriter: () => WKTWriter, decodeHex: () => decodeHex, encodeHex: () => encodeHex, isTWKB: () => isTWKB, isWKB: () => isWKB, isWKT: () => isWKT, parseWKBHeader: () => parseWKBHeader }); module.exports = __toCommonJS(dist_exports); // dist/lib/utils/version.js var VERSION = true ? "4.3.1" : "latest"; // dist/lib/parse-wkt-crs.js function parseWKTCRS(wkt, options) { if (options == null ? void 0 : options.debug) { console.log("[wktcrs] parse starting with\n", wkt); } wkt = wkt.replace(/[A-Z][A-Z\d_]+\[/gi, (match) => `["${match.substr(0, match.length - 1)}",`); wkt = wkt.replace(/, ?([A-Z][A-Z\d_]+[,\]])/gi, (match, p1) => { const varname = p1.substr(0, p1.length - 1); return `,"${(options == null ? void 0 : options.raw) ? "raw:" : ""}${varname}"${p1[p1.length - 1]}`; }); if (options == null ? void 0 : options.raw) { wkt = wkt.replace(/, {0,2}(-?[\.\d]+)(?=,|\])/g, function(match, p1) { return `,"${(options == null ? void 0 : options.raw) ? "raw:" : ""}${p1}"`; }); } if (options == null ? void 0 : options.debug) { console.log(`[wktcrs] json'd wkt: '${wkt}'`); } let data; try { data = JSON.parse(wkt); } catch (error) { console.error(`[wktcrs] failed to parse '${wkt}'`); throw error; } if (options == null ? void 0 : options.debug) { console.log(`[wktcrs] json parsed: '${wkt}'`); } function process(data2, parent) { const kw = data2[0]; data2.forEach(function(it) { if (Array.isArray(it)) { process(it, data2); } }); const kwarr = `MULTIPLE_${kw}`; if (kwarr in parent) { parent[kwarr].push(data2); } else if (kw in parent) { parent[kwarr] = [parent[kw], data2]; delete parent[kw]; } else { parent[kw] = data2; } return parent; } const result = process(data, [data]); if (options == null ? void 0 : options.debug) { console.log("[wktcrs] parse returning", result); } if (options == null ? void 0 : options.sort) { sort(result, options); } return result; } function sort(data, options) { const keys = Object.keys(data).filter((k) => !/\d+/.test(k)); const keywords = (options == null ? void 0 : options.keywords) || []; if (!(options == null ? void 0 : options.keywords)) { const counts = {}; if (Array.isArray(data)) { data.forEach((it) => { if (Array.isArray(it) && it.length >= 2 && typeof it[1] === "string") { const k = it[0]; if (!counts[k]) counts[k] = 0; counts[k]++; } }); for (const k in counts) { if (counts[k] > 0) keywords.push(k); } } } keys.forEach((key) => { data[key] = sort(data[key]); }); keywords.forEach((key) => { const indices = []; const params = []; data.forEach((item, i) => { if (Array.isArray(item) && item[0] === key) { indices.push(i); params.push(item); } }); params.sort((a, b) => { a = a[1].toString(); b = b[1].toString(); return a < b ? -1 : a > b ? 1 : 0; }); params.forEach((param, i) => { data[indices[i]] = param; }); }); return data; } // dist/wkt-crs-loader.js var WKTCRSLoader = { dataType: null, batchType: null, name: "WKT CRS (Well-Known Text Coordinate Reference System)", id: "wkt-crs", module: "wkt-crs", version: VERSION, worker: true, extensions: [], mimeTypes: ["text/plain"], category: "json", text: true, options: { "wkt-crs": {} }, parse: async (arrayBuffer, options) => parseWKTCRS(new TextDecoder().decode(arrayBuffer), options == null ? void 0 : options["wkt-crs"]), parseTextSync: (string, options) => parseWKTCRS(string, options == null ? void 0 : options["wkt-crs"]) }; // dist/lib/encode-wkt-crs.js function encodeWKTCRS(wkt, options) { if (Array.isArray(wkt) && wkt.length === 1 && Array.isArray(wkt[0])) { wkt = wkt[0]; } const [kw, ...attrs] = wkt; const str = `${kw}[${attrs.map((attr) => { if (Array.isArray(attr)) { return encodeWKTCRS(attr, options); } else if (typeof attr === "number") { return attr.toString(); } else if (typeof attr === "string") { if (attr.startsWith("raw:")) { return attr.replace("raw:", ""); } return `"${attr}"`; } throw new Error(`[wktcrs] unexpected attribute "${attr}"`); }).join(",")}]`; return str; } // dist/wkt-crs-writer.js var WKTCRSWriter = { name: "WKT CRS (Well-Known Text Coordinate Reference System)", id: "wkt-crs", module: "wkt-crs", version: VERSION, worker: true, extensions: [], mimeTypes: ["text/plain"], // category: 'json', text: true, options: { "wkt-crs": {} }, encode: async (wktcrs, options) => new TextEncoder().encode(encodeWKTCRS(wktcrs, options == null ? void 0 : options["wkt-crs"])), encodeSync: (wktcrs, options) => new TextEncoder().encode(encodeWKTCRS(wktcrs, options == null ? void 0 : options["wkt-crs"])), encodeTextSync: (wktcrs, options) => encodeWKTCRS(wktcrs, options == null ? void 0 : options["wkt-crs"]) }; // dist/lib/parse-wkt.js var numberRegexp = /[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/; var tuples = new RegExp("^" + numberRegexp.source + "(\\s" + numberRegexp.source + "){1,}"); var WKT_MAGIC_STRINGS = [ "POINT(", "LINESTRING(", "POLYGON(", "MULTIPOINT(", "MULTILINESTRING(", "MULTIPOLYGON(", "GEOMETRYCOLLECTION(" // We only support this "geojson" subset of the OGC simple features standard ]; function isWKT(input) { return WKT_MAGIC_STRINGS.some((magicString) => input.startsWith(magicString)); } function parseWKT(input, options) { return parseWKTToGeometry(input, options); } function parseWKTToGeometry(input, options) { var _a; const parts = input.split(";"); let _ = parts.pop(); const srid = (parts.shift() || "").split("=").pop(); const state = { parts, _, i: 0 }; const geometry = parseGeometry(state); return ((_a = options == null ? void 0 : options.wkt) == null ? void 0 : _a.crs) ? addCRS(geometry, srid) : geometry; } function parseGeometry(state) { return parsePoint(state) || parseLineString(state) || parsePolygon(state) || parseMultiPoint(state) || parseMultiLineString(state) || parseMultiPolygon(state) || parseGeometryCollection(state); } function addCRS(obj, srid) { if (obj && (srid == null ? void 0 : srid.match(/\d+/))) { const crs = { type: "name", properties: { name: "urn:ogc:def:crs:EPSG::" + srid } }; obj.crs = crs; } return obj; } function parsePoint(state) { if (!$(/^(POINT(\sz)?)/i, state)) { return null; } white(state); if (!$(/^(\()/, state)) { return null; } const c = coords(state); if (!c) { return null; } white(state); if (!$(/^(\))/, state)) { return null; } return { type: "Point", coordinates: c[0] }; } function parseMultiPoint(state) { var _a, _b; if (!$(/^(MULTIPOINT)/i, state)) { return null; } white(state); const newCoordsFormat = (_b = state._) == null ? void 0 : _b.substring(((_a = state._) == null ? void 0 : _a.indexOf("(")) + 1, state._.length - 1).replace(/\(/g, "").replace(/\)/g, ""); state._ = "MULTIPOINT (" + newCoordsFormat + ")"; const c = multicoords(state); if (!c) { return null; } white(state); return { type: "MultiPoint", coordinates: c }; } function parseLineString(state) { if (!$(/^(LINESTRING(\sz)?)/i, state)) { return null; } white(state); if (!$(/^(\()/, state)) { return null; } const c = coords(state); if (!c) { return null; } if (!$(/^(\))/, state)) { return null; } return { type: "LineString", coordinates: c }; } function parseMultiLineString(state) { if (!$(/^(MULTILINESTRING)/i, state)) return null; white(state); const c = multicoords(state); if (!c) { return null; } white(state); return { // @ts-ignore type: "MultiLineString", // @ts-expect-error coordinates: c }; } function parsePolygon(state) { if (!$(/^(POLYGON(\sz)?)/i, state)) { return null; } white(state); const c = multicoords(state); if (!c) { return null; } return { // @ts-ignore type: "Polygon", // @ts-expect-error coordinates: c }; } function parseMultiPolygon(state) { if (!$(/^(MULTIPOLYGON)/i, state)) { return null; } white(state); const c = multicoords(state); if (!c) { return null; } return { type: "MultiPolygon", // @ts-expect-error coordinates: c }; } function parseGeometryCollection(state) { const geometries = []; let geometry; if (!$(/^(GEOMETRYCOLLECTION)/i, state)) { return null; } white(state); if (!$(/^(\()/, state)) { return null; } while (geometry = parseGeometry(state)) { geometries.push(geometry); white(state); $(/^(,)/, state); white(state); } if (!$(/^(\))/, state)) { return null; } return { type: "GeometryCollection", geometries }; } function multicoords(state) { white(state); let depth = 0; const rings = []; const stack = [rings]; let pointer = rings; let elem; while (elem = $(/^(\()/, state) || $(/^(\))/, state) || $(/^(,)/, state) || $(tuples, state)) { if (elem === "(") { stack.push(pointer); pointer = []; stack[stack.length - 1].push(pointer); depth++; } else if (elem === ")") { if (pointer.length === 0) return null; pointer = stack.pop(); if (!pointer) return null; depth--; if (depth === 0) break; } else if (elem === ",") { pointer = []; stack[stack.length - 1].push(pointer); } else if (!elem.split(/\s/g).some(isNaN)) { Array.prototype.push.apply(pointer, elem.split(/\s/g).map(parseFloat)); } else { return null; } white(state); } if (depth !== 0) return null; return rings; } function coords(state) { const list = []; let item; let pt; while (pt = $(tuples, state) || $(/^(,)/, state)) { if (pt === ",") { list.push(item); item = []; } else if (!pt.split(/\s/g).some(isNaN)) { if (!item) item = []; Array.prototype.push.apply(item, pt.split(/\s/g).map(parseFloat)); } white(state); } if (item) list.push(item); else return null; return list.length ? list : null; } function $(regexp, state) { var _a; const match = (_a = state._) == null ? void 0 : _a.substring(state.i).match(regexp); if (!match) return null; else { state.i += match[0].length; return match[0]; } } function white(state) { $(/^\s*/, state); } // dist/wkt-loader.js var WKTWorkerLoader = { dataType: null, batchType: null, name: "WKT (Well-Known Text)", id: "wkt", module: "wkt", version: VERSION, worker: true, extensions: ["wkt"], mimeTypes: ["text/plain"], category: "geometry", text: true, tests: WKT_MAGIC_STRINGS, testText: isWKT, options: { wkt: { shape: "geojson-geometry", crs: true } } }; var WKTLoader = { ...WKTWorkerLoader, parse: async (arrayBuffer, options) => parseWKT(new TextDecoder().decode(arrayBuffer), options), parseTextSync: (string, options) => parseWKT(string, options) }; // dist/lib/encode-wkt.js function encodeWKT(geometry) { if (geometry.type === "Feature") { geometry = geometry.geometry; } switch (geometry.type) { case "Point": return `POINT ${wrapParens(pairWKT(geometry.coordinates))}`; case "LineString": return `LINESTRING ${wrapParens(ringWKT(geometry.coordinates))}`; case "Polygon": return `POLYGON ${wrapParens(ringsWKT(geometry.coordinates))}`; case "MultiPoint": return `MULTIPOINT ${wrapParens(ringWKT(geometry.coordinates))}`; case "MultiPolygon": return `MULTIPOLYGON ${wrapParens(multiRingsWKT(geometry.coordinates))}`; case "MultiLineString": return `MULTILINESTRING ${wrapParens(ringsWKT(geometry.coordinates))}`; case "GeometryCollection": return `GEOMETRYCOLLECTION ${wrapParens(geometry.geometries.map(encodeWKT).join(", "))}`; default: throw new Error("stringify requires a valid GeoJSON Feature or geometry object as input"); } } function pairWKT(c) { return c.join(" "); } function ringWKT(r) { return r.map(pairWKT).join(", "); } function ringsWKT(r) { return r.map(ringWKT).map(wrapParens).join(", "); } function multiRingsWKT(r) { return r.map(ringsWKT).map(wrapParens).join(", "); } function wrapParens(s) { return `(${s})`; } // dist/wkt-writer.js var WKTWriter = { name: "WKT (Well Known Text)", id: "wkt", module: "wkt", version: VERSION, extensions: ["wkt"], text: true, encode: async (geometry) => encodeWKTSync(geometry), encodeSync: encodeWKTSync, encodeTextSync: encodeWKT, options: { wkt: {} } }; function encodeWKTSync(geometry) { return new TextEncoder().encode(encodeWKT(geometry)).buffer; } // dist/lib/parse-wkb.js var import_gis = require("@loaders.gl/gis"); // dist/lib/parse-wkb-header.js var EWKB_FLAG_Z = 2147483648; var EWKB_FLAG_M = 1073741824; var EWKB_FLAG_SRID = 536870912; var MAX_SRID = 1e4; var WKBGeometryType; (function(WKBGeometryType2) { WKBGeometryType2[WKBGeometryType2["Point"] = 1] = "Point"; WKBGeometryType2[WKBGeometryType2["LineString"] = 2] = "LineString"; WKBGeometryType2[WKBGeometryType2["Polygon"] = 3] = "Polygon"; WKBGeometryType2[WKBGeometryType2["MultiPoint"] = 4] = "MultiPoint"; WKBGeometryType2[WKBGeometryType2["MultiLineString"] = 5] = "MultiLineString"; WKBGeometryType2[WKBGeometryType2["MultiPolygon"] = 6] = "MultiPolygon"; WKBGeometryType2[WKBGeometryType2["GeometryCollection"] = 7] = "GeometryCollection"; })(WKBGeometryType || (WKBGeometryType = {})); function isWKB(arrayBuffer) { const dataView = new DataView(arrayBuffer); let byteOffset = 0; const endianness = dataView.getUint8(byteOffset); byteOffset += 1; if (endianness > 1) { return false; } const littleEndian = endianness === 1; const geometry = dataView.getUint32(byteOffset, littleEndian); byteOffset += 4; const geometryType = geometry & 7; if (geometryType === 0 || geometryType > 7) { return false; } const geometryFlags = geometry - geometryType; if (geometryFlags === 0 || geometryFlags === 1e3 || geometryFlags === 2e3 || geometryFlags === 3e3) { return true; } if ((geometryFlags & ~(EWKB_FLAG_Z | EWKB_FLAG_M | EWKB_FLAG_SRID)) !== 0) { return false; } if (geometryFlags & EWKB_FLAG_SRID) { const srid = dataView.getUint32(byteOffset, littleEndian); byteOffset += 4; if (srid > MAX_SRID) { return false; } } return true; } function parseWKBHeader(dataView, target) { const wkbHeader = Object.assign(target || {}, { type: "wkb", geometryType: 1, dimensions: 2, coordinates: "xy", littleEndian: true, byteOffset: 0 }); wkbHeader.littleEndian = dataView.getUint8(wkbHeader.byteOffset) === 1; wkbHeader.byteOffset++; const geometryCode = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian); wkbHeader.byteOffset += 4; wkbHeader.geometryType = geometryCode & 7; const isoType = (geometryCode - wkbHeader.geometryType) / 1e3; switch (isoType) { case 0: break; case 1: wkbHeader.type = "iso-wkb"; wkbHeader.dimensions = 3; wkbHeader.coordinates = "xyz"; break; case 2: wkbHeader.type = "iso-wkb"; wkbHeader.dimensions = 3; wkbHeader.coordinates = "xym"; break; case 3: wkbHeader.type = "iso-wkb"; wkbHeader.dimensions = 4; wkbHeader.coordinates = "xyzm"; break; default: throw new Error(`WKB: Unsupported iso-wkb type: ${isoType}`); } const ewkbZ = geometryCode & EWKB_FLAG_Z; const ewkbM = geometryCode & EWKB_FLAG_M; const ewkbSRID = geometryCode & EWKB_FLAG_SRID; if (ewkbZ && ewkbM) { wkbHeader.type = "ewkb"; wkbHeader.dimensions = 4; wkbHeader.coordinates = "xyzm"; } else if (ewkbZ) { wkbHeader.type = "ewkb"; wkbHeader.dimensions = 3; wkbHeader.coordinates = "xyz"; } else if (ewkbM) { wkbHeader.type = "ewkb"; wkbHeader.dimensions = 3; wkbHeader.coordinates = "xym"; } if (ewkbSRID) { wkbHeader.type = "ewkb"; wkbHeader.srid = dataView.getUint32(wkbHeader.byteOffset, wkbHeader.littleEndian); wkbHeader.byteOffset += 4; } return wkbHeader; } // dist/lib/parse-wkb.js function parseWKB(arrayBuffer, options) { var _a; const binaryGeometry = parseWKBToBinary(arrayBuffer, options); const shape = ((_a = options == null ? void 0 : options.wkb) == null ? void 0 : _a.shape) || "binary-geometry"; switch (shape) { case "binary-geometry": return binaryGeometry; case "geojson-geometry": return (0, import_gis.binaryToGeometry)(binaryGeometry); case "geometry": console.error('WKBLoader: "geometry" shape is deprecated, use "binary-geometry" instead'); return (0, import_gis.binaryToGeometry)(binaryGeometry); default: throw new Error(shape); } } function parseWKBToBinary(arrayBuffer, options) { const dataView = new DataView(arrayBuffer); const wkbHeader = parseWKBHeader(dataView); const { geometryType, dimensions, littleEndian } = wkbHeader; const offset = wkbHeader.byteOffset; switch (geometryType) { case WKBGeometryType.Point: const point = parsePoint2(dataView, offset, dimensions, littleEndian); return point.geometry; case WKBGeometryType.LineString: const line = parseLineString2(dataView, offset, dimensions, littleEndian); return line.geometry; case WKBGeometryType.Polygon: const polygon = parsePolygon2(dataView, offset, dimensions, littleEndian); return polygon.geometry; case WKBGeometryType.MultiPoint: const multiPoint = parseMultiPoint2(dataView, offset, dimensions, littleEndian); multiPoint.type = "Point"; return multiPoint; case WKBGeometryType.MultiLineString: const multiLine = parseMultiLineString2(dataView, offset, dimensions, littleEndian); multiLine.type = "LineString"; return multiLine; case WKBGeometryType.MultiPolygon: const multiPolygon = parseMultiPolygon2(dataView, offset, dimensions, littleEndian); multiPolygon.type = "Polygon"; return multiPolygon; default: throw new Error(`WKB: Unsupported geometry type: ${geometryType}`); } } function parsePoint2(dataView, offset, dimension, littleEndian) { const positions = new Float64Array(dimension); for (let i = 0; i < dimension; i++) { positions[i] = dataView.getFloat64(offset, littleEndian); offset += 8; } return { geometry: { type: "Point", positions: { value: positions, size: dimension } }, offset }; } function parseLineString2(dataView, offset, dimension, littleEndian) { const nPoints = dataView.getUint32(offset, littleEndian); offset += 4; const positions = new Float64Array(nPoints * dimension); for (let i = 0; i < nPoints * dimension; i++) { positions[i] = dataView.getFloat64(offset, littleEndian); offset += 8; } const pathIndices = [0]; if (nPoints > 0) { pathIndices.push(nPoints); } return { geometry: { type: "LineString", positions: { value: positions, size: dimension }, pathIndices: { value: new Uint32Array(pathIndices), size: 1 } }, offset }; } var cumulativeSum = (sum) => (value) => sum += value; function parsePolygon2(dataView, offset, dimension, littleEndian) { const nRings = dataView.getUint32(offset, littleEndian); offset += 4; const rings = []; for (let i = 0; i < nRings; i++) { const parsed = parseLineString2(dataView, offset, dimension, littleEndian); const { positions } = parsed.geometry; offset = parsed.offset; rings.push(positions.value); } const concatenatedPositions = new Float64Array(concatTypedArrays(rings).buffer); const polygonIndices = [0]; if (concatenatedPositions.length > 0) { polygonIndices.push(concatenatedPositions.length / dimension); } const primitivePolygonIndices = rings.map((l) => l.length / dimension).map(cumulativeSum(0)); primitivePolygonIndices.unshift(0); return { geometry: { type: "Polygon", positions: { value: concatenatedPositions, size: dimension }, polygonIndices: { value: new Uint32Array(polygonIndices), size: 1 }, primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 } }, offset }; } function parseMultiPoint2(dataView, offset, dimension, littleEndian) { const nPoints = dataView.getUint32(offset, littleEndian); offset += 4; const binaryPointGeometries = []; for (let i = 0; i < nPoints; i++) { const littleEndianPoint = dataView.getUint8(offset) === 1; offset++; if (dataView.getUint32(offset, littleEndianPoint) % 1e3 !== 1) { throw new Error("WKB: Inner geometries of MultiPoint not of type Point"); } offset += 4; const parsed = parsePoint2(dataView, offset, dimension, littleEndianPoint); offset = parsed.offset; binaryPointGeometries.push(parsed.geometry); } return concatenateBinaryPointGeometries(binaryPointGeometries, dimension); } function parseMultiLineString2(dataView, offset, dimension, littleEndian) { const nLines = dataView.getUint32(offset, littleEndian); offset += 4; const binaryLineGeometries = []; for (let i = 0; i < nLines; i++) { const littleEndianLine = dataView.getUint8(offset) === 1; offset++; if (dataView.getUint32(offset, littleEndianLine) % 1e3 !== 2) { throw new Error("WKB: Inner geometries of MultiLineString not of type LineString"); } offset += 4; const parsed = parseLineString2(dataView, offset, dimension, littleEndianLine); offset = parsed.offset; binaryLineGeometries.push(parsed.geometry); } return concatenateBinaryLineGeometries(binaryLineGeometries, dimension); } function parseMultiPolygon2(dataView, offset, dimension, littleEndian) { const nPolygons = dataView.getUint32(offset, littleEndian); offset += 4; const binaryPolygonGeometries = []; for (let i = 0; i < nPolygons; i++) { const littleEndianPolygon = dataView.getUint8(offset) === 1; offset++; if (dataView.getUint32(offset, littleEndianPolygon) % 1e3 !== 3) { throw new Error("WKB: Inner geometries of MultiPolygon not of type Polygon"); } offset += 4; const parsed = parsePolygon2(dataView, offset, dimension, littleEndianPolygon); offset = parsed.offset; binaryPolygonGeometries.push(parsed.geometry); } return concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension); } function concatenateBinaryPointGeometries(binaryPointGeometries, dimension) { const positions = binaryPointGeometries.map((geometry) => geometry.positions.value); const concatenatedPositions = new Float64Array(concatTypedArrays(positions).buffer); return { type: "Point", positions: { value: concatenatedPositions, size: dimension } }; } function concatenateBinaryLineGeometries(binaryLineGeometries, dimension) { const lines = binaryLineGeometries.map((geometry) => geometry.positions.value); const concatenatedPositions = new Float64Array(concatTypedArrays(lines).buffer); const pathIndices = lines.map((line) => line.length / dimension).map(cumulativeSum(0)); pathIndices.unshift(0); return { type: "LineString", positions: { value: concatenatedPositions, size: dimension }, pathIndices: { value: new Uint32Array(pathIndices), size: 1 } }; } function concatenateBinaryPolygonGeometries(binaryPolygonGeometries, dimension) { const polygons = []; const primitivePolygons = []; for (const binaryPolygon of binaryPolygonGeometries) { const { positions, primitivePolygonIndices: primitivePolygonIndices2 } = binaryPolygon; polygons.push(positions.value); primitivePolygons.push(primitivePolygonIndices2.value); } const concatenatedPositions = new Float64Array(concatTypedArrays(polygons).buffer); const polygonIndices = polygons.map((p) => p.length / dimension).map(cumulativeSum(0)); polygonIndices.unshift(0); const primitivePolygonIndices = [0]; for (const primitivePolygon of primitivePolygons) { primitivePolygonIndices.push(...primitivePolygon.filter((x) => x > 0).map((x) => x + primitivePolygonIndices[primitivePolygonIndices.length - 1])); } return { type: "Polygon", positions: { value: concatenatedPositions, size: dimension }, polygonIndices: { value: new Uint32Array(polygonIndices), size: 1 }, primitivePolygonIndices: { value: new Uint32Array(primitivePolygonIndices), size: 1 } }; } function concatTypedArrays(arrays) { let byteLength = 0; for (let i = 0; i < arrays.length; ++i) { byteLength += arrays[i].byteLength; } const buffer = new Uint8Array(byteLength); let byteOffset = 0; for (let i = 0; i < arrays.length; ++i) { const data = new Uint8Array(arrays[i].buffer); byteLength = data.length; for (let j = 0; j < byteLength; ++j) { buffer[byteOffset++] = data[j]; } } return buffer; } // dist/wkb-loader.js var WKBWorkerLoader = { dataType: null, batchType: null, name: "WKB", id: "wkb", module: "wkt", version: VERSION, worker: true, category: "geometry", extensions: ["wkb"], mimeTypes: [], // TODO can we define static, serializable tests, eg. some binary strings? tests: [isWKB], options: { wkb: { shape: "binary-geometry" // 'geojson-geometry' } } }; var WKBLoader = { ...WKBWorkerLoader, parse: async (arrayBuffer) => parseWKB(arrayBuffer), parseSync: parseWKB }; // dist/lib/utils/binary-writer.js var LE = true; var BE = false; var BinaryWriter = class { arrayBuffer; dataView; byteOffset = 0; allowResize = false; constructor(size, allowResize) { this.arrayBuffer = new ArrayBuffer(size); this.dataView = new DataView(this.arrayBuffer); this.byteOffset = 0; this.allowResize = allowResize || false; } writeUInt8(value) { this._ensureSize(1); this.dataView.setUint8(this.byteOffset, value); this.byteOffset += 1; } writeUInt16LE(value) { this._ensureSize(2); this.dataView.setUint16(this.byteOffset, value, LE); this.byteOffset += 2; } writeUInt16BE(value) { this._ensureSize(2); this.dataView.setUint16(this.byteOffset, value, BE); this.byteOffset += 2; } writeUInt32LE(value) { this._ensureSize(4); this.dataView.setUint32(this.byteOffset, value, LE); this.byteOffset += 4; } writeUInt32BE(value) { this._ensureSize(4); this.dataView.setUint32(this.byteOffset, value, BE); this.byteOffset += 4; } writeInt8(value) { this._ensureSize(1); this.dataView.setInt8(this.byteOffset, value); this.byteOffset += 1; } writeInt16LE(value) { this._ensureSize(2); this.dataView.setInt16(this.byteOffset, value, LE); this.byteOffset += 2; } writeInt16BE(value) { this._ensureSize(2); this.dataView.setInt16(this.byteOffset, value, BE); this.byteOffset += 2; } writeInt32LE(value) { this._ensureSize(4); this.dataView.setInt32(this.byteOffset, value, LE); this.byteOffset += 4; } writeInt32BE(value) { this._ensureSize(4); this.dataView.setInt32(this.byteOffset, value, BE); this.byteOffset += 4; } writeFloatLE(value) { this._ensureSize(4); this.dataView.setFloat32(this.byteOffset, value, LE); this.byteOffset += 4; } writeFloatBE(value) { this._ensureSize(4); this.dataView.setFloat32(this.byteOffset, value, BE); this.byteOffset += 4; } writeDoubleLE(value) { this._ensureSize(8); this.dataView.setFloat64(this.byteOffset, value, LE); this.byteOffset += 8; } writeDoubleBE(value) { this._ensureSize(8); this.dataView.setFloat64(this.byteOffset, value, BE); this.byteOffset += 8; } /** A varint uses a variable number of bytes */ writeVarInt(value) { let length = 1; while ((value & 4294967168) !== 0) { this.writeUInt8(value & 127 | 128); value >>>= 7; length++; } this.writeUInt8(value & 127); return length; } /** Append another ArrayBuffer to this ArrayBuffer */ writeBuffer(arrayBuffer) { this._ensureSize(arrayBuffer.byteLength); const tempArray = new Uint8Array(this.arrayBuffer); tempArray.set(new Uint8Array(arrayBuffer), this.byteOffset); this.byteOffset += arrayBuffer.byteLength; } /** Resizes this.arrayBuffer if not enough space */ _ensureSize(size) { if (this.arrayBuffer.byteLength < this.byteOffset + size) { if (this.allowResize) { const newArrayBuffer = new ArrayBuffer(this.byteOffset + size); const tempArray = new Uint8Array(newArrayBuffer); tempArray.set(new Uint8Array(this.arrayBuffer)); this.arrayBuffer = newArrayBuffer; } else { throw new Error("BinaryWriter overflow"); } } } }; // dist/lib/encode-wkb.js var WKB; (function(WKB2) { WKB2[WKB2["Point"] = 1] = "Point"; WKB2[WKB2["LineString"] = 2] = "LineString"; WKB2[WKB2["Polygon"] = 3] = "Polygon"; WKB2[WKB2["MultiPoint"] = 4] = "MultiPoint"; WKB2[WKB2["MultiLineString"] = 5] = "MultiLineString"; WKB2[WKB2["MultiPolygon"] = 6] = "MultiPolygon"; WKB2[WKB2["GeometryCollection"] = 7] = "GeometryCollection"; })(WKB || (WKB = {})); function encodeWKB(geometry, options = {}) { if (geometry.type === "Feature") { geometry = geometry.geometry; } switch (geometry.type) { case "Point": return encodePoint(geometry.coordinates, options); case "LineString": return encodeLineString(geometry.coordinates, options); case "Polygon": return encodePolygon(geometry.coordinates, options); case "MultiPoint": return encodeMultiPoint(geometry, options); case "MultiPolygon": return encodeMultiPolygon(geometry, options); case "MultiLineString": return encodeMultiLineString(geometry, options); case "GeometryCollection": return encodeGeometryCollection(geometry, options); default: const exhaustiveCheck = geometry; throw new Error(`Unhandled case: ${exhaustiveCheck}`); } } function getGeometrySize(geometry, options) { switch (geometry.type) { case "Point": return getPointSize(options); case "LineString": return getLineStringSize(geometry.coordinates, options); case "Polygon": return getPolygonSize(geometry.coordinates, options); case "MultiPoint": return getMultiPointSize(geometry, options); case "MultiPolygon": return getMultiPolygonSize(geometry, options); case "MultiLineString": return getMultiLineStringSize(geometry, options); case "GeometryCollection": return getGeometryCollectionSize(geometry, options); default: const exhaustiveCheck = geometry; throw new Error(`Unhandled case: ${exhaustiveCheck}`); } } function encodePoint(coordinates, options) { const writer = new BinaryWriter(getPointSize(options)); writer.writeInt8(1); writeWkbType(writer, WKB.Point, options); if (typeof coordinates[0] === "undefined" && typeof coordinates[1] === "undefined") { writer.writeDoubleLE(NaN); writer.writeDoubleLE(NaN); if (options.hasZ) { writer.writeDoubleLE(NaN); } if (options.hasM) { writer.writeDoubleLE(NaN); } } else { writeCoordinate(writer, coordinates, options); } return writer.arrayBuffer; } function writeCoordinate(writer, coordinate, options) { writer.writeDoubleLE(coordinate[0]); writer.writeDoubleLE(coordinate[1]); if (options.hasZ) { writer.writeDoubleLE(coordinate[2]); } if (options.hasM) { writer.writeDoubleLE(coordinate[3]); } } function getPointSize(options) { const coordinateSize = getCoordinateSize(options); return 1 + 4 + coordinateSize; } function encodeLineString(coordinates, options) { const size = getLineStringSize(coordinates, options); const writer = new BinaryWriter(size); writer.writeInt8(1); writeWkbType(writer, WKB.LineString, options); writer.writeUInt32LE(coordinates.length); for (const coordinate of coordinates) { writeCoordinate(writer, coordinate, options); } return writer.arrayBuffer; } function getLineStringSize(coordinates, options) { const coordinateSize = getCoordinateSize(options); return 1 + 4 + 4 + coordinates.length * coordinateSize; } function encodePolygon(coordinates, options) { const writer = new BinaryWriter(getPolygonSize(coordinates, options)); writer.writeInt8(1); writeWkbType(writer, WKB.Polygon, options); const [exteriorRing, ...interiorRings] = coordinates; if (exteriorRing.length > 0) { writer.writeUInt32LE(1 + interiorRings.length); writer.writeUInt32LE(exteriorRing.length); } else { writer.writeUInt32LE(0); } for (const coordinate of exteriorRing) { writeCoordinate(writer, coordinate, options); } for (const interiorRing of interiorRings) { writer.writeUInt32LE(interiorRing.length); for (const coordinate of interiorRing) { writeCoordinate(writer, coordinate, options); } } return writer.arrayBuffer; } function getPolygonSize(coordinates, options) { const coordinateSize = getCoordinateSize(options); const [exteriorRing, ...interiorRings] = coordinates; let size = 1 + 4 + 4; if (exteriorRing.length > 0) { size += 4 + exteriorRing.length * coordinateSize; } for (const interiorRing of interiorRings) { size += 4 + interiorRing.length * coordinateSize; } return size; } function encodeMultiPoint(multiPoint, options) { const writer = new BinaryWriter(getMultiPointSize(multiPoint, options)); const points = multiPoint.coordinates; writer.writeInt8(1); writeWkbType(writer, WKB.MultiPoint, options); writer.writeUInt32LE(points.length); for (const point of points) { const arrayBuffer = encodePoint(point, options); writer.writeBuffer(arrayBuffer); } return writer.arrayBuffer; } function getMultiPointSize(multiPoint, options) { let coordinateSize = getCoordinateSize(options); const points = multiPoint.coordinates; coordinateSize += 5; return 1 + 4 + 4 + points.length * coordinateSize; } function encodeMultiLineString(multiLineString, options) { const writer = new BinaryWriter(getMultiLineStringSize(multiLineString, options)); const lineStrings = multiLineString.coordinates; writer.writeInt8(1); writeWkbType(writer, WKB.MultiLineString, options); writer.writeUInt32LE(lineStrings.length); for (const lineString of lineStrings) { const encodedLineString = encodeLineString(lineString, options); writer.writeBuffer(encodedLineString); } return writer.arrayBuffer; } function getMultiLineStringSize(multiLineString, options) { let size = 1 + 4 + 4; const lineStrings = multiLineString.coordinates; for (const lineString of lineStrings) { size += getLineStringSize(lineString, options); } return size; } function encodeMultiPolygon(multiPolygon, options) { const writer = new BinaryWriter(getMultiPolygonSize(multiPolygon, options)); const polygons = multiPolygon.coordinates; writer.writeInt8(1); writeWkbType(writer, WKB.MultiPolygon, options); writer.writeUInt32LE(polygons.length); for (const polygon of polygons) { const encodedPolygon = encodePolygon(polygon, options); writer.writeBuffer(encodedPolygon); } return writer.arrayBuffer; } function getMultiPolygonSize(multiPolygon, options) { let size = 1 + 4 + 4; const polygons = multiPolygon.coordinates; for (const polygon of polygons) { size += getPolygonSize(polygon, options); } return size; } function encodeGeometryCollection(collection, options) { const writer = new BinaryWriter(getGeometryCollectionSize(collection, options)); writer.writeInt8(1); writeWkbType(writer, WKB.GeometryCollection, options); writer.writeUInt32LE(collection.geometries.length); for (const geometry of collection.geometries) { const arrayBuffer = encodeWKB(geometry, options); writer.writeBuffer(arrayBuffer); } return writer.arrayBuffer; } function getGeometryCollectionSize(collection, options) { let size = 1 + 4 + 4; for (const geometry of collection.geometries) { size += getGeometrySize(geometry, options); } return size; } function writeWkbType(writer, geometryType, options) { const { hasZ, hasM, srid } = options; let dimensionType = 0; if (!srid) { if (hasZ && hasM) { dimensionType += 3e3; } else if (hasZ) { dimensionType += 1e3; } else if (hasM) { dimensionType += 2e3; } } else { if (hasZ) { dimensionType |= 2147483648; } if (hasM) { dimensionType |= 1073741824; } } writer.writeUInt32LE(dimensionType + geometryType >>> 0); } function getCoordinateSize(options) { let coordinateSize = 16; if (options.hasZ) { coordinateSize += 8; } if (options.hasM) { coordinateSize += 8; } return coordinateSize; } // dist/wkb-writer.js var WKBWriter = { name: "WKB (Well Known Binary)", id: "wkb", module: "wkt", version: VERSION, extensions: ["wkb"], options: { wkb: { hasZ: false, hasM: false } }, async encode(data, options) { return encodeWKB(data, options == null ? void 0 : options.wkb); }, encodeSync(data, options) { return encodeWKB(data, options == null ? void 0 : options.wkb); } }; // dist/lib/utils/hex-transcoder.js var alphabet = "0123456789abcdef"; var encodeLookup = []; var decodeLookup = []; for (let i = 0; i < 256; i++) { encodeLookup[i] = alphabet[i >> 4 & 15] + alphabet[i & 15]; if (i < 16) { if (i < 10) { decodeLookup[48 + i] = i; } else { decodeLookup[97 - 10 + i] = i; } } } function encodeHex(array) { const length = array.length; let string = ""; let i = 0; while (i < length) { string += encodeLookup[array[i++]]; } return string; } function decodeHex(string) { const sizeof = string.length >> 1; const length = sizeof << 1; const array = new Uint8Array(sizeof); let n = 0; let i = 0; while (i < length) { array[n++] = decodeLookup[string.charCodeAt(i++)] << 4 | decodeLookup[string.charCodeAt(i++)]; } return array; } // dist/hex-wkb-loader.js var HexWKBLoader = { dataType: null, batchType: null, name: "Hexadecimal WKB", id: "wkb", module: "wkt", version: VERSION, worker: true, category: "geometry", extensions: ["wkb"], mimeTypes: [], options: WKBLoader.options, text: true, testText: isHexWKB, // TODO - encoding here seems wasteful - extend hex transcoder? parse: async (arrayBuffer) => parseHexWKB(new TextDecoder().decode(arrayBuffer)), parseTextSync: parseHexWKB }; function parseHexWKB(text, options) { var _a, _b; const uint8Array = decodeHex(text); const binaryGeometry = (_b = (_a = WKBLoader).parseSync) == null ? void 0 : _b.call(_a, uint8Array.buffer, options); return binaryGeometry; } function isHexWKB(string) { if (!string) { return false; } if (string.length < 10 || string.length % 2 !== 0) { return false; } if (!string.startsWith("00") && !string.startsWith("01")) { return false; } return /^[0-9a-fA-F]+$/.test(string.slice(2)); } // dist/lib/utils/binary-reader.js var BinaryReader = class { arrayBuffer; dataView; byteOffset; littleEndian; constructor(arrayBuffer, isBigEndian = false) { this.arrayBuffer = arrayBuffer; this.dataView = new DataView(arrayBuffer); this.byteOffset = 0; this.littleEndian = !isBigEndian; } readUInt8() { const value = this.dataView.getUint8(this.byteOffset); this.byteOffset += 1; return value; } readUInt16() { const value = this.dataView.getUint16(this.byteOffset, this.littleEndian); this.byteOffset += 2; return value; } readUInt32() { const value = this.dataView.getUint32(this.byteOffset, this.littleEndian); this.byteOffset += 4; return value; } readInt8() { const value = this.dataView.getInt8(this.byteOffset); this.byteOffset += 1; return value; } readInt16() { const value = this.dataView.getInt16(this.byteOffset, this.littleEndian); this.byteOffset += 2; return value; } readInt32() { const value = this.dataView.getInt32(this.byteOffset, this.littleEndian); this.byteOffset += 4; return value; } readFloat() { const value = this.dataView.getFloat32(this.byteOffset, this.littleEndian); this.byteOffset += 4; return value; } readDouble() { const value = this.dataView.getFloat64(this.byteOffset, this.littleEndian); this.byteOffset += 8; return value; } readVarInt() { let result = 0; let bytesRead = 0; let nextByte; do { nextByte = this.dataView.getUint8(this.byteOffset + bytesRead); result += (nextByte & 127) << 7 * bytesRead; bytesRead++; } while (nextByte >= 128); this.byteOffset += bytesRead; return result; } }; // dist/lib/parse-twkb.js function isTWKB(arrayBuffer) { const binaryReader = new BinaryReader(arrayBuffer); const type = binaryReader.readUInt8(); const geometryType = type & 15; if (geometryType < 1 || geometryType > 7) { return false; } return true; } function parseTWKBGeometry(arrayBuffer) { const binaryReader = new BinaryReader(arrayBuffer); const context = parseTWKBHeader(binaryReader); if (context.hasSizeAttribute) { binaryReader.readVarInt(); } if (context.hasBoundingBox) { let dimensions = 2; if (context.hasZ) { dimensions++; } if (context.hasM) { dimensions++; } for (let i = 0; i < dimensions; i++) { binaryReader.readVarInt(); binaryReader.readVarInt(); } } return parseGeometry2(binaryReader, context, context.geometryType); } function parseTWKBHeader(binaryReader) { const type = binaryReader.readUInt8(); const metadataHeader = binaryReader.readUInt8(); const geometryType = type & 15; const precision = zigZagDecode(type >> 4); const hasExtendedPrecision = Boolean(metadataHeader >> 3 & 1); let hasZ = false; let hasM = false; let zPrecision = 0; let zPrecisionFactor = 1; let mPrecision = 0; let mPrecisionFactor = 1; if (hasExtendedPrecision) { const extendedPrecision = binaryReader.readUInt8(); hasZ = (extendedPrecision & 1) === 1; hasM = (extendedPrecision & 2) === 2; zPrecision = zigZagDecode((extendedPrecision & 28) >> 2); zPrecisionFactor = Math.pow(10, zPrecision); mPrecision = zigZagDecode((extendedPrecision & 224) >> 5); mPrecisionFactor = Math.pow(10, mPrecision); } return { geometryType, precision, precisionFactor: Math.pow(10, precision), hasBoundingBox: Boolean(metadataHeader >> 0 & 1), hasSizeAttribute: Boolean(metadataHeader >> 1 & 1), hasIdList: Boolean(metadataHeader >> 2 & 1), hasExtendedPrecision, isEmpty: Boolean(metadataHeader >> 4 & 1), hasZ, hasM, zPrecision, zPrecisionFactor, mPrecision, mPrecisionFactor }; } function parseGeometry2(binaryReader, context, geometryType) { switch (geometryType) { case WKBGeometryType.Point: return parsePoint3(binaryReader, context); case WKBGeometryType.LineString: return parseLineString3(binaryReader, context); case WKBGeometryType.Polygon: return parsePolygon3(binaryReader, context); case WKBGeometryType.MultiPoint: return parseMultiPoint3(binaryReader, context); case WKBGeometryType.MultiLineString: return parseMultiLineString3(binaryReader, context); case WKBGeometryType.MultiPolygon: return parseMultiPolygon3(binaryReader, context); case WKBGeometryType.GeometryCollection: return parseGeometryCollection2(binaryReader, context); default: throw new Error(`GeometryType ${geometryType} not supported`); } } function parsePoint3(reader, context) { if (context.isEmpty) { return { type: "Point", coordinates: [] }; } return { type: "Point", coordinates: readFirstPoint(reader, context) }; } function parseLineString3(reader, context) { if (context.isEmpty) { return { type: "LineString", coordinates: [] }; } const pointCount = reader.readVarInt(); const previousPoint = makePreviousPoint(context); const points = []; for (let i = 0; i < pointCount; i++) { points.push(parseNextPoint(reader, context, previousPoint)); } return { type: "LineString", coordinates: points }; } function parsePolygon3(reader, context) { if (context.isEmpty) { return { type: "Polygon", coordinates: [] }; } const ringCount = reader.readVarInt(); const previousPoint = makePreviousPoint(context); const exteriorRingLength = reader.readVarInt(); const exteriorRing = []; for (let i = 0; i < exteriorRingLength; i++) { exteriorRing.push(parseNextPoint(reader, context, previousPoint)); } const polygon = [exteriorRing]; for (let i = 1; i < ringCount; i++) { const interiorRingCount = reader.readVarInt(); const interiorRing = []; for (let j = 0; j < interiorRingCount; j++) { interiorRing.push(parseNextPoint(reader, context, previousPoint)); } polygon.push(interiorRing); } return { type: "Polygon", coordinates: polygon }; } function parseMultiPoint3(reader, context) { if (context.isEmpty) { return { type: "MultiPoint", coordinates: [] }; } const previousPoint = makePreviousPoint(context); const pointCount = reader.readVarInt(); const coordinates = []; for (let i = 0; i < pointCount; i++) { coordinates.push(parseNextPoint(reader, context, previousPoint)); } return { type: "MultiPoint", coordinates }; } function parseMultiLineString3(reader, context) { if (context.isEmpty) { return { type: "MultiLineString", coordinates: [] }; } const previousPoint = makePreviousPoint(context); const lineStringCount = reader.readVarInt(); const coordinates = []; for (let i = 0; i < lineStringCount; i++) { const pointCount = reader.readVarInt(); const lineString = []; for (let j = 0; j < pointCount; j++) { lineString.push(parseNextPoint(reader, context, previousPoint)); } coordinates.push(lineString); } return { type: "MultiLineString", coordinates }; } function parseMultiPolygon3(reader, context) { if (context.isEmpty) { return { type: "MultiPolygon", coordinates: [] }; } const previousPoint = makePreviousPoint(context); const polygonCount = reader.readVarInt(); const polygons = []; for (let i = 0; i < polygonCount; i++) { const ringCount = reader.readVarInt(); const exteriorPointCount = reader.readVarInt(); const exteriorRing = []; for (let j = 0; j < exteriorPointCount; j++) { exteriorRing.push(parseNextPoint(reader, context, previousPoint)); } const polygon = exteriorRing ? [exteriorRing] : []; for (let j = 1; j < ringCount; j++) { const interiorRing = []; const interiorRingLength = reader.readVarInt(); for (let k = 0; k < interiorRingLength; k++) { interiorRing.push(parseNextPoint(reader, context, previousPoint)); } polygon.push(interiorRing); } polygons.push(polygon); } return { type: "MultiPolygon", coordinates: polygons }; } function parseGeometryCollection2(reader, context) { return { type: "GeometryCollection", geometries: [] }; } function zigZagDecode(value) { return value >> 1 ^ -(value & 1); } function makePointCoordinates(x, y, z, m) { return z !== void 0 ? m !== void 0 ? [x, y, z, m] : [x, y, z] : [x, y]; } function makePreviousPoint(context) { return makePointCoordinates(0, 0, context.hasZ ? 0 : void 0, context.hasM ? 0 : void 0); } function readFirstPoint(reader, context) { const x = zigZagDecode(reader.readVarInt()) / context.precisionFactor; const y = zigZagDecode(reader.readVarInt()) / context.precisionFactor; const z = context.hasZ ? zigZagDecode(reader.readVarInt()) / context.zPrecisionFactor : void 0; const m = context.hasM ? zigZagDecode(reader.readVarInt()) / context.mPrecisionFactor : void 0; return makePointCoordinates(x, y, z, m); } function parseNextPoint(reader, context, previousPoint) { previousPoint[0] += zigZagDecode(reader.readVarInt()) / context.precisionFactor; previousPoint[1] += zigZagDecode(reader.readVarInt()) / context.precisionFactor; if (context.hasZ) { previousPoint[2] += zigZagDecode(reader.readVarInt()) / context.zPrecisionFactor; } if (context.hasM) { previousPoint[3] += zigZagDecode(reader.readVarInt()) / context.mPrecisionFactor; } return previousPoint.slice(); } // dist/twkb-loader.js var TWKBWorkerLoader = { dataType: null, batchType: null, name: "TWKB (Tiny Well-Known Binary)", id: "twkb", module: "wkt", version: VERSION, worker: true, category: "geometry", extensions: ["twkb"], mimeTypes: [], // TODO can we define static, serializable tests, eg. some binary strings? tests: [isTWKB], options: { wkb: { shape: "binary-geometry" // 'geojson-geometry' } } }; var TWKBLoader = { ...TWKBWorkerLoader, parse: async (arrayBuffer) => parseTWKBGeometry(arrayBuffer), parseSync: parseTWKBGeometry }; // dist/lib/encode-twkb.js function encodeTWKB(geometry, options) { const writer = new BinaryWriter(0, true); const context = { ...getTwkbPrecision(5, 0, 0), hasZ: options == null ? void 0 : options.hasZ, hasM: options == null ? void 0 : options.hasM }; encodeGeometry(writer, geometry, context); return writer.arrayBuffer; } function encodeGeometry(writer, geometry, context) { switch (geometry.type) { case "Point": return encodePoint2(writer, context, geometry); case "LineString": return encodeLineString2(writer, context, geometry); case "Polygon": return encodePolygon2(writer, context, geometry); case "MultiPoint": return encodeMultiPoint2(writer, context, geometry); case "MultiLineString": return encodeMultiLineString2(writer, context, geometry); case "MultiPolygon": return encodeMultiPolygon2(writer, context, geometry); case "GeometryCollection": return encodeGeometryCollection2(writer, context, geometry); default: throw new Error("unsupported geometry type"); } } function encodePoint2(writer, context, point) { const isEmpty = point.coordinates.length === 0 || point[0] === "undefined" || point[1] === "undefined"; writeTwkbHeader(writer, context, WKBGeometryType.Point, isEmpty); if (!isEmpty) { const previousPoint = [0, 0, 0, 0]; writeTwkbPoint(writer, context, point.coordinates, previousPoint); } } function encodeLineString2(writer, context, lineString) { const points = lineString.coordinates; const isEmpty = points.length === 0; writeTwkbHeader(writer, context, WKBGeometryType.LineString, isEmpty); if (!isEmpty) { writer.writeVarInt(points.length); const previousPoint = [0, 0, 0, 0]; for (const point of points) { writeTwkbPoint(writer, context, point, previousPoint); } } return writer.arrayBuffer; } function encodePolygon2(writer, context, polygon) { const polygonRings = polygon.coordinates; const isEmpty = polygonRings.length === 0; writeTwkbHeader(writer, context, WKBGeometryType.Polygon, isEmpty); if (!isEmpty) { writer.writeVarInt(polygonRings.length); const previousPoint = [0, 0, 0, 0]; for (const ring of polygonRings) { writer.writeVarInt(ring.length); for (const point of ring) { writeTwkbPoint(writer, context, previousPoint, point); } } } return writer.arrayBuffer; } function encodeMultiPoint2(writer, context, multiPoint) { const points = multiPoint.coordinates; const isEmpty = points.length === 0; writeTwkbHeader(writer, context, WKBGeometryType.MultiPoint, isEmpty); if (!isEmpty) { writer.writeVarInt(points.length); const previousPoint = [0, 0, 0, 0]; for (let i = 0; i < points.length; i++) { writeTwkbPoint(writer, context, previousPoint, points[i]); } } } function encodeMultiLineString2(writer, context, multiLineStrings) { const lineStrings = multiLineStrings.coordinates; const isEmpty = lineStrings.length === 0; writeTwkbHeader(writer, context, WKBGeometryType.MultiLineString, isEmpty); if (!isEmpty) { writer.writeVarInt(lineStrings.length); const previousPoint = [0, 0, 0, 0]; for (const lineString of lineStrings) { writer.writeVarInt(lineString.length); for (const point of lineString) { writeTwkbPoint(writer, context, previousPoint, point); } } } return writer.arrayBuffer; } function encodeMultiPolygon2(writer, context, multiPolygon) { const { coordinates } = multiPolygon; const isEmpty = coordinates.length === 0; writeTwkbHeader(writer, context, WKBGeometryType.MultiPolygon, isEmpty); if (!isEmpty) { const polygons = coordinates; writer.writeVarInt(polygons.length); const previousPoint = [0, 0, 0, 0]; for (const polygonRings of polygons) { writer.writeVarInt(polygonRings.length); for (const ring of polygonRings) { writer.writeVarInt(ring.length); for (const point of ring) { writeTwkbPoint(writer, context, previousPoint, point); } } } } } function encodeGeometryCollection2(writer, context, geometryCollection) { const { geometries } = geometryCollection; const isEmpty = geometries.length === 0; writeTwkbHeader(writer, context, WKBGeometryType.GeometryCollection, isEmpty); if (geometries.length > 0) { writer.writeVarInt(geometries.length); for (const geometry of geometries) { encodeGeometry(writer, geometry, context); } } } function writeTwkbHeader(writer, context, geometryType, isEmpty) { const type = (zigZagEncode(context.xy) << 4) + geometryType; let metadataHeader = context.hasZ || context.hasM ? 1 << 3 : 0; metadataHeader += isEmpty ? 1 << 4 : 0; writer.writeUInt8(type); writer.writeUInt8(metadataHeader); if (context.hasZ || context.hasM) { let extendedPrecision = 0; if (context.hasZ) { extendedPrecision |= 1; } if (context.hasM) { extendedPrecision |= 2; } writer.writeUInt8(extendedPrecision); } } function writeTwkbPoint(writer, context, point, previousPoint) { const x = point[0] * context.xyFactor; const y = point[1] * context.xyFactor; const z = point[2] * context.zFactor; const m = point[3] * context.mFactor; writer.writeVarInt(zigZagEncode(x - previousPoint[0])); writer.writeVarInt(zigZagEncode(y - previousPoint[1])); if (context.hasZ) { writer.writeVarInt(zigZagEncode(z - previousPoint[2])); } if (context.hasM) { writer.writeVarInt(zigZagEncode(m - previousPoint[3])); } previousPoint[0] = x; previousPoint[1] = y; previousPoint[2] = z; previousPoint[3] = m; } function zigZagEncode(value) { return value << 1 ^ value >> 31; } function getTwkbPrecision(xyPrecision, zPrecision, mPrecision) { return { xy: xyPrecision, z: zPrecision, m: mPrecision, xyFactor: Math.pow(10, xyPrecision), zFactor: Math.pow(10, zPrecision), mFactor: Math.pow(10, mPrecision) }; } // dist/twkb-writer.js var TWKBWriter = { name: "TWKB (Tiny Well Known Binary)", id: "twkb", module: "wkt", version: VERSION, extensions: ["twkb"], encode: async (geometry, options) => encodeTWKB(geometry, options == null ? void 0 : options.twkb), encodeSync: (geometry, options) => encodeTWKB(geometry, options == null ? void 0 : options.twkb), options: { twkb: { hasZ: false, hasM: false } } }; //# sourceMappingURL=index.cjs.map