UNPKG

simplify-geojson-visvalingam

Version:

GeoJSON simplification library using the Visvalingam algorithm for efficient point reduction and geometry preservation.

1 lines 28.6 kB
{"version":3,"sources":["../src/index.ts","../src/lib/typeGuards.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'\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\ntype Groups = {\n sortIndexes: Uint32Array\n groupedFrom: Uint32Array\n groupedTo: Uint32Array\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 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 groupedTo[0] = groupedTo.length - 1\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\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 toDelete--\n isDeleted[positions.nextIndexes[k]] = 1\n isDeleted[positions.prevIndexes[k]] = 1\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"],"mappings":"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","names":["index_exports","__export","index_default","__toCommonJS","isFinitePositiveNumber","value","isObject","isFeature","isFeatureCollection","isLineString","isMultiLineString","isPolygon","isMultiPolygon","isGeometryCollection","index_default","geojson","options","isObject","tolerance","isFinitePositiveNumber","fraction","mutate","positions","collectPositions","updatePositions","deletePositions","groupPositions","coordinates","sortIndexes","groupedFrom","groupedTo","i","a","b","j","getPositionArea","heapcompare","priority","heapsink","heap","heapRev","l","r","t","heapswap","heapbubble","heapupdate","val","heappop","heapify","groups","n","isDeleted","toDelete","candidatesByGroupFrom","isCandidate","k","index","isFeatureCollection","isFeature","isGeometryCollection","isLineString","updateLinePositions","isMultiLineString","isPolygon","remove","updateRingsPositions","isMultiPolygon","offset","updateRingPositions","collectLinePositions","collectRingPositions","p"]}