Definite number of agents from a GIS file attribute

76 views
Skip to first unread message

Joël

unread,
Sep 10, 2013, 5:25:46 AM9/10/13
to gama-p...@googlegroups.com
Hi,

In the model tutorial_gis_city_traffic, instead of creating 100 people randomly spread in residential buildings (any_location_in (living_place)), I would like to know how to create a definite number of people in each residential building based on an integer attribute in the building shapefile defining the number of inhabitants contained within each object.

Anyone can provide me with a code for version 1.5.1 ?

Thanks in advance, best

j.

Patrick Taillandier

unread,
Sep 10, 2013, 9:46:30 AM9/10/13
to gama-p...@googlegroups.com
Hi,

You can do it like this : 


global {

file shape_file_buildings <- file('../includes/building.shp');

...

init {

create building from: shape_file_buildings with: [type::string(read ('NATURE')), nb_people::float(read('NB_PEOPLE'))] {

if type='Industrial' {

set color <- rgb('blue') ;

                        create people numbernb_people {

set location <- any_location_in (myself);

}

}

...

}

 ...

}

entities {

species building {

string type;

int nb_people;

rgb color <- rgb('gray')  ;

aspect base {

draw shape  color: color ;

}

}

}


Cheers,

Patrick


2013/9/10 Joël <joel...@gmail.com>

--
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 http://groups.google.com/group/gama-platform.
For more options, visit https://groups.google.com/groups/opt_out.

Joël

unread,
Sep 11, 2013, 4:30:38 AM9/11/13
to gama-p...@googlegroups.com
Thanks very much, works great.

But now I have another problem: how can I do to force my people agents to come back to their initial residential building (living_place) after work considering that each building has a single identifier in the shapefile (ID) ?

And beside, how could display the total number of my people agents in the parameter window ? Thanks in advance, cheers

Here is my code:

model tutorial_gis_city_traffic


global {
    file shape_file_buildings <- file('../includes/building.shp');
    file shape_file_roads <- file('../includes/road.shp');
    file shape_file_bounds <- file('../includes/bounds.shp');
    int nb_people <- 0;
    int day_time update: time mod 144 ;
    int min_work_start <- 36;
    int max_work_start <- 60;
    int min_work_end <- 84;
    int max_work_end <- 132;
    int location_id <- 0;
    float min_speed <- 50.0;
    float max_speed <- 100.0;
    float destroy <- 0.02;
    int repair_time <- 6 ;
    graph the_graph;
   
    init {
        create building from: shape_file_buildings with: [Id_bat::int(read ('ID')), type::string(read ('NATURE')), nb_people::int(read('NB_PEOPLE'))] 
        {
            if type='Industrial' {
                set color <- rgb('blue') ;
            }
            if type='Residential' {
                set color <- rgb('red') ;
            }
            if type='' {
                set color <- rgb('white') ;
            }
        let residential_buildings type: list of: building <- list(building) where (each.type='Residential');
        let industrial_buildings type: list of: building <- (building as list) where (each.type='Industrial') ;

        create people number: nb_people {
            set location <- any_location_in (myself);
            set speed <- min_speed + rnd (max_speed - min_speed) ;
            set start_work <- min_work_start + rnd (max_work_start - min_work_start) ;
            set end_work <- min_work_end + rnd (max_work_end - min_work_end) ;
            set living_place <- one_of(residential_buildings) ;
            set working_place <- one_of(industrial_buildings) ;
            }
        }
        create road from: shape_file_roads ;
        let weights_map type: map <- (list (road)) as_map [each:: each.destruction_coeff];
        set the_graph <- as_edge_graph(list(road)) with_weights weights_map;


    }
   
}
entities {
    species building {
        string type;
        int nb_people;
        rgb color <- rgb('gray')  ;
        aspect base {
            draw geometry color: color ;
        }
    }

    species road  {
        float destruction_coeff <- 1.0 ;
        int colorValue <- int(255*(destruction_coeff - 1)) update: int(255*(destruction_coeff - 1));
        rgb color <- rgb([min([255, colorValue]),max ([0, 255 - colorValue]),0])  update: rgb([min([255, colorValue]),max ([0, 255 - colorValue]),0]) ;
        aspect base {
            draw geometry: shape color: color ;
        }
    }
    species people skills: [moving]{
        rgb color <- rgb('yellow') ;
        building living_place <- nil ;
        building working_place <- nil ;
        int start_work ;
        int end_work  ;
        string objective ;
        point the_target <- nil ;
       
        reflex time_to_work when: day_time = start_work {
            set objective <- 'working' ;
            set the_target <- any_location_in (working_place);
        }
        reflex time_to_go_home when: day_time = end_work {
            set objective <- 'go home' ;
            set the_target <- living_place;
        } 
        reflex move when: the_target != nil {
            let path_followed type: path <- self goto [target::the_target, on::the_graph, return_path:: true];
            let segments type: list of: geometry <- path_followed.segments;
            loop line over: segments {
                let dist type: float <- line.perimeter;
                let ag type: road <- road(path_followed agent_from_geometry line);
                ask road(ag) {
                    set destruction_coeff <- destruction_coeff + (destroy * dist / shape.perimeter);
                }
            }
            switch the_target {
                match location {set the_target <- nil ;}
            }
        }
        aspect base {
            draw shape: circle color: color size: 15 ;
        }
    }
}
environment bounds: shape_file_bounds ;

experiment road_traffic type: gui {
    parameter 'Number of people agents' var: nb_people category: 'People' ;
   
    output {
        display city_display refresh_every: 1 {
            species building aspect: base ;
            species road aspect: base ;
            species people aspect: base ;
        }

    }
}

joel chet

unread,
Sep 17, 2013, 4:12:35 AM9/17/13
to gama-p...@googlegroups.com
Hi there,

No one to help on this issue ?

In the meantime, I managed to display the total number of my people agents in the console.

Best

Joël


2013/9/11 Joël <joel...@gmail.com>

--

Alexis Drogoul

unread,
Sep 17, 2013, 4:19:56 AM9/17/13
to gama-p...@googlegroups.com
Hi,

I don’t know the model but it seems to me that each agent knows where it lives and works (variables living_place and working_place). From these variables, if they are correctly initialized, you have access to the whole building agent, and of course its location, etc.

So the algorithm is quite simple : if (end_of_work) then let my target become my living place and do move. Something like that.

Otherwise, regarding the display of the number of agents, you have many choices : if you are in 1.6, you can inspect the different populations from the menu (you can choose « Browse.. »), which gives you access to this information as well as details on each agent, or, in 1.5, you can create a new monitor (or declare it in the model) and enter « length(my_agents) » .

Cheers
Alexis
--
Senior Researcher, UMI UMMISCO 209, IRD & UPMC, France.
Invited Researcher, DREAM, Can Tho University, Viet Nam.
--
alexis....@gmail.com | http://tiny.cc/liqemw
[Vietnam] +84915088155 [France] +33608698845
--
GAMA: https://code.google.com/p/gama-platform/

Joël

unread,
Sep 17, 2013, 4:49:58 AM9/17/13
to gama-p...@googlegroups.com
Thanks for your reply. The algorithm is indeed quite simple but the code doesn't work. My problem is that the living_place variable does not appear to be specific and the consequence is that some people agents go to another living_place rather than the initial one after work. What am I doing wrong ? What could do the trick ?

Best

Joël

Alexis Drogoul

unread,
Sep 17, 2013, 4:53:24 AM9/17/13
to gama-p...@googlegroups.com
Well, it’s perhaps a simple problem of initialization of your agents. I think that if you initialize them like this :


> create people number: nb_people {

> set speed <- min_speed + rnd (max_speed - min_speed) ;
> set start_work <- min_work_start + rnd (max_work_start - min_work_start) ;
> set end_work <- min_work_end + rnd (max_work_end - min_work_end) ;
> set living_place <- one_of(residential_buildings) ;

set location <- any_location_in (living_place);

> set working_place <- one_of(industrial_buildings) ;
> }


They will enter the simulation in their house and go back to it after work as intended.

Joël

unread,
Sep 17, 2013, 5:08:55 AM9/17/13
to gama-p...@googlegroups.com
It seems to do the trick but the initial number of people agents initiated in each residential building (nb_people attribute in the shape_file_building) is wrong and varries at each run... :-(

Alexis Drogoul

unread,
Sep 17, 2013, 5:18:24 AM9/17/13
to gama-p...@googlegroups.com
Well, in that case, consider the logic of your model ; you create all the agents in the global section, using a « nb_people » defined as a global parameter, but you don’t actually use the « nb_people » stored in the residential buildings .

something like

for b over residential_buildings {
create people number: b. nb_people {
… all your create stuff with just one change : …
set living_place <- b;
}}

should work.

Joël

unread,
Sep 17, 2013, 5:28:46 AM9/17/13
to gama-p...@googlegroups.com
Is this v1.6 syntax ? I thought of doing a loop but did not know how to do it in v1.5.1

Alexis Drogoul

unread,
Sep 17, 2013, 5:33:33 AM9/17/13
to gama-p...@googlegroups.com
Hmm.. I guess it should the same syntax. But maybe

for var: b over: residential_buildings

is safer in 1.5.1.

Benoit Gaudou

unread,
Sep 17, 2013, 5:39:05 AM9/17/13
to gama-p...@googlegroups.com
And perhaps with 'loop' instead of 'for' 
loop var: b over: residential_buildings {
  .... 
}
Benoit


2013/9/17 Alexis Drogoul <alexis....@gmail.com>

Alexis Drogoul

unread,
Sep 17, 2013, 5:40:08 AM9/17/13
to gama-p...@googlegroups.com
Oops.

Too much Java these last days :)

Joël

unread,
Sep 17, 2013, 5:47:10 AM9/17/13
to gama-p...@googlegroups.com
We're nearly done... The correct syntax uses loop as suggested by Benoit. But I guess there is still a condition missing to reach my aim.

Consider building A should have 3 people and building C 6 people. The following bit of code displays 9 people in each residential building:


loop var:b over: residential_buildings {
        create people number: nb_people {
        write b;

            set speed <- min_speed + rnd (max_speed - min_speed) ;
            set start_work <- min_work_start + rnd (max_work_start - min_work_start) ;
            set end_work <- min_work_end + rnd (max_work_end - min_work_end) ;
            set living_place <- b;

Alexis Drogoul

unread,
Sep 17, 2013, 5:50:54 AM9/17/13
to gama-p...@googlegroups.com
you forgot the b.nb_people in the create.

Joël

unread,
Sep 17, 2013, 6:09:25 AM9/17/13
to gama-p...@googlegroups.com
ok sorry, but still I have multiple agents :<(

here is the whole init bit of my code:

init {
        create building from: shape_file_buildings with: [type::string(read ('NATURE')), nb_people::int(read('NB_PEOPLE')), no_bat::int(read('NO_BAT'))] 
        {
            if type='Industrial' {
                set color <- rgb('blue') ;
            }
            if type='Residential' {
                set color <- rgb('red') ;
            }
            if type='' {
                set color <- rgb('white') ;
            }
           
        let residential_buildings type: list of: building <- list(building) where (each.type='Residential');
        let industrial_buildings type: list of: building <- (building as list) where (each.type='Industrial') ;

        loop var:b over: residential_buildings {
        create people number: b.nb_people {

            set speed <- min_speed + rnd (max_speed - min_speed) ;
            set start_work <- min_work_start + rnd (max_work_start - min_work_start) ;
            set end_work <- min_work_end + rnd (max_work_end - min_work_end) ;
            set living_place <- b;
            set location <- any_location_in (living_place);
            set working_place <- one_of(industrial_buildings) ;
            }
            }
        let list_people type:list of: people <- list(people);
        set tot_people <- nb_people+tot_people;
        }
        write 'Total number of people: ' +tot_people;

Alexis Drogoul

unread,
Sep 17, 2013, 6:12:36 AM9/17/13
to gama-p...@googlegroups.com
Hi,

I’m sorry but I have no time right now to answer this question. Maybe a bit later or tomorrow !

Good luck

Alexis

Joël

unread,
Sep 17, 2013, 6:15:10 AM9/17/13
to gama-p...@googlegroups.com
No problem, thanks for your time and interest ! Looking forward for any hints when it suits you.

Cheers, j.

Patrick Taillandier

unread,
Sep 17, 2013, 6:23:21 AM9/17/13
to gama-p...@googlegroups.com
You have a lot of errors concerning the delimitation of blocks (several  "}" are misplaced ). Moreover, I did not understand one of your line : 

 let list_people type:list of: people <- list(people);


Can you try this :

init {

        create building from: shape_file_buildings with: [type::string(read ('NATURE')), nb_people::int(read('NB_PEOPLE')), no_bat::int(read('NO_BAT'))]  

        {

            if type='Industrial' {

                set color <- rgb('blue') ;

            }

            if type='Residential' {

                set color <- rgb('red') ;

            }

            if type='' {

                set color <- rgb('white') ;

            }

        }

            

        let residential_buildings type: list of: building <- list(building) where (each.type='Residential');

        let industrial_buildings type: list of: building <- (building as list) where (each.type='Industrial') ;


        loop b over: residential_buildings {

        create people number: b.nb_people {

            set speed <- min_speed + rnd (max_speed - min_speed) ;

            set start_work <- min_work_start + rnd (max_work_start - min_work_start) ;

            set end_work <- min_work_end + rnd (max_work_end - min_work_end) ;

            set living_place <- b;

            set location <- any_location_in (living_place);

            set working_place <- one_of(industrial_buildings) ;

        }

        //let list_people type:list of: people <- list(people); Je comprends pas du tout cette ligne

        set tot_people <- nb_people+tot_people;

        }

        write 'Total number of people: ' +tot_people;


        create road from: shape_file_roads ;

        let weights_map type: map <- (list (road)) as_map [each:: each.destruction_coeff];

        set the_graph <- as_edge_graph(list(road)) with_weights weights_map;


    }



Cheers,


Patrick



2013/9/17 Joël <joel...@gmail.com>

Patrick Taillandier

unread,
Sep 17, 2013, 6:24:15 AM9/17/13
to gama-p...@googlegroups.com
oups... you sould replace : set tot_people <- nb_people+tot_people;
by: set tot_people <- b.nb_people+tot_people;


2013/9/17 Patrick Taillandier <patrick.t...@gmail.com>

Joël

unread,
Sep 17, 2013, 6:37:53 AM9/17/13
to gama-p...@googlegroups.com
Thanks Patrick for  your help, seems to work fine except for the Total number of people result in the console.

set tot_people <- b.nb_people+tot_people; //brings an error

Joël

unread,
Sep 17, 2013, 6:47:34 AM9/17/13
to gama-p...@googlegroups.com
Everything's working properly now. Your code is correct, don't know why the debugger showed an error message at once.

Thanks very much for all your inputs.

Best

Joël
Reply all
Reply to author
Forward
0 new messages