File size: 6,949 Bytes
63ec258 e3db752 63ec258 0f04201 e3db752 63ec258 187a965 63ec258 e3db752 63ec258 e3db752 e5f444f e3db752 e5f444f 0950a4c e5f444f 63ec258 cb47347 63ec258 cb47347 187a965 cc1b4c0 63ec258 cc1b4c0 63ec258 cb47347 63ec258 cb47347 cc1b4c0 63ec258 cb47347 63ec258 962f893 0f04201 962f893 63ec258 247bc50 63ec258 962f893 63ec258 962f893 e5f444f 63ec258 cb47347 63ec258 cb47347 63ec258 cb47347 e3db752 |
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
from datetime import datetime
import requests
from langchain.tools import tool
from loguru import logger
from .common import config, vehicle
def find_coordinates(address):
"""
Find the coordinates of a specific address.
:param address (string): Required. The address
"""
# https://developer.tomtom.com/geocoding-api/documentation/geocode
url = f"https://api.tomtom.com/search/2/geocode/{address}.json?key={config.TOMTOM_API_KEY}"
response = requests.get(url, timeout=5)
data = response.json()
lat = data["results"][0]["position"]["lat"]
lon = data["results"][0]["position"]["lon"]
return lat, lon
def find_address(lat, lon):
"""
Find the address of a specific location.
Args:
lat (string): Required. The latitude
lon (string): Required. The longitude
"""
# https://developer.tomtom.com/search-api/documentation/reverse-geocoding
url = f"https://api.tomtom.com/search/2/reverseGeocode/{lat},{lon}.json?key={config.TOMTOM_API_KEY}"
response = requests.get(url, timeout=5)
data = response.json()
address = data["addresses"][0]["address"]["freeformAddress"]
return address
def calculate_route(origin, destination):
"""This function is called when the origin or destination is updated in the GUI. It calculates the route between the origin and destination."""
print(f"calculate_route(origin: {origin}, destination: {destination})")
origin_coords = find_coordinates(origin)
destination_coords = find_coordinates(destination)
orig_coords_str = ",".join(map(str, origin_coords))
dest_coords_str = ",".join(map(str, destination_coords))
print(f"origin_coords: {origin_coords}, destination_coords: {destination_coords}")
vehicle.destination = destination
vehicle.location_coordinates = origin_coords
vehicle.location = origin
# origin = "49.631997,6.171029"
# destination = "49.586745,6.140002"
url = f"https://api.tomtom.com/routing/1/calculateRoute/{orig_coords_str}:{dest_coords_str}/json?key={config.TOMTOM_API_KEY}"
response = requests.get(url, timeout=5)
data = response.json()
points = data["routes"][0]["legs"][0]["points"]
return vehicle, points
def find_route_tomtom(
lat_depart="0",
lon_depart="0",
lat_dest="0",
lon_dest="0",
depart_datetime="",
**kwargs,
):
"""
Return the distance and the estimated time to go to a specific destination from the current place, at a specified depart time.
:param lat_depart (string): latitude of depart
:param lon_depart (string): longitude of depart
:param lat_dest (string): latitude of destination
:param lon_dest (string): longitude of destination
:param depart_time (string): departure hour, in the format '08:00:20'.
"""
# https://developer.tomtom.com/routing-api/documentation/routing/calculate-route
# https://developer.tomtom.com/routing-api/documentation/routing/guidance-instructions
url = f"https://api.tomtom.com/routing/1/calculateRoute/{lat_depart},{lon_depart}:{lat_dest},{lon_dest}/json?key={config.TOMTOM_API_KEY}&departAt={depart_datetime}"
print(f"Calling TomTom API: {url}")
r = requests.get(
url,
timeout=5,
)
# Parse JSON from the response
response = r.json()
try:
result = response["routes"][0]["summary"]
except KeyError:
print(f"Failed to find a route: {response}")
return "Failed to find a route", response
distance_m = result["lengthInMeters"]
duration_s = result["travelTimeInSeconds"]
arrival_time = result["arrivalTime"]
# Convert string to datetime object
arrival_time = datetime.fromisoformat(arrival_time)
return {
"distance_m": distance_m,
"duration_s": duration_s,
"arrival_time": arrival_time,
}, response
def find_route_a_to_b(origin="", destination=""):
"""Get a route between origin and destination.
Args:
origin (string): Optional. The origin name.
destination (string): Optional. The destination name.
"""
if not destination:
destination = vehicle.destination
lat_dest, lon_dest = find_coordinates(destination)
print(f"lat_dest: {lat_dest}, lon_dest: {lon_dest}")
if not origin:
# Extract the latitude and longitude of the vehicle
vehicle_coordinates = getattr(vehicle, "location_coordinates")
lat_depart, lon_depart = vehicle_coordinates
else:
lat_depart, lon_depart = find_coordinates(origin)
print(f"lat_depart: {lat_depart}, lon_depart: {lon_depart}")
date = getattr(vehicle, "date")
time = getattr(vehicle, "time")
departure_time = f"{date}T{time}"
trip_info, raw_response = find_route_tomtom(
lat_depart, lon_depart, lat_dest, lon_dest, departure_time
)
return _format_tomtom_trip_info(trip_info, destination)
@tool
def find_route(destination):
"""Get a route to a destination from the current location of the vehicle.
Args:
destination (string): Optional. The destination name.
"""
if not destination:
destination = vehicle.destination
# lat, lon, city = check_city_coordinates(lat_depart,lon_depart,city_depart)
lat_dest, lon_dest = find_coordinates(destination)
print(f"lat_dest: {lat_dest}, lon_dest: {lon_dest}")
# Extract the latitude and longitude of the vehicle
vehicle_coordinates = getattr(vehicle, "location_coordinates")
lat_depart, lon_depart = vehicle_coordinates
print(f"lat_depart: {lat_depart}, lon_depart: {lon_depart}")
date = getattr(vehicle, "date")
time = getattr(vehicle, "time")
departure_time = f"{date}T{time}"
trip_info, raw_response = find_route_tomtom(
lat_depart, lon_depart, lat_dest, lon_dest, departure_time
)
return _format_tomtom_trip_info(trip_info, destination)
# raw_response["routes"][0]["legs"][0]["points"]
def _format_tomtom_trip_info(trip_info, destination="destination"):
distance, duration, arrival_time = (
trip_info["distance_m"],
trip_info["duration_s"],
trip_info["arrival_time"],
)
# Calculate distance in kilometers (1 meter = 0.001 kilometers)
distance_km = distance * 0.001
# Calculate travel time in minutes (1 second = 1/60 minutes)
time_minutes = duration / 60
if time_minutes < 60:
time_display = f"{time_minutes:.0f} minutes"
else:
hours = int(time_minutes / 60)
minutes = int(time_minutes % 60)
time_display = f"{hours} hours" + (
f" and {minutes} minutes" if minutes > 0 else ""
)
# Extract and display the arrival hour in HH:MM format
arrival_hour_display = arrival_time.strftime("%H:%M")
# return the distance and time
return f"The route to {destination} is {distance_km:.2f} km which takes {time_display}. Leaving now, the arrival time is estimated at {arrival_hour_display}."
|