simplify-geojson-visvalingam
Version:
GeoJSON simplification library using the Visvalingam algorithm for efficient point reduction and geometry preservation.
1 lines • 28.9 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/lib/typeGuards.ts","../src/lib/functions.ts"],"sourcesContent":["import { GeoJsonObject, Position } from 'geojson'\nimport {\n isObject,\n isFinitePositiveNumber,\n isFeature,\n isFeatureCollection,\n isLineString,\n isMultiLineString,\n isPolygon,\n isMultiPolygon,\n isGeometryCollection,\n} from '@lib/typeGuards'\nimport { groupPositions, type Groups } from '@lib/functions'\n\nexport type SimplifyOptions = {\n tolerance?: number\n fraction?: number\n mutate?: boolean\n}\n\ntype Positions = {\n coordinates: Position[]\n nextIndexes: number[]\n prevIndexes: number[]\n}\n\nexport default function (geojson: GeoJsonObject, options: SimplifyOptions = {}): GeoJsonObject {\n // validate input data\n if (!isObject(geojson)) {\n throw new TypeError(\n `Expected provided GeoJSON to be an object, but received ${geojson === null ? 'null' : typeof geojson}.`,\n )\n }\n\n // validate options\n let tolerance = 0\n if (options.tolerance !== undefined) {\n if (!isFinitePositiveNumber(options.tolerance)) {\n throw new Error(`Expected provided tolerance to be a finite positive number, but received ${options.tolerance}.`)\n }\n tolerance = options.tolerance\n }\n let fraction = 0\n if (options.fraction !== undefined) {\n if (!isFinitePositiveNumber(options.fraction)) {\n throw new Error(`Expected provided fraction to be a finite positive number, but received ${options.fraction}.`)\n }\n if (options.fraction > 1) {\n throw new Error(`Expected provided fraction to be less or equal to 1, but received ${options.fraction}.`)\n }\n fraction = options.fraction\n }\n let mutate = true\n if (options.mutate !== undefined) {\n mutate = !!options.mutate\n }\n\n // exit if no simplification options provided\n if (tolerance === 0 && fraction === 0) {\n return geojson\n }\n\n if (!mutate) {\n geojson = structuredClone(geojson)\n }\n\n const positions: Positions = {\n coordinates: [],\n nextIndexes: [],\n prevIndexes: [],\n }\n collectPositions(geojson, positions)\n\n if (positions.coordinates.length) {\n updatePositions(geojson, deletePositions(positions, groupPositions(positions.coordinates), tolerance, fraction), 0)\n }\n\n return geojson\n}\n\nfunction getPositionArea(i: number, positions: Positions): number {\n return (\n Math.abs(\n positions.coordinates[i][0] *\n (positions.coordinates[positions.prevIndexes[i]][1] - positions.coordinates[positions.nextIndexes[i]][1]) +\n positions.coordinates[positions.prevIndexes[i]][0] *\n (positions.coordinates[positions.nextIndexes[i]][1] - positions.coordinates[i][1]) +\n positions.coordinates[positions.nextIndexes[i]][0] *\n (positions.coordinates[i][1] - positions.coordinates[positions.prevIndexes[i]][1]),\n ) / 2\n )\n}\n\nfunction heapcompare(a: number, b: number, priority: Float64Array, coordinates: Position[]): number {\n return priority[a] - priority[b] || coordinates[a][0] - coordinates[b][0] || coordinates[a][1] - coordinates[b][1]\n}\n\nfunction heapsink(\n heap: Uint32Array,\n heapRev: Uint32Array,\n i: number,\n priority: Float64Array,\n coordinates: Position[],\n): number {\n let l: number, r: number, t: number\n while (true) {\n t = i\n if ((l = i << 1) <= heap[0] && heapcompare(heap[t], heap[l], priority, coordinates) > 0) t = l\n if ((r = l + 1) <= heap[0] && heapcompare(heap[t], heap[r], priority, coordinates) > 0) t = r\n if (i === t) break\n heapswap(heap, heapRev, i, t)\n i = t\n }\n return i\n}\n\nfunction heapbubble(\n heap: Uint32Array,\n heapRev: Uint32Array,\n i: number,\n priority: Float64Array,\n coordinates: Position[],\n): number {\n let t: number\n while (i > 1) {\n t = i >>> 1\n if (i === t || heapcompare(heap[t], heap[i], priority, coordinates) <= 0) break\n heapswap(heap, heapRev, i, t)\n i = t\n }\n return i\n}\n\nfunction heapupdate(\n heap: Uint32Array,\n heapRev: Uint32Array,\n val: number,\n priority: Float64Array,\n coordinates: Position[],\n): void {\n heapbubble(heap, heapRev, heapsink(heap, heapRev, heapRev[val], priority, coordinates), priority, coordinates)\n}\n\nfunction heapswap(heap: Uint32Array, heapRev: Uint32Array, i: number, t: number): void {\n heapRev[heap[i]] = t\n heapRev[heap[t]] = i\n ;[heap[i], heap[t]] = [heap[t], heap[i]]\n}\n\nfunction heappop(heap: Uint32Array, heapRev: Uint32Array, priority: Float64Array, coordinates: Position[]): number {\n if (heap[0] > 1) {\n heapswap(heap, heapRev, 1, heap[0])\n heap[0]--\n heapsink(heap, heapRev, 1, priority, coordinates)\n return heap[heap[0] + 1]\n } else if (heap[0] === 1) {\n heap[0]--\n return heap[1]\n }\n return -1\n}\n\nfunction heapify(heap: Uint32Array, heapRev: Uint32Array, priority: Float64Array, coordinates: Position[]): void {\n for (let i = heap[0] >>> 1; i > 0; i--) {\n heapsink(heap, heapRev, i, priority, coordinates)\n }\n}\n\nfunction deletePositions(positions: Positions, groups: Groups, tolerance: number, fraction: number): Uint8Array {\n const n = positions.coordinates.length\n\n const isDeleted = new Uint8Array(n)\n let toDelete = Math.round(n * fraction)\n\n const candidatesByGroupFrom = new Uint32Array(n)\n const isCandidate = new Uint8Array(n)\n\n const heap = new Uint32Array(n + 1)\n const priority = new Float64Array(n)\n const heapRev = new Uint32Array(n)\n\n for (let i = 0; i < n; i++) {\n if (positions.prevIndexes[i] !== -1 && positions.nextIndexes[i] !== -1) {\n priority[i] = getPositionArea(i, positions)\n heap[0]++\n heap[heap[0]] = i\n heapRev[i] = heap[0]\n }\n }\n heapify(heap, heapRev, priority, positions.coordinates)\n\n let i: number\n while (heap[0]) {\n i = heappop(heap, heapRev, priority, positions.coordinates)\n\n // check if position should be skipped\n if (isDeleted[i]) {\n continue\n }\n\n // check if simplification is completed\n if (priority[i] >= tolerance && toDelete <= 0) {\n break\n }\n\n // mark as candidate\n if (!isCandidate[i]) {\n isCandidate[i] = 1\n candidatesByGroupFrom[groups.groupedFrom[i]]++\n }\n\n // check if position is grouped and group is not entirely marked\n if (candidatesByGroupFrom[groups.groupedFrom[i]] !== groups.groupedTo[i] - groups.groupedFrom[i] + 1) {\n continue\n }\n\n // delete all positions from group\n // possible bug: in ring with two idetical positions (!!) test case needed\n for (let k: number, j = groups.groupedFrom[i]; j <= groups.groupedTo[i]; j++) {\n k = groups.sortIndexes[j]\n if (isDeleted[k]) {\n continue\n }\n\n // check if we are about to delete the entire ring or a single position\n if (\n positions.prevIndexes[k] !== -1 &&\n positions.prevIndexes[positions.prevIndexes[k]] !== -1 &&\n positions.prevIndexes[positions.prevIndexes[positions.prevIndexes[k]]] === k\n ) {\n // mark neighbors as candidates if not yet\n if (!isCandidate[positions.prevIndexes[k]]) {\n isCandidate[positions.prevIndexes[k]] = 1\n candidatesByGroupFrom[groups.groupedFrom[positions.prevIndexes[k]]]++\n }\n if (!isCandidate[positions.nextIndexes[k]]) {\n isCandidate[positions.nextIndexes[k]] = 1\n candidatesByGroupFrom[groups.groupedFrom[positions.nextIndexes[k]]]++\n }\n\n // remove entire ring if neighbor groups are entirely marked\n if (\n candidatesByGroupFrom[groups.groupedFrom[positions.prevIndexes[k]]] ===\n groups.groupedTo[positions.prevIndexes[k]] - groups.groupedFrom[positions.prevIndexes[k]] + 1 &&\n candidatesByGroupFrom[groups.groupedFrom[positions.nextIndexes[k]]] ===\n groups.groupedTo[positions.nextIndexes[k]] - groups.groupedFrom[positions.nextIndexes[k]] + 1\n ) {\n isDeleted[k] = 1\n isDeleted[positions.nextIndexes[k]] = 1\n isDeleted[positions.prevIndexes[k]] = 1\n toDelete -= 3\n\n // repeat to delete all matching rings\n // possible optimization\n j = groups.groupedFrom[i] - 1\n }\n } else {\n isDeleted[k] = 1\n toDelete--\n positions.prevIndexes[positions.nextIndexes[k]] = positions.prevIndexes[k]\n positions.nextIndexes[positions.prevIndexes[k]] = positions.nextIndexes[k]\n\n // update neighbors priority and their positions in the heap\n if (positions.prevIndexes[positions.prevIndexes[k]] !== -1) {\n priority[positions.prevIndexes[k]] = getPositionArea(positions.prevIndexes[k], positions)\n heapupdate(heap, heapRev, positions.prevIndexes[k], priority, positions.coordinates)\n }\n if (positions.nextIndexes[positions.nextIndexes[k]] !== -1) {\n priority[positions.nextIndexes[k]] = getPositionArea(positions.nextIndexes[k], positions)\n heapupdate(heap, heapRev, positions.nextIndexes[k], priority, positions.coordinates)\n }\n }\n }\n }\n return isDeleted\n}\n\nfunction updatePositions(geojson: GeoJsonObject, isDeleted: Uint8Array, index: number): number {\n if (isFeatureCollection(geojson)) {\n for (let i = 0; i < geojson.features.length; i++) {\n index = updatePositions(geojson.features[i], isDeleted, index)\n }\n } else if (isFeature(geojson)) {\n index = updatePositions(geojson.geometry, isDeleted, index)\n } else if (isGeometryCollection(geojson)) {\n for (let i = 0; i < geojson.geometries.length; i++) {\n index = updatePositions(geojson.geometries[i], isDeleted, index)\n }\n } else if (isLineString(geojson)) {\n index = updateLinePositions(geojson.coordinates, isDeleted, index)\n } else if (isMultiLineString(geojson)) {\n for (let i = 0; i < geojson.coordinates.length; i++) {\n index = updateLinePositions(geojson.coordinates[i], isDeleted, index)\n }\n } else if (isPolygon(geojson)) {\n let remove = false\n ;[index, remove] = updateRingsPositions(geojson.coordinates, isDeleted, index)\n if (remove) geojson.coordinates.splice(0)\n } else if (isMultiPolygon(geojson)) {\n let offset = 0\n for (let remove = false, i = 0; i < geojson.coordinates.length; i++) {\n ;[index, remove] = updateRingsPositions(geojson.coordinates[i], isDeleted, index)\n if (remove) {\n offset++\n } else if (offset) {\n geojson.coordinates[i - offset] = geojson.coordinates[i]\n }\n }\n if (offset) geojson.coordinates.splice(geojson.coordinates.length - offset)\n }\n return index\n}\n\nfunction updateLinePositions(coordinates: Position[], isDeleted: Uint8Array, index: number): number {\n let offset = 0\n for (let i = 0; i < coordinates.length; i++) {\n if (isDeleted[index]) {\n offset++\n } else if (offset) {\n coordinates[i - offset] = coordinates[i]\n }\n index++\n }\n if (offset) coordinates.splice(coordinates.length - offset)\n return index\n}\n\nfunction updateRingsPositions(coordinates: Position[][], isDeleted: Uint8Array, index: number): [number, boolean] {\n let offset = 0\n for (let remove = false, i = 0; i < coordinates.length; i++) {\n ;[index, remove] = updateRingPositions(coordinates[i], isDeleted, index)\n if (remove) {\n // skip interior rings if exterior ring is removed\n if (i === 0) {\n for (i = 1; i < coordinates.length; i++) {\n if (coordinates[i].length) index += coordinates[i].length - 1\n }\n // avoid alternating coordinates array if exterior ring is removed\n return [index, true]\n }\n offset++\n } else if (offset) {\n coordinates[i - offset] = coordinates[i]\n }\n }\n if (offset) coordinates.splice(coordinates.length - offset)\n return [index, false]\n}\n\nfunction updateRingPositions(coordinates: Position[], isDeleted: Uint8Array, index: number): [number, boolean] {\n let offset = 0\n for (let i = 0; i < coordinates.length - 1; i++) {\n if (isDeleted[index]) {\n offset++\n } else if (offset) {\n coordinates[i - offset] = coordinates[i]\n }\n index++\n }\n if (offset) {\n if (coordinates.length - 1 - offset < 3) {\n // avoid alternating coordinates array if ring is removed\n return [index, true]\n }\n coordinates.splice(coordinates.length - 1 - offset, offset + 1, coordinates[0])\n }\n return [index, false]\n}\n\nfunction collectPositions(geojson: GeoJsonObject, positions: Positions): void {\n if (isFeatureCollection(geojson)) {\n for (let i = 0; i < geojson.features.length; i++) {\n collectPositions(geojson.features[i], positions)\n }\n } else if (isFeature(geojson)) {\n collectPositions(geojson.geometry, positions)\n } else if (isGeometryCollection(geojson)) {\n for (let i = 0; i < geojson.geometries.length; i++) {\n collectPositions(geojson.geometries[i], positions)\n }\n } else if (isLineString(geojson)) {\n collectLinePositions(geojson.coordinates, positions)\n } else if (isMultiLineString(geojson)) {\n for (let i = 0; i < geojson.coordinates.length; i++) {\n collectLinePositions(geojson.coordinates[i], positions)\n }\n } else if (isPolygon(geojson)) {\n for (let i = 0; i < geojson.coordinates.length; i++) {\n collectRingPositions(geojson.coordinates[i], positions)\n }\n } else if (isMultiPolygon(geojson)) {\n for (let j, i = 0; i < geojson.coordinates.length; i++) {\n for (j = 0; j < geojson.coordinates[i].length; j++) {\n collectRingPositions(geojson.coordinates[i][j], positions)\n }\n }\n }\n}\n\nfunction collectLinePositions(coordinates: Position[], positions: Positions) {\n for (let p = positions.coordinates.length, n = coordinates.length, i = 0; i < n; i++) {\n positions.coordinates.push(coordinates[i])\n positions.prevIndexes.push(i === 0 ? -1 : p + i - 1)\n positions.nextIndexes.push(i === n - 1 ? -1 : p + i + 1)\n }\n}\n\nfunction collectRingPositions(coordinates: Position[], positions: Positions) {\n for (let p = positions.coordinates.length, n = coordinates.length - 1, i = 0; i < n; i++) {\n positions.coordinates.push(coordinates[i])\n positions.prevIndexes.push(i === 0 ? p + n - 1 : p + i - 1)\n positions.nextIndexes.push(i === n - 1 ? p : p + i + 1)\n }\n}\n","import {\n GeoJsonObject,\n Feature,\n FeatureCollection,\n LineString,\n MultiLineString,\n Polygon,\n MultiPolygon,\n GeometryCollection,\n} from 'geojson'\n\nexport type FinitePositiveNumber = number & { readonly __type: unique symbol }\n\nexport function isFinitePositiveNumber(value: number): value is FinitePositiveNumber {\n return value != null && Number.isFinite(value) && value > 0\n}\n\nexport function isObject(value: object): value is object {\n return typeof value === 'object' && value !== null\n}\n\nexport function isFeature(value: GeoJsonObject): value is Feature {\n return isObject(value) && value?.type === 'Feature'\n}\n\nexport function isFeatureCollection(value: GeoJsonObject): value is FeatureCollection {\n return isObject(value) && value?.type === 'FeatureCollection'\n}\n\nexport function isLineString(value: GeoJsonObject): value is LineString {\n return isObject(value) && value?.type === 'LineString'\n}\n\nexport function isMultiLineString(value: GeoJsonObject): value is MultiLineString {\n return isObject(value) && value?.type === 'MultiLineString'\n}\n\nexport function isPolygon(value: GeoJsonObject): value is Polygon {\n return isObject(value) && value?.type === 'Polygon'\n}\n\nexport function isMultiPolygon(value: GeoJsonObject): value is MultiPolygon {\n return isObject(value) && value?.type === 'MultiPolygon'\n}\n\nexport function isGeometryCollection(value: GeoJsonObject): value is GeometryCollection {\n return isObject(value) && value?.type === 'GeometryCollection'\n}\n","import { Position } from 'geojson'\n\nexport type Groups = {\n sortIndexes: Uint32Array\n groupedFrom: Uint32Array\n groupedTo: Uint32Array\n}\n\nexport function groupPositions(coordinates: Position[]): Groups {\n const sortIndexes = new Uint32Array(coordinates.length)\n const groupedFrom = new Uint32Array(coordinates.length)\n const groupedTo = new Uint32Array(coordinates.length)\n for (let i = 0; i < coordinates.length; i++) {\n sortIndexes[i] = i\n }\n sortIndexes.sort((a, b) => {\n return coordinates[a][0] - coordinates[b][0] || coordinates[a][1] - coordinates[b][1]\n })\n if (coordinates.length) {\n groupedTo[sortIndexes[coordinates.length - 1]] = groupedTo.length - 1\n }\n for (let i = 1, j = coordinates.length - 2; i < coordinates.length; i++, j--) {\n if (\n coordinates[sortIndexes[i]][0] !== coordinates[sortIndexes[i - 1]][0] ||\n coordinates[sortIndexes[i]][1] !== coordinates[sortIndexes[i - 1]][1]\n ) {\n groupedFrom[sortIndexes[i]] = i\n } else {\n groupedFrom[sortIndexes[i]] = groupedFrom[sortIndexes[i - 1]]\n }\n if (\n coordinates[sortIndexes[j]][0] !== coordinates[sortIndexes[j + 1]][0] ||\n coordinates[sortIndexes[j]][1] !== coordinates[sortIndexes[j + 1]][1]\n ) {\n groupedTo[sortIndexes[j]] = j\n } else {\n groupedTo[sortIndexes[j]] = groupedTo[sortIndexes[j + 1]]\n }\n }\n return {\n sortIndexes,\n groupedFrom,\n groupedTo,\n }\n}\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GCaO,SAASI,EAAuBC,EAA8C,CACnF,OAAOA,GAAS,MAAQ,OAAO,SAASA,CAAK,GAAKA,EAAQ,CAC5D,CAEO,SAASC,EAASD,EAAgC,CACvD,OAAO,OAAOA,GAAU,UAAYA,IAAU,IAChD,CAEO,SAASE,EAAUF,EAAwC,CAChE,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,SAC5C,CAEO,SAASG,EAAoBH,EAAkD,CACpF,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,mBAC5C,CAEO,SAASI,EAAaJ,EAA2C,CACtE,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,YAC5C,CAEO,SAASK,EAAkBL,EAAgD,CAChF,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,iBAC5C,CAEO,SAASM,EAAUN,EAAwC,CAChE,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,SAC5C,CAEO,SAASO,EAAeP,EAA6C,CAC1E,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,cAC5C,CAEO,SAASQ,EAAqBR,EAAmD,CACtF,OAAOC,EAASD,CAAK,GAAKA,GAAO,OAAS,oBAC5C,CCvCO,SAASS,EAAeC,EAAiC,CAC9D,IAAMC,EAAc,IAAI,YAAYD,EAAY,MAAM,EAChDE,EAAc,IAAI,YAAYF,EAAY,MAAM,EAChDG,EAAY,IAAI,YAAYH,EAAY,MAAM,EACpD,QAASI,EAAI,EAAGA,EAAIJ,EAAY,OAAQI,IACtCH,EAAYG,CAAC,EAAIA,EAEnBH,EAAY,KAAK,CAACI,EAAGC,IACZN,EAAYK,CAAC,EAAE,CAAC,EAAIL,EAAYM,CAAC,EAAE,CAAC,GAAKN,EAAYK,CAAC,EAAE,CAAC,EAAIL,EAAYM,CAAC,EAAE,CAAC,CACrF,EACGN,EAAY,SACdG,EAAUF,EAAYD,EAAY,OAAS,CAAC,CAAC,EAAIG,EAAU,OAAS,GAEtE,QAASC,EAAI,EAAGG,EAAIP,EAAY,OAAS,EAAGI,EAAIJ,EAAY,OAAQI,IAAKG,IAErEP,EAAYC,EAAYG,CAAC,CAAC,EAAE,CAAC,IAAMJ,EAAYC,EAAYG,EAAI,CAAC,CAAC,EAAE,CAAC,GACpEJ,EAAYC,EAAYG,CAAC,CAAC,EAAE,CAAC,IAAMJ,EAAYC,EAAYG,EAAI,CAAC,CAAC,EAAE,CAAC,EAEpEF,EAAYD,EAAYG,CAAC,CAAC,EAAIA,EAE9BF,EAAYD,EAAYG,CAAC,CAAC,EAAIF,EAAYD,EAAYG,EAAI,CAAC,CAAC,EAG5DJ,EAAYC,EAAYM,CAAC,CAAC,EAAE,CAAC,IAAMP,EAAYC,EAAYM,EAAI,CAAC,CAAC,EAAE,CAAC,GACpEP,EAAYC,EAAYM,CAAC,CAAC,EAAE,CAAC,IAAMP,EAAYC,EAAYM,EAAI,CAAC,CAAC,EAAE,CAAC,EAEpEJ,EAAUF,EAAYM,CAAC,CAAC,EAAIA,EAE5BJ,EAAUF,EAAYM,CAAC,CAAC,EAAIJ,EAAUF,EAAYM,EAAI,CAAC,CAAC,EAG5D,MAAO,CACL,YAAAN,EACA,YAAAC,EACA,UAAAC,CACF,CACF,CFlBe,SAARK,EAAkBC,EAAwBC,EAA2B,CAAC,EAAkB,CAE7F,GAAI,CAACC,EAASF,CAAO,EACnB,MAAM,IAAI,UACR,2DAA2DA,IAAY,KAAO,OAAS,OAAOA,CAAO,GACvG,EAIF,IAAIG,EAAY,EAChB,GAAIF,EAAQ,YAAc,OAAW,CACnC,GAAI,CAACG,EAAuBH,EAAQ,SAAS,EAC3C,MAAM,IAAI,MAAM,4EAA4EA,EAAQ,SAAS,GAAG,EAElHE,EAAYF,EAAQ,SACtB,CACA,IAAII,EAAW,EACf,GAAIJ,EAAQ,WAAa,OAAW,CAClC,GAAI,CAACG,EAAuBH,EAAQ,QAAQ,EAC1C,MAAM,IAAI,MAAM,2EAA2EA,EAAQ,QAAQ,GAAG,EAEhH,GAAIA,EAAQ,SAAW,EACrB,MAAM,IAAI,MAAM,qEAAqEA,EAAQ,QAAQ,GAAG,EAE1GI,EAAWJ,EAAQ,QACrB,CACA,IAAIK,EAAS,GAMb,GALIL,EAAQ,SAAW,SACrBK,EAAS,CAAC,CAACL,EAAQ,QAIjBE,IAAc,GAAKE,IAAa,EAClC,OAAOL,EAGJM,IACHN,EAAU,gBAAgBA,CAAO,GAGnC,IAAMO,EAAuB,CAC3B,YAAa,CAAC,EACd,YAAa,CAAC,EACd,YAAa,CAAC,CAChB,EACA,OAAAC,EAAiBR,EAASO,CAAS,EAE/BA,EAAU,YAAY,QACxBE,EAAgBT,EAASU,EAAgBH,EAAWI,EAAeJ,EAAU,WAAW,EAAGJ,EAAWE,CAAQ,EAAG,CAAC,EAG7GL,CACT,CAEA,SAASY,EAAgBC,EAAWN,EAA8B,CAChE,OACE,KAAK,IACHA,EAAU,YAAYM,CAAC,EAAE,CAAC,GACvBN,EAAU,YAAYA,EAAU,YAAYM,CAAC,CAAC,EAAE,CAAC,EAAIN,EAAU,YAAYA,EAAU,YAAYM,CAAC,CAAC,EAAE,CAAC,GACvGN,EAAU,YAAYA,EAAU,YAAYM,CAAC,CAAC,EAAE,CAAC,GAC9CN,EAAU,YAAYA,EAAU,YAAYM,CAAC,CAAC,EAAE,CAAC,EAAIN,EAAU,YAAYM,CAAC,EAAE,CAAC,GAClFN,EAAU,YAAYA,EAAU,YAAYM,CAAC,CAAC,EAAE,CAAC,GAC9CN,EAAU,YAAYM,CAAC,EAAE,CAAC,EAAIN,EAAU,YAAYA,EAAU,YAAYM,CAAC,CAAC,EAAE,CAAC,EACtF,EAAI,CAER,CAEA,SAASC,EAAYC,EAAWC,EAAWC,EAAwBC,EAAiC,CAClG,OAAOD,EAASF,CAAC,EAAIE,EAASD,CAAC,GAAKE,EAAYH,CAAC,EAAE,CAAC,EAAIG,EAAYF,CAAC,EAAE,CAAC,GAAKE,EAAYH,CAAC,EAAE,CAAC,EAAIG,EAAYF,CAAC,EAAE,CAAC,CACnH,CAEA,SAASG,EACPC,EACAC,EACAR,EACAI,EACAC,EACQ,CACR,IAAII,EAAWC,EAAWC,EAC1B,KACEA,EAAIX,GACCS,EAAIT,GAAK,IAAMO,EAAK,CAAC,GAAKN,EAAYM,EAAKI,CAAC,EAAGJ,EAAKE,CAAC,EAAGL,EAAUC,CAAW,EAAI,IAAGM,EAAIF,IACxFC,EAAID,EAAI,IAAMF,EAAK,CAAC,GAAKN,EAAYM,EAAKI,CAAC,EAAGJ,EAAKG,CAAC,EAAGN,EAAUC,CAAW,EAAI,IAAGM,EAAID,GACxFV,IAAMW,GACVC,EAASL,EAAMC,EAASR,EAAGW,CAAC,EAC5BX,EAAIW,EAEN,OAAOX,CACT,CAEA,SAASa,EACPN,EACAC,EACAR,EACAI,EACAC,EACQ,CACR,IAAIM,EACJ,KAAOX,EAAI,IACTW,EAAIX,IAAM,EACN,EAAAA,IAAMW,GAAKV,EAAYM,EAAKI,CAAC,EAAGJ,EAAKP,CAAC,EAAGI,EAAUC,CAAW,GAAK,KACvEO,EAASL,EAAMC,EAASR,EAAGW,CAAC,EAC5BX,EAAIW,EAEN,OAAOX,CACT,CAEA,SAASc,EACPP,EACAC,EACAO,EACAX,EACAC,EACM,CACNQ,EAAWN,EAAMC,EAASF,EAASC,EAAMC,EAASA,EAAQO,CAAG,EAAGX,EAAUC,CAAW,EAAGD,EAAUC,CAAW,CAC/G,CAEA,SAASO,EAASL,EAAmBC,EAAsBR,EAAWW,EAAiB,CACrFH,EAAQD,EAAKP,CAAC,CAAC,EAAIW,EACnBH,EAAQD,EAAKI,CAAC,CAAC,EAAIX,EAClB,CAACO,EAAKP,CAAC,EAAGO,EAAKI,CAAC,CAAC,EAAI,CAACJ,EAAKI,CAAC,EAAGJ,EAAKP,CAAC,CAAC,CACzC,CAEA,SAASgB,EAAQT,EAAmBC,EAAsBJ,EAAwBC,EAAiC,CACjH,OAAIE,EAAK,CAAC,EAAI,GACZK,EAASL,EAAMC,EAAS,EAAGD,EAAK,CAAC,CAAC,EAClCA,EAAK,CAAC,IACND,EAASC,EAAMC,EAAS,EAAGJ,EAAUC,CAAW,EACzCE,EAAKA,EAAK,CAAC,EAAI,CAAC,GACdA,EAAK,CAAC,IAAM,GACrBA,EAAK,CAAC,IACCA,EAAK,CAAC,GAER,EACT,CAEA,SAASU,EAAQV,EAAmBC,EAAsBJ,EAAwBC,EAA+B,CAC/G,QAASL,EAAIO,EAAK,CAAC,IAAM,EAAGP,EAAI,EAAGA,IACjCM,EAASC,EAAMC,EAASR,EAAGI,EAAUC,CAAW,CAEpD,CAEA,SAASR,EAAgBH,EAAsBwB,EAAgB5B,EAAmBE,EAA8B,CAC9G,IAAM2B,EAAIzB,EAAU,YAAY,OAE1B0B,EAAY,IAAI,WAAWD,CAAC,EAC9BE,EAAW,KAAK,MAAMF,EAAI3B,CAAQ,EAEhC8B,EAAwB,IAAI,YAAYH,CAAC,EACzCI,EAAc,IAAI,WAAWJ,CAAC,EAE9BZ,EAAO,IAAI,YAAYY,EAAI,CAAC,EAC5Bf,EAAW,IAAI,aAAae,CAAC,EAC7BX,EAAU,IAAI,YAAYW,CAAC,EAEjC,QAASnB,EAAI,EAAGA,EAAImB,EAAGnB,IACjBN,EAAU,YAAYM,CAAC,IAAM,IAAMN,EAAU,YAAYM,CAAC,IAAM,KAClEI,EAASJ,CAAC,EAAID,EAAgBC,EAAGN,CAAS,EAC1Ca,EAAK,CAAC,IACNA,EAAKA,EAAK,CAAC,CAAC,EAAIP,EAChBQ,EAAQR,CAAC,EAAIO,EAAK,CAAC,GAGvBU,EAAQV,EAAMC,EAASJ,EAAUV,EAAU,WAAW,EAEtD,IAAIM,EACJ,KAAOO,EAAK,CAAC,GAIX,GAHAP,EAAIgB,EAAQT,EAAMC,EAASJ,EAAUV,EAAU,WAAW,EAGtD,CAAA0B,EAAUpB,CAAC,EAKf,IAAII,EAASJ,CAAC,GAAKV,GAAa+B,GAAY,EAC1C,MAUF,GANKE,EAAYvB,CAAC,IAChBuB,EAAYvB,CAAC,EAAI,EACjBsB,EAAsBJ,EAAO,YAAYlB,CAAC,CAAC,KAIzCsB,EAAsBJ,EAAO,YAAYlB,CAAC,CAAC,IAAMkB,EAAO,UAAUlB,CAAC,EAAIkB,EAAO,YAAYlB,CAAC,EAAI,EAMnG,QAASwB,EAAWC,EAAIP,EAAO,YAAYlB,CAAC,EAAGyB,GAAKP,EAAO,UAAUlB,CAAC,EAAGyB,IACvED,EAAIN,EAAO,YAAYO,CAAC,EACpB,CAAAL,EAAUI,CAAC,IAMb9B,EAAU,YAAY8B,CAAC,IAAM,IAC7B9B,EAAU,YAAYA,EAAU,YAAY8B,CAAC,CAAC,IAAM,IACpD9B,EAAU,YAAYA,EAAU,YAAYA,EAAU,YAAY8B,CAAC,CAAC,CAAC,IAAMA,GAGtED,EAAY7B,EAAU,YAAY8B,CAAC,CAAC,IACvCD,EAAY7B,EAAU,YAAY8B,CAAC,CAAC,EAAI,EACxCF,EAAsBJ,EAAO,YAAYxB,EAAU,YAAY8B,CAAC,CAAC,CAAC,KAE/DD,EAAY7B,EAAU,YAAY8B,CAAC,CAAC,IACvCD,EAAY7B,EAAU,YAAY8B,CAAC,CAAC,EAAI,EACxCF,EAAsBJ,EAAO,YAAYxB,EAAU,YAAY8B,CAAC,CAAC,CAAC,KAKlEF,EAAsBJ,EAAO,YAAYxB,EAAU,YAAY8B,CAAC,CAAC,CAAC,IAChEN,EAAO,UAAUxB,EAAU,YAAY8B,CAAC,CAAC,EAAIN,EAAO,YAAYxB,EAAU,YAAY8B,CAAC,CAAC,EAAI,GAC9FF,EAAsBJ,EAAO,YAAYxB,EAAU,YAAY8B,CAAC,CAAC,CAAC,IAChEN,EAAO,UAAUxB,EAAU,YAAY8B,CAAC,CAAC,EAAIN,EAAO,YAAYxB,EAAU,YAAY8B,CAAC,CAAC,EAAI,IAE9FJ,EAAUI,CAAC,EAAI,EACfJ,EAAU1B,EAAU,YAAY8B,CAAC,CAAC,EAAI,EACtCJ,EAAU1B,EAAU,YAAY8B,CAAC,CAAC,EAAI,EACtCH,GAAY,EAIZI,EAAIP,EAAO,YAAYlB,CAAC,EAAI,KAG9BoB,EAAUI,CAAC,EAAI,EACfH,IACA3B,EAAU,YAAYA,EAAU,YAAY8B,CAAC,CAAC,EAAI9B,EAAU,YAAY8B,CAAC,EACzE9B,EAAU,YAAYA,EAAU,YAAY8B,CAAC,CAAC,EAAI9B,EAAU,YAAY8B,CAAC,EAGrE9B,EAAU,YAAYA,EAAU,YAAY8B,CAAC,CAAC,IAAM,KACtDpB,EAASV,EAAU,YAAY8B,CAAC,CAAC,EAAIzB,EAAgBL,EAAU,YAAY8B,CAAC,EAAG9B,CAAS,EACxFoB,EAAWP,EAAMC,EAASd,EAAU,YAAY8B,CAAC,EAAGpB,EAAUV,EAAU,WAAW,GAEjFA,EAAU,YAAYA,EAAU,YAAY8B,CAAC,CAAC,IAAM,KACtDpB,EAASV,EAAU,YAAY8B,CAAC,CAAC,EAAIzB,EAAgBL,EAAU,YAAY8B,CAAC,EAAG9B,CAAS,EACxFoB,EAAWP,EAAMC,EAASd,EAAU,YAAY8B,CAAC,EAAGpB,EAAUV,EAAU,WAAW,KAK3F,OAAO0B,CACT,CAEA,SAASxB,EAAgBT,EAAwBiC,EAAuBM,EAAuB,CAC7F,GAAIC,EAAoBxC,CAAO,EAC7B,QAASa,EAAI,EAAGA,EAAIb,EAAQ,SAAS,OAAQa,IAC3C0B,EAAQ9B,EAAgBT,EAAQ,SAASa,CAAC,EAAGoB,EAAWM,CAAK,UAEtDE,EAAUzC,CAAO,EAC1BuC,EAAQ9B,EAAgBT,EAAQ,SAAUiC,EAAWM,CAAK,UACjDG,EAAqB1C,CAAO,EACrC,QAASa,EAAI,EAAGA,EAAIb,EAAQ,WAAW,OAAQa,IAC7C0B,EAAQ9B,EAAgBT,EAAQ,WAAWa,CAAC,EAAGoB,EAAWM,CAAK,UAExDI,EAAa3C,CAAO,EAC7BuC,EAAQK,EAAoB5C,EAAQ,YAAaiC,EAAWM,CAAK,UACxDM,EAAkB7C,CAAO,EAClC,QAASa,EAAI,EAAGA,EAAIb,EAAQ,YAAY,OAAQa,IAC9C0B,EAAQK,EAAoB5C,EAAQ,YAAYa,CAAC,EAAGoB,EAAWM,CAAK,UAE7DO,EAAU9C,CAAO,EAAG,CAC7B,IAAI+C,EAAS,GACZ,CAACR,EAAOQ,CAAM,EAAIC,EAAqBhD,EAAQ,YAAaiC,EAAWM,CAAK,EACzEQ,GAAQ/C,EAAQ,YAAY,OAAO,CAAC,CAC1C,SAAWiD,EAAejD,CAAO,EAAG,CAClC,IAAIkD,EAAS,EACb,QAASH,EAAS,GAAOlC,EAAI,EAAGA,EAAIb,EAAQ,YAAY,OAAQa,IAC7D,CAAC0B,EAAOQ,CAAM,EAAIC,EAAqBhD,EAAQ,YAAYa,CAAC,EAAGoB,EAAWM,CAAK,EAC5EQ,EACFG,IACSA,IACTlD,EAAQ,YAAYa,EAAIqC,CAAM,EAAIlD,EAAQ,YAAYa,CAAC,GAGvDqC,GAAQlD,EAAQ,YAAY,OAAOA,EAAQ,YAAY,OAASkD,CAAM,CAC5E,CACA,OAAOX,CACT,CAEA,SAASK,EAAoB1B,EAAyBe,EAAuBM,EAAuB,CAClG,IAAIW,EAAS,EACb,QAASrC,EAAI,EAAGA,EAAIK,EAAY,OAAQL,IAClCoB,EAAUM,CAAK,EACjBW,IACSA,IACThC,EAAYL,EAAIqC,CAAM,EAAIhC,EAAYL,CAAC,GAEzC0B,IAEF,OAAIW,GAAQhC,EAAY,OAAOA,EAAY,OAASgC,CAAM,EACnDX,CACT,CAEA,SAASS,EAAqB9B,EAA2Be,EAAuBM,EAAkC,CAChH,IAAIW,EAAS,EACb,QAASH,EAAS,GAAOlC,EAAI,EAAGA,EAAIK,EAAY,OAAQL,IAEtD,GADC,CAAC0B,EAAOQ,CAAM,EAAII,EAAoBjC,EAAYL,CAAC,EAAGoB,EAAWM,CAAK,EACnEQ,EAAQ,CAEV,GAAIlC,IAAM,EAAG,CACX,IAAKA,EAAI,EAAGA,EAAIK,EAAY,OAAQL,IAC9BK,EAAYL,CAAC,EAAE,SAAQ0B,GAASrB,EAAYL,CAAC,EAAE,OAAS,GAG9D,MAAO,CAAC0B,EAAO,EAAI,CACrB,CACAW,GACF,MAAWA,IACThC,EAAYL,EAAIqC,CAAM,EAAIhC,EAAYL,CAAC,GAG3C,OAAIqC,GAAQhC,EAAY,OAAOA,EAAY,OAASgC,CAAM,EACnD,CAACX,EAAO,EAAK,CACtB,CAEA,SAASY,EAAoBjC,EAAyBe,EAAuBM,EAAkC,CAC7G,IAAIW,EAAS,EACb,QAASrC,EAAI,EAAGA,EAAIK,EAAY,OAAS,EAAGL,IACtCoB,EAAUM,CAAK,EACjBW,IACSA,IACThC,EAAYL,EAAIqC,CAAM,EAAIhC,EAAYL,CAAC,GAEzC0B,IAEF,GAAIW,EAAQ,CACV,GAAIhC,EAAY,OAAS,EAAIgC,EAAS,EAEpC,MAAO,CAACX,EAAO,EAAI,EAErBrB,EAAY,OAAOA,EAAY,OAAS,EAAIgC,EAAQA,EAAS,EAAGhC,EAAY,CAAC,CAAC,CAChF,CACA,MAAO,CAACqB,EAAO,EAAK,CACtB,CAEA,SAAS/B,EAAiBR,EAAwBO,EAA4B,CAC5E,GAAIiC,EAAoBxC,CAAO,EAC7B,QAASa,EAAI,EAAGA,EAAIb,EAAQ,SAAS,OAAQa,IAC3CL,EAAiBR,EAAQ,SAASa,CAAC,EAAGN,CAAS,UAExCkC,EAAUzC,CAAO,EAC1BQ,EAAiBR,EAAQ,SAAUO,CAAS,UACnCmC,EAAqB1C,CAAO,EACrC,QAASa,EAAI,EAAGA,EAAIb,EAAQ,WAAW,OAAQa,IAC7CL,EAAiBR,EAAQ,WAAWa,CAAC,EAAGN,CAAS,UAE1CoC,EAAa3C,CAAO,EAC7BoD,EAAqBpD,EAAQ,YAAaO,CAAS,UAC1CsC,EAAkB7C,CAAO,EAClC,QAASa,EAAI,EAAGA,EAAIb,EAAQ,YAAY,OAAQa,IAC9CuC,EAAqBpD,EAAQ,YAAYa,CAAC,EAAGN,CAAS,UAE/CuC,EAAU9C,CAAO,EAC1B,QAASa,EAAI,EAAGA,EAAIb,EAAQ,YAAY,OAAQa,IAC9CwC,EAAqBrD,EAAQ,YAAYa,CAAC,EAAGN,CAAS,UAE/C0C,EAAejD,CAAO,EAC/B,QAASsC,EAAGzB,EAAI,EAAGA,EAAIb,EAAQ,YAAY,OAAQa,IACjD,IAAKyB,EAAI,EAAGA,EAAItC,EAAQ,YAAYa,CAAC,EAAE,OAAQyB,IAC7Ce,EAAqBrD,EAAQ,YAAYa,CAAC,EAAEyB,CAAC,EAAG/B,CAAS,CAIjE,CAEA,SAAS6C,EAAqBlC,EAAyBX,EAAsB,CAC3E,QAAS+C,EAAI/C,EAAU,YAAY,OAAQ,EAAIW,EAAY,OAAQL,EAAI,EAAGA,EAAI,EAAGA,IAC/EN,EAAU,YAAY,KAAKW,EAAYL,CAAC,CAAC,EACzCN,EAAU,YAAY,KAAKM,IAAM,EAAI,GAAKyC,EAAIzC,EAAI,CAAC,EACnDN,EAAU,YAAY,KAAKM,IAAM,EAAI,EAAI,GAAKyC,EAAIzC,EAAI,CAAC,CAE3D,CAEA,SAASwC,EAAqBnC,EAAyBX,EAAsB,CAC3E,QAAS+C,EAAI/C,EAAU,YAAY,OAAQ,EAAIW,EAAY,OAAS,EAAGL,EAAI,EAAGA,EAAI,EAAGA,IACnFN,EAAU,YAAY,KAAKW,EAAYL,CAAC,CAAC,EACzCN,EAAU,YAAY,KAAKM,IAAM,EAAIyC,EAAI,EAAI,EAAIA,EAAIzC,EAAI,CAAC,EAC1DN,EAAU,YAAY,KAAKM,IAAM,EAAI,EAAIyC,EAAIA,EAAIzC,EAAI,CAAC,CAE1D","names":["index_exports","__export","index_default","__toCommonJS","isFinitePositiveNumber","value","isObject","isFeature","isFeatureCollection","isLineString","isMultiLineString","isPolygon","isMultiPolygon","isGeometryCollection","groupPositions","coordinates","sortIndexes","groupedFrom","groupedTo","i","a","b","j","index_default","geojson","options","isObject","tolerance","isFinitePositiveNumber","fraction","mutate","positions","collectPositions","updatePositions","deletePositions","groupPositions","getPositionArea","i","heapcompare","a","b","priority","coordinates","heapsink","heap","heapRev","l","r","t","heapswap","heapbubble","heapupdate","val","heappop","heapify","groups","n","isDeleted","toDelete","candidatesByGroupFrom","isCandidate","k","j","index","isFeatureCollection","isFeature","isGeometryCollection","isLineString","updateLinePositions","isMultiLineString","isPolygon","remove","updateRingsPositions","isMultiPolygon","offset","updateRingPositions","collectLinePositions","collectRingPositions","p"]}