Spaces:
Sleeping
Sleeping
| """ | |
| Distance Calculation Tool - Haversine Formula Implementation. | |
| This module provides accurate distance calculations between geographic | |
| coordinates using the haversine formula for spherical distance calculation. | |
| It's used for filtering surf spots by proximity to user location. | |
| The haversine formula accounts for the Earth's spherical shape and | |
| provides distance calculations accurate to within a few meters for | |
| most surf spot finding applications. | |
| Formula: d = 2r * arcsin(sqrt(sin²(Δφ/2) + cos(φ1) * cos(φ2) * sin²(Δλ/2))) | |
| Where: | |
| - φ is latitude in radians | |
| - λ is longitude in radians | |
| - r is Earth's radius (6371 km) | |
| - Δφ, Δλ are differences in latitude and longitude | |
| Example: | |
| >>> tool = DistanceTool() | |
| >>> result = await tool.run({ | |
| ... "lat1": 36.72, "lon1": -4.42, # Málaga | |
| ... "lat2": 36.18, "lon2": -5.92 # Tarifa | |
| ... }) | |
| >>> print(f"Distance: {result['distance_km']:.1f}km") | |
| Author: Surf Spot Finder Team | |
| License: MIT | |
| """ | |
| from pydantic import BaseModel | |
| from typing import Dict, Any | |
| import math | |
| class DistanceTool: | |
| """ | |
| Geographic distance calculation tool using haversine formula. | |
| Computes spherical distances between coordinate pairs on Earth's surface. | |
| Provides accurate results for surf spot proximity filtering and ranking. | |
| The haversine formula is well-suited for this use case because: | |
| - Accurate for distances up to several hundred kilometers | |
| - Computationally efficient | |
| - Accounts for Earth's spherical shape | |
| - Suitable for surf spot search radii (typically 10-100km) | |
| Attributes: | |
| Earth radius is set to 6371 km (mean radius) | |
| Example: | |
| >>> tool = DistanceTool() | |
| >>> input_data = { | |
| ... "lat1": 40.7128, "lon1": -74.0060, # NYC | |
| ... "lat2": 40.7589, "lon2": -73.9851 # Central Park | |
| ... } | |
| >>> result = await tool.run(input_data) | |
| """ | |
| class DistanceInput(BaseModel): | |
| """Input schema for distance calculation. | |
| Attributes: | |
| lat1: Origin latitude in decimal degrees (-90 to 90). | |
| lon1: Origin longitude in decimal degrees (-180 to 180). | |
| lat2: Destination latitude in decimal degrees (-90 to 90). | |
| lon2: Destination longitude in decimal degrees (-180 to 180). | |
| """ | |
| lat1: float | |
| lon1: float | |
| lat2: float | |
| lon2: float | |
| async def run(self, input_data: Dict[str, Any]) -> Dict[str, Any]: | |
| """Calculate spherical distance between two coordinate pairs. | |
| Implements the haversine formula for accurate distance calculation | |
| on Earth's surface. Suitable for surf spot proximity filtering. | |
| Args: | |
| input_data: Dict containing lat1, lon1, lat2, lon2 coordinates. | |
| Returns: | |
| Dict with 'distance_km' key containing distance in kilometers. | |
| Example: | |
| >>> result = await tool.run({ | |
| ... "lat1": 36.72, "lon1": -4.42, | |
| ... "lat2": 36.18, "lon2": -5.92 | |
| ... }) | |
| >>> print(result["distance_km"]) # 142.3 | |
| """ | |
| inp = self.DistanceInput(**input_data) | |
| # Earth's mean radius in kilometers | |
| R = 6371 | |
| # Convert latitude and longitude differences to radians | |
| d_lat = math.radians(inp.lat2 - inp.lat1) | |
| d_lon = math.radians(inp.lon2 - inp.lon1) | |
| # Haversine formula calculation | |
| a = ( | |
| math.sin(d_lat / 2) ** 2 | |
| + math.cos(math.radians(inp.lat1)) | |
| * math.cos(math.radians(inp.lat2)) | |
| * math.sin(d_lon / 2) ** 2 | |
| ) | |
| c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) | |
| distance = R * c | |
| return {"distance_km": distance} | |