Statistical mean of polygon areas in a landscape - netlogo

I have a landscape with polygons composed of several patches.
The polygons are numbered from 1 to 80. I calculated the polygon area (in ha) as follows :
to calculate-polygon-area
let patch-area 0.01 ;; one patch = 0.01 ha
let list-ID-polygon ( [plabel] of patches )
set list-ID-polygon remove-duplicates list-ID-polygon
set list-ID-polygon remove "" list-ID-polygon
foreach list-ID-polygon [
ask patches with [plabel = ?] [
set polygon-area count patches with [plabel = ?] * patch-area ] ]
end
I would like to calculate the statistical mean of polygon areas in my landscape. How can I define the list with the area of each unique polygon because
mean [polygon-area] of patches
gives the mean of areas by patch ?
Thank you very much for your help.

Instead of going through the patches, you can just get it from the polygon ids. To do so, you can use map to return the area of each polygon, and then just use mean on that:
mean map [ count patches with [ plabel = ? ] * patch-area ] list-ID-polygon

Related

calculate the total move distance of one turtle

I am new to Netlogo and learning a model is about animals moving around to eat grass based on the grazing model from NetLogo. The moving behavior is based on the biomass's richness, so it is not just impacting at right angles.
Given the conditions, I don't know how to add a monitor in my model that calculates the total distance a turtle moved by traveling each pixel.
Move specifically, I wonder if there is a way to calculate the total length of the pen-marked lines. (Show in the picture)
enter image description here
The basic setting of move is
to move-turtles
uphill-biomass
forward 1
set distance-traveled (distance-traveled + 1)
if not can-move? 1 [ rt random 150 ]
end
to uphill-biomass
let biomass-ahead biomass-scent-at-angle 0
let biomass-right biomass-scent-at-angle 35
let biomass-left biomass-scent-at-angle -35
if (biomass-right = biomass-ahead) and (biomass-left = biomass-ahead) [ wiggle ]
if (biomass-right > biomass-ahead) or (biomass-left > biomass-ahead)
[ ifelse biomass-right > biomass-left
[ rt 35 ]
[ lt 35 ] ]
end
Thank you very much for any helps!
You need to use some turtle variables with the turtles-own primitive and do the distance calculation by hand.
The easiest way to do such a calculation is to save the coordinates between a turtle's previous coordinates with turtle variables and then use the distancexy primitive (link for dictionary entry: https://ccl.northwestern.edu/netlogo/docs/dictionary.html#distancexy)
Here's a simple implementation:
turtles-own [last-x last-y distance-traveled]
move-turtle
uphill-biomass
set last-x xcor
set last-y ycor
forward 1
set distance-traveled (distance-traveled + (distancexy last-x last-y))
if not can-move? 1 [ rt random 150 ]
end
I hope this answers your question.

Adding obstacles and targets from shapefile in netlogo

I am new to NetLogo, so my apologies in advance if that question is very stupid. I would like to create an Agent-Based Model where animals move around in a complex terrain looking for water sources. Movement should be downhill, constrained by steep slopes (>25°) and targets should be lakes. I am using a real-world example from GIS data for this, and I have already managed to setup a world containing an ASCII elevation grid, a shapefile containing lines that represent slopes steeper 25degrees and a shapefile containing areas representing lakes. I have created animals (cows) and found a code line telling them to move downhill. Now, I would like to tell them
a) to avoid slopes >25° by using the slope shapefiles as obstacles and
b) to go to the lakes by using the lake shapfiles as targets
Can someone help me how to code this?
Many thanks in advance!
Here is the code I have put together so far
breed [ cows cow ]
extensions [ gis ]
patches-own [ elevation ]
globals [
slope-dataset
lake-dataset
elevation-dataset
]
to setup-terrain
clear-all
reset-ticks
set slope-dataset gis:load-dataset "FILENAME.shp" ;;extent of GIS datasets is N42.3-43.4 and W120.0-121.1
set lake-dataset gis:load-dataset "FILENAME.shp"
set elevation-dataset gis:load-dataset "FILENAME.asc"
gis:set-world-envelope gis:envelope-of slope-dataset
gis:set-world-envelope gis:envelope-of lake-dataset
gis:set-world-envelope gis:envelope-of elevation-dataset
end
to display-slopes
gis:set-drawing-color red
gis:draw slope-dataset 0.5
end
to display-lakes
gis:set-drawing-color blue
gis:draw lake-dataset 2
end
to display-elevation-in-patches
gis:apply-raster elevation-dataset elevation
let min-elevation gis:minimum-of elevation-dataset
let max-elevation gis:maximum-of elevation-dataset
ask patches
[ ; note the use of the "<= 0 or >= 0" technique to filter out
; "not a number" values, as discussed in the documentation.
if (elevation <= 0) or (elevation >= 0)
[ set pcolor scale-color black elevation min-elevation max-elevation ] ]
end
to setup-cows
set-default-shape cows "cow"
create-cows 100 [
setxy random-pxcor random-pycor
set size 1
set color white
]
end
to move
move-to patch-here ;; go to patch center
let p min-one-of neighbors [elevation]
if [elevation] of p < elevation [
face p
move-to p ;; makes cows move to the next lower elevation patch, if no lower
elevetion is present, cow doesn't move
]
end
to go
ask cows [
move
]
end
Thanks Seth, I have found the solution using the gis:intersects? primitive you suggested:
to display-slopes
ask patches gis:intersecting slope-dataset
[ set pcolor red ]
end
to go
ask cows
[fd 1
avoid-ostacles]
tick
end
to avoid-obstacles
ask cows [
if [pcolor] of patch-ahead 1 = red
[rt 90 fd 1]]
end
This way I can color the patches in red that intersect with the shapefile containing the slope vector dataset and then ask the cows to avoid and move around red colored patches.
Thanks again!

Find the nearest polygon patches from edge to edge distance calculated between two polygons

My objective is to find the nearest polygon patches from edge to edge distance calculated between two polygons. From edge to edge distance between patches with netlogo, here is my code to find the nearest polygon edges:
to-report calculate-distance [ID-polygon-A ID-polygon-B]
let polygon-distance nobody
let edges-of-polygon-A create-edge-turtles ID-polygon-A
let edges-of-polygon-B create-edge-turtles ID-polygon-B
set polygon-distance min [ min [ distance myself ] of edges-of-polygon-B ] of edges-of-polygon-A
## find the nearest edge in the polygon A
let nearest-edge-in-polygon-A edges-of-polygon-A with-min [ min [ distance myself ] of edges-of-polygon-B]
ask nearest-edge-in-polygon-A [
set color red
set shape "x"
set size 2 ]
## find the nearest edge in the polygon B
let nearest-edge-in-polygon-B edges-of-polygon-B with-min [ min [ distance myself ] of edges-of-polygon-A]
ask nearest-edge-in-polygon-B [
set color red
set shape "x"
set size 2 ]
ask edges-of-polygon-A with [ shape = "dot"] [ die ]
ask edges-of-polygon-B with [ shape = "dot"] [ die ]
report polygon-distance
end
From How to find a patch with a specific ID where there is a red turtle?, here is my code to find the nearest patches from the nearest edges:
show patches with [ ID-polygon = [ my-ID-polygon ] of myself and any? (turtles-here with [ color = red and shape = "x" ])
I don't understand why I obtain :
(agentset, 1 patch)
(agentset, 0 patches)
However, the two turtles with shape = "x" are well-visible on the polygons. If my code is not correct, is there another way to find the two nearest polygon patches based on distance ?
Thanks in advance for your help.

Creating a random shape (blob) of a given area in NetLogo

Is it possible to create random shapes (see below for example) of a given area in NetLogo?
A first stab at Seth's suggestion #1. It creates a neat visual too!
patches-own [ height ]
to blobbify
clear-all
repeat (ceiling 2 * (ln (world-height * world-width))) [
ask patch (round (random (world-width / 2)) - world-width / 4)
(round (random (world-height / 2)) - world-height / 4)
[ set height world-width * world-height ] ]
while [ count patches with [ height > 1 ] < (world-width * world-height / 4)]
[ diffuse height 1
ask patches with [ height > 0 ] [ set pcolor height ]
]
ask patches with [ height > 1 ] [ set pcolor white ]
end
I found a really simple approach that produces pretty nice results.
Create a turtle. The turtle performs a random walk. After each step, they set the uncolored patch closest to them to the desired color. The turtle does this a number of times equal to the desired area.
Here's the code:
to make-blob [ area ]
let blob-maker nobody
crt 1 [ set blob-maker self ]
repeat area [
ask blob-maker [
ask min-one-of patches with [ pcolor = black ] [ distance myself ] [ set pcolor blue ]
rt random 360
fd 1
]
]
ask blob-maker [ die ]
end
This naturally produces nicely curved blobs.
Making the turtle's step size smaller makes the blob more circle-y. Making it bigger results in thinner, more sporadic blobs (though you run the risk of getting disconnected patches).
Edit:
I noticed that my answer runs quite slowly when you have a gigantic number of patches. Here's a much faster version:
to make-blob [ area x y ]
let blob-maker nobody
crt 1 [ set blob-maker self setxy x y ]
let border patch-set [ patch-here ] of blob-maker
repeat area [
ask blob-maker [
ask min-one-of border [ distance myself ] [
set pcolor green
set border (patch-set border neighbors4) with [ pcolor = black ]
]
rt random 360
fd .8
]
]
ask blob-maker [ die ]
end
Generating random blobs is a hard problem with no obvious solution. Fixing the area of the blob makes it even harder.
You'll need to pick an approach, then try to figure out how to express that approach in NetLogo code.
As for what approach to pick, I imagine there's literature on this if you search. But just off the top of my head, I have three ideas:
Scatter random points around the world, use diffuse to make a smooth landscape around these peaks. (See the Diffusion Graphics model, in the Art section of NetLogo's Models Library, for code for this; you'll want to turn world wrapping off, though.) Then select only those patches where the "elevation" exceeds some threshold. To get the desired area, vary the threshold until the target is reached.
Draw a curve around the center point using polar coordinates, where theta goes from 0 to 360 and 4 varies randomly. You'll need a way to get smooth random variation in the radius, perhaps by generating random numbers and then applying a smoothing function to them. In order to force the blob to have the desired area, first generate the whole curve, then scale it as needed. You'll need some trick to avoid a discontinuity where theta = 0, perhaps by using a smoothing function that wraps.
Generate a random polygon by scattering points around the world, then discarding some or all points in the middle. (You could take the convex hull, but then you'll always get a convex shape, which might not be "blobby" enough for you. So you might want to something like like generating n random points and then keeping the m points that are farthest from the center, without regard to convexity.) Once you've got the random polygon, apply some smoothing function to turn it into a curvy blob. Then scale the whole thing as necessary to get the desired area.

edge to edge distance between polygons that are situated within a buffer

I would like to calculate edge to edge distance between a polygon in which is situated a turtle and each polygon that is situated in a radius of 2 km around the polygon in which is situated the turtle. The polygons are represented by different IDs and each polygon is composed of several patches. I obtain a error message with the following code "FOREACH expected this input to be a list, but got an agentset instead". I don't understand why "patches with [plabel = ID-polygon])" is not a list ? In fact, I would like to select all patches of which label is equal to label of the polygon.
Thank you for your help.
to-report create-edge-turtles [ID-polygon]
let edge-turtles nobody
ask ID-polygon [
foreach (patches with [plabel = ID-polygon]) [
foreach sort neighbors [
sprout 1 [
if [plabel] of neighbors != ID-polygon [
face ?
fd distance ? / 2
set edge-turtles (turtle-set edge-turtles self)] ] ] ] ]
report edge-turtles
end code here
to-report edge-distance-between-polygons-in-buffer [indvidual]
ask individual [
set list-ID-polygon-in-buffer ([plabel] of patch-here in-radius 2)
set list-ID-polygon-in-buffer remove ([plabel] of patch-here) list-ID-polygon-in-buffer
foreach list-ID-polygon-in-buffer [
let ID-polygon-with-individual ([plabel] of patch-here)
let ID-polygon-in-buffer ?
let edges-polygon-with-individual create-edge-turtles ID-polygon-with-individual
let edges-polygon-in-buffer create-edge-turtles ID-polygon-in_buffer
set distance-patches min [ min [ distance myself ] of edges-polygon-in-buffer ] of edges-polygon-with-individual
ask edges-polygon-with-individual [ die ]
ask edges-polygon-in-buffer [ die ] ] ]
report distance-patches
end
The command
patches with [plabel = ID-polygon]
returns an agentset, not a list. To turn an agentset into list simply use the sort keyword, as such
sort patches with [plabel = ID-polygon]