geo-polygonize 0.39.13 → 0.40.1

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.
Files changed (40) hide show
  1. package/README.md +21 -27
  2. package/dist/geo_polygonize.wasm +0 -0
  3. package/dist/geo_polygonize_simd.wasm +0 -0
  4. package/dist/slim/cjs/bindings/OutputFilterOptions.d.ts +6 -0
  5. package/dist/slim/cjs/bindings/PolygonizerOptions.d.ts +5 -0
  6. package/dist/slim/cjs/index.d.ts +1 -0
  7. package/dist/slim/cjs/index_slim.d.ts +1 -0
  8. package/dist/slim/cjs/index_slim.js +3 -0
  9. package/dist/slim/cjs/index_threads.d.ts +1 -0
  10. package/dist/slim/es/bindings/OutputFilterOptions.d.ts +6 -0
  11. package/dist/slim/es/bindings/PolygonizerOptions.d.ts +5 -0
  12. package/dist/slim/es/index.d.ts +1 -0
  13. package/dist/slim/es/index_slim.d.ts +1 -0
  14. package/dist/slim/es/index_slim.js +3 -0
  15. package/dist/slim/es/index_threads.d.ts +1 -0
  16. package/dist/slim/pkg-wrapper/bindings/OutputFilterOptions.d.ts +6 -0
  17. package/dist/slim/pkg-wrapper/bindings/PolygonizerOptions.d.ts +5 -0
  18. package/dist/standard/cjs/bindings/OutputFilterOptions.d.ts +6 -0
  19. package/dist/standard/cjs/bindings/PolygonizerOptions.d.ts +5 -0
  20. package/dist/standard/cjs/index.d.ts +1 -0
  21. package/dist/standard/cjs/index.js +5 -2
  22. package/dist/standard/cjs/index_slim.d.ts +1 -0
  23. package/dist/standard/cjs/index_threads.d.ts +1 -0
  24. package/dist/standard/es/bindings/OutputFilterOptions.d.ts +6 -0
  25. package/dist/standard/es/bindings/PolygonizerOptions.d.ts +5 -0
  26. package/dist/standard/es/index.d.ts +1 -0
  27. package/dist/standard/es/index.js +5 -2
  28. package/dist/standard/es/index_slim.d.ts +1 -0
  29. package/dist/standard/es/index_threads.d.ts +1 -0
  30. package/dist/standard/pkg-wrapper/bindings/OutputFilterOptions.d.ts +6 -0
  31. package/dist/standard/pkg-wrapper/bindings/PolygonizerOptions.d.ts +5 -0
  32. package/dist/threads/es/bindings/OutputFilterOptions.d.ts +6 -0
  33. package/dist/threads/es/bindings/PolygonizerOptions.d.ts +5 -0
  34. package/dist/threads/es/index.d.ts +1 -0
  35. package/dist/threads/es/index.js +3 -0
  36. package/dist/threads/es/index_slim.d.ts +1 -0
  37. package/dist/threads/es/index_threads.d.ts +1 -0
  38. package/dist/threads/pkg-wrapper/bindings/OutputFilterOptions.d.ts +6 -0
  39. package/dist/threads/pkg-wrapper/bindings/PolygonizerOptions.d.ts +5 -0
  40. package/package.json +1 -1
package/README.md CHANGED
@@ -7,45 +7,39 @@ A native Rust port of the JTS/GEOS polygonization algorithm. This crate allows y
7
7
  ## Features
8
8
 
9
9
  - **Robust Polygonization**: Extracts polygons from unstructured linework.
10
- - **Robust Noding**: Implements **Iterated Snap Rounding (ISR)** to guarantee topological correctness on dirty inputs (self-intersections, overlaps).
10
+ - **Iterative Grid Noding (Unchecked)**: Splits and snaps dirty linework, without claiming certified snap-rounding guarantees.
11
11
  - **Hardware Acceleration**: Uses **SIMD** instructions (via `wide` crate) for critical geometric predicates like Point-in-Polygon checks.
12
12
  - **Wasm Optimized**: Tailored for WebAssembly with `talc` allocator and binary GeoArrow support.
13
- - **Performance**: Competitive with GEOS/Shapely (C++), outperforming it on random sparse inputs and scaling well on dense grids.
13
+ - **Performance**: SIMD, spatial indexing, and optional parallel execution, with checked-in benchmark tooling.
14
14
  - **Geo Ecosystem**: Fully integrated with `geo-types` and `geo` crates.
15
15
  - **GeoArrow Support**: Arrow C Data Interface and Arrow IPC integration with GeoArrow metadata.
16
16
 
17
17
  ## Engineering Roadmap
18
18
 
19
- For an ambitious, prioritized plan covering performance, security, API consistency, and maintainability, see [docs/roadmap.md](docs/roadmap.md).
19
+ For an ambitious, prioritized plan covering performance, security, API consistency, and maintainability, see [ROADMAP.md](ROADMAP.md).
20
20
 
21
21
  ## Usage
22
22
 
23
23
  ### Library
24
24
 
25
25
  ```rust
26
- use geo_polygonize_core::Polygonizer;
27
- use geo_types::LineString;
26
+ use geo_polygonize_core::{polygonize, Coord3D, Line3D};
27
+ use geo_polygonize_core::options::PolygonizerOptions;
28
28
 
29
29
  fn main() {
30
- let mut poly = Polygonizer::new();
31
-
32
- // Enable robust noding if lines might intersect
33
- poly.node_input = true;
34
- // Optional: Configure snap grid (default 1e-10)
35
- poly.snap_grid_size = 1e-6;
36
-
37
- // Add lines (e.g., a square with diagonals)
38
- poly.add_geometry(LineString::from(vec![
39
- (0.0, 0.0), (10.0, 0.0), (10.0, 10.0), (0.0, 10.0), (0.0, 0.0)
40
- ]).into());
41
- poly.add_geometry(LineString::from(vec![
42
- (0.0, 0.0), (10.0, 10.0)
43
- ]).into());
44
-
45
- let polygons = poly.polygonize().expect("Polygonization failed");
46
-
47
- for p in polygons {
48
- println!("Found polygon with area: {}", p.unsigned_area());
30
+ let points = [
31
+ Coord3D::new(0.0, 0.0, 0.0),
32
+ Coord3D::new(10.0, 0.0, 0.0),
33
+ Coord3D::new(10.0, 10.0, 0.0),
34
+ Coord3D::new(0.0, 10.0, 0.0),
35
+ ];
36
+ let lines = (0..4).map(|i| Line3D::new(points[i], points[(i + 1) % 4], i as u32));
37
+
38
+ let result = polygonize(lines, &PolygonizerOptions::default())
39
+ .expect("Polygonization failed");
40
+
41
+ for polygon in result.polygons {
42
+ println!("Found polygon with area: {}", polygon.unsigned_area_2d());
49
43
  }
50
44
  }
51
45
  ```
@@ -55,7 +49,7 @@ fn main() {
55
49
  Polygonization quality is heavily influenced by input noding strategy.
56
50
 
57
51
  - **`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.
52
+ - **`node_input = true`**: Enables unchecked iterative grid noding. Use this for real-world datasets that may contain slight misalignments, overlaps, or self-intersections, and validate outputs when correctness must be certified.
59
53
  - **`snap_grid_size`** controls how aggressively coordinates are snapped during robust noding:
60
54
  - Start with `1e-10` for high-precision projected data.
61
55
  - Increase to `1e-8` or `1e-6` when near-duplicate vertices prevent clean topology.
@@ -254,7 +248,7 @@ async function run() {
254
248
  ```
255
249
 
256
250
  **Important:** Multithreaded WebAssembly requires `SharedArrayBuffer`, which is only available in secure contexts. You **must** serve your page with the following headers:
257
- ```
251
+ ```text
258
252
  Cross-Origin-Opener-Policy: same-origin
259
253
  Cross-Origin-Embedder-Policy: require-corp
260
254
  ```
@@ -332,7 +326,7 @@ This implementation moves away from the pointer-based graph structures of JTS/GE
332
326
  See [ARCHITECTURE.md](ARCHITECTURE.md) for a deep dive into the optimization strategies.
333
327
 
334
328
  Key optimizations include:
335
- 1. **Robust Noding**: Iterated Snap Rounding (ISR) using `rstar` for intersection detection and grid snapping.
329
+ 1. **Noding**: Unchecked iterative grid noding with spatially dispatched intersection detection.
336
330
  2. **Vectorization**: SIMD-accelerated Ray Casting for efficient Hole Assignment.
337
331
  3. **Memory Layout**: Structure of Arrays (SoA) for graph nodes and `talc` allocator for Wasm.
338
332
 
Binary file
Binary file
@@ -0,0 +1,6 @@
1
+ export type OutputFilterOptions = {
2
+ /**
3
+ * Keep faces whose area is greater than or equal to this value.
4
+ */
5
+ minimum_face_area?: number;
6
+ };
@@ -2,6 +2,7 @@ import type { ContainmentOptions } from "./ContainmentOptions";
2
2
  import type { DeterminismOptions } from "./DeterminismOptions";
3
3
  import type { DiagnosticsOptions } from "./DiagnosticsOptions";
4
4
  import type { NodingOptions } from "./NodingOptions";
5
+ import type { OutputFilterOptions } from "./OutputFilterOptions";
5
6
  import type { ProvenanceOptions } from "./ProvenanceOptions";
6
7
  import type { SnapStrategy } from "./SnapStrategy";
7
8
  /**
@@ -78,6 +79,10 @@ export type PolygonizerOptions = {
78
79
  * Options for mapping final faces back to original input geometry IDs.
79
80
  */
80
81
  provenance: ProvenanceOptions;
82
+ /**
83
+ * Optional application-level filtering applied after topology is established.
84
+ */
85
+ output_filter: OutputFilterOptions;
81
86
  /**
82
87
  * An optional identifier for the input dataset.
83
88
  */
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";
@@ -892,6 +892,9 @@ const cfbRobustOptions = {
892
892
  enabled: true,
893
893
  include_boundary_line_ids: true,
894
894
  },
895
+ output_filter: {
896
+ minimum_face_area: undefined,
897
+ },
895
898
  input_profile_id: "cfb_robust_v1",
896
899
  };
897
900
 
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";
@@ -0,0 +1,6 @@
1
+ export type OutputFilterOptions = {
2
+ /**
3
+ * Keep faces whose area is greater than or equal to this value.
4
+ */
5
+ minimum_face_area?: number;
6
+ };
@@ -2,6 +2,7 @@ import type { ContainmentOptions } from "./ContainmentOptions";
2
2
  import type { DeterminismOptions } from "./DeterminismOptions";
3
3
  import type { DiagnosticsOptions } from "./DiagnosticsOptions";
4
4
  import type { NodingOptions } from "./NodingOptions";
5
+ import type { OutputFilterOptions } from "./OutputFilterOptions";
5
6
  import type { ProvenanceOptions } from "./ProvenanceOptions";
6
7
  import type { SnapStrategy } from "./SnapStrategy";
7
8
  /**
@@ -78,6 +79,10 @@ export type PolygonizerOptions = {
78
79
  * Options for mapping final faces back to original input geometry IDs.
79
80
  */
80
81
  provenance: ProvenanceOptions;
82
+ /**
83
+ * Optional application-level filtering applied after topology is established.
84
+ */
85
+ output_filter: OutputFilterOptions;
81
86
  /**
82
87
  * An optional identifier for the input dataset.
83
88
  */
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";
@@ -889,6 +889,9 @@ const cfbRobustOptions = {
889
889
  enabled: true,
890
890
  include_boundary_line_ids: true,
891
891
  },
892
+ output_filter: {
893
+ minimum_face_area: undefined,
894
+ },
892
895
  input_profile_id: "cfb_robust_v1",
893
896
  };
894
897
 
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";
@@ -0,0 +1,6 @@
1
+ export type OutputFilterOptions = {
2
+ /**
3
+ * Keep faces whose area is greater than or equal to this value.
4
+ */
5
+ minimum_face_area?: number;
6
+ };
@@ -2,6 +2,7 @@ import type { ContainmentOptions } from "./ContainmentOptions";
2
2
  import type { DeterminismOptions } from "./DeterminismOptions";
3
3
  import type { DiagnosticsOptions } from "./DiagnosticsOptions";
4
4
  import type { NodingOptions } from "./NodingOptions";
5
+ import type { OutputFilterOptions } from "./OutputFilterOptions";
5
6
  import type { ProvenanceOptions } from "./ProvenanceOptions";
6
7
  import type { SnapStrategy } from "./SnapStrategy";
7
8
  /**
@@ -78,6 +79,10 @@ export type PolygonizerOptions = {
78
79
  * Options for mapping final faces back to original input geometry IDs.
79
80
  */
80
81
  provenance: ProvenanceOptions;
82
+ /**
83
+ * Optional application-level filtering applied after topology is established.
84
+ */
85
+ output_filter: OutputFilterOptions;
81
86
  /**
82
87
  * An optional identifier for the input dataset.
83
88
  */
@@ -0,0 +1,6 @@
1
+ export type OutputFilterOptions = {
2
+ /**
3
+ * Keep faces whose area is greater than or equal to this value.
4
+ */
5
+ minimum_face_area?: number;
6
+ };
@@ -2,6 +2,7 @@ import type { ContainmentOptions } from "./ContainmentOptions";
2
2
  import type { DeterminismOptions } from "./DeterminismOptions";
3
3
  import type { DiagnosticsOptions } from "./DiagnosticsOptions";
4
4
  import type { NodingOptions } from "./NodingOptions";
5
+ import type { OutputFilterOptions } from "./OutputFilterOptions";
5
6
  import type { ProvenanceOptions } from "./ProvenanceOptions";
6
7
  import type { SnapStrategy } from "./SnapStrategy";
7
8
  /**
@@ -78,6 +79,10 @@ export type PolygonizerOptions = {
78
79
  * Options for mapping final faces back to original input geometry IDs.
79
80
  */
80
81
  provenance: ProvenanceOptions;
82
+ /**
83
+ * Optional application-level filtering applied after topology is established.
84
+ */
85
+ output_filter: OutputFilterOptions;
81
86
  /**
82
87
  * An optional identifier for the input dataset.
83
88
  */
@@ -6,6 +6,7 @@ export * from "./bindings/DeterminismOptions";
6
6
  export * from "./bindings/DiagnosticsOptions";
7
7
  export * from "./bindings/NodingBackend";
8
8
  export * from "./bindings/NodingOptions";
9
+ export * from "./bindings/OutputFilterOptions";
9
10
  export * from "./bindings/ProvenanceOptions";
10
11
  export * from "./bindings/SnapStrategy";
11
12
  export * from "./bindings/TileOwnershipPolicy";