M3S - Multi Spatial Subdivision System
A unified package for working with hierarchical spatial grid systems in Python and JavaScript (via WASM). Both bindings call one shared Rust core, so a cell encoded in one language decodes identically in the other. M3S (Multi Spatial Subdivision System) provides a consistent interface for working with different spatial indexing systems including Geohash, MGRS, H3, Quadkey, S2, Slippy Map tiles, C-squares, GARS, Maidenhead, Plus Codes, EA-Quad, rHEALPix, and A5.
Features
Direct grid access
- 🎯 No instantiation needed: just
m3s.H3,m3s.Geohash, etc. - 🌐 Universal Geometry: Single
from_geometry()handles points, polygons, bboxes, GeoDataFrames - 🔍 Smart Precision: Auto-select optimal precision or choose by use case, area, or cell count
- 🔄 Easy Conversion: Convert between grids with
.to_h3(),.to_geohash(), etc. - 📦 Powerful Collections: Filter, map, export with
GridCellCollection
Core Capabilities
- 13 Grid Systems: Geohash, MGRS, H3, Quadkey, S2, Slippy, C-squares, GARS, Maidenhead, Plus Codes, EA-Quad, rHEALPix, A5
- Area Calculations: All grids support
area_km2property - GeoPandas Integration: Native GeoDataFrame support with automatic CRS transformation
- UTM Zone Integration: Automatic UTM zone detection and inclusion
- Polygon Intersection: Find grid cells intersecting any Shapely polygon or GeoDataFrame
- Hierarchical Operations: Parent/child relationships and multi-resolution analysis
- Neighbor Finding: Get neighboring cells across all grid systems
- Parallel Processing: Threaded parallelism and streaming for large datasets
- Modern Python: Type hints, comprehensive documentation and test suite
Installation
Python — from PyPI:
uv pip install m3s # or: pip install m3s
JavaScript — from npm:
npm install @nkarasiak/m3s
The npm package bundles both a Node (CommonJS WASM) and a browser (ESM WASM)
build; the right one is selected automatically through the exports map. See
bindings/js/README.md for the JS API and how to build
from source.
For development:
git clone https://github.com/nkarasiak/m3s.git
cd m3s
uv sync # create the dev environment (.venv) from uv.lock
Quick Start
M3S gives direct access to grid systems, auto-precision selection, and universal geometry handling:
import m3s
from shapely.geometry import Polygon
# Direct access to grid systems (no instantiation needed!)
# Coordinate tuples use GIS-native (lon, lat) / (x, y) order, like shapely.
cell = m3s.Geohash.from_geometry((-74.0060, 40.7128)) # Point tuple (lon, lat)
print(f"Cell: {cell.id}, Area: {cell.area_km2:.2f} km²")
# Output: Cell: dr5re, Area: 18.11 km²
# Works with any geometry type: points, polygons, GeoDataFrames, bbox tuples
polygon = Polygon([(-74.1, 40.7), (-73.9, 40.7), (-73.9, 40.8), (-74.1, 40.8)])
cells = m3s.H3.from_geometry(polygon) # Uses default precision (7)
print(f"Found {len(cells)} H3 cells with total area {cells.total_area_km2:.2f} km²")
# Output: Found 47 H3 cells with total area 244.01 km²
# For optimal precision with large areas, find it explicitly first:
precision = m3s.H3.find_precision(polygon, method='auto') # Minimizes coverage variance
cells = m3s.H3.from_geometry(polygon, precision=precision)
# Get neighbors
neighbors = m3s.Geohash.neighbors(cell, depth=1)
print(f"Cell has {len(neighbors)} neighbors (including itself)")
# Output: Cell has 9 neighbors (including itself)
# Or find optimal precision
precision = m3s.H3.find_precision(polygon, method='auto') # Minimizes coverage variance
cells = m3s.H3.from_geometry(polygon, precision=precision)
# Easy conversions between grid systems
h3_cells = cells.to_geohash() # Convert H3 → Geohash
gdf = h3_cells.to_gdf() # Convert to GeoDataFrame
# Collection operations
large_cells = cells.filter(lambda c: c.area_km2 > 10.0)
ids = cells.to_ids()
polygons = cells.to_polygons()
# Find precision by use case
precision = m3s.Geohash.find_precision_for_use_case('neighborhood') # ~1-10 km²
# Other use cases: 'global', 'continental', 'country', 'region',
# 'city', 'neighborhood', 'street', 'building', 'room'
# Dynamic, config-driven grid access by name
grid = m3s.grid('h3', precision=7) # -> same wrapper as m3s.H3
print(m3s.grids()) # ['csquares', 'eaquad', 'gars', 'h3', ...]
# Visualize straight from a collection (delegates to GeoPandas/folium)
cells.explore() # interactive Leaflet map
cells.plot(edgecolor='black') # static matplotlib axes
# Persist and reload (round-trips through ids or a vector file)
cells.save('cells.geojson')
same = m3s.H3.from_ids(cells.to_ids()) # ids -> wrapper-aware collection
Available grid systems:
m3s.Geohash- Base32-encoded spatial indexm3s.MGRS- Military Grid Reference Systemm3s.H3- Uber's hexagonal gridm3s.S2- Google's spherical geometrym3s.Quadkey- Microsoft Bing Maps tilesm3s.Slippy- OpenStreetMap tilesm3s.CSquares- Marine data indexingm3s.GARS- Global Area Reference Systemm3s.Maidenhead- Amateur radio locatorm3s.PlusCode- Open Location Codesm3s.EAQuad- Equal-area quadtree (power-of-two km cells)m3s.RHEALPix- rHEALPix equal-area DGGS (aperture 9)m3s.A5- Pentagonal equal-area DGGS
Coordinate order: M3S uses GIS-native (lon, lat) / (x, y) order for coordinate tuples — matching shapely, geopandas and pyproj.
GridCell.bounds,GridCell.centroidandfrom_bboxall follow the same order, sogrid.from_bbox(collection.bounds)round-trips correctly.
JavaScript
The JS API mirrors the Python facade in camelCase and produces identical cells. The wrapper is thin — polygon fill, precision strategies, GeoPandas export and cross-grid conversion stay Python-only.
import * as m3s from "@nkarasiak/m3s";
await m3s.ready(); // awaits WASM init (no-op on Node)
// Direct grid access — (lon, lat, precision)
const cell = m3s.Geohash.fromPoint(-74.0060, 40.7128, 6);
console.log(`Cell: ${cell.id}, Area: ${cell.areaKm2.toFixed(2)} km²`);
// Cells across a bounding box [minLon, minLat, maxLon, maxLat]
const cells = m3s.H3.fromBbox([-74.1, 40.7, -73.9, 40.8], 8);
console.log(`${cells.length} cells`, cells.toIds());
Grid Systems
Geohash
Hierarchical spatial data structure using Base32 encoding. Each character represents 5 bits of spatial precision.
- Precision Levels: 1-12
- Cell Shape: Rectangular
- Use Cases: Databases, simple spatial indexing
MGRS (Military Grid Reference System)
Coordinate system based on UTM with standardized square cells.
- Precision Levels: 0-5 (100km to 1m)
- Cell Shape: Square
- Use Cases: Military, surveying, precise location reference
H3 (Uber's Hexagonal Hierarchical Spatial Index)
Hexagonal grid system with uniform neighbor relationships and excellent area representation.
- Resolution Levels: 0-15
- Cell Shape: Hexagonal
- Use Cases: Spatial analysis, ride-sharing, logistics
Quadkey (Microsoft Bing Maps)
Quadtree-based square tiles used by Microsoft Bing Maps.
- Levels: 1-23
- Cell Shape: Square
- Use Cases: Web mapping, tile-based applications
S2 (Google's Spherical Geometry)
Spherical geometry cells using Hilbert curve for optimal spatial locality.
- Levels: 0-30
- Cell Shape: Curved (spherical quadrilaterals)
- Use Cases: Large-scale applications, global spatial indexing
Slippy Map Tiles
Standard web map tiles used by OpenStreetMap and most web mapping services.
- Zoom Levels: 0-22
- Cell Shape: Square (in Web Mercator projection)
- Use Cases: Web mapping, tile servers, caching
API Reference
Parallel Processing
from m3s.parallel import ParallelGridEngine, ParallelConfig
# Configure parallel processing
config = ParallelConfig(
n_workers=4,
chunk_size=10000
)
# Process large datasets in parallel
engine = ParallelGridEngine(config)
result = engine.intersect_parallel(grid, large_gdf)
Development
Setup
git clone https://github.com/nkarasiak/m3s.git
cd m3s
uv sync # create the dev environment (.venv) from uv.lock
Running Tests
uv run pytest
Code Formatting
uv run black m3s tests examples
Type Checking
uv run mypy m3s
Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Dependencies
Required
- Shapely - Geometric operations
- PyProj - Coordinate transformations
- GeoPandas - Geospatial data manipulation
- mgrs - MGRS coordinate conversions
- h3 - H3 hexagonal grid operations
- s2sphere - S2 spherical geometry operations
Notes:
- Geohash, Quadkey, and Slippy Map Tiles are implemented using pure Python (no external dependencies)
- S2 functionality requires the s2sphere library for proper spherical geometry calculations
Acknowledgments
- Built for geospatial analysis and location intelligence applications
- Thanks to the maintainers of the underlying spatial libraries
Metadata
Release files for m3s 0.6.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| m3s-0.6.4.tar.gz | 146.0 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| m3s-0.6.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 256.9 kB
Release files / m3s-0.6.4.tar.gz
| Download URL | m3s-0.6.4.tar.gz |
|---|---|
| Size | 146.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8acbba09569f432586d34f914a35ae1efe5cb1afa51e31cb95ad338c7bdd6694
|
|
BLAKE2b-256 checksum How to use checksums |
da56c27f8de5dbd27f80643c825e40dddd42bca3d770b0a246a889b0dc114099
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logRelease files / m3s-0.6.4-py3-none-any.whl
| Download URL | m3s-0.6.4-py3-none-any.whl |
|---|---|
| Size | 110.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a8692fc3cb8b260f4de9656f585ba00498e84180a73fb416ac55179d2086d0e
|
|
BLAKE2b-256 checksum How to use checksums |
62d8b95badeaef1f4b3c984f5cdb774cc847dad7eb9d8dd5e771eb8ca542aa19
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logSecurity for m3s 0.6.4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for m3s-0.6.4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 9, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.