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.
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
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:
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!