find_closest_stop
Locate the nearest public transport stop in Vilnius using specific latitude and longitude coordinates for efficient route planning.
Instructions
Find the closest public transport stop to given coordinates
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| coordinates | Yes | Coordinates as 'latitude, longitude' (e.g., '54.687157, 25.279652') |
Implementation Reference
- The main handler function that executes the find_closest_stop tool: validates input, parses coordinates, loads stops, computes distances using helper functions, finds the minimum distance stop, and formats a response with stop details and Google Maps link.async def handle_find_closest_stop(arguments: Any) -> List[TextContent]: """Handle the find_closest_stop tool call.""" if not isinstance(arguments, dict) or "coordinates" not in arguments: raise ValueError("Invalid arguments: 'coordinates' is required") try: coord_str = arguments["coordinates"] logger.info(f'Processing coordinates: {coord_str}') # Parse coordinates lat, lon = parse_coordinates(coord_str) # Get stops data stops_df = gk.get_stops(feed) # Calculate distances to all stops distances = calculate_distances(lat, lon, stops_df) # Find the closest stop closest_idx = distances.idxmin() closest_stop = stops_df.loc[closest_idx] distance_km = distances[closest_idx] # Format response response_text = ( f"Closest stop to coordinates ({lat:.6f}, {lon:.6f}):\n" f"- {closest_stop['stop_name']}\n" f" ID: {closest_stop['stop_id']}\n" f" Location: {float(closest_stop['stop_lat']):.6f}, {float(closest_stop['stop_lon']):.6f}\n" f" Distance: {distance_km:.2f} km" ) logger.info(f'Found closest stop: {closest_stop["stop_name"]}') return [TextContent( type="text", text=response_text )] except ValueError as e: logger.error(f"Invalid coordinates: {str(e)}") return [TextContent( type="text", text=f"Error: {str(e)}" )] except Exception as e: logger.error(f"Error finding closest stop: {str(e)}") raise RuntimeError(f"Error finding closest stop: {str(e)}")
- The tool schema definition in list_tools(), specifying the name, description, and input schema requiring a 'coordinates' string in 'lat,lon' format.Tool( name="find_closest_stop", description="Find the closest public transport stop to given coordinates", inputSchema={ "type": "object", "properties": { "coordinates": { "type": "string", "description": "Coordinates as 'latitude, longitude' (e.g., '54.687157, 25.279652')", }, }, "required": ["coordinates"], }, ),
- src/vilnius_transport_mcp/transport.py:119-120 (registration)Tool dispatch/registration in the call_tool handler: routes calls to 'find_closest_stop' to the handle_find_closest_stop function.elif name == "find_closest_stop": return await handle_find_closest_stop(arguments)
- Helper function to parse and validate coordinates from input string 'latitude, longitude'.def parse_coordinates(coord_str: str) -> Tuple[float, float]: """Parse coordinates string into latitude and longitude. Args: coord_str: String containing latitude and longitude separated by comma Returns: Tuple of (latitude, longitude) as floats Raises: ValueError: If coordinates are invalid or out of range """ try: lat_str, lon_str = coord_str.split(',') lat = float(lat_str.strip()) lon = float(lon_str.strip()) if not (-90 <= lat <= 90) or not (-180 <= lon <= 180): raise ValueError("Coordinates out of valid range") return lat, lon except ValueError as e: raise ValueError("Invalid coordinates format. Expected 'latitude, longitude'") from e
- Helper function implementing Haversine formula to compute distances from given lat/lon to all stops in the GTFS stops DataFrame.def calculate_distances(lat: float, lon: float, stops_df: 'pd.DataFrame') -> 'pd.Series': """Calculate distances from given point to all stops using Haversine formula. Args: lat: Latitude of the point lon: Longitude of the point stops_df: DataFrame containing stops data Returns: Series containing distances to all stops in kilometers """ R = 6371 # Earth's radius in kilometers # Convert degrees to radians lat1, lon1 = np.radians(lat), np.radians(lon) lat2, lon2 = np.radians(stops_df['stop_lat']), np.radians(stops_df['stop_lon']) # Haversine formula dlat = lat2 - lat1 dlon = lon2 - lon1 a = np.sin(dlat / 2) ** 2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon / 2) ** 2 c = 2 * np.arcsin(np.sqrt(a)) return R * c