geo-polygonize 0.2.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,6 +14,10 @@ A native Rust port of the JTS/GEOS polygonization algorithm. This crate allows y
14
14
  - **Geo Ecosystem**: Fully integrated with `geo-types` and `geo` crates.
15
15
  - **GeoArrow Support**: Zero-copy data transfer via Arrow C Data Interface and Arrow IPC (Wasm).
16
16
 
17
+ ## Engineering Roadmap
18
+
19
+ For an ambitious, prioritized plan covering performance, security, API consistency, and maintainability, see [docs/roadmap.md](docs/roadmap.md).
20
+
17
21
  ## Usage
18
22
 
19
23
  ### Library
@@ -46,6 +50,32 @@ fn main() {
46
50
  }
47
51
  ```
48
52
 
53
+ ### Choosing `node_input` and `snap_grid_size`
54
+
55
+ Polygonization quality is heavily influenced by input noding strategy.
56
+
57
+ - **`node_input = false`** (default): Fastest path. Use this when your input linework is already noded (all intersections are explicit vertices).
58
+ - **`node_input = true`**: Enables Iterated Snap Rounding (ISR). Use this for real-world datasets that may contain slight misalignments, overlaps, or self-intersections.
59
+ - **`snap_grid_size`** controls how aggressively coordinates are snapped during robust noding:
60
+ - Start with `1e-10` for high-precision projected data.
61
+ - Increase to `1e-8` or `1e-6` when near-duplicate vertices prevent clean topology.
62
+ - Avoid very large values unless your coordinate units are coarse; oversnapping can collapse narrow features.
63
+
64
+ Practical workflow:
65
+ 1. Run with `node_input = false` first on trusted data.
66
+ 2. If you observe missing polygons, sliver artifacts, or unresolved intersections, enable `node_input`.
67
+ 3. Tune `snap_grid_size` upward incrementally until topology stabilizes.
68
+
69
+ ### Output semantics
70
+
71
+ The polygonizer intentionally returns only valid polygonal areas that can be formed from closed cycles:
72
+
73
+ - **Dangles are removed**: dead-end edges do not appear in output polygons.
74
+ - **Cut edges are excluded**: edges that are connected but cannot bound a face are ignored.
75
+ - **Holes and nested shells are preserved** when enough boundary information is present.
76
+
77
+ This behavior matches classical JTS/GEOS polygonization semantics and is useful for cleaning linework before area analysis.
78
+
49
79
  ### GeoArrow Integration
50
80
 
51
81
  The library supports ingesting data directly from Arrow arrays via the `arrow_api` module and `ffi`.
@@ -116,7 +146,12 @@ async function run() {
116
146
  };
117
147
 
118
148
  // Returns a GeoJSON FeatureCollection string
119
- const result = polygonize(JSON.stringify(geojson));
149
+ // Pass explicitly matching backend configuration if desired
150
+ const result = polygonize(
151
+ JSON.stringify(geojson),
152
+ true, // node_input
153
+ 0.5 // snap_grid_size
154
+ );
120
155
  console.log(JSON.parse(result));
121
156
 
122
157
  // Or use Arrow IPC bytes
Binary file
Binary file
@@ -45,6 +45,10 @@ function getUint8ArrayMemory0$1() {
45
45
  return cachedUint8ArrayMemory0$1;
46
46
  }
47
47
 
48
+ function isLikeNone$1(x) {
49
+ return x === undefined || x === null;
50
+ }
51
+
48
52
  function passArray32ToWasm0$1(arg, malloc) {
49
53
  const ptr = malloc(arg.length * 4, 4) >>> 0;
50
54
  getUint32ArrayMemory0$1().set(arg, ptr / 4);
@@ -214,15 +218,18 @@ if (Symbol.dispose) WasmPolygonResult$1.prototype[Symbol.dispose] = WasmPolygonR
214
218
 
215
219
  /**
216
220
  * @param {string} geojson_str
221
+ * @param {boolean | null} [node_input]
222
+ * @param {number | null} [snap_grid_size]
223
+ * @param {boolean | null} [extract_only_polygonal]
217
224
  * @returns {string}
218
225
  */
219
- function polygonize$1(geojson_str) {
226
+ function polygonize$1(geojson_str, node_input, snap_grid_size, extract_only_polygonal) {
220
227
  let deferred3_0;
221
228
  let deferred3_1;
222
229
  try {
223
230
  const ptr0 = passStringToWasm0$1(geojson_str, wasm$1.__wbindgen_malloc, wasm$1.__wbindgen_realloc);
224
231
  const len0 = WASM_VECTOR_LEN$1;
225
- const ret = wasm$1.polygonize(ptr0, len0);
232
+ const ret = wasm$1.polygonize(ptr0, len0, isLikeNone$1(node_input) ? 0xFFFFFF : node_input ? 1 : 0, !isLikeNone$1(snap_grid_size), isLikeNone$1(snap_grid_size) ? 0 : snap_grid_size, isLikeNone$1(extract_only_polygonal) ? 0xFFFFFF : extract_only_polygonal ? 1 : 0);
226
233
  var ptr2 = ret[0];
227
234
  var len2 = ret[1];
228
235
  if (ret[3]) {
@@ -467,6 +474,10 @@ function getUint8ArrayMemory0() {
467
474
  return cachedUint8ArrayMemory0;
468
475
  }
469
476
 
477
+ function isLikeNone(x) {
478
+ return x === undefined || x === null;
479
+ }
480
+
470
481
  function passArray32ToWasm0(arg, malloc) {
471
482
  const ptr = malloc(arg.length * 4, 4) >>> 0;
472
483
  getUint32ArrayMemory0().set(arg, ptr / 4);
@@ -636,15 +647,18 @@ if (Symbol.dispose) WasmPolygonResult.prototype[Symbol.dispose] = WasmPolygonRes
636
647
 
637
648
  /**
638
649
  * @param {string} geojson_str
650
+ * @param {boolean | null} [node_input]
651
+ * @param {number | null} [snap_grid_size]
652
+ * @param {boolean | null} [extract_only_polygonal]
639
653
  * @returns {string}
640
654
  */
641
- function polygonize(geojson_str) {
655
+ function polygonize(geojson_str, node_input, snap_grid_size, extract_only_polygonal) {
642
656
  let deferred3_0;
643
657
  let deferred3_1;
644
658
  try {
645
659
  const ptr0 = passStringToWasm0(geojson_str, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
646
660
  const len0 = WASM_VECTOR_LEN;
647
- const ret = wasm.polygonize(ptr0, len0);
661
+ const ret = wasm.polygonize(ptr0, len0, isLikeNone(node_input) ? 0xFFFFFF : node_input ? 1 : 0, !isLikeNone(snap_grid_size), isLikeNone(snap_grid_size) ? 0 : snap_grid_size, isLikeNone(extract_only_polygonal) ? 0xFFFFFF : extract_only_polygonal ? 1 : 0);
648
662
  var ptr2 = ret[0];
649
663
  var len2 = ret[1];
650
664
  if (ret[3]) {
@@ -42,6 +42,10 @@ function getUint8ArrayMemory0$1() {
42
42
  return cachedUint8ArrayMemory0$1;
43
43
  }
44
44
 
45
+ function isLikeNone$1(x) {
46
+ return x === undefined || x === null;
47
+ }
48
+
45
49
  function passArray32ToWasm0$1(arg, malloc) {
46
50
  const ptr = malloc(arg.length * 4, 4) >>> 0;
47
51
  getUint32ArrayMemory0$1().set(arg, ptr / 4);
@@ -211,15 +215,18 @@ if (Symbol.dispose) WasmPolygonResult$1.prototype[Symbol.dispose] = WasmPolygonR
211
215
 
212
216
  /**
213
217
  * @param {string} geojson_str
218
+ * @param {boolean | null} [node_input]
219
+ * @param {number | null} [snap_grid_size]
220
+ * @param {boolean | null} [extract_only_polygonal]
214
221
  * @returns {string}
215
222
  */
216
- function polygonize$1(geojson_str) {
223
+ function polygonize$1(geojson_str, node_input, snap_grid_size, extract_only_polygonal) {
217
224
  let deferred3_0;
218
225
  let deferred3_1;
219
226
  try {
220
227
  const ptr0 = passStringToWasm0$1(geojson_str, wasm$1.__wbindgen_malloc, wasm$1.__wbindgen_realloc);
221
228
  const len0 = WASM_VECTOR_LEN$1;
222
- const ret = wasm$1.polygonize(ptr0, len0);
229
+ const ret = wasm$1.polygonize(ptr0, len0, isLikeNone$1(node_input) ? 0xFFFFFF : node_input ? 1 : 0, !isLikeNone$1(snap_grid_size), isLikeNone$1(snap_grid_size) ? 0 : snap_grid_size, isLikeNone$1(extract_only_polygonal) ? 0xFFFFFF : extract_only_polygonal ? 1 : 0);
223
230
  var ptr2 = ret[0];
224
231
  var len2 = ret[1];
225
232
  if (ret[3]) {
@@ -464,6 +471,10 @@ function getUint8ArrayMemory0() {
464
471
  return cachedUint8ArrayMemory0;
465
472
  }
466
473
 
474
+ function isLikeNone(x) {
475
+ return x === undefined || x === null;
476
+ }
477
+
467
478
  function passArray32ToWasm0(arg, malloc) {
468
479
  const ptr = malloc(arg.length * 4, 4) >>> 0;
469
480
  getUint32ArrayMemory0().set(arg, ptr / 4);
@@ -633,15 +644,18 @@ if (Symbol.dispose) WasmPolygonResult.prototype[Symbol.dispose] = WasmPolygonRes
633
644
 
634
645
  /**
635
646
  * @param {string} geojson_str
647
+ * @param {boolean | null} [node_input]
648
+ * @param {number | null} [snap_grid_size]
649
+ * @param {boolean | null} [extract_only_polygonal]
636
650
  * @returns {string}
637
651
  */
638
- function polygonize(geojson_str) {
652
+ function polygonize(geojson_str, node_input, snap_grid_size, extract_only_polygonal) {
639
653
  let deferred3_0;
640
654
  let deferred3_1;
641
655
  try {
642
656
  const ptr0 = passStringToWasm0(geojson_str, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
643
657
  const len0 = WASM_VECTOR_LEN;
644
- const ret = wasm.polygonize(ptr0, len0);
658
+ const ret = wasm.polygonize(ptr0, len0, isLikeNone(node_input) ? 0xFFFFFF : node_input ? 1 : 0, !isLikeNone(snap_grid_size), isLikeNone(snap_grid_size) ? 0 : snap_grid_size, isLikeNone(extract_only_polygonal) ? 0xFFFFFF : extract_only_polygonal ? 1 : 0);
645
659
  var ptr2 = ret[0];
646
660
  var len2 = ret[1];
647
661
  if (ret[3]) {