find_parking_facilities
Locate parking facilities (lots, garages, street parking) near a specified location with options to filter by type and view capacity or fee details. Ideal 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
| Name | Required | Description | Default |
|---|---|---|---|
| latitude | Yes | ||
| longitude | Yes | ||
| parking_type | No | ||
| radius | No |
Implementation Reference
- src/osm_mcp_server/server.py:1460-1596 (handler)The main handler function for the 'find_parking_facilities' MCP tool. It queries the Overpass API for parking facilities (amenity=parking) within a bounding box derived from the input coordinates and radius, filters by parking_type if specified, calculates distances using the haversine formula, and returns a structured list of facilities sorted by distance.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) }