Skip to main content

Approximate irregular polygons as sets of circles using differentiable rendering

Project description

Geomantic

Tests Coverage PyPI Python License: MIT

TL;DR

A Python package to approximate an irregular polygon as a set of circles, with optional auto-detection of optimal circle count. Accepts standard polygon input, produces both raw circle data and a visualization, and is engineered with DevOps hygiene suitable for portfolio/demo use.

Installation

pip install geomantic

Quick Start

from geomantic import pack_polygon, visualize_packing

# Define a polygon (list of coordinate tuples)
polygon = [(0, 0), (2, 0), (2, 1), (0, 1)]

# Pack circles into the polygon (auto-detect optimal count)
circles = pack_polygon(polygon)

# Visualize the result
visualize_packing(polygon, circles)

For geographic data (lat/lon coordinates):

# Use projection for geographic coordinates
circles = pack_polygon(
    polygon,
    n=5,  # Or None for auto-detection
    use_projection=True  # Ensures circles stay circular on Earth's surface
)

Architecture

Geomantic uses a modular architecture with four main components:

geomantic/
├── core.py          # Main API: pack_polygon() orchestrates the pipeline
├── optimizer.py     # PyTorch-based optimization engine
├── projection.py    # Geographic coordinate transformations (WGS84 ↔ UTM)
└── visualization.py # Plotting and output utilities

Key modules:

  • core.py: Main entry point with pack_polygon() function. Handles input parsing, projection setup, normalization, and result formatting.

  • optimizer.py: Contains the differentiable rendering optimization:

    • CircleModel: PyTorch neural network with learnable circle positions and radii
    • DifferentiableRenderer: Rasterizes polygons to binary masks
    • optimize_circles(): Gradient descent optimization with IoU loss
    • Smart initialization samples circle positions inside the polygon
    • Containment and repulsion penalties prevent circles from escaping or collapsing
  • projection.py: Coordinate transformation utilities:

    • MetricProjector: WGS84 ↔ UTM transformations with auto-zone detection
    • MetricNormalizer: Scales coordinates to [0,1] normalized space for optimization
  • visualization.py: Visualization tools including visualize_packing() and print_circle_summary()

Optimization pipeline:

Input Polygon → [Projection to UTM] → Normalization →
PyTorch Optimization (IoU + Containment + Repulsion) →
Denormalization → [Projection back to WGS84] → Circle Results

Project Goals

Problem Statement

Traditional geometric approximation methods struggle with irregular polygons, especially when physical interpretability matters. Geographic boundaries (ZIP codes, districts, protected areas) often need to be simplified for:

  • Spatial analysis: Coverage estimation, service area planning, accessibility modeling
  • Visualization: Reducing visual complexity while preserving spatial meaning
  • Approximation: Replacing complex polygons with analytically tractable primitives

Existing solutions either produce poor approximations (convex hulls, bounding boxes) or lack geographic awareness (treating lat/lon as Cartesian coordinates produces distorted circles).

What Geomantic Solves

1. Physically Accurate Geographic Approximation

  • Automatically projects WGS84 coordinates to UTM before optimization, ensuring circles remain circular on Earth's surface
  • Handles latitude-dependent longitude scaling for correct distance calculations
  • Eliminates the "stretched ellipse" problem common in naive lat/lon circle fitting

2. Smart Optimization with Constraints

  • Uses differentiable rendering with PyTorch for gradient-based optimization (faster convergence than genetic algorithms)
  • Containment penalties keep circles inside polygon boundaries (critical for concave shapes)
  • Repulsion penalties prevent circle collapse, ensuring diverse coverage
  • Auto-detection finds optimal circle count using elbow method on IoU loss

3. Production-Ready Engineering

  • Type-safe codebase with full mypy compliance
  • Comprehensive test coverage with pytest
  • Pre-commit hooks for code quality (Black, flake8, mypy)
  • CI/CD pipeline with multi-version Python testing (3.8-3.12)
  • Installable via pip with minimal dependencies

Use Cases

  • Urban planning: Approximate service areas (fire stations, schools) for quick distance calculations
  • Ecology: Simplify habitat boundaries for circular buffer analysis
  • Marketing: Convert trade areas or ZIP code boundaries to radial coverage zones
  • Education: Demonstrate optimization techniques, differentiable rendering, and coordinate projections
  • Data visualization: Replace complex polygons with simpler circular representations for cleaner maps

What Geomantic Is NOT

  • Not a general-purpose polygon simplification tool (use Shapely's simplify() for that)
  • Not optimized for real-time applications (optimization takes seconds to minutes depending on complexity)
  • Not a commercial SaaS product (open-source library for integration into your own tools)
  • Not a replacement for precise geometric operations (approximation introduces error by design)

User Stories

  • As a Data Scientist, I want to fit circles to arbitrary polygons, so that I can demonstrate geometric optimization in presentations.
  • As a developer, I want to import this as a Python library, so that I can integrate it into Jupyter notebooks or pipelines.
  • As a hobbyist, I want to visualize the packing, so that I can experiment and tweak inputs for different shapes.

Functional Requirements

  • Core Algorithm (Priority: High)
    • Accept input polygon (list of coordinates or GeoJSON).
    • Accept optional n; otherwise autodetect using suitable metric (e.g., elbow method).
    • Grid-based differentiable rasterization for circle fitting.
    • Compute suitable initial centroids.
  • API/Interface (Priority: High)
    • Python function/class interface.
    • Output: Array of dictionaries, each with radius, centroid_x, centroid_y.
  • Visualization (Priority: Medium)
    • Function to generate an image (matplotlib, etc.) showing polygon outline and circles.
  • Packaging (Priority: High)
    • Installable via pip (or equivalent, e.g., Poetry support).
  • Testing & Code Quality (Priority: High)
    • Unit tests for inputs/outputs, edge cases, and algorithm steps.
    • Automated linting and type-checking, e.g., with flake8/black/pylint and mypy.
  • DevOps & Deployment (Priority: Medium)
    • GitHub Actions to run tests/linting on commit/push.
    • (Optional) Terraform/GCP scripts for potential future hosting.

User Experience

  • User installs via pip.
  • Imports in notebook/script: from geomantic import pack_polygon
  • Calls main function, passing polygon and options.
  • Receives output (list of circles), optionally calls viz function for output.
  • Views resulting image in notebook or as file.

Technical Considerations

  • Python-first; minimal non-Python dependencies.
  • Codebase ready for CI (GitHub Actions).
  • Focus on modularity/testability: split main algorithm from I/O and viz.
  • Type hints and docstrings throughout.
  • Testing: Use pytest; test basic input validation, algorithm output, and (if feasible) some image output.

Success Metrics

  • All primary features covered by automated tests and CI.
  • Can be imported and run in a clean virtualenv.
  • Generates accurate results for at least 3 "typical" test polygons.
  • README/docs clear enough for DS/engineering peers to use and understand.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

geomantic-0.1.0.tar.gz (42.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

geomantic-0.1.0-py3-none-any.whl (19.5 kB view details)

Uploaded Python 3

File details

Details for the file geomantic-0.1.0.tar.gz.

File metadata

  • Download URL: geomantic-0.1.0.tar.gz
  • Upload date:
  • Size: 42.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for geomantic-0.1.0.tar.gz
Algorithm Hash digest
SHA256 78deada7044760c75012c7f16f60e42f3c328a9fe18feea0c35c9569a17db008
MD5 8457b5f0ed471fe6cff554e8e9a1e078
BLAKE2b-256 36924395703bb2ac9cde619064abd561adcfbad5c61db7d88d6afb1bfdcd8839

See more details on using hashes here.

Provenance

The following attestation bundles were made for geomantic-0.1.0.tar.gz:

Publisher: publish.yml on horeilly/geomantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file geomantic-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: geomantic-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 19.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for geomantic-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b0c22006057eb3134b131583223444141be2c5c66f8ccee781a0d85ebe71ce18
MD5 62a9c5160089cf4fa765edb1429acf02
BLAKE2b-256 78270ff8c8b41e58736b6e26916eb4321f147ba7da5493917f329fa56cd2bffb

See more details on using hashes here.

Provenance

The following attestation bundles were made for geomantic-0.1.0-py3-none-any.whl:

Publisher: publish.yml on horeilly/geomantic

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page