I have animals walk around and a line then connects all the locations that they walked to. The line forms a closed polygon. I also used the graphics extension to fill the polygon for visual purposes. But I don't know how to have all of the patches that fall within the polygon become the territory of the owner (i.e., the animal that formed the polygon). It is possible for patches to be owned by multiple animals. The code below illustrates overlapping polygons. I'd really appreciate any help on this. Thanks!
extensions [graphics]
breed [animals animal]
breed [homeranges homerange]
animals-own
[
Name
X
Y
]
patches-own
[
owner
]
homeranges-own
[
Name
]
to setup
clear-all
random-seed 4
ask patches
[
set owner nobody
set pcolor grey
]
let $colors [brown orange violet sky lime]
let $Name ["t6" "t7" "t8" "t9" "t10"]
ask n-of 5 patches with [(pycor < 10 and pycor > -10) and (pxcor < 10 and pxcor > -10)]
[
sprout-animals 1
[
set shape "circle"
set color item who $colors
set pcolor color
set X (list xcor)
set Y (list ycor)
set Name item who $Name
set owner self
]
]
graphics:initialize min-pxcor max-pycor patch-size
reset-ticks
end
to go
repeat 5
[
ask animals
[
rt 45
fd 2
set X lput pxcor X
set Y lput pycor Y
set pcolor [color] of self
]
]
ask animals
[
pen-up
let tempXY (map [list ?1 ?2] X Y)
graphics:fill-polygon tempXY
; create a turtle, which draws the homerange boundary
hatch-homeranges 1
[
hide-turtle
set Name [Name] of myself
set color [color] of myself
]
; draw the homerange boundary
foreach tempXY
[
ask homeranges with [Name = [Name] of myself]
[
move-to patch (item 0 ?) (item 1 ?)
pen-down
]
]
; connect the last point of the homerange with the first one, to close the polygon
ask homeranges with [Name = [Name] of myself]
[
let lastpoint first tempXY
move-to patch (item 0 lastpoint) (item 1 lastpoint)
]
]
end
If you look at http://netlogo-users.18673.x6.nabble.com/Netlogo-Point-in-Polygon-td4980030.html you'll find a past (2012) discussion of solutions to this problem.
At the end of the thread, Jim Lyons posts a link to a model on the Modeling Commons, but the model doesn't seem to exist there anymore. He's here on Stack Overflow if you want to ask him about it.
An answer was provided in this post: NetLogo - misalignment with imported GIS shapefiles. The polygons are exported as a GIS shapefile and imported back in using the GIS extension. Then the gis:intersecting was used to give a variable to those patches that fall within the GIS-imported polygons.
Related
I want to extract points from line feature from shapefile.
I have search for solutions, it shows that most of people use gis:vertex-lists-of to do this.
For example,
However I got an error message below when I try to do that:
Extension exception: not a VectorFeature:
org.myworldgis.netlogo.VectorDataset#ca24265
error while observer running GIS:VERTEX-LISTS-OF
called by procedure DRAW-CITIES
called by Button 'draw-cities'
Code below:
to draw-cities
gis:set-drawing-color red
gis:draw cities-dataset 1
foreach gis:vertex-lists-of cities-dataset [
a ->
]
end
cities-dataset is a points collection shapefile from Netlogo library ""GIS general examples" model
I don't understand that even I put a points feature in the function, I just got an error.
Do I misuse the function? How can I corectly use it? Thank you.
The reason for the error is because your foreach function is missing the action steps a foreach function looks something like this:
foreach [1 2 3][a -> print a + 1]
If you wanted to do something like the code you linked to then it would look like this:
extensions [ gis ]
globals [ cities-dataset]
breed [ cities city ]
breed [nodes node]
cities-own [ name country population ]
to setup
set cities-dataset gis:load-dataset "C:/Program Files/NetLogo 6.2.2/app/models/Code Examples/Extensions Examples/gis/data/cities.shp"
draw-cities
end
to draw-cities
gis:set-drawing-color red
gis:draw cities-dataset 1
foreach gis:feature-list-of cities-dataset[
i ->
foreach gis:vertex-lists-of i[
j ->
let first-node-point nobody
let previous-node-point nobody
foreach j [
k ->
let location gis:location-of k
if not empty? location [
ifelse any? nodes with [
xcor = item 0 location and ycor = item 1 location
]
[]
[
create-nodes 1[
set xcor item 0 location
set ycor item 1 location
set size 0.23
set shape "circle"
set color 23
set hidden? false
]
]
;to create links
let node-here (nodes with [
xcor = item 0 location and ycor = item 1 location
])
ifelse previous-node-point = nobody
[set first-node-point node-here]
[let who-node 0
let who-prev 0
ask node-here
[create-link-with previous-node-point
set who-node who]
ask previous-node-point[
set who-prev who
]
set previous-node-point one-of node-here
]
]
]
]
]
end
I'm not entirely sure what you're looking to do, but feel free to ask for more help.
This one is long so please bear with me. I have Two rasters in my world, one of a department and one of a very important lake (it was a shape file that I rasterized). I load both rasters and use them to set the variable lake (tota) and the elevation. Then Im trying to set the distance between non lake patches and lake patches but Im getting an error "DISTANCE expected input to be an agent but got NOBODY instead.
error while patch 571 969 running DISTANCE"
This error doesn't make sense to my as the variable im checking is only for those who have tota (water) I know the code will be long and i tried my best to simplify but it is still a bit cluttered
extensions [ gis ]
globals [ world lake show-lake water]
patches-own[
distance-water
tota
]
to draw-tota
let min-elevation gis:minimum-of world
let max-elevation gis:maximum-of world
ask patches [
set elevation gis:raster-sample worldself
if (elevation <= 0) or (elevation >= 0) [
set pcolor scale-color green elevation 2900 max-elevation
]
]
end
to draw-lake
ask patches [
set water gis:raster-sample lake self
if (water >= 0) [
set pcolor blue
set tota 1
]
]
end
to setup-map
set world gis:load-dataset "D:/Geografico/DEM_Lago_Tota.asc"
gis:set-transformation [-72.994844704 -72.835891153 5.418413284 5.648012857666661] [0 1000 0 1000]
set lake gis:load-dataset "D:/Geografico/Lago_Tota_Raster.asc"
draw-tota
draw-lake
end
;;set up conditions
to set-houses
ask patches [
set dano_suelo (1 + random 5) ;;
set distance-lake distance min-one-of patches with [tota = 1] [distance myself]
]; This is the line that is giving me trouble!
set-default-shape turtles "person"
create-turtles 100
end
to setup
ca
resize-world 0 1000 0 1000
;set-lago
; set-predios
set-houses
reset-ticks
end
It is a lot, and unfortunately i dont know how to show you a picture. Any guidance will be appreciated as Im really lost. Thanks in advance.
Edit: Now the names are in English, Tota is the name of the lake in question. Thanks Matteo for the tip.
What I know about your problem indicates that there is not always a patch that fulfills the requirements of min-one-of patches with [tota = 1] [distance myself]. You could try running the code with an added if statement to check for that.
ifelse any? patches with [tota = 1] [
set distancia_agua distance min-one-of patches with [tota = 1] [distance myself]
] [
set distancia_agua "na"
]
As an edit based on your comment:
In order to reduce the number of operations I introduced let tota-edge <...>. This means that you check only once which patches qualify as tota rather than doing it 1002001 times (since every single patch would do this same operation). So 1002001 times instead of 1.004006e+12.
I don't know how big tota itself is but if it is a sizable portion of the world, ask patches with [tota != 1] will speed up your program some more. Finally, I only used the edges of tota since the middle of the lake is never the closest part of the lake to a non-lake patch.
ifelse any? patches with [tota = 1] [
let tota-edge patches with [tota = 1 and any? neighbors with [tota != 1]]
ask patches with [tota != 1] [ set distancia_agua distance min-one-of tota-edge [distance myself] ]
ask patches with [tota = 1] [ set distancia_agua 0 ]
] [
ask patches [ set distancia_agua "na" ]
]
This is my code so far. I only want the turtles to follow the green lines, however they just continue forever in the random direction they are facing when I setup the model.
Code:
extensions [gis]
breed [observer]
turtles-own [ vision-distance vision-width steps green-steps gray-steps attr-prob]
patches-own [land nearest-patch]
to setup
clear-all
create-turtles 10
set-default-shape turtles "butterfly"
ask turtles [set size 25
if pxcor = min-pxcor [die]]
reset-ticks
let view gis:load-dataset "City_Plan_Boundary.shp"
gis:set-world-envelope gis:envelope-of view
foreach gis:feature-list-of view
[
gis:set-drawing-color green
gis:draw ? 1.0
]
end
to go
ask turtles [
count-steps
pen-down
let green_target turtles
let perceived_patches patches in-cone vision-distance vision-width
let patch-under-me patch-here set green_target perceived_patches with [ (pcolor = green and self != patch-under-me) or (pcolor = black and self != patch-under-me)]
ifelse count green_target != 0 [
let target min-one-of green_target[ distance myself ]
let target_heading towards target
move-to patch-at-heading-and-distance target_heading 1 ]
[ fd 1]
]
end
to count-steps
set steps steps + 1
ifelse land = green [set green-steps green-steps + 1][set gray-steps gray-steps + 1] ;;Does not currently account for CYAN Park squares
end
First, your foreach loop that applies your GIS layer is only creating lines in the drawing layer of NetLogo, not actually changing the patches themselves. You'll have to assign some component of the shapefile to the patches themselves for turtles to be able to assess them- look at the "GIS General Examples" model in the Models Library.
Second, pathfinding can be accomplished in a variety of ways, and it really depends on what behaviour you're trying to model. For a few examples, check out the "Look Ahead" example in the Models library, or look at the below toy model for a very simplistic approach:
to setup
ca
ask patch min-pxcor 0 [
set pcolor green
sprout 1 [
set color red
pd
]
spread-right
]
reset-ticks
end
to spread-right
if pxcor < max-pxcor [
ask one-of neighbors with [ pxcor = [pxcor] of myself + 1] [
set pcolor green
spread-right
]
]
end
to go
ask turtles [
let target one-of neighbors in-cone 1.5 90 with [ pcolor = green ]
ifelse target != nobody [
face target
move-to target
] [
rt one-of [ 45 -45 ]
]
]
tick
end
I'm just starting with using Netlogo to create an Agent Based Model. I have two shapefiles I want to use: a network map of a city (line-shapefile) and a point-shapefile of scooters in the city. The idea is to have them drive through the city on the lines of the network shapefile. Since I am new to Netlogo, I only managed to load these shapefiles in my model. Could someone give me a headstart by helping me to create turtles from the scooter registrations (points) and let them move over the network lines. I have found little help so far on the internet and it won't work with trial and error. So far, my code is just this:
extensions [ gis ]
to load
ca
let network gis:load-dataset "Roads_Asmterdam.shp"
foreach gis:feature-list-of network
[ gis:set-drawing-color white
gis:draw ? 0.3
]
let people gis:load-dataset "scooters_Amsterdam.shp"
foreach gis:feature-list-of people
[ gis:set-drawing-color blue
gis:draw people 3
]
end
So, as far as I know, I need a to go function where I want to move the turtles. And I need a function to create possible moving turtles out of the point-shapefile, but also I need to let them know to only use the lines instead of the whole area.
Many thanks in advance!
After loading the lines shape file you need to convert these into a network of agents/turtles and link them. NetLogo doesn't do that for you, you need to iterate over all the features, line segments and coordinates yourself. Then you need to place the scooters onto the coordinates from the line network, and then you can "ask" them to move around.
Here's what I came up with:
extensions [ gis ]
globals [ roads-dataset scooter-dataset ]
breed [ nodes node ]
breed [ scooters scooter ]
breed [ walkers walker ]
walkers-own [ wlocation ]
scooters-own [slocation]
to setup
; reset
clear-all
reset-ticks
; load data set
gis:load-coordinate-system (word "C:/Program Files/NetLogo 5.3.1/app/models/Code Examples/GIS/data/WGS_84_Geographic.prj")
set roads-dataset gis:load-dataset "C:/shape/roads.shp"
set scooter-dataset gis:load-dataset "C:/shape/scooter.shp"
gis:set-world-envelope (gis:envelope-of roads-dataset)
; draw data set
gis:set-drawing-color blue
gis:draw roads-dataset 1
make-road-network
end
to make-road-network
clear-links
let first-node nobody
let previous-node nobody
foreach gis:feature-list-of roads-dataset [ ; each polyline
foreach gis:vertex-lists-of ? [ ; each polyline segment / coordinate pair
foreach ? [ ; each coordinate
let location gis:location-of ?
if not empty? location [ ; some coordinates are empty []
create-nodes 1 [
set color green
set size 1
set xcor item 0 location
set ycor item 1 location
set hidden? true
if first-node = nobody [
set first-node self
]
if previous-node != nobody [
create-link-with previous-node
]
set previous-node self
]
]
]
set previous-node nobody
]
]
; connect adjacent polylines/roads
ask nodes [ create-links-with other nodes in-radius 0.001 ]
end
to add-agents
create-walkers 5 [
set color red
set wlocation one-of nodes
move-to wlocation
]
end
to add-scooters
foreach gis:feature-list-of scooter-dataset [
foreach gis:vertex-lists-of ? [
let location gis:location-of (first ?)
create-scooters 1 [
set color yellow
set size 1
set xcor item 0 location
set ycor item 1 location
let nearest-node min-one-of (nodes in-radius 10)[distance myself]
set slocation nearest-node
move-to slocation
]
]
]
end
to go
ask walkers [
let new-location one-of [link-neighbors] of wlocation
move-to new-location
set wlocation new-location
]
ask scooters [
let new-location one-of [link-neighbors] of slocation
move-to new-location
set slocation new-location
]
end
Some resources and example code I found particularly helpful:
NetLogo Programming Guide & example models about "walking" and "networks" that come with NetLogo
NetLogo Bag of Tricks - Venice Example Code
Duncan Golicher: Importing points into Netlogo and forming a network
My patches contain attributes such as elevation :
set mnt gis:load-dataset "F:/StageM2/Modelisation/Modele/mnt.asc"
gis:apply-raster mnt alt
gis:set-transformation (list 567887.504252 573503.504252 6183200.86463 6187628.86463) (list min-pxcor max-pxcor min-pycor max-pycor)
gis:set-world-envelope gis:envelope-of mnt
and turtles are created from raster of forest :
to import-foret93
set foret-93 gis:load-dataset "F:/StageM2/Modelisation/Modele/foret76_93.asc"
gis:apply-raster foret-93 f93
ask patches with [f93 = 1]
[
set pcolor black
set foret93? true
;ask n-of 2813 patches with [foret93? = true] [ hatch 2813 ]
sprout-arbres 1 [set color pink
set size 4]
]
end
The layers have the same spatial reference : RGF1993, so it is in meters.
Now, I want to create new turtles from existing turtles and randomly in a radius of 150m from the turtle (the new turtle can be hatch at 1m or at 130m). For instance, I ask just one turtle to hatch a turtle at a distance giving by an input box in the interface named dispersal-dist.
to disp-graines
ask turtle 2918
[
hatch-arbres 1
[
let seedX xcor
let seedY ycor
let ran-bear random 360
lt ran-bear
move-to one-of patches in-radius dispersal-dist
set color magenta
set size 15
]
]
end
But the created turtle go further then the dispersal distance giving in meters.
Did I forget something to transforme the netlogo scale in meters ? Or it is another problem?
Thank you in advance for your help !
While your raster dataset is expressed in meters in your case, your patches don't have a real world scale. Assuming your raster has square pixels, you can calculate a patch scale with something like:
let patch-scale (item 1 gis:world-envelope - item 0 gis:world-envelope ) / world-width
You could then use it in your existing code:
move-to one-of patches in-radius dispersal-dist / patch-scale
If your pixels in your raster have different real world height and width, you will have to do the patch-scale for the horizontal and vertical dimension separately.