Save graph weights to a shapefile

83 views
Skip to first unread message

Chintan Pathak

unread,
Mar 11, 2019, 10:04:37 PM3/11/19
to GAMA
Dear all,

I have weights associated with all edges of the graph. While in the attached case, all the weights are non-zero. In another case, some of the weights might be zero. For example, when trying to denote traffic flow on a road. I want to export a shapefile that contains the weights of the edges, so I can draw the map in a GIS application in line widths proportional to weights or something to denote traffic flow, or a colorbar.

I tried using the "save" statement as below:

save shpfile to:"../results/road_network_weighted.shp" type: "shp" with:[weight:: shortest_path.weight];

But I only get one column in the shapefile, called geometry. I discovered this, when I read the file in R. When I imported this in QGIS, I see nothing in the attribute table.

If a shapefile cannot be saved with weights, is there any other way, I can export the weights, and then overlay it on the map.

Complete code:

/***
* 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);


// 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"))));
}

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

write "Time between source and target:" + shortest_path.weight + " seconds";
write(shortest_path);

create shpfile from: [geometry(road_network_weighted)];
save shpfile to:"../results/road_network_weighted.shp" type: "shp" with:[weight:: shortest_path.weight];

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

// save vehicle to:"../results/vehicle.shp" type:"shp"; //with: [location: the_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 shpfile{
float weight;
aspect k{
draw shape+50 color:#orange;
}
}

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;
}

}

}

}

Also, shared here: https://drive.google.com/file/d/11I_9qPEQn4upQ0se9QX75zAMtsl7YGGS/view?usp=sharing

Thanks

Benoit Gaudou

unread,
Mar 11, 2019, 10:14:14 PM3/11/19
to gama-p...@googlegroups.com
Dear,

We you look in the model library, the models related to the save statement, you can see as an example: 

save building to:"../results/buildings.shp" type:"shp" attributes: ["ID":: int(self), "TYPE"::type];


In addition to access to the weights of a road, the simplest way to it is perhaps to declare the variable map<road, float> map_weights as global.

And write map_weights[self] to get the weight of the current road.

So you get something like: 


save shpfile to:"../results/road_network_weighted.shp" type: "shp" attributes:["weight":: map_weights[self]]; 


Cheers


Benoit


--
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,
Mar 12, 2019, 11:03:32 PM3/12/19
to GAMA
Dear Benoit,

Thank you for your reply. I tried the following things:

1. create shpfile from: [geometry(road_network_weighted)];
save shpfile to:"../results/road_network_weighted.shp" type: "shp" attributes:["weights" :: map_weights];

This saved the file, however, the resulting shapefile still does not show weights as attributes in QGIS/R.

2. Other things I tried that did not work:
create shpfile from: [road_network_weighted];
or
save shpfile to:"../results/road_network_weighted.shp" type: "shp" attributes:["weights" :: map_weights[self]];


While the "Save to SHP" library model worked well for me, I am able to see the attributes in the attribute table, when I try the same ID::int(self) with my shapefile, it doesnt work. Maybe this is because 'graph' is a different type of species.

Thanks

Benoit Gaudou

unread,
Mar 13, 2019, 12:49:36 AM3/13/19
to gama-p...@googlegroups.com
Hi,

As you want to save the roads in the graph, you use: 

save road to:"../results/road_network_weighted.shp" type: "shp" attributes:["weight"::roads_weight[self]]; 


(note that the warning on the self is a kind of GAMA bug, but the statement seems to work in my case).


Cheers


Benoit

Chintan Pathak

unread,
Mar 14, 2019, 3:27:07 AM3/14/19
to GAMA
Dear Benoit,

Thanks a lot for your reply. The solution you suggested works for me. I tried reading the file in R and QGIS and I get the extra column. This clarifies the weights a little as well. So they are not attached to the graph? They are then separate objects and can be mapped during operations, but otherwise correlated with the road object and not the graph object.

Thanks

Benoit Gaudou

unread,
Mar 14, 2019, 3:34:17 AM3/14/19
to gama-p...@googlegroups.com
Hi,

Concerning the link between graph and weight ... I would say that it depends on how you them :-)

For example, in the following piec of code, weights are in the graph (when you use the "with_weights" operator on a graph.

create road from: shape_file_roads ;

map<road,float> weights_map <- road as_map (each:: (each.destruction_coeff * each.shape.perimeter));

the_graph <- as_edge_graph(road) with_weights weights_map;

write the_graph;

loop r over: road {

write the_graph weight_of(r);

}


Cheers

Benoit
Reply all
Reply to author
Forward
0 new messages