CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-h3

Python bindings for H3, a hierarchical hexagonal geospatial indexing system

84

0.95x
Overview
Eval results
Files

measurements.mddocs/

Measurements

Functions for calculating areas, lengths, and distances within the H3 system. These functions provide precise measurements for cells, edges, and distances using spherical geometry calculations, supporting multiple units of measurement.

Capabilities

Cell Area Measurements

Calculate the surface area of H3 cells and average areas at different resolutions.

def cell_area(h: str, unit: str = 'km^2') -> float:
    """
    Calculate the surface area of a specific H3 cell.
    
    Uses spherical geometry to compute the exact area of the cell
    on the Earth's surface.
    
    Args:
        h: H3 cell identifier
        unit: Unit for area result:
            - 'km^2': Square kilometers (default)
            - 'm^2': Square meters
            - 'rads^2': Square radians
            
    Returns:
        Cell area in specified units
        
    Raises:
        H3CellInvalidError: If h is not a valid H3 cell
        ValueError: If unit is not supported
        
    Note:
        Pentagons have slightly different areas than hexagons at the same resolution.
        Calculation uses spherical triangulation for accuracy.
    """

def average_hexagon_area(res: int, unit: str = 'km^2') -> float:
    """
    Get the average area of hexagon cells at a given resolution.
    
    This average excludes pentagons and represents typical cell area.
    
    Args:
        res: H3 resolution (0-15)
        unit: Unit for area result:
            - 'km^2': Square kilometers (default)
            - 'm^2': Square meters  
            - 'rads^2': Square radians
            
    Returns:
        Average hexagon area in specified units
        
    Raises:
        H3ResDomainError: If res < 0 or res > 15
        ValueError: If unit is not supported
        
    Note:
        Pentagon areas may differ from this average.
        Higher resolutions have smaller cell areas (~1/7 per resolution level).
    """

Edge Length Measurements

Calculate the length of H3 edges and average edge lengths at different resolutions.

def edge_length(e: str, unit: str = 'km') -> float:
    """
    Calculate the length of a specific H3 directed edge.
    
    Uses spherical geometry to compute the exact length of the edge
    on the Earth's surface.
    
    Args:
        e: H3 directed edge identifier
        unit: Unit for length result:
            - 'km': Kilometers (default)
            - 'm': Meters
            - 'rads': Radians
            
    Returns:
        Edge length in specified units
        
    Raises:
        H3DirEdgeInvalidError: If e is not a valid H3 directed edge
        ValueError: If unit is not supported
        
    Note:
        Edge lengths may vary slightly within a resolution due to
        spherical projection effects and pentagon locations.
    """

def average_hexagon_edge_length(res: int, unit: str = 'km') -> float:
    """
    Get the average edge length of hexagon cells at a given resolution.
    
    This average excludes pentagon edges and represents typical edge length.
    
    Args:
        res: H3 resolution (0-15)
        unit: Unit for length result:
            - 'km': Kilometers (default)
            - 'm': Meters
            - 'rads': Radians
            
    Returns:
        Average hexagon edge length in specified units
        
    Raises:
        H3ResDomainError: If res < 0 or res > 15
        ValueError: If unit is not supported
        
    Note:
        Pentagon edge lengths may differ from this average.
        Higher resolutions have shorter edges (~1/√7 ≈ 0.378 per resolution level).
    """

Distance Calculations

Calculate spherical distances between geographic points.

def great_circle_distance(
    latlng1: tuple[float, float], 
    latlng2: tuple[float, float], 
    unit: str = 'km'
) -> float:
    """
    Calculate the great circle (spherical) distance between two points.
    
    Uses the haversine formula to compute the shortest distance between
    two points on the Earth's surface.
    
    Args:
        latlng1: First point as (latitude, longitude) in degrees
        latlng2: Second point as (latitude, longitude) in degrees  
        unit: Unit for distance result:
            - 'km': Kilometers (default)
            - 'm': Meters
            - 'rads': Radians
            
    Returns:
        Spherical distance between points in specified units
        
    Raises:
        H3LatLngDomainError: If any coordinate is outside valid range
        ValueError: If unit is not supported
        
    Note:
        This is the same distance calculation used internally by H3
        for all spherical geometry operations.
    """

Usage Examples

Cell Area Analysis

import h3

# Compare cell areas across resolutions
print("Cell area comparison across resolutions:")
lat, lng = 37.7749, -122.4194  # San Francisco

for res in range(0, 11, 2):  # Every other resolution
    cell = h3.latlng_to_cell(lat, lng, res)
    
    # Get actual cell area
    area_km2 = h3.cell_area(cell, 'km^2')
    area_m2 = h3.cell_area(cell, 'm^2')
    
    # Compare to system average
    avg_area = h3.average_hexagon_area(res, 'km^2')
    
    cell_type = "pentagon" if h3.is_pentagon(cell) else "hexagon"
    
    print(f"Resolution {res:2d} ({cell_type:7}): {area_km2:10.3f} km² ({area_m2:12,.0f} m²)")
    print(f"              Average: {avg_area:10.3f} km² (ratio: {area_km2/avg_area:.3f})")
    print()

# Show area scaling between resolutions
print("Area scaling factors:")
for res in range(1, 6):
    area_coarse = h3.average_hexagon_area(res-1, 'km^2')
    area_fine = h3.average_hexagon_area(res, 'km^2')
    scaling = area_coarse / area_fine
    
    print(f"Resolution {res-1} -> {res}: {scaling:.2f}x smaller")

Pentagon vs Hexagon Area Comparison

import h3

# Compare pentagon and hexagon areas at the same resolution
resolution = 6

# Get pentagons and a regular hexagon
pentagons = h3.get_pentagons(resolution)
all_cells = h3.get_res0_cells()
hexagon_res0 = [cell for cell in all_cells if not h3.is_pentagon(cell)][0]
hexagon = h3.cell_to_children(hexagon_res0, resolution)[0]

print(f"Area comparison at resolution {resolution}:")

# Calculate pentagon areas
pentagon_areas = []
for i, pentagon in enumerate(pentagons[:5]):  # Just first 5 pentagons
    area = h3.cell_area(pentagon, 'km^2')
    pentagon_areas.append(area)
    print(f"Pentagon {i+1}: {area:.3f} km²")

# Calculate hexagon area
hexagon_area = h3.cell_area(hexagon, 'km^2')
print(f"Hexagon:     {hexagon_area:.3f} km²")

# Statistics
avg_pentagon_area = sum(pentagon_areas) / len(pentagon_areas)
system_avg = h3.average_hexagon_area(resolution, 'km^2')

print(f"\nAverage pentagon area: {avg_pentagon_area:.3f} km²")
print(f"System average (hexagon): {system_avg:.3f} km²")
print(f"Pentagon vs hexagon ratio: {avg_pentagon_area / hexagon_area:.3f}")
print(f"Pentagon vs system avg: {avg_pentagon_area / system_avg:.3f}")

Edge Length Analysis

import h3

# Analyze edge lengths for different cell types
resolution = 8

# Get a regular hexagon
center = h3.latlng_to_cell(0, 0, resolution)  # Equator
pentagon = h3.get_pentagons(resolution)[0]

print(f"Edge length analysis at resolution {resolution}:")

# Analyze hexagon edges
hex_edges = h3.origin_to_directed_edges(center)
hex_edge_lengths = []

print(f"\nHexagon edges ({len(hex_edges)}):")
for i, edge in enumerate(hex_edges):
    length_km = h3.edge_length(edge, 'km')
    length_m = h3.edge_length(edge, 'm')
    hex_edge_lengths.append(length_km)
    print(f"  Edge {i}: {length_km:.3f} km ({length_m:.0f} m)")

# Analyze pentagon edges  
pent_edges = h3.origin_to_directed_edges(pentagon)
pent_edge_lengths = []

print(f"\nPentagon edges ({len(pent_edges)}):")
for i, edge in enumerate(pent_edges):
    length_km = h3.edge_length(edge, 'km')
    length_m = h3.edge_length(edge, 'm')
    pent_edge_lengths.append(length_km)
    print(f"  Edge {i}: {length_km:.3f} km ({length_m:.0f} m)")

# Compare to system averages
system_avg = h3.average_hexagon_edge_length(resolution, 'km')
hex_avg = sum(hex_edge_lengths) / len(hex_edge_lengths)
pent_avg = sum(pent_edge_lengths) / len(pent_edge_lengths)

print(f"\nComparison:")
print(f"System average: {system_avg:.3f} km")
print(f"Hexagon average: {hex_avg:.3f} km (variation: {abs(hex_avg - system_avg) / system_avg:.1%})")
print(f"Pentagon average: {pent_avg:.3f} km (vs system: {pent_avg / system_avg:.3f})")

Distance Calculations

import h3

# Calculate distances between famous landmarks
landmarks = {
    "San Francisco": (37.7749, -122.4194),
    "New York": (40.7589, -73.9851),
    "London": (51.5074, -0.1278),
    "Tokyo": (35.6762, 139.6503),
    "Sydney": (-33.8688, 151.2093)
}

print("Great circle distances between major cities:")

cities = list(landmarks.keys())
for i in range(len(cities)):
    for j in range(i+1, len(cities)):
        city1, city2 = cities[i], cities[j]
        coord1, coord2 = landmarks[city1], landmarks[city2]
        
        # Calculate distance in different units
        dist_km = h3.great_circle_distance(coord1, coord2, 'km')
        dist_m = h3.great_circle_distance(coord1, coord2, 'm')
        dist_rads = h3.great_circle_distance(coord1, coord2, 'rads')
        
        print(f"{city1:12} - {city2:12}: {dist_km:7.0f} km ({dist_m:10,.0f} m, {dist_rads:.4f} rads)")

# Verify against H3 cell center distances
print(f"\nVerification using H3 cell centers:")
resolution = 4  # Coarse resolution for global coverage

sf_cell = h3.latlng_to_cell(*landmarks["San Francisco"], resolution)
ny_cell = h3.latlng_to_cell(*landmarks["New York"], resolution)

sf_center = h3.cell_to_latlng(sf_cell)
ny_center = h3.cell_to_latlng(ny_cell)

direct_dist = h3.great_circle_distance(landmarks["San Francisco"], landmarks["New York"], 'km')
cell_dist = h3.great_circle_distance(sf_center, ny_center, 'km')

print(f"SF-NY direct: {direct_dist:.0f} km")
print(f"SF-NY via H3 cells (res {resolution}): {cell_dist:.0f} km")
print(f"Difference: {abs(direct_dist - cell_dist):.0f} km ({abs(direct_dist - cell_dist) / direct_dist:.1%})")

Resolution Scaling Analysis

import h3

# Analyze how measurements scale across resolutions
print("H3 Resolution Scaling Analysis:")
print("Resolution | Avg Area (km²) | Avg Edge (km) | Area Ratio | Edge Ratio")
print("-" * 70)

prev_area = None
prev_edge = None

for res in range(0, 16):
    avg_area = h3.average_hexagon_area(res, 'km^2')
    avg_edge = h3.average_hexagon_edge_length(res, 'km')
    
    area_ratio = prev_area / avg_area if prev_area else None
    edge_ratio = prev_edge / avg_edge if prev_edge else None
    
    print(f"{res:8d}   | {avg_area:12.6f} | {avg_edge:10.6f} | "
          f"{area_ratio:8.2f} | {edge_ratio:8.2f}" if area_ratio else 
          f"{res:8d}   | {avg_area:12.6f} | {avg_edge:10.6f} |    -     |    -   ")
    
    prev_area = avg_area
    prev_edge = avg_edge

print(f"\nTheoretical scaling factors:")
print(f"Area ratio: ~7.0 (each level has ~1/7 the area)")
print(f"Edge ratio: ~√7 ≈ 2.65 (each level has ~1/√7 the edge length)")

Measurement Precision Comparison

import h3
import math

# Compare H3 measurements with theoretical calculations
print("Measurement precision analysis:")

# Test at different latitudes to see projection effects
test_points = [
    ("Equator", 0, 0),
    ("Tropical", 23.5, 0),  # Tropic of Cancer
    ("Mid-latitude", 45, 0),
    ("High latitude", 60, 0),
    ("Arctic", 80, 0)
]

resolution = 7

print(f"Resolution {resolution} analysis:")
print("Location      | Cell Area (km²) | Avg Area | Ratio  | Edge Length (km) | Avg Edge | Ratio")
print("-" * 95)

for name, lat, lng in test_points:
    # Get cell measurements
    cell = h3.latlng_to_cell(lat, lng, resolution)
    cell_area = h3.cell_area(cell, 'km^2')
    
    # Get an edge from this cell
    edges = h3.origin_to_directed_edges(cell)
    edge_length = h3.edge_length(edges[0], 'km')
    
    # Compare to system averages
    avg_area = h3.average_hexagon_area(resolution, 'km^2')
    avg_edge = h3.average_hexagon_edge_length(resolution, 'km')
    
    area_ratio = cell_area / avg_area
    edge_ratio = edge_length / avg_edge
    
    print(f"{name:12} | {cell_area:13.6f} | {avg_area:8.6f} | {area_ratio:.3f} | "
          f"{edge_length:14.6f} | {avg_edge:8.6f} | {edge_ratio:.3f}")

Area Coverage Calculations

import h3

# Calculate total area coverage for different scenarios
print("Area coverage calculations:")

# Scenario 1: City coverage
city_center = h3.latlng_to_cell(37.7749, -122.4194, 8)  # San Francisco
city_cells = h3.grid_disk(city_center, k=5)

total_area = sum(h3.cell_area(cell, 'km^2') for cell in city_cells)
avg_area = h3.average_hexagon_area(8, 'km^2')
approx_area = len(city_cells) * avg_area

print(f"City coverage (k=5 at resolution 8):")
print(f"  Cells: {len(city_cells)}")
print(f"  Exact total area: {total_area:.2f} km²")
print(f"  Approximate area: {approx_area:.2f} km²")
print(f"  Difference: {abs(total_area - approx_area):.2f} km² ({abs(total_area - approx_area) / total_area:.1%})")

# Scenario 2: Country-scale coverage
country_polygon = h3.LatLngPoly([
    (49.0, -125.0), (49.0, -66.0), (25.0, -66.0), (25.0, -125.0)  # Rough USA bounds
])

country_cells = h3.h3shape_to_cells(country_polygon, 4)  # Coarse resolution
country_area = sum(h3.cell_area(cell, 'km^2') for cell in country_cells)
usa_actual_area = 9834000  # km² (approximate)

print(f"\nCountry coverage (USA approximation at resolution 4):")
print(f"  Cells: {len(country_cells)}")
print(f"  H3 calculated area: {country_area:,.0f} km²")
print(f"  Actual USA area: {usa_actual_area:,.0f} km²")
print(f"  Coverage ratio: {country_area / usa_actual_area:.3f}")

# Show the impact of resolution on coverage accuracy
print(f"\nResolution impact on area calculation:")
for res in [3, 4, 5, 6]:
    cells = h3.h3shape_to_cells(country_polygon, res)
    area = sum(h3.cell_area(cell, 'km^2') for cell in cells)
    ratio = area / usa_actual_area
    print(f"  Resolution {res}: {len(cells):6,} cells, {area:9,.0f} km² (ratio: {ratio:.3f})")

Install with Tessl CLI

npx tessl i tessl/pypi-h3

docs

advanced-operations.md

cell-hierarchy.md

core-cell-operations.md

directed-edges.md

grid-navigation.md

index.md

measurements.md

polygon-operations.md

tile.json