Controlling turtles’ behavior within the neighboring polygons coming from the shape file

Viewed 41

Would you please help me to solve the following netlogo problem? Following is my problem:

  • Each farmer is represented by a turtle
  • Farmers are created randomly within the county polygon boundary, which is imported from the shape file. The shape file has the attribute that shows farmer no (FarmNo) in each county. These numbers are used to select random farmers (please see the image).
  • I created a text file, Neighbor.text which carry the information on each polygon id and the ids of neighboring polygons.
  • I need to create farmers’ agent sets for each neighboring counties, where within each agent set the number of farmers will be counted by the farmers within their own county and their adjacent neighboring counties.
  • Suppose a farmer has an adoption threshold value of AT. Now a famer will be positive if the adoption rate of a crop among the farmers within the neighborhood is higher than his AT value. The neighborhood is defined by above point (farmers within their county + Neighboring counties).
  • I applied following codes to create the world with the shape file, imported neighborhood information, and created farmers inside the polygons. But, I am missing to created the farmers’ agent sets within the neighboring counties.

enter image description here

extensions [gis]

globals [
  GA-dataset  ;; the shape file
  ]
patches-own [
  ID     ;;patch ID is identical with polygon ID_ID
  farm          ;;number of farmers in each county
  myneighbors  ;;neighboring polygons' 
  AR ;; adoption ratio
    ]
turtles-own [
  tId ; id of each farmer
  AT ; adoption threshold
  tneighbors ; an agentset of its neighbor turtles 
  positive  ; if AR > AT
]

to setup
  ca
  reset-ticks

  set GA-dataset gis:load-dataset "County.shp"
  gis:set-world-envelope gis:envelope-of GA-dataset

  gis:apply-coverage GA-dataset "CODE" ID
  gis:apply-coverage GA-dataset "FARMNO" farm
 
  file-close
  file-open "Neighbor.txt"

  while [not file-at-end?] [
    let x file-read let y file-read
    ask patches with [ID = x ] [
      set myneighbors ( patch-set myneighbors patches with [ID = y ] )
    ]
  ]
file-close

  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 tID who
        set shape "person"
        set color green
        set size 2
        ]
    ]
  ]

 ask turtles [
    set AT random-normal 0.2  0.1920 
    set label precision AT 2
    ]
  ask patches [
  set AR 0
   ]
  ask turtles [
set tneighbors [myneighbors] of patch-here
]
  ;; Draw boundary
  gis:set-drawing-color white
  gis:draw GA-dataset 1

end

to go
  ask turtles [
  set positive count tneighbors with [AT <= AR]
  ]
  if ticks = 11 [stop]
  tick
end
1 Answers

It looks like there are four distinct kinds of entities in this model:

  1. Unit Land Areas
  2. Counties
  3. Farms
  4. (Kinds of) Crops (maybe? or are we looking at just one crop?)
  5. 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
Related