def get_multimodal(inData, params, request, plot=True): o = request.origin d = request.destination params.GTFS.beta = 5 # A find transfer stop from ride to transit # get two distances leg1 = inData.skims.ride.loc[inData.transit_stops.node][ o] # from origin to all transit_stops via road network leg2 = inData.skims.transit.loc[d][ inData.transit_stops. node] / params.GTFS.beta # and from all transit_stop to destination with transit multimodalRT = pd.concat( [leg1, leg2], axis=1) # merge them by the stop_point (two columns of travel times) multimodalRT['time'] = multimodalRT.sum(axis=1) +\ params.GTFS.transfer_penalty # calculate sum of travel times plus transfer penalty transfer_pointRT = multimodalRT.time.idxmin( ) # find stop of minimal total time - this is transfer point # B find transfer stop from transit to ride leg1 = inData.skims.transit.loc[inData.transit_stops.node][ o] / params.GTFS.beta # transit distances from origin to stop points leg2 = inData.skims.ride.loc[d][ inData.transit_stops. node] # ride distances from transit stops to destination multimodalTR = pd.concat([leg1, leg2], axis=1) # merge to two-clumn data frame multimodalTR['time'] = multimodalTR.sum( axis=1) + params.GTFS.transfer_penalty # calc total travel and penalty transfer_pointTR = multimodalTR.time.idxmin( ) # find transfer point of minimal time if plot: import seaborn as sns dists = DotMap() G = inData.GTFS.G palette = sns.color_palette("bright") ev = [ 0.001 if 'IVT' in edge[-1].keys() else 0.3 for edge in G.edges(data=True) ] # assign line weights colors = [ 'blue' if 'IVT' in edge[-1].keys() else 'grey' for edge in G.edges(data=True) ] # assign color #plot graph fig, ax = ox.plot_graph(G, fig_height=15, fig_width=15, node_size=0, edge_linewidth=ev, show=False, close=False, edge_color=colors) # plot stops ax.scatter(inData.transit_stops.x, inData.transit_stops.y, s=3, c='black', marker='x') # plot O and D ax.annotate( 'O', (inData.nodes.loc[o].x * 1.0002, inData.nodes.loc[o].y * 1.00001)) ax.annotate( 'D', (inData.nodes.loc[d].x * 1.0002, inData.nodes.loc[d].y * 1.00001)) # plot two transfer points TRp = inData.transit_stops[inData.transit_stops.node == transfer_pointTR].squeeze() ax.scatter(TRp.x, TRp.y, s=30, c='brown', marker='o') ax.annotate('T->R', (TRp.x * 1.0002, TRp.y * 1.00001)) TRp = inData.transit_stops[inData.transit_stops.node == transfer_pointRT].squeeze() ax.scatter(TRp.x, TRp.y, s=30, c='green', marker='o') ax.annotate('R->T', (TRp.x * 1.0002, TRp.y * 1.00001)) route = nx.shortest_path(G, o, d, weight='TRANSIT_COST') dists.transit = nx.shortest_path_length( G, o, d, weight='TRANSIT_COST') / params.GTFS.beta ax = add_route(G, ax, route, color='black', alpha=0.7, key='length') route = nx.shortest_path(G, o, d, weight='length') dists.ride = nx.shortest_path_length( G, o, d, weight='length') / params.speeds.ride ax = add_route(G, ax, route, color='blue', alpha=0.7, key='length') route = nx.shortest_path(G, o, transfer_pointRT, weight='length') ax = add_route(G, ax, route, color='green', alpha=0.7, key='length') route = nx.shortest_path(G, transfer_pointRT, d, weight='TRANSIT_COST') ax = add_route(G, ax, route, color='green', alpha=0.7, key='length') dists.RT_R = nx.shortest_path_length( G, o, transfer_pointRT, weight='length') / params.speeds.ride dists.RT_T = nx.shortest_path_length( G, transfer_pointRT, d, weight='TRANSIT_COST') / params.GTFS.beta dists.RT = dists.RT_R + dists.RT_T route = nx.shortest_path(G, o, transfer_pointTR, weight='TRANSIT_COST') ax = add_route(G, ax, route, color='brown', alpha=0.7, key='length') route = nx.shortest_path(G, transfer_pointTR, d, weight='length') ax = add_route(G, ax, route, color='brown', alpha=0.7, key='length') dists.TR_T = nx.shortest_path_length( G, o, transfer_pointTR, weight='TRANSIT_COST') / params.GTFS.beta dists.TR_R = nx.shortest_path_length( G, transfer_pointTR, d, weight='length') / params.speeds.ride dists.TR = dists.TR_R + dists.TR_T return pd.Series(dists).to_frame().drop(['_typ', '_subtyp'])