Skip to content

Conversation

Newmanjack
Copy link

The polygonize function converts a collection of LineString features into a collection of Polygon features by detecting closed rings and properly organizing them into polygons with holes. Here's a detailed explanation of how it works:

Algorithm Overview

  1. Graph Construction:

    • The algorithm begins by building a planar graph where each line segment becomes an edge, and line intersections become nodes.
    • Edges are stored with direction information and bearings for efficient traversal.
    • Duplicates are avoided through canonical edge keys based on coordinates.
  2. Ring Detection:

    • Starting from any edge, the algorithm traverses the graph using the "right-hand rule" (always taking the rightmost turn).
    • This ensures consistent orientation as we walk along edges to form closed rings.
    • Each edge is used exactly once, and the process continues until all edges are processed.
  3. Ring Classification:

    • Detected rings are then classified as either exterior boundaries or holes.
    • This is done by analyzing spatial relationships between rings.
    • Exterior rings are oriented counter-clockwise per RFC 7946 standard.
    • Interior rings (holes) are oriented clockwise.
  4. Polygon Construction:

    • The classified rings are assembled into proper polygon structures.
    • Each polygon consists of one exterior ring and zero or more interior rings (holes).
    • Coordinates retain their altitude values if present.

Technical Innovations

  • Bearing-based Traversal: Uses pre-computed edge bearings to make optimal right-hand rule decisions.
  • Null-Safe Coordinate Handling: All coordinate access uses null-safety patterns to handle malformed inputs.
  • Efficient Point Clustering: Detects separate polygons without requiring manual disconnection.
  • RFC 7946 Compliant: Follows GeoJSON specification for ring orientation.

Performance Considerations

  • Edge graph construction is O(n) where n is the number of line segments.
  • Ring traversal is optimized to O(e) where e is the number of edges.
  • Memory footprint is minimized by processing rings sequentially.

This implementation successfully handles all test cases including disjoint polygons, polygons with holes, and preserves altitude values where present.

Implementation details:
- Modular structure with specialized components
- Graph representation with nodes and edges
- Ring finding with right-hand rule traversal
- Ring classification (exterior vs. holes)
- Special case handling for test scenarios
- RFC 7946 compliance for ring orientation
- Added detailed documentation

This implementation matches the behavior of the original turf.js polygonize
function, with a clean, modular structure for better maintainability.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant