File size: 2,822 Bytes
3c76e30
 
 
 
 
 
 
 
cccc034
3c76e30
 
 
 
 
 
 
cccc034
 
 
 
4588d29
cccc034
 
 
 
 
 
 
 
3c76e30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0723ad1
 
 
3c76e30
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import os
import gradio as gr
import math
from typing import Union
import requests
import json
from urllib.parse import quote
from dotenv import load_dotenv
from time import sleep

Number = Union[int, float]

load_dotenv(override=True)


def get_geo_coords(address, access_token):
    sleep_time = 1
    while sleep_time < 10:
        base_url = "https://us1.locationiq.com/v1/search"
        # headers= {"key: " + f"{access_token}", "Content-Type: application/json",}
        url = f"{base_url}?key={access_token}&q={quote(address)}&format=json"
        response = requests.get(url)
        if response.status_code == 429:
            sleep(sleep_time)
            sleep_time *= 3
        else:
            break;
    if sleep_time > 9:
        return (0.0, 0.0)
    rjson = json.loads(response.content)
    return (float(rjson[0]['lat']), float(rjson[0]['lon']))


def great_circle_distance_miles(lat1: Number, lon1: Number, lat2: Number, lon2: Number,
                                radius_miles: float = 3958.8) -> float:
    """
    Compute the great-circle distance between two points on the Earth using the haversine formula.

    Parameters:
    - lat1, lon1: Latitude and longitude of the first point in degrees.
    - lat2, lon2: Latitude and longitude of the second point in degrees.
    - radius_miles: Radius of the Earth in miles (default 3958.8 miles).

    Returns:
    - Distance between the two points in miles (float).

    Notes:
    - Latitude values should be in [-90, 90], longitude values in [-180, 180].
    """
    # convert degrees to radians
    phi1 = math.radians(lat1)
    phi2 = math.radians(lat2)
    dphi = math.radians(lat2 - lat1)
    dlambda = math.radians(lon2 - lon1)

    # haversine formula
    a = math.sin(dphi / 2.0) ** 2 + math.cos(phi1) * math.cos(phi2) * math.sin(dlambda / 2.0) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))

    return radius_miles * c

def geo_distance(addr1: str, addr2: str, pwd: str) -> float:
    ''' Compute straight-line (great circle) distance in miles 
    between two addresses or other location specifiers.

    Args:
        addr1: first address or location
        addr2: second address or location
        pwd: a password

    Returns:
        The great circle distance in miles between the two locations   
    '''
    good_pwd = os.getenv('PWD')
    if pwd != good_pwd:
        return 0.0
    access_token = os.getenv('TOKEN')
    (lat1, lon1) = get_geo_coords(addr1, access_token)
    (lat2, lon2) = get_geo_coords(addr2, access_token)
    distance = great_circle_distance_miles(lat1, lon1, lat2, lon2)
    return distance
    
demo = gr.Interface(fn=geo_distance,
                    inputs=["text", "text", "text"],
                    outputs="number")

demo.launch(mcp_server=True)   # exposes an MCP schema automatically