Skip to main content
Glama

find_nearby_stations

Locate nearby weather stations within a specified radius from a given geographic coordinate using latitude, longitude, and distance in kilometers.

Instructions

Find weather stations within a given radius (in km) from a given geographic coordinate.

Args: lat: Latitude in decimal degrees (e.g., 43.36) lon: Longitude in decimal degrees (e.g., -8.41) radio_km: Search radius in kilometers

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
latYes
lonYes
radio_kmNo

Implementation Reference

  • The primary handler function decorated with @mcp.tool(), implementing the logic to find nearby weather stations using haversine distance calculation.
    @mcp.tool()
    async def find_nearby_stations(lat: float, lon: float, radio_km: float = 25):
        """
        Find weather stations within a given radius (in km) from a given geographic coordinate.
    
        Args:
            lat: Latitude in decimal degrees (e.g., 43.36)
            lon: Longitude in decimal degrees (e.g., -8.41)
            radio_km: Search radius in kilometers
        """
    
        url = f"{AEMET_API_BASE}/valores/climatologicos/inventarioestaciones/todasestaciones"
        estaciones = await make_aemet_request(url)
        if not estaciones:
            return {"error": "Could not retrieve station list."}
    
        resultado = []
        for est in estaciones:
            try:
                est_dict: dict = est  # type: ignore
                est_lat = sexagesimal_to_decimal(est_dict["latitud"])
                est_lon = sexagesimal_to_decimal(est_dict["longitud"])
                dist = haversine(lat, lon, est_lat, est_lon)
                if dist <= radio_km:
                    est_dict["distancia_km"] = round(dist, 2)
                    resultado.append(est_dict)
            except Exception:
                continue
    
        return resultado
        #return sorted(resultado, key=lambda x: x["distancia_km"])
  • Supporting utility function to calculate the great-circle distance (haversine formula) between two latitude/longitude coordinates in kilometers. Used in find_nearby_stations.
    def haversine(lat1, lon1, lat2, lon2):
        # Distancia entre dos coordenadas en km
        R = 6371.0  # radio de la Tierra en km
        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
  • Supporting utility function to parse AEMET's sexagesimal coordinate format (e.g., degrees minutes seconds with N/S/E/W) into decimal degrees. Used to process station coordinates.
    def sexagesimal_to_decimal(coord: str) -> float:
        """
        Convert AEMET-style sexagesimal string to decimal degrees.
        Examples:
            '424607N' -> 42.768611
            '070103W' -> -7.0175
        """
    
        direction = coord[-1]
        coord = coord[:-1]
    
        degrees = int(coord[:2])
        minutes = int(coord[2:4])
        seconds = int(coord[4:])
    
        decimal = degrees + minutes / 60 + seconds / 3600
        if direction in 'SW':
            decimal = -decimal
    
        return decimal
  • General helper function to make authenticated asynchronous requests to the AEMET OpenData API, handling the two-step response process.
    async def make_aemet_request(url: str) -> dict[str, Any] | list[Any] | None:
        logger.info(f"make_aemet_request")
        headers = {
            "api_key": API_KEY,
            "Accept": "application/json"
        }
        async with httpx.AsyncClient() as client:
            try:
                response = await client.get(url, headers=headers, timeout=30.0)
                response.raise_for_status()
                data_info = response.json()
                if data_info.get("estado") == 200:
                    data_url = data_info.get("datos")
                    if data_url:
                        data_response = await client.get(data_url, timeout=30.0)
                        data_response.raise_for_status()
                        content = data_response.content.decode('latin1')
                        return json.loads(content)
                return None
            except Exception as e:
                logger.error(f"Error connecting to AEMET: {str(e)}")
                return None

Tool Definition Quality

Score is being calculated. Check back soon.

Install Server

Other Tools

Related Tools

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/AnCode666/aemet-mcp'

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