Note
Go to the end to download the full example code.
Quickstart Guide for M3S - GridBuilder API#
This example demonstrates the GridBuilder fluent interface and intelligent precision selection.
Note: M3S v0.5.1+ also provides a simpler API for quick start: See examples/quickstart_new_api.py for the simplified direct access API.
- For most use cases, the simplified API is recommended:
import m3s cell = m3s.Geohash.from_geometry((40.7, -74.0))
This example shows the advanced GridBuilder API for complex workflows.
======================================================================
Example 1: Basic Point Query
======================================================================
Cell ID: 872a1072cffffff
Area: 5.19 km²
Precision: 7
======================================================================
Example 2: Intelligent Precision Selection
======================================================================
Use-case 'neighborhood' recommendation:
Precision: 9
Confidence: 95%
H3 precision 9 optimized for 'neighborhood' use case (avg cell area: 0.10 km²)
Area-based (target 10 km²) recommendation:
Precision: 7
Actual area: 5.16 km²
Confidence: 0%
Distance-based (target 500m edges) recommendation:
Precision: 8
Actual edge length: 532.6 m
Confidence: 78%
======================================================================
Example 3: Complete Fluent Workflow
======================================================================
Found 9 cells (original + neighbors)
Using precision: 5 (confidence: 95%)
First few cells:
gcpvj - 14.91 km²
gcpvm - 14.90 km²
gcpuv - 14.93 km²
gcpvn - 14.91 km²
gcpvh - 14.91 km²
======================================================================
Example 4: Batch Point Queries
======================================================================
Queried 4 cities:
New York: 872a1072cffffff
Los Angeles: 8729a1d75ffffff
London: 87195da49ffffff
Tokyo: 872f5a363ffffff
======================================================================
Example 5: Regional Analysis with Filtering
======================================================================
Found 10 cells in Manhattan (filtered, limited to 10)
Average area: 0.566 km²
======================================================================
Example 6: Export to GeoPandas
======================================================================
GeoDataFrame columns: ['identifier', 'precision', 'area_km2', 'geometry']
Shape: (4, 4)
First row:
identifier ... geometry
0 89c2585 ... POLYGON ((-74.00651 40.77819, -74.00651 40.758...
[1 rows x 4 columns]
======================================================================
Example 7: Multi-Grid Comparison
======================================================================
Same point in different grid systems:
geohash : dr5re (18.11 km²)
h3 : 872a1072cffffff (5.19 km²)
s2 : 89c25b (69.83 km²)
Regional coverage comparison:
system precision cell_count avg_cell_size_km2
0 geohash 5 18 18.097568
1 h3 7 47 5.191624
2 s2 10 8 69.679955
======================================================================
Example 8: Performance-Based Precision Selection
======================================================================
Performance-optimized precision:
Precision: 8
Estimated time: 18.5 ms
Estimated cells: 135
Confidence: 82%
======================================================================
Quickstart Complete!
======================================================================
Key Takeaways:
1. Use GridBuilder for all queries (replaces direct grid class usage)
2. Use PrecisionSelector for intelligent precision selection
3. Method chaining enables elegant, readable workflows
4. Type-safe results with .single, .many, .to_geodataframe()
5. All grid systems use unified 'precision' parameter
from m3s import GridBuilder, PrecisionSelector
# ============================================================================
# Example 1: Basic Point Query with Explicit Precision
# ============================================================================
print("=" * 70)
print("Example 1: Basic Point Query")
print("=" * 70)
# Query a single point using H3 grid at precision 7
result = (
GridBuilder.for_system("h3").with_precision(7).at_point(40.7128, -74.0060).execute()
)
# Access single cell result
cell = result.single
print(f"Cell ID: {cell.identifier}")
print(f"Area: {cell.area_km2:.2f} km²")
print(f"Precision: {cell.precision}")
print()
# ============================================================================
# Example 2: Intelligent Precision Selection
# ============================================================================
print("=" * 70)
print("Example 2: Intelligent Precision Selection")
print("=" * 70)
# Create precision selector for H3 grid
selector = PrecisionSelector("h3")
# Strategy 1: Use-case based (most common)
rec = selector.for_use_case("neighborhood")
print("\nUse-case 'neighborhood' recommendation:")
print(f" Precision: {rec.precision}")
print(f" Confidence: {rec.confidence:.0%}")
print(f" {rec.explanation}")
# Strategy 2: Area-based
rec = selector.for_area(target_area_km2=10.0)
print("\nArea-based (target 10 km²) recommendation:")
print(f" Precision: {rec.precision}")
print(f" Actual area: {rec.actual_area_km2:.2f} km²")
print(f" Confidence: {rec.confidence:.0%}")
# Strategy 3: Distance-based
rec = selector.for_distance(edge_length_m=500.0)
print("\nDistance-based (target 500m edges) recommendation:")
print(f" Precision: {rec.precision}")
print(f" Actual edge length: {rec.edge_length_m:.1f} m")
print(f" Confidence: {rec.confidence:.0%}")
print()
# ============================================================================
# Example 3: Fluent Workflow with Auto-Precision
# ============================================================================
print("=" * 70)
print("Example 3: Complete Fluent Workflow")
print("=" * 70)
# Intelligent precision + point query + neighbors
selector = PrecisionSelector("geohash")
rec = selector.for_use_case("city")
result = (
GridBuilder.for_system("geohash")
.with_auto_precision(rec)
.at_point(51.5074, -0.1278) # London
.find_neighbors(depth=1)
.execute()
)
print(f"\nFound {len(result)} cells (original + neighbors)")
print(f"Using precision: {rec.precision} (confidence: {rec.confidence:.0%})")
print("\nFirst few cells:")
for cell in result.many[:5]:
print(f" {cell.identifier} - {cell.area_km2:.2f} km²")
print()
# ============================================================================
# Example 4: Batch Operations
# ============================================================================
print("=" * 70)
print("Example 4: Batch Point Queries")
print("=" * 70)
# Query multiple cities simultaneously
cities = [
(40.7128, -74.0060), # New York
(34.0522, -118.2437), # Los Angeles
(51.5074, -0.1278), # London
(35.6762, 139.6503), # Tokyo
]
result = GridBuilder.for_system("h3").with_precision(7).at_points(cities).execute()
print(f"\nQueried {len(result)} cities:")
for i, cell in enumerate(result.many):
city_names = ["New York", "Los Angeles", "London", "Tokyo"]
print(f" {city_names[i]}: {cell.identifier}")
print()
# ============================================================================
# Example 5: Regional Analysis with Filtering
# ============================================================================
print("=" * 70)
print("Example 5: Regional Analysis with Filtering")
print("=" * 70)
# Get cells in Manhattan bounding box, filter by size
result = (
GridBuilder.for_system("geohash")
.with_precision(6)
.in_bbox(40.7, -74.05, 40.85, -73.9) # Manhattan area
.filter(lambda cell: cell.area_km2 < 1.0) # Only smaller cells
.limit(10) # Limit for display
.execute()
)
print(f"\nFound {len(result)} cells in Manhattan (filtered, limited to 10)")
print(f"Average area: {sum(c.area_km2 for c in result.many) / len(result):.3f} km²")
print()
# ============================================================================
# Example 6: Convert to GeoDataFrame
# ============================================================================
print("=" * 70)
print("Example 6: Export to GeoPandas")
print("=" * 70)
result = (
GridBuilder.for_system("s2")
.with_precision(12)
.in_bbox(40.75, -74.0, 40.77, -73.97)
.limit(5)
.execute()
)
gdf = result.to_geodataframe()
print("\nGeoDataFrame columns:", list(gdf.columns))
print(f"Shape: {gdf.shape}")
print("\nFirst row:")
print(gdf.head(1))
print()
# ============================================================================
# Example 7: Multi-Grid Comparison
# ============================================================================
print("=" * 70)
print("Example 7: Multi-Grid Comparison")
print("=" * 70)
from m3s import MultiGridComparator
# Compare same location across different grid systems
comparator = MultiGridComparator([("geohash", 5), ("h3", 7), ("s2", 10)])
results = comparator.query_all(40.7128, -74.0060)
print("\nSame point in different grid systems:")
for system, cell in results.items():
print(f" {system:10s}: {cell.identifier:20s} ({cell.area_km2:.2f} km²)")
# Compare coverage for a region
coverage_df = comparator.compare_coverage((40.7, -74.1, 40.8, -73.9))
print("\nRegional coverage comparison:")
print(coverage_df[["system", "precision", "cell_count", "avg_cell_size_km2"]])
print()
# ============================================================================
# Example 8: Performance-Based Precision
# ============================================================================
print("=" * 70)
print("Example 8: Performance-Based Precision Selection")
print("=" * 70)
selector = PrecisionSelector("h3")
# Balance precision vs computational cost
rec = selector.for_performance(
operation_type="intersect",
time_budget_ms=50.0, # 50ms budget
region_size_km2=100.0, # 100 km² region
)
print("\nPerformance-optimized precision:")
print(f" Precision: {rec.precision}")
print(f" Estimated time: {rec.metadata['estimated_time_ms']:.1f} ms")
print(f" Estimated cells: {rec.metadata['estimated_cells']}")
print(f" Confidence: {rec.confidence:.0%}")
print()
print("=" * 70)
print("Quickstart Complete!")
print("=" * 70)
print("\nKey Takeaways:")
print(" 1. Use GridBuilder for all queries (replaces direct grid class usage)")
print(" 2. Use PrecisionSelector for intelligent precision selection")
print(" 3. Method chaining enables elegant, readable workflows")
print(" 4. Type-safe results with .single, .many, .to_geodataframe()")
print(" 5. All grid systems use unified 'precision' parameter")
Total running time of the script: (0 minutes 47.602 seconds)