CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-googlemaps

Python client library for Google Maps Platform providing access to mapping services, geocoding, routing, and location APIs

Pending
Overview
Eval results
Files

roads.mddocs/

Roads API

Snap GPS coordinates to road networks, find nearest roads, and retrieve speed limit information for navigation and tracking applications with support for path interpolation and road segment analysis.

Capabilities

Road Snapping

Snap GPS coordinates to the road network for accurate positioning and route tracking.

def snap_to_roads(client, path, interpolate=False):
    """
    Snap GPS coordinates to the road network.
    
    Args:
        client (Client): Google Maps API client instance
        path (list): List of GPS coordinates as (lat, lng) tuples to snap to roads.
                    Maximum 100 points.
        interpolate (bool): Whether to interpolate additional points along snapped path
                           to create smoother route representation
    
    Returns:
        dict: Response containing:
              - snappedPoints: List of snapped coordinates with placeId references
              - warningMessage: Optional warnings about the snapping process
    
    Raises:
        googlemaps.exceptions.ApiError: When API returns an error
        googlemaps.exceptions.TransportError: When HTTP request fails
        googlemaps.exceptions.Timeout: When request times out
    """

Nearest Roads

Find the nearest roads to given GPS coordinates for road identification and mapping.

def nearest_roads(client, points):
    """
    Find nearest roads to given GPS coordinates.
    
    Args:
        client (Client): Google Maps API client instance
        points (list): List of GPS coordinates as (lat, lng) tuples.
                      Maximum 100 points.
    
    Returns:
        dict: Response containing:
              - snappedPoints: List of nearest road points with placeId references
              - No path interpolation is performed
    
    Raises:
        googlemaps.exceptions.ApiError: When API returns an error
        googlemaps.exceptions.TransportError: When HTTP request fails
        googlemaps.exceptions.Timeout: When request times out
    """

Speed Limits

Retrieve speed limit information for road segments identified by place IDs.

def speed_limits(client, place_ids):
    """
    Get speed limits for road segments by place IDs.
    
    Args:
        client (Client): Google Maps API client instance
        place_ids (list): List of place IDs for road segments.
                         Maximum 100 place IDs.
    
    Returns:
        dict: Response containing:
              - speedLimits: List of speed limit information for each place ID
              - Each entry contains speedLimit, units, and placeId
    
    Raises:
        googlemaps.exceptions.ApiError: When API returns an error
        googlemaps.exceptions.TransportError: When HTTP request fails
        googlemaps.exceptions.Timeout: When request times out
    """

def snapped_speed_limits(client, path):
    """
    Get speed limits along a snapped path.
    
    Args:
        client (Client): Google Maps API client instance
        path (list): List of GPS coordinates as (lat, lng) tuples representing
                    a path. Maximum 100 points.
    
    Returns:
        dict: Response containing:
              - snappedPoints: GPS coordinates snapped to roads with place IDs
              - speedLimits: Speed limit information for each road segment
    
    Raises:
        googlemaps.exceptions.ApiError: When API returns an error
        googlemaps.exceptions.TransportError: When HTTP request fails
        googlemaps.exceptions.Timeout: When request times out
    """

Usage Examples

Basic Road Snapping

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

# GPS coordinates that may be slightly off the road
gps_points = [
    (40.714728, -73.998672),  # Near NYC street
    (40.714758, -73.998734),  # Slightly off road
    (40.714812, -73.998842),  # Another GPS point
    (40.714867, -73.998951)   # End point
]

# Snap to roads
snapped_result = gmaps.snap_to_roads(path=gps_points)

print("Snapped coordinates:")
for i, point in enumerate(snapped_result['snappedPoints']):
    lat = point['location']['latitude']
    lng = point['location']['longitude']
    place_id = point.get('placeId', 'N/A')
    
    print(f"Point {i+1}: ({lat:.6f}, {lng:.6f}) - Place ID: {place_id}")

# Check for warnings
if 'warningMessage' in snapped_result:
    print(f"Warning: {snapped_result['warningMessage']}")

Road Snapping with Interpolation

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

# Sparse GPS points along a route
sparse_path = [
    (37.7749, -122.4194),   # San Francisco start
    (37.7849, -122.4094),   # Middle point
    (37.7949, -122.3994)    # End point
]

# Snap with interpolation for smoother path
interpolated_result = gmaps.snap_to_roads(
    path=sparse_path,
    interpolate=True
)

print(f"Original points: {len(sparse_path)}")
print(f"Snapped points: {len(interpolated_result['snappedPoints'])}")

# The result will have additional interpolated points
print("\nInterpolated snapped path:")
for i, point in enumerate(interpolated_result['snappedPoints']):
    lat = point['location']['latitude']
    lng = point['location']['longitude']
    original_index = point.get('originalIndex')
    
    status = "Original" if original_index is not None else "Interpolated"
    print(f"Point {i+1}: ({lat:.6f}, {lng:.6f}) - {status}")

Finding Nearest Roads

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

# Points that might be off-road (parking lots, buildings, etc.)
off_road_points = [
    (40.758896, -73.985130),  # Times Square area
    (40.748817, -73.985428),  # Empire State Building area
    (40.741895, -73.989308)   # Union Square area
]

# Find nearest roads
nearest_result = gmaps.nearest_roads(points=off_road_points)

print("Nearest roads:")
for i, point in enumerate(nearest_result['snappedPoints']):
    lat = point['location']['latitude']
    lng = point['location']['longitude']
    place_id = point.get('placeId', 'N/A')
    original_index = point.get('originalIndex', i)
    
    print(f"Original point {original_index + 1} -> Nearest road: ({lat:.6f}, {lng:.6f})")
    print(f"  Place ID: {place_id}")

Speed Limit Lookup by Place ID

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

# First, snap some points to get place IDs
path_points = [
    (40.714728, -73.998672),
    (40.714728, -73.998172),
    (40.714728, -73.997672)
]

snapped = gmaps.snap_to_roads(path=path_points)

# Extract place IDs from snapped points
place_ids = []
for point in snapped['snappedPoints']:
    if 'placeId' in point:
        place_ids.append(point['placeId'])

if place_ids:
    # Get speed limits for these road segments
    speed_limits_result = gmaps.speed_limits(place_ids=place_ids)
    
    print("Speed limits for road segments:")
    for limit_info in speed_limits_result['speedLimits']:
        place_id = limit_info['placeId']
        speed_limit = limit_info['speedLimit']
        units = limit_info['units']
        
        print(f"Place ID: {place_id}")
        print(f"Speed Limit: {speed_limit} {units}")
        print("---")
else:
    print("No place IDs found in snapped results")

Speed Limits Along a Path

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

# Define a driving route
driving_path = [
    (40.758896, -73.985130),  # Times Square
    (40.748817, -73.985428),  # Empire State Building
    (40.741895, -73.989308),  # Union Square
    (40.728224, -73.994521),  # Washington Square Park
    (40.718217, -74.000165)   # World Trade Center
]

# Get speed limits along the entire path
speed_limits_result = gmaps.snapped_speed_limits(path=driving_path)

print("Speed limits along route:")
print("=" * 40)

# Process snapped points and speed limits
snapped_points = speed_limits_result['snappedPoints']
speed_limits = speed_limits_result['speedLimits']

# Create a mapping of place IDs to speed limits
speed_limit_map = {limit['placeId']: limit for limit in speed_limits}

for i, point in enumerate(snapped_points):
    lat = point['location']['latitude']
    lng = point['location']['longitude']
    place_id = point.get('placeId')
    
    print(f"Point {i+1}: ({lat:.6f}, {lng:.6f})")
    
    if place_id and place_id in speed_limit_map:
        limit_info = speed_limit_map[place_id]
        speed_limit = limit_info['speedLimit']
        units = limit_info['units']
        print(f"  Speed Limit: {speed_limit} {units}")
    else:
        print("  Speed Limit: Not available")
    print()

Route Analysis with Roads API

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

def analyze_route_roads(origin, destination):
    """Analyze roads along a route including speed limits."""
    
    # Get route directions first
    directions = gmaps.directions(origin, destination)
    
    if not directions:
        print("No route found")
        return
    
    route = directions[0]
    
    # Decode the polyline to get path points
    from googlemaps.convert import decode_polyline
    polyline = route['overview_polyline']['points']
    path_points = decode_polyline(polyline)
    
    # Sample every 10th point to stay within API limits
    sampled_points = path_points[::max(1, len(path_points) // 50)][:100]
    
    print(f"Route: {route['legs'][0]['start_address']} to {route['legs'][0]['end_address']}")
    print(f"Distance: {route['legs'][0]['distance']['text']}")
    print(f"Duration: {route['legs'][0]['duration']['text']}")
    print(f"Analyzing {len(sampled_points)} points along route...")
    print("=" * 60)
    
    # Get speed limits along the route
    try:
        speed_result = gmaps.snapped_speed_limits(path=sampled_points)
        
        # Analyze speed limits
        speed_limits = speed_result.get('speedLimits', [])
        if speed_limits:
            speeds = [limit['speedLimit'] for limit in speed_limits if 'speedLimit' in limit]
            if speeds:
                avg_speed_limit = sum(speeds) / len(speeds)
                max_speed_limit = max(speeds)
                min_speed_limit = min(speeds)
                
                print(f"Speed Limit Analysis:")
                print(f"  Average: {avg_speed_limit:.1f} mph")
                print(f"  Maximum: {max_speed_limit} mph")
                print(f"  Minimum: {min_speed_limit} mph")
                print(f"  Segments analyzed: {len(speeds)}")
            else:
                print("No speed limit data available")
        else:
            print("No speed limits found along route")
            
    except Exception as e:
        print(f"Error getting speed limits: {e}")

# Example usage
analyze_route_roads("JFK Airport, NY", "LaGuardia Airport, NY")

GPS Track Cleaning

import googlemaps

gmaps = googlemaps.Client(key='YOUR_API_KEY')

def clean_gps_track(raw_gps_points, interpolate=True):
    """Clean and improve GPS tracking data using road snapping."""
    
    # Split into chunks if too many points (API limit is 100)
    chunk_size = 100
    cleaned_track = []
    
    for i in range(0, len(raw_gps_points), chunk_size):
        chunk = raw_gps_points[i:i + chunk_size]
        
        try:
            # Snap chunk to roads
            snapped_result = gmaps.snap_to_roads(
                path=chunk,
                interpolate=interpolate
            )
            
            for point in snapped_result['snappedPoints']:
                lat = point['location']['latitude']
                lng = point['location']['longitude']
                cleaned_track.append((lat, lng))
                
        except Exception as e:
            print(f"Error processing chunk {i//chunk_size + 1}: {e}")
            # Fall back to original points for this chunk
            cleaned_track.extend(chunk)
    
    return cleaned_track

# Example: Clean noisy GPS data
noisy_gps_data = [
    (40.714728, -73.998672),  # Good point
    (40.714858, -73.998834),  # Slightly off
    (40.714728, -73.999672),  # Way off (GPS error)
    (40.714928, -73.998472),  # Back on track
    (40.715028, -73.998272),  # Good point
]

print("Original GPS track:")
for i, point in enumerate(noisy_gps_data):
    print(f"  {i+1}: {point}")

cleaned_track = clean_gps_track(noisy_gps_data)

print(f"\nCleaned GPS track ({len(cleaned_track)} points):")
for i, point in enumerate(cleaned_track):
    print(f"  {i+1}: ({point[0]:.6f}, {point[1]:.6f})")

Install with Tessl CLI

npx tessl i tessl/pypi-googlemaps

docs

address-validation.md

client-config.md

elevation-geography.md

geocoding.md

geolocation-maps.md

index.md

places.md

roads.md

routing.md

tile.json