Search code examples
vectornetlogopatchpopulation

Create turtles according to real population within vectors


I want to create a population in NetLogo. Therefore, I want to create turtles within districts dependent on the population within this district. However, I am not entirely sure how to do that.

I got the population within the district as a patch-value like that:

gis:apply-coverage lor-dataset "GESBEV" population

But when I create the population with this I get the amount of people within a district in every patch instead of the amount of people within every district.

Is there the possibility to get the population value only once per district? I would also be grateful for any sources where I can do some further reading. I haven't found anything on my own.


Solution

  • There's probably a bunch of ways to go about this, but here are two options. First, some example data that I found on Esri Open data- the 2015 population data for Haiti. I extracted the shapefile and associated files into a folder called 'gis'. We'll use the population value found in the `gis:property-name': "POPULATION". With this setup:

    extensions [ gis ]
    
    globals [
      state-layer 
    ]
    
    to setup
      ca
      resize-world 0 110 0 80
      set-patch-size 6.5
      set state-layer gis:load-dataset "gis/Population_2015.shp"
      gis:set-world-envelope gis:envelope-of state-layer
      gis:set-drawing-color white
      gis:draw state-layer 1
      reset-ticks
    end
    

    The first option is to just sprout the entire population (in this case, divided by 1000 to not spawn way too many turtles) at the centroid of each feature.

    to sprout-at-centroid
      foreach gis:feature-list-of state-layer [
        state ->
    
        ; Get the population for this state, divided by 1000
        ; to get a reasonable number
        let pop ( gis:property-value state "POPULATION" ) / 1000
    
        ; get the 'gis:location-of', an x-y list, for the 
        ; centroid of the current state / district
        let center gis:location-of gis:centroid-of state
    
        ; get the patch with the center xy values to sprout pop
        ask patch first center last center [
          sprout pop
        ]    
      ] 
    end
    

    Output looks like this: enter image description here

    Looks pretty good! All turtles are sprouted in the geographic center of each feature. Depending on your dataset however, you may run into problems. Notice that the island in the center is actually part of a multi-part feature, and so the population for that multi-part feature has spawned outside of the boundaries. This may not present a problem for you, depending on the shapes of your districts.

    Option 2 is a little more convoluted, and you may introduce some rounding errors. It's also a lot slower, and depending on the size of your world and population could take a long time / you could run out of memory. First, get the count of your population and the count of patches contained within your districts. Then, divide the population by the patches in the district to get an average population per patch. Then, have each contained-patch sprout that number of turtles:

    to apply-evenly
      foreach gis:feature-list-of state-layer [
        state ->
    
        ; Get the population for this state, divided by 10000
        ; to get a reasonable number
        let pop ( gis:property-value state "POPULATION" ) / 1000
    
        ; Get the patches contained by the state. This is slow!
        ; Using 'gis:intersecting' alone is much faster, but results
        ; in overlaps as geographic boundaries don't align with  patch boundaries
        let target-patches ( patches gis:intersecting state ) with [ gis:contained-by? self state ] 
    
        if any? target-patches [
    
          ; Get the number of turtles that should be in each target-patch:
          let avg-turtles round ( pop / count target-patches )
    
          ; Get the contained patches to sprout the appropriate number of turtles
          ask target-patches [
            sprout avg-turtles
          ]    
        ]
      ] 
    end
    

    Output for this one looks like:

    enter image description here

    But note that it does take much longer with larger populations than the one I used here as an example, especially since I divided by 1000. Also note that if your patches are too big to be contained by a certain district, you will not have any turtles spawn within your district (eg. the smaller islands off the south coast).

    Hopefully this gets you pointed in the right direction!