<jupyter_start><jupyter_text>Distances API Route Example  SetupInstall the Signal Ocean SDK:```pip install signal-ocean```Set your subscription key acquired here: https://apis.signalocean.com/profile<jupyter_code>pip install signal-ocean
pip install folium
signal_ocean_api_key = '' #replace with your subscription key<jupyter_output><empty_output><jupyter_text>Get the route between 2 portsCreate a connections towards distances API.Then call the distance API to get the actual route between Basrah and Milazzo for a Suezmax vessel (corresponding restrictions applied)<jupyter_code>from signal_ocean import Connection
from signal_ocean.distances import DistancesAPI, VesselClassFilter, PortFilter, LoadingCondition

connection = Connection(api_key=signal_ocean_api_key)
distances_api = DistancesAPI(connection)

load_port = distances_api.get_ports(PortFilter(name_like='Basrah'))[0]
discharge_port = distances_api.get_ports(PortFilter(name_like='Milazzo'))[0]

vessel_class = distances_api.get_vessel_classes(VesselClassFilter(name_like='suezmax'))[0]
routeResponse = distances_api.get_port_to_port_route(vessel_class, LoadingCondition.BALLAST, load_port, discharge_port)<jupyter_output><empty_output><jupyter_text>Display some properties for the routeThe route response objects holds information on properties regarding the route like:- The total distance covered.- The seca distance covered within the route.- The hra distance covered within the route.- Any significant routing points met across the route (i.e: Suez)<jupyter_code>print(f"Total distance: {routeResponse.distance}")
print(f"Seca distance: {routeResponse.seca_distance}")
print(f"Hra distance: {routeResponse.piracy_distance}")
print(f"Significant routing points: {[(routing_point.name) for routing_point in routeResponse.routing_points_on_route if routing_point.is_shown]}")<jupyter_output>Total distance: 4574.86
Seca distance: 0
Hra distance: 1301.22
Significant routing points: ['Suez']<jupyter_text>Display the route on a mapFinally you can get all route coordinates and display them on the map.<jupyter_code>import folium

coordinatesList = []
for point in routeResponse.calculated_route:
    newList = [float(point.lat), float(point.lon)]
    coordinatesList.append(newList)
m = folium.Map(zoom_start=10)
gh_fg = folium.FeatureGroup(name=f"Path ({load_port.name}) -> ({discharge_port.name})").add_to(m)
folium.PolyLine(locations=coordinatesList, weight=2, color='cadetblue').add_to(gh_fg)
folium.LayerControl().add_to(m)

#Get bounding box of route:
bbox = [[float(routeResponse.bbox[1]), float(routeResponse.bbox[0])], [float(routeResponse.bbox[3]), float(routeResponse.bbox[2])]]
m.fit_bounds(bbox)

#put some markers to display start and stop
folium.Marker(
    location=[routeResponse.start_point.lat, routeResponse.start_point.lon],
    popup= load_port.name,
    icon=folium.Icon(color='green')
).add_to(m)

folium.Marker(
    location=[routeResponse.end_point.lat, routeResponse.end_point.lon],
    popup= discharge_port.name,
    icon=folium.Icon(color='red')
).add_to(m)

m<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10301263362487852, 'fraction_numerical': 0.007774538386783284, 'mean_word_length': 7.822857142857143, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 17, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '165815', 'license': 'Apache-2.0', 'n_tokens_mistral': 1005, 'n_tokens_neox': 959, 'n_words': 228, 'path': 'docs/examples/jupyter/DistancesAPI/DistancesWithRouteExample.ipynb', 'repo_name': 'SignalOceanSdk/SignalSDK', 'size': '3087'}