I have a GeoDataFrame of GPS points and I want to calculate the length and duration of trip from each point to all other points.
My input GeoDataFrame looks like this:
id Longitude Latitude geometry 0 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 1 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 2 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 3 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 4 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 5 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 6 7 -71.353066 46.821339 POINT (-71.35307 46.82134)
I have cross joined the gdf with itself to have a row of origin and destination points for all possible routes or trips. The crossed gdf looks like this:
id_o Longitude_o Latitude_o geometry_o id_d Longitude_d Latitude_d geometry_d 1 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 2 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 3 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 4 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 5 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 6 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 7 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 9 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 10 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 11 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 12 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 13 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 14 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 15 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 17 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 18 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 19 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 20 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 21 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 22 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 23 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 25 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 26 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 27 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 28 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 29 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 30 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 31 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 33 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 34 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 35 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 36 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 37 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 38 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 39 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 41 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 42 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 43 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 44 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 45 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 46 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 47 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 6 -71.227372 46.814365 POINT (-71.22737 46.81437)
Then, I used the following script to calculate the length and duration of trip for each row of this crossed gdf:
origins_x = list(gdf['geometry_o'].x)
origins_y = list(gdf['geometry_o'].y)
destinations_x = list(gdf['geometry_d'].x)
destinations_y = list(gdf['geometry_d'].y)
trans_modes = ['drive', 'bike', 'walk']
# Downloading network for each mode of transport
for mode in trans_modes:
print("calculations for this mode of transoprt is started: " + mode )
G = ox.graph_from_bbox(bbx_north, bbx_south, bbx_east, bbx_west, network_type=mode)
# impute speed on all edges missing data
G = ox.add_edge_speeds(G)
# calculate travel time (seconds) for all edges
G = ox.add_edge_travel_times(G)
origin_nodes = ox.distance.nearest_nodes(G, origins_x, origins_y)
destination_nodes = ox.distance.nearest_nodes(G, destinations_x, destinations_y)
routes = ox.shortest_path(G, origin_nodes, destination_nodes, weight='length')
# gdf['routes'] = routes
gdf['length_' + str(mode)] = [int(sum(ox.utils_graph.get_route_edge_attributes(G, routes[i], "length"))) for i in range(len(routes))]
gdf['duration_' + str(mode)] = [int(sum(ox.utils_graph.get_route_edge_attributes(G, routes[i], "travel_time"))) for i in range(len(routes))]
then I have this gdf as output:
id_o Longitude_o Latitude_o geometry_o id_d Longitude_d Latitude_d geometry_d len_dr dur_dr len_bi dur_bi len_wa dur_wa 1 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 2 -71.225308 46.814997 POINT (-71.22531 46.81500) 6791 386 7369 563 6916 538 2 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 3 -71.214790 46.811887 POINT (-71.21479 46.81189) 7559 441 8136 618 7800 603 3 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 4 -71.215936 46.846704 POINT (-71.21594 46.84670) 7450 509 8705 628 8515 627 4 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 5 -71.214600 46.812775 POINT (-71.21460 46.81278) 7922 469 8249 630 7858 609 5 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 6 -71.227372 46.814365 POINT (-71.22737 46.81437) 6429 360 7030 538 6707 522 6 1 -71.275580 46.837460 POINT (-71.27558 46.83746) 7 -71.353066 46.821339 POINT (-71.35307 46.82134) 7651 465 7938 630 9803 726
I have compared the results with google maps. It seems that length is almost correct for all of them. However, the duration is only correct for "dr" which is short for "drive" mode. Why "walk" and "bike" modes do not have correct durations!!
In fact, it seems that I have calculated the correct route length for bike and walk modes of transport, but at the end, I have calculated the duration of that length with the speed of car instead of bike or walk!!
How can I calculate the correct duration for bike and walk?