Skip to main content
Glama
jagan-shanmugam

OpenStreetMap MCP Server

find_parking_facilities

Locate parking facilities near a specific location, including lots, garages, and street parking, with capacity and fee details for trip planning and urban navigation.

Instructions

Locate parking facilities near a specific location.

This tool finds parking options (lots, garages, street parking) near a specified location. Results can be filtered by parking type and include capacity information where available. Useful for trip planning, city navigation, and evaluating parking availability in urban areas.

Args: latitude: Center point latitude (decimal degrees) longitude: Center point longitude (decimal degrees) radius: Search radius in meters (defaults to 1000m/1km) parking_type: Optional filter for specific types of parking facilities ("surface", "underground", "multi-storey", etc.)

Returns: List of parking facilities with: - Name and type - Capacity information if available - Fee structure if available - Access restrictions - Distance from search point

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
latitudeYes
longitudeYes
radiusNo
parking_typeNo

Implementation Reference

  • The handler function implementing the 'find_parking_facilities' tool. It queries the Overpass API for parking amenities (nodes, ways, relations) within a bounding box derived from the center coordinates and radius. Filters by parking_type if provided, extracts coordinates, calculates haversine distances, structures the results with details like capacity, fee, access, etc., sorts by distance, and returns a dictionary with query params and list of facilities.
    async def find_parking_facilities(
        latitude: float,
        longitude: float,
        ctx: Context,
        radius: float = 1000,
        parking_type: str = None  # e.g., "surface", "underground", "multi-storey"
    ) -> Dict[str, Any]:
        """
        Locate parking facilities near a specific location.
        
        This tool finds parking options (lots, garages, street parking) near a specified location.
        Results can be filtered by parking type and include capacity information where available.
        Useful for trip planning, city navigation, and evaluating parking availability in urban areas.
        
        Args:
            latitude: Center point latitude (decimal degrees)
            longitude: Center point longitude (decimal degrees)
            radius: Search radius in meters (defaults to 1000m/1km)
            parking_type: Optional filter for specific types of parking facilities
                         ("surface", "underground", "multi-storey", etc.)
            
        Returns:
            List of parking facilities with:
            - Name and type
            - Capacity information if available
            - Fee structure if available
            - Access restrictions
            - Distance from search point
        """
        osm_client = ctx.request_context.lifespan_context.osm_client
        
        # Convert radius to bounding box
        lat_delta = radius / 111000
        lon_delta = radius / (111000 * math.cos(math.radians(latitude)))
        
        bbox = (
            longitude - lon_delta,
            latitude - lat_delta,
            longitude + lon_delta,
            latitude + lat_delta
        )
        
        # Build Overpass query for parking facilities
        overpass_url = "https://overpass-api.de/api/interpreter"
        
        query = f"""
        [out:json];
        (
            node["amenity"="parking"]({{bbox}});
            way["amenity"="parking"]({{bbox}});
            relation["amenity"="parking"]({{bbox}});
        );
        out body;
        """
        
        query = query.replace("{bbox}", f"{bbox[1]},{bbox[0]},{bbox[3]},{bbox[2]}")
        
        async with aiohttp.ClientSession() as session:
            async with session.post(overpass_url, data={"data": query}) as response:
                if response.status == 200:
                    data = await response.json()
                    parking_facilities = data.get("elements", [])
                else:
                    raise Exception(f"Failed to find parking facilities: {response.status}")
        
        # Process and filter results
        results = []
        for facility in parking_facilities:
            tags = facility.get("tags", {})
            
            # Filter by parking type if specified
            if parking_type and tags.get("parking", "") != parking_type:
                continue
            
            # Get coordinates based on feature type
            coords = {}
            if facility.get("type") == "node":
                coords = {
                    "latitude": facility.get("lat"),
                    "longitude": facility.get("lon")
                }
            elif "center" in facility:
                coords = {
                    "latitude": facility.get("center", {}).get("lat"),
                    "longitude": facility.get("center", {}).get("lon")
                }
            
            # Skip if no valid coordinates
            if not coords:
                continue
            
            # Calculate distance from search point
            from math import radians, sin, cos, sqrt, asin
            
            def haversine(lat1, lon1, lat2, lon2):
                R = 6371000  # Earth radius in meters
                dLat = radians(lat2 - lat1)
                dLon = radians(lon2 - lon1)
                a = sin(dLat/2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dLon/2)**2
                c = 2 * asin(sqrt(a))
                return R * c
            
            distance = haversine(latitude, longitude, coords["latitude"], coords["longitude"])
            
            results.append({
                "id": facility.get("id"),
                "name": tags.get("name", "Unnamed Parking"),
                "type": tags.get("parking", "surface"),
                "coordinates": coords,
                "distance": round(distance, 1),
                "capacity": tags.get("capacity", "Unknown"),
                "fee": tags.get("fee", "Unknown"),
                "access": tags.get("access", "public"),
                "opening_hours": tags.get("opening_hours", "Unknown"),
                "levels": tags.get("levels", "1"),
                "address": {
                    "street": tags.get("addr:street", ""),
                    "housenumber": tags.get("addr:housenumber", ""),
                    "city": tags.get("addr:city", ""),
                    "postcode": tags.get("addr:postcode", "")
                },
                "tags": tags
            })
        
        # Sort by distance
        results.sort(key=lambda x: x["distance"])
        
        return {
            "query": {
                "latitude": latitude,
                "longitude": longitude,
                "radius": radius,
                "parking_type": parking_type
            },
            "parking_facilities": results,
            "count": len(results)
        }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jagan-shanmugam/open-streetmap-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server