Find time to travel on a path based on speeds of road segments

79 views
Skip to first unread message

Chintan Pathak

unread,
Feb 25, 2019, 10:23:04 PM2/25/19
to GAMA
Dear all,

I would like to calculate the time it would take to traverse a certain distance by driving on a path. The speed of driving is to be determined by the speed limit on the individual road segment. I can always simulate the travel and see the time taken. However, I want to this before making the actual travel and hopefully, do this efficiently.

My model is attached. The code is below:

model pathlength

/* Insert your model definition here */
global {
graph the_graph;
file roads_shapefile <- file("../includes/SpatialJoin/WA_roads.shp");
file od_csvfile <- csv_file("../includes/zipcodes_OD_WA.csv", ",");

path shortest_path;
geometry shape <- envelope(roads_shapefile);
matrix od_pairs <- matrix(od_csvfile);
int od_count <- od_pairs.rows;
point source;
point target;
point source_temp1;
point source_temp2;
float lookup_distance <- 10 / 0.000621371; // convert miles to m
init {
// Create road from roads_shapefile - it contains ID, and maxspped for each segment
create road from: roads_shapefile
with: [maxspeed :: float(read('Spd')) #miles / #hour,
road_ID :: int(read('ID'))] ;

the_graph <- as_edge_graph(road);

loop i from: 51 to: 51 {
source <- point(the_graph.vertices closest_to (point(to_GAMA_CRS({float(od_pairs[3, i]), float(od_pairs[2, i])}, "EPSG:4326"))));
target <- point(the_graph.vertices closest_to (point(to_GAMA_CRS({float(od_pairs[6, i]), float(od_pairs[5, i])}, "EPSG:4326"))));
}

shortest_path <- path_between(the_graph, source, target);

// To find time_to_travel on the shortest_path, like so:
// total_time = length_1 / speed_1 + length_2 / speed_2 + ....
// where length_i is the length of the road segment with speed limit speed_i

}

}

species road {
geometry display_shape <- line(shape.points, 2.0);
float maxspeed;
int road_ID;
aspect default {
draw shape color: #black;
}

}

experiment goto_network type: gui {
output {
display objects_display type: opengl {
species road aspect: default;
graphics points_display {
draw circle(1000) color: #red at: source;
draw circle(1000) color: #blue at: target;

draw geometry(shortest_path.segments) color: #green width: 4;
}

}

}

}

Some of the examples seem like I can attach weights to the graph edges. However, it is still not clear to me, how I would use the weights, if I attach speed as the weight to an edge?

Thanks
Chintan Pathak

Chintan Pathak

unread,
Feb 25, 2019, 11:31:56 PM2/25/19
to GAMA
Forgot to attach the model. Shared in Google Drive here: https://drive.google.com/file/d/1jiw_0byr2G41TLU95JJBodraPsGX05Mm/view?usp=sharing

Patrick Taillandier

unread,
Feb 26, 2019, 11:40:09 AM2/26/19
to gama-p...@googlegroups.com
Hi,

A solution is to set the weights of the edges to the time necessary to travel across, and then to compute the weights of the path:
the_graph <- as_edge_graph(road);
map<road, float> map_weights <- road as_map (each::each.shape.perimeter/each.maxspeed);
the_graph <- the_graph with_weights map_weights;

shortest_path <- path_between(the_graph, source, target);
write "Time between source and target:" + shortest_path.weight + " seconds";


Cheers,

Patrick

--
You received this message because you are subscribed to the Google Groups "GAMA" group.
To unsubscribe from this group and stop receiving emails from it, send an email to gama-platfor...@googlegroups.com.
To post to this group, send email to gama-p...@googlegroups.com.
Visit this group at https://groups.google.com/group/gama-platform.
For more options, visit https://groups.google.com/d/optout.

Chintan Pathak

unread,
Feb 27, 2019, 1:10:14 AM2/27/19
to GAMA
Patrick,

A very elegrant solution, exactly what I waws looking for.

Thanks

Chintan Pathak

unread,
Mar 5, 2019, 10:08:19 PM3/5/19
to GAMA
Dear Patrick,

While this worked for me for the purpose intended, adding weights to the road has an unintended side-effect that I am not able to understand.

When I implemented the weights in my full model, where a vehicle moves on the road, using the "goto" operator, the real_speed is out of whack with weights (close to 2000% of what it should be).

I tried creating a new graph with weights, adding weights to the same graph, creating a copy of the graph, all resulted in the same behavior. The real_speed (which is internally set) becomes much higher than the real_speed without the weights.

/***
* Name: pathlength
* Author: chintan
* Description:
* Tags: Tag1, Tag2, TagN
***/
model pathlength

/* Insert your model definition here */
global {
graph road_network;
graph road_network_weighted;
file roads_shapefile <- file("../includes/SpatialJoin/WA_roads.shp");
file od_csvfile <- csv_file("../includes/zipcodes_OD_WA.csv", ",");
float step <- 1 #mn; // Time step of 1 minute for the simulation
path shortest_path;
geometry shape <- envelope(roads_shapefile);
matrix od_pairs <- matrix(od_csvfile);
int od_count <- od_pairs.rows;
point source;
point target;
point source_temp1;
point source_temp2;

list<road> roadsList;
init {
// Create road from roads_shapefile - it contains ID, and maxspped for each segment
create road from: roads_shapefile
with: [maxspeed :: float(read('Spd')) #miles / #hour,
road_ID :: int(read('ID'))] ;

road_network <- as_edge_graph(road);

// create a list of roads - this is needed for finding the current road etc.
roadsList <- (road as list);

// **** Uncomment to see the change in real_speed **** //

// // Add time to travel as weights to the map
// map<road, float> map_weights <- road as_map (each::each.shape.perimeter / each.maxspeed);
// road_network_weighted <- copy(road_network with_weights map_weights);

loop i from: 500 to: 500 {
source <- point(road_network.vertices closest_to (point(to_GAMA_CRS({float(od_pairs[3, i]), float(od_pairs[2, i])}, "EPSG:4326"))));
target <- point(road_network.vertices closest_to (point(to_GAMA_CRS({float(od_pairs[6, i]), float(od_pairs[5, i])}, "EPSG:4326"))));
}

// **** Uncomment to see the change in real_speed **** //

// shortest_path <- path_between(road_network_weighted, source, target);
//
// write "Time between source and target:" + shortest_path.weight + " seconds";

create vehicle with: [
shape:: source,
the_target:: target
];
}
}

species vehicle skills: [moving] {
point the_target;
float veh_speed <- 1.0;
road currentRoad;
reflex move {
currentRoad <- (roadsList select (each != currentRoad)) with_min_of (each distance_to self);
// Find the speed of traffic on this road
ask currentRoad {
myself.veh_speed <- self.maxspeed; // Use maxpseed until the speed of traffic is found
write("Vehicle speed: " + myself.veh_speed + " m/s");
}
// Goto the target
path path_travelled <- goto(target: the_target, on: road_network, speed: veh_speed, return_path: true);
write(location);
}


aspect default {
draw circle(1000) color: #magenta;
}
}

species road {
geometry display_shape <- line(shape.points, 2.0);
float maxspeed;
int road_ID;
aspect default {
draw shape color: #black;
}

}

experiment goto_network type: gui {
output {
display objects_display type: opengl {

species road aspect: default refresh: false;
species vehicle aspect: default;

graphics points_display {
draw circle(1000) color: #red at: source;
draw circle(1000) color: #blue at: target;

draw geometry(shortest_path.segments) color: #green width: 4;
}

}

}

}

Model on google drive:
https://drive.google.com/file/d/166z6yJLO2HqKNWsbCkpNMscXWzltRSRq/view?usp=sharing


Thanks
time_to_travel_weighted.rar

Patrick Taillandier

unread,
Mar 7, 2019, 4:08:33 AM3/7/19
to gama-p...@googlegroups.com
Hi,

Your model was almost good, there is just a small mistake when using the copy operator on the graph (Line 41):
road_network_weighted <- copy(road_network with_weights map_weights);
should be:
road_network_weighted <- copy(road_network) with_weights map_weights;

You should first do the copy, then modify the weights of the graph (the weights are directly modified by the operator with_weights).

Cheers,

Patrick


chintan pathak

unread,
Mar 7, 2019, 11:04:05 PM3/7/19
to gama-p...@googlegroups.com
Patrick,

Thanks a lot. This works for me now. The real_speed is as it should be. The default behavior of object copy has trumped me more than once, and coming from C, I do not find it intuitive. :)

Thanks


You received this message because you are subscribed to a topic in the Google Groups "GAMA" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/gama-platform/g7rjqnHG-JU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to gama-platfor...@googlegroups.com.

To post to this group, send email to gama-p...@googlegroups.com.
Visit this group at https://groups.google.com/group/gama-platform.
For more options, visit https://groups.google.com/d/optout.


--
Reply all
Reply to author
Forward
0 new messages