In [1]:
import googlemaps
import os
import urllib
import time
import fiona
import polyline
import folium
import xyzservices.providers as xyz
import pandas as pd
import geopandas as gpd
from dotenv import load_dotenv,find_dotenv
from datetime import datetime
from shapely.geometry import LineString
In [2]:
load_dotenv(find_dotenv())
gmaps = googlemaps.Client(key=os.getenv('GOOGLE_API_KEY_GK'))
access_token = os.getenv('MAPBOX_API_KEY')
In [3]:
def make_magic(source_text,target_coords,buffer_dist,iso_times,departure_time_gmaps,departure_time_mapbox):
iso_times = [str(el) for el in iso_times]
iso_times = ','.join(iso_times)
resp_source = gmaps.geocode(source_text,language='it')
source_address = resp_source[0]['formatted_address']
source_lat = resp_source[0]['geometry']['location']['lat']
source_lon = resp_source[0]['geometry']['location']['lng']
id = 1
source_df = pd.DataFrame([{
'id': id,
'address': source_address,
'lat': source_lat,
'lon': source_lon
}])
source = gpd.GeoDataFrame(source_df, geometry=gpd.points_from_xy(source_df['lon'], source_df['lat'], crs=4326))
target_lat = float(target_coords.split(',')[0].strip())
target_lon = float(target_coords.split(',')[1].strip())
target_df = pd.DataFrame([{
'id_t': 1,
'lat': target_lat,
'lon': target_lon
}])
target = gpd.GeoDataFrame(target_df, geometry=gpd.points_from_xy(target_df['lon'],target_df['lat']))
buff = source.copy()
buff['geometry'] = buff['geometry'].to_crs(32632).buffer(buffer_dist).to_crs(4326)
api_url = 'https://api.mapbox.com'
service = 'isochrone'
version = 'v1'
profile = 'mapbox/driving-traffic'
minutes = iso_times
if departure_time_mapbox == '':
depart_at = ''
else:
depart_at = f'&depart_at={departure_time_mapbox}'
for attempt in range(10):
try:
lon = source_lon
lat = source_lat
url =f'{api_url}/{service}/{version}/{profile}/{lon},{lat}?contours_minutes={minutes}{depart_at}&polygons=true&access_token={access_token}'
print(url)
iso = gpd.read_file(url)
iso['center'] = id
except urllib.error.HTTPError as err:
print(f'tentativo = {attempt} - {err}')
time.sleep(20)
except fiona.errors.DriverError as err:
print(f'Location out of road - {err}')
df = pd.DataFrame([{'geometry': None}])
iso = gpd.GeoDataFrame(df, geometry=df['geometry'])
iso['center'] = id
break
else:
break
departure_time = datetime.strptime(departure_time_gmaps, '%Y-%m-%dT%H:%M:%SZ')
directions_result = gmaps.directions((source_lat,source_lon),
(target_lat,target_lon),
mode="driving", #walking #bicycling #transit
departure_time=departure_time,
alternatives=True,
language='it')
print(f"Distanza: {directions_result[0]['legs'][0]['distance']['text']}")
print(f"Durata: {directions_result[0]['legs'][0]['duration']['text']}")
print(f"Durata con traffico: {directions_result[0]['legs'][0]['duration_in_traffic']['text']}")
for i,direction in enumerate(directions_result,start=1):
for leg in direction['legs']:
print(f"Soluzione {i} - {leg['duration_in_traffic']['text']}")
steps_out = list()
steps = directions_result[0]['legs'][0]['steps']
for i,step in enumerate(steps, start=1):
if i == len(steps):
desc = 'Destinazione raggiunta'
else:
desc = steps[i]['html_instructions']
l = polyline.decode(step['polyline']['points'])
l = [(el[1],el[0]) for el in l]
geom = LineString(l)
d = {'id': f'{i:02}','geom': geom, 'desc': desc}
steps_out.append(d)
gdf = gpd.GeoDataFrame(steps_out, geometry='geom',crs=4326)
m = buff.explore(color='black',
tiles=xyz.CartoDB.Voyager,
style_kwds={'fill':False},name=f'buffer ({int(buffer_dist/1000)} KM)')
for contour in iso['contour'].unique():
m = iso[iso['contour']==contour].explore(m=m,color='fillColor',name=f'mapbox iso ({contour} min)')
gdf.explore(m=m,
name='google directions',
column='id',
popup='desc',
tooltip=False,
style_kwds={'weight':4}
)
m = target.explore(m=m,color='black', name='target')
m = source.explore(m=m,color='black', name='start')
folium.LayerControl().add_to(m)
return m
In [4]:
source_text = 'Via Cornelio Celso 11 Roma'
#target_text = 'Via cherasco 96 Roma'
buffer_dist = 30_000
iso_times = [7,15,30]
departure_time_gmaps = '2025-02-14T13:00:00Z'
departure_time_mapbox = ''
#departure_time_mapbox = '2025-01-14T19:00:00Z'
In [5]:
make_magic(source_text,'41.98648839206951, 12.403421333214846',buffer_dist,iso_times,departure_time_gmaps,departure_time_mapbox)
https://api.mapbox.com/isochrone/v1/mapbox/driving-traffic/12.5105544,41.91218569999999?contours_minutes=7,15,30&polygons=true&access_token=pk.eyJ1IjoiZ2thcmltaXppIiwiYSI6ImNseGVyOWE2ejBoeDQybHIyYTRzb2NwcXMifQ.hA2f7LSM_CZPGRiTniMqxA
Distanza: 19,9 km Durata: 27 min Durata con traffico: 29 min Soluzione 1 - 29 min Soluzione 2 - 34 min
Out[5]:
Make this Notebook Trusted to load map: File -> Trust Notebook
In [ ]: