Skip to main content

sigmap-pytools

Documentation PyPI version Python Version License

Documentation | GitHub Repository | PyPI

A Python package for downloading and manipulating geometries by subdividing them using geohash. This package provides efficient tools for spatial processing, geohash-based polygon subdivision, and visualization.

🚀 Features

  • Geohash-based Polygon Subdivision: Generate adaptive or fixed-level geohash coverage for any polygon geometry
  • GADM Integration: Download country geometries directly from the GADM database
  • Coordinate Encoding: Convert coordinates to geohash strings and vice versa
  • Flexible Coverage Algorithms:
    • Adaptive coverage with multi-level refinement
    • Single-level coverage for uniform tiling
  • Visualization Tools: Plot geohash coverage with customizable styling
  • Efficient Processing: Uses spatial indexes (STRtree) for fast intersection checks
  • Geohash Utilities: Comprehensive set of tools for geohash manipulation and conversion

📦 Installation

From PyPI

pip install sigmap-pytools

🏃 Quick Start

import sigmap.polygeohasher as polygeohasher
from shapely.geometry import box, MultiPolygon

# Download a country geometry from GADM
country_gdf = polygeohasher.download_gadm_country('BEL', cache_dir='./gadm_cache')

# Build a single multipolygon from the GeoDataFrame
country_geom = polygeohasher.build_single_multipolygon(country_gdf)

# Generate adaptive geohash coverage (refines at boundaries)
geohash_dict, tiles_gdf = polygeohasher.adaptive_geohash_coverage(
    country_geom,
    min_level=2,
    max_level=5,
    coverage_threshold=0.95
)

print(f"Generated {sum(len(v) for v in geohash_dict.values())} geohashes")

📊 Visual Examples

Coverage Comparison

The package supports two coverage strategies. Here's a visual comparison showing how each approach covers the same geometry:

Adaptive Coverage Single-Level Coverage
Adaptive Coverage Single-Level Coverage
Multi-level refinement: larger tiles in interior, smaller at boundaries Uniform tile size across entire geometry

Statistics & Analysis

Additional visualization capabilities include level distribution statistics and geometric comparisons:

Level Statistics Geohash Comparison
Level Statistics Boxes Comparison
Distribution of tiles across geohash levels Geohash boxes vs actual polygon boundaries

📚 Main Features

1. Geohash Coverage Generation

Adaptive Coverage

Adaptive coverage automatically refines geohash tiles at polygon boundaries, using finer resolution where needed. This results in fewer tiles overall while maintaining high accuracy at boundaries:

geohash_dict, tiles_gdf = polygeohasher.adaptive_geohash_coverage(
    geometry,
    min_level=2,        # Starting geohash level
    max_level=5,         # Maximum refinement level
    coverage_threshold=0.95,  # Threshold for considering a tile "fully covered"
    use_strtree=True,    # Use spatial index for performance
    debug=False
)

# Access results
for level, geohashes in geohash_dict.items():
    print(f"Level {level}: {len(geohashes)} tiles")

Visual Example: Adaptive Coverage Adaptive coverage uses multi-level refinement: large tiles in the interior, smaller tiles at boundaries for optimal coverage with fewer total tiles.

Single-Level Coverage

Generate uniform geohash coverage at a specific level. All tiles have the same size, providing consistent resolution across the entire geometry:

geohash_dict = polygeohasher.geohash_coverage(
    geometry,
    level=3,            # Geohash level (1-12, typically 3-6)
    use_strtree=True,
    debug=False
)

Visual Example: Single-Level Coverage Single-level coverage uses uniform tile sizes across the entire geometry. All tiles are at the same geohash level.

Comparison

Adaptive Coverage (recommended for most cases):

  • ✅ Fewer tiles needed for good coverage
  • ✅ Automatically optimizes resolution at boundaries
  • ✅ Better performance with large geometries
  • ✅ More efficient storage and processing

Single-Level Coverage:

  • ✅ Consistent resolution everywhere
  • ✅ Simpler to understand and debug
  • ✅ Predictable tile count
  • ⚠️ May require more tiles for accurate boundary coverage

2. GADM Country Data Download

Download country geometries from the GADM database:

# Download Belgium geometry
belgium_gdf = polygeohasher.download_gadm_country(
    'BEL',                    # ISO3 country code
    cache_dir='./gadm_cache'  # Cache directory
)

# Convert to single geometry
belgium_geom = polygeohasher.build_single_multipolygon(belgium_gdf)

3. Geohash Encoding and Decoding

# Encode coordinates to geohash
geohash = polygeohasher.encode_geohash(lon=6.1, lat=49.6, L=5)
print(geohash)  # 'u0u64'

# Convert geohash to polygon
polygon = polygeohasher.geohash_to_polygon('u0u64')
print(polygon.bounds)  # (5.625, 49.21875, 7.03125, 50.625)

# Get geohash resolution
lon_res, lat_res = polygeohasher.lonlat_res_for_length(5)
print(f"Level 5: {lon_res:.4f}° longitude, {lat_res:.4f}° latitude")

4. Geohash Conversion Utilities

# Convert multiple geohashes to boxes
boxes = polygeohasher.geohashes_to_boxes(['u0u', 'u0v', 'u0w'])
# Returns: {'u0u': <Polygon>, 'u0v': <Polygon>, ...}

# Convert geohashes to a single multipolygon
multipolygon = polygeohasher.geohashes_to_multipolygon(
    ['u0u', 'u0v', 'u0w'],
    dissolve=True  # Union all geohashes into one geometry
)

# Convert to GeoDataFrame
gdf = polygeohasher.geohashes_to_gdf(['u0u', 'u0v', 'u0w'])

# Get children of a geohash
children = polygeohasher.get_geohash_children('u0u')
# Returns: ['u0u0', 'u0u1', 'u0u2', ...] (32 children)

5. Visualization

The package includes powerful visualization tools to understand your geohash coverage:

from sigmap.polygeohasher import plot_geohash_coverage

# Plot coverage results with customizable styling
fig, ax = plot_geohash_coverage(
    country_geom=country_geom,
    geohash_dict=geohash_dict,
    tiles_gdf=tiles_gdf,
    style='adaptive',        # 'adaptive', 'simple', or 'heatmap'
    save_path='coverage.png',
    show_stats=True,
    color_by_level=True,
    title='Geohash Coverage Visualization'
)

Additional Visualizations:

The plotting function can also generate statistics visualizations:

Level Statistics Bar Chart Bar chart showing tile distribution across geohash levels

Geohash Boxes Comparison Visualisation on how tiles can be represent and manipulated as (Multi)Polygons, and how the merging affects the geometry.

For more visualization examples, check the exemples/plot_geohash_coverage.py and exemples/geohash_conversion.py scripts.

🔧 API Reference

Core Coverage Functions

  • adaptive_geohash_coverage(geometry, min_level, max_level, ...) - Generate adaptive multi-level geohash coverage
  • geohash_coverage(geometry, level, ...) - Generate single-level geohash coverage

Geohash Utilities

  • encode_geohash(lon, lat, L) - Encode coordinates to geohash string
  • geohash_to_polygon(geohash) - Convert geohash to polygon geometry
  • geohashes_to_boxes(geohashes) - Convert geohashes to dictionary of box polygons
  • geohashes_to_multipolygon(geohashes, dissolve=True) - Union geohashes into a multipolygon
  • geohashes_to_gdf(geohashes, crs='EPSG:4326') - Convert geohashes to GeoDataFrame
  • get_geohash_children(parent_geohash) - Get all children of a geohash
  • lonlat_res_for_length(L) - Get spatial resolution for a geohash length
  • candidate_geohashes_covering_bbox(lon_min, lat_min, lon_max, lat_max, L) - Find candidate geohashes for a bounding box

Data Download

  • download_gadm_country(iso3, cache_dir=None) - Download country geometry from GADM
  • clear_gadm_temp_files(dirs=None, patterns=None, dry_run=False) - Clean up temporary GADM files

Visualization

  • plot_geohash_coverage(country_geom, geohash_dict, tiles_gdf=None, ...) - Plot geohash coverage with various styles
  • quick_plot(country_geom, geohash_dict, tiles_gdf=None) - Quick visualization helper

Polygon Utilities

  • build_single_multipolygon(gdf) - Build a single MultiPolygon from a GeoDataFrame

📖 Examples

See the exemples/ directory for complete usage examples:

  • geohash_coverage_simple.py - Basic coverage generation workflow
  • geohash_conversion.py - Comprehensive geohash conversion examples
  • plot_geohash_coverage.py - Visualization examples

Example: Covering a Custom Polygon

import sigmap.polygeohasher as polygeohasher
from shapely.geometry import Polygon

# Create a custom L-shaped polygon
polygon = Polygon([
    (0, 0), (2, 0), (2, 2), (1, 2),
    (1, 3), (0, 3), (0, 0)
])

# Generate adaptive coverage
geohash_dict, tiles_gdf = polygeohasher.adaptive_geohash_coverage(
    polygon,
    min_level=3,
    max_level=6
)

# Visualize
polygeohasher.plot_geohash_coverage(
    polygon,
    geohash_dict,
    tiles_gdf,
    save_path='custom_coverage.png'
)

📋 Requirements

  • Python >= 3.12
  • geopandas >= 1.1.1
  • shapely >= 2.1.2
  • numpy >= 2.3.3
  • pandas >= 2.3.3
  • requests >= 2.32.5
  • matplotlib

📦 Project Structure

Geohash/
├── docs/
├── exemples/
│   ├── generated_plot/
│   ├── geohash_conversion.py
│   ├── geohash_coverage_simple.py
│   └── plot_geohash_coverage.py
│
├── sigmap-pytools/
│   ├── src/sigmap/polygeohasher/
│   │   ├── adaptative_geohash_coverage.py
│   │   ├── plot_geohash_coverage.py
│   │   ├── logger.py
│   │   └── utils/
│   ├── tests/
│   └── pyproject.toml
├── LICENSE
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
└── README.md

📝 License

This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.

👤 Author

William Hubaux

🤝 Support

Questions about using sigmap-pytools may be asked by opening a discussion.

Bugs may be reported at the GitHub issues page.

Contributions are welcome! Please see our Contributing Guide and Code of Conduct.

Metadata

Release files for sigmap-pytools 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sigmap-pytools 0.0.1
File Size Uploaded
sigmap_pytools-0.0.1.tar.gz 32.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sigmap-pytools 0.0.1
File Interpreter ABI Platform
sigmap_pytools-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 54.9 kB

Release files / sigmap_pytools-0.0.1.tar.gz

Download URL sigmap_pytools-0.0.1.tar.gz
Size 32.6 kB
Tags Source
SHA-256 checksum
How to use checksums
926f00bca97d56abfd6584c6c39c17e8dc26fcf94dee81cc72ee7d29f7e18d1d
BLAKE2b-256 checksum
How to use checksums
c508a9a85f732cea6204fe35524e442f2a3469441c8656345683ef629be13769
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release files / sigmap_pytools-0.0.1-py3-none-any.whl

Download URL sigmap_pytools-0.0.1-py3-none-any.whl
Size 22.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7620c3d85f1f35c1c5c26d38c5df3db59ee90e2a3b3c1e1f750bd97f1d7e057c
BLAKE2b-256 checksum
How to use checksums
47ab9768689e6f086865854e9314c428881ae933f441aa24c1de1a092971db87
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.12

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page