It looks like there are four distinct kinds of entities in this model:
- Unit Land Areas
- Counties
- Farms
- (Kinds of) Crops (maybe? or are we looking at just one crop?)
- Adopted Crops (maybe? or are we looking at just one crop?)
Unit Land Areas (ULA)
- Are spatially arranged and fixed in location
- Provide location of farms
- Contain county ID information from the source data
- So can be used to define the counties
- Implemented as patches
Counties
- Encompass ULAs (patches)
- Defined by a county ID on the ULA in the source data
- So, inherit spatial information from the ULAs
- Have a relationship with adjacent counties, defined in a text file
- Maintain records of crop adaption rates among farmers in the county
- Implemented as a breed of turtles, one per county.
Farms
- Located in a ULA (patch)
- Adopt Crops from the Kinds of Crops
- Are also in a county
- Are influenced by the choices of other farms...
- including those from adjacent counties
- Implemented as a breed of turtles - one per farm.
Crops
- Defines what crops are available to farms
- an archetype
- Used by counties to maintain records of adoption rates
- Can count adoption rates for its Kind of crop
- Implemented as a breed of turtles, one per kind of crop
- Farms link to Kinds of Crops
Adopted Crops
- Adopted by a Farm
- Needs to be countable
- Implemented as a directed link breed, one per crop adopted by a farm
- Farms use this to link to Kinds of Crops
- If adopted crops have any statistics (percent of production, value per ULA, whatever), they are owned by the Adopted Crop link.
- Farms may adopt more than one kind
- Can also be used by Counties to easily manage per-crop statistics
- terrible name, sorry, maybe "plantings" or "selections" or something else instead?
With these you can easily get answers like:
- What is most AR for each kind of crop considering farmers in this county and neighboring counties?
- What crop has the highest AR in the neighborhood?
- What is the total adoption rate for each kind of crop in all counties?
These questions would asked in code like:
;; show top neighborhood crop for each county
ask counties
[
show [ label ]
of max-one-of
crops
[ count
[ my-adopted-crop-neighbors ]
of [ neighborhood-farms ]
of myself
]
]
Looks complex, but made of simple pieces based on the relationships.
Note: There's plenty of room for human confusion because of NetLogo's own uses of "neighbors" for patches and links, and the model's use of "neighbors" and "neighborhood" for counties. Consider using an alternate word, or wrap netlogo's confusing names in less-confusing reporters. Like to-report my-plantings report my-adopted-crop-neighbors end
To be clear: unless you want specifically to visualize something, only patches and farms are visible (and even farms should probably just be a colored square, perhaps indicating top-crop adoption).
Even if there is only one kind of Crop, and it's a yes/no question, you can still make use of the kinds and adopted breeds for bookkeeping.
The code that follows is an example of how such a system of agents might be set up. As it is, it compiles without errors. Feel free to use anything that helps.
extensions [gis]
globals
[
GA-dataset ;; the shape file
]
breed [ Counties County ]
breed [ Farms Farm ]
breed [ Crops Crop ]
directed-link-breed [ Adopted-Crops Adopted-Crop ]
patches-own
[
p-ID ;; ID of the patch's county from the source data
p-county ;; points to the patch's county turtle
farm-count ;; count of farms in this patch
AR ;; adoption ratio (is this a patch-level value or a county one?)
]
farms-own
[
f-ID ;; ID of the county from the source
f-County ;; points to the farm's county turtle
AT ;; adoption threshold (per crop?)
;; (is this a farm-level value or a county value?)
;; is this one value or set of values? (ie, all the crops)
;; if this is per-crop (a list), then this is eliminated
;; by the adopted crops
positive ;; if AR > AT ;; same-- this may be a per-crop value
]
Crops-Own
[ ;; label ;; use the built in label for values like "oranges" or "corn"
;; add variables as needed for things like..
;; cost
;; market-value
;; adoption-preference
;; etc.
]
Adopted-Crops-Own
[ ;; add variables for per-farm or per-county things like:
;; % of production
;; production amount?
;; label -- copy the label from the Crop,
;; this will probably be convenient to have
]
counties-own
[ county-ID ;; ID number of the county from Source
county-patches ;; patches in this county
border-patches ;; set of patches on the border of the country
;; useful to draw the map
;; and later may be useful for visualization
;; that needs to highlight a county
county-farms ;; farmers in this country
county-crops ;; unless it frequently changes membership,
;; the set of all adopted-crops links for all my farms
adjacent-counties ;; set of counties sharing a border
adjacent-farms ;; set of farms from those counties
neighborhood ;; set of this and adjacent counties
neighborhood-farms ;; farms in this and adjacent counties
neighborhood-crops ;; crops adopted in this and adjacent counties
;; any other county-level variables, like adoption rate history
]
to setup-patches-from-GIS
set GA-dataset gis:load-dataset "County.shp"
gis:set-world-envelope gis:envelope-of GA-dataset
gis:apply-coverage GA-dataset "CODE" p-ID
gis:apply-coverage GA-dataset "FARMNO" farm-count
end
to setup-counties
let list-of-county-ids remove-duplicates [ p-ID ] of patches
foreach list-of-county-ids
[ $ID ->
create-counties 1
[ set county-ID $ID
set county-patches patches with [ p-ID = $ID ]
]
]
end
to setup-county-neighbors
ask counties
[ set adjacent-counties no-turtles
]
file-close-all
file-open "Neighbors.txt"
while [ not file-at-end? ]
[
let $a file-read
let $b file-read
let $AA one-of counties with [ county-ID = $a ]
let $BB one-of counties with [ county-ID = $b ]
ask $AA [ set adjacent-counties ( patch-set $BB adjacent-counties) ]
ask $BB [ set adjacent-counties ( patch-set $AA adjacent-counties) ]
]
set neighborhood ( patch-set self adjacent-counties )
file-close
end
to setup-crops
let crop-list
[
[ "apples" ] ;; include any other per-crop values to initialize
[ "oranges" ] ;; you could also store this list is a file
[ "rice" ]
[ "beans" ]
[ "coffee" ]
]
foreach crop-list
[ crop-data-row ->
create-Crops 1
[ hide-turtle
set size 0
set color black
set heading 0
set label item 0 crop-data-row
;; set other-property item 1 crop-data-row
;; etc
]
]
end
to setup-farms
;; this is confusing... did we not already
;; load ID and farmno into the patches?
;; so.. can we just use that?
ask patches with [ farm-count > 0 ]
[ sprout-farms farm-count
[ set f-ID p-ID
set f-county p-county
set shape "person"
set color green
set heading 0
set size 0
]
]
;; setup adopted-crops
ask farms
[ create-adopted-crops-to crops
[ hide-link
]
]
;;foreach gis:feature-list-of GA-dataset
;;[ feature ->
;; let target-patches ( patches gis:intersecting feature )
;; with [ gis:contained-by? self feature ]
;; ;; Get the number of turtles that should be in each target-patch:
;; let farm1 round gis:property-value feature "FarmNo"
;; if any? target-patches
;; [
;; gis:create-turtles-inside-polygon feature turtles farm1
;; [
;; set t-ID who
;; set shape "person"
;; set color green
;; set size 2
;; set t-county one-of counties with [ county-ID =
;; ]
;; ]
;; ]
end
to setup-farm-data
ask farms
[
set AT random-normal 0.2 0.1920
set label precision AT 2
]
ask patches
[
set AR 0
]
end
to update-county-datasets
ask counties
[ let this-ID county-ID
set border-patches county-patches with
[ any? neighbors with [ p-ID != this-ID ]
]
set county-farms farms-on county-patches
set county-crops (link-set [ my-adopted-crops ] of county-farms)
]
ask counties
[
set adjacent-farms (turtle-set [ county-farms ] of adjacent-counties)
set neighborhood-farms (turtle-set [ county-farms ] of neighborhood)
set neighborhood-crops ( link-set [ my-adopted-crops ] of neighborhood-farms)
]
end
to draw-boundaries
;; Draw boundary
gis:set-drawing-color white
gis:draw GA-dataset 1
end
to setup
setup-patches-from-GIS
setup-counties
setup-county-neighbors
setup-crops
setup-farms
setup-farm-data
update-county-datasets
draw-boundaries
end