-
Nathancoisne authoredNathancoisne authored
1_Buildings and roads environment.gaml 6.70 KiB
/***
* Part of the SWITCH Project
* Author: Nathan Coisne, code inspired from Patrick Taillandier
* Tags: gis, OSM data
***/
model switch_utilities_gis
/*
* Genere les fichiers buildings.shp et roads.shp pour la ville de Marseille
*
* Données requises pour générer les fichiers buildings.shp et roads.shp d'une ville quelconque :
* https://download.geofabrik.de/europe/france.html pour le shp 'initial' des builings
* https://geoservices.ign.fr/documentation/diffusion/telechargement-donnees-libres.html#bd-topo pour le shapefile à partir duquel on extrait les attributs qu'on donne aux buildings initiaux
* Les frontières de la zone considérée
*
*/
global {
string dataset_path <- "../includes/Marseille/";
//define the bounds of the studied area
file data_file <-shape_file(dataset_path + "boundary_Marseille.shp");
//define the initial building shapefile, extracted from OSM database
file shape_file_buildings <- shape_file(dataset_path + "buildings_marseille.shp");
//define the OSM points of interest buildings, for more types
file shape_file_pois <- shape_file("../includes/Marseille/points_of_interest.shp");
//define the building shapefile with many types, extracted from IGN database
file ign_file <- shape_file(dataset_path + "buildings_ign.shp");
//define the initial building shapefile, extracted from OSM database
file shape_file_roads <- shape_file(dataset_path + "roads_marseille.shp");
list<string> shop_places <- ["commercial", "kiosk", "chapel", "church", "service", "Commercial et services", "Religieux", "religious"];
list<string> sport_places <- ["Sportif"];
float min_area_buildings <- 20.0;
int nb_for_building_shapefile_split <- 50000;
int nb_for_road_shapefile_split <- 20000;
list<string> living_places <- ["house", "apartments", "dormitory", "hotel", "residential", "Résidentiel"];
list<string> work_places <- ["industrial", "office", "construction", "garages", "hospital"];
list<string> study_places <- ["university", "college", "school"];
list<string> leisure_places <- ["commercial", "kiosk", "chapel", "church", "service", "Sportif", "Commercial et services", "Religieux", "religious"];
bool parallel <- true;
bool buildings <- true;
bool roads <- false;
geometry shape <- envelope(data_file);
graph the_graph;
map<road,float> road_weights;
init {
write "Start the pre-processing process";
list<int> list_of_id;
if buildings{
create Building from: shape_file_buildings with: [type::get ("type"), id::int(get("osm_id"))]{
if not (self overlaps world) {
do die;
}
list_of_id << id;
if (type != nil and type != ""){
types << type;
}
}
write "Number of buildings created : "+ length(Building);
ask Building where (each.shape.area < min_area_buildings) {
do die;
}
write "Small building removed";
create Building_ign from: ign_file {
if not (self overlaps world) {
do die;
}
}
write "Number of buildings ign created : "+ length(Building_ign);
ask Building parallel: parallel {
list<Building_ign> neigh <- Building_ign overlapping self;
if not empty(neigh) {
Building_ign bestCand;
if (length(neigh) = 1) {
bestCand <- first(neigh);
} else {
bestCand <- neigh with_max_of (each inter self).area;
if (bestCand = nil) {
bestCand <- neigh with_min_of (each.location distance_to location);
}
if (bestCand = nil){
write("aucun building correspondant a ce building ign");
}
}
if (bestCand.USAGE1 != nil and bestCand.USAGE1 != ""){
types << bestCand.USAGE1;
}
else if (bestCand.USAGE2 != nil and bestCand.USAGE2 != ""){
types << bestCand.USAGE2;
}
if (bestCand.HAUTEUR != nil and bestCand.HAUTEUR > 0){
height <- bestCand.HAUTEUR;
}
}
}
create Building from: shape_file_pois with: [id::int(read("osm_id")), type::read("fclass")]{
if not (self overlaps world){
do die;
}
if not (id in list_of_id){
list_of_id << id;
types_str <- type;
types << type;
}
else{ // fclass devient le type du bâtiment déjà existant
Building real_building <- Building first_with (each.id = self.id);
real_building.type <- type;
real_building.types << type;
real_building.types_str <- type + "," + real_building.types_str;
do die;
}
}
ask Building where empty(each.types){
do die;
}
ask Building parallel: parallel {
type <- first(types); //si le building a déjà un type dans le shapefile initial : on le garde en position 1. Sinon on prend celui de building_ign (USAGE1 ou USAGE2)
types_str <- type;
if (length(types) > 1) {
loop i from: 1 to: length(types) - 1 {
types_str <-types_str + "," + types[i] ;
}
}
}
ask Building_ign{
do die;
}
write("All buildings created and typed. Start cleaning roads");
}
if roads{
write("cleaning roads");
list<geometry> clean_lines <- clean_network(shape_file_roads.contents,3.0 , true, true);
write("road shapefile cleaned");
create road from: clean_lines with: [id::int(get("osm_id")), fclass::get("fclass"), maxspeed::int(get("maxspeed"))]{
if not (self overlaps world) {
do die;
}
}
write "Number of roads created : "+ length(road);
}
if buildings{
write("Saving buildings");
save Building to: dataset_path + "buildings.shp" type: shp attributes: ["id"::id,"type"::type, "types_str"::types_str ,"height"::height];
}
if roads{
write("Saving roads");
save road to: dataset_path + "roads.shp" type: shp attributes: ["id"::id,"fclass"::fclass, "maxspeed"::maxspeed];
}
}
}
species Building_ign {
/*nature du bati; valeurs possibles:
* Indifférenciée | Arc de triomphe | Arène ou théâtre antique | Industriel, agricole ou commercial |
Chapelle | Château | Eglise | Fort, blockhaus, casemate | Monument | Serre | Silo | Tour, donjon | Tribune | Moulin à vent
*/
string NATURE;
/*
* Usage du bati; valeurs possibles: Agricole | Annexe | Commercial et services | Industriel | Religieux | Sportif | Résidentiel |
Indifférencié
*/
string USAGE1; //usage principale
string USAGE2; //usage secondaire
int NB_LOGTS; //nombre de logements;
int NB_ETAGES;// nombre d'étages
float HAUTEUR;
}
species Building {
string type;
list<string> types;
string types_str;
float height;
int id;
}
species road {
int id;
int maxspeed;
string fclass;
aspect base {
draw shape color: color width: 2;
}
}
experiment generateGISdata type: gui {
}