I have a polygon feature data set of emergency service zones for Tucson Metropolitan Area and want to copy the polygon attributes to the patches. The code is only creating/coloring these patches.(Picture shown below).
enter image description here
I want to create a patch that covers the entire emergency service zone (second picture shown below)
enter image description here
Here is my code. I tried using the vertex of the polygon and was not successful. I tried using the center of the polygon and I came out with a different output than what I want.
My code is:
to setup-gis ;; copy gis features to patches
clear-patches
show "Loading patches..."
gis:apply-coverage ESZs-dataset "STATION_NO" emergency-zone
foreach gis:feature-list-of ESZs-dataset [ feature ->
ask patches [
let centroid1 gis:location-of gis:centroid-of feature
ask patch item 0 centroid1 item 1 centroid1 [
set emergency-zone gis:property-value feature "STATION_NO"
set pcolor yellow
;show emergency-zone
]
]
]
show "Done"
end
foreach gis:feature-list-of ESZs-dataset [ ;for each polygon
polygon ->
ask patches gis:intersecting polygon [
set emergency-zone (gis:property-value polygon "STATION_NO")
set pcolor yellow ]
]
If I understood well, you want to give attribute values to all the patches that intersecting corresponding polygon.. So you should ask patches that are intersecting with ask patches gis:intersecting
Related
I want to run my NetLogo model to see how the change in landscape scenario 'baseline' and 'future' affects agents' annual travel distance. I have initialized agents on a random patch within their residential postcode boundary.
To be able to compare changes in travel, I should have them initialized from the same patch for both scenarios. I have been trying using random-seed but can't get it to work. I want to run the model for 100 different initial patches but maintain the same patch for each baseline and future scenario in a single run (ideally that is two runs, one with baseline scenario and one future scenario.
When I use random-seed in setup, it initializes agents from different patches for each scenario.
I tried setting a global variable random-seed-turtles and tried 2 runs in behaviour space with two different seeds.
[ "random-seed-turtles" 1 2 ]
[ "landscape-scenario" "baseline" "future"]
It creates turtles from the same patch for each run for baseline but differs for future scenario.
Is there a way to code so that I can have a different initial patch for turtles for each of the 100 runs but same origin for individual runs.
e.g.
run1
baseline my_home = patch 113 224
future my_home = patch 113 224
Also, does the place where you insert the random-seed command matter?
The patch value (landscape availability) changes every tick, reading from a raster prepared for that timestep. Landscape_scenario is a chooser on the interface with the values for 'baseline' and 'future' each reading a different set of rasters. Does this interfere random-seed?
NOTE: The answer below assumes that your situation is such that you want the baseline and the future scenarios to be run as part of a single model iteration.
Also, I propose two (very similar) approaches. The one you'll prefer will depend on your specific situation and needs, that we don't know since you didn't share the structure of your model.
You have to create a turtles-own variable where each turtle will directly store its starting patch.
Then, when you close your baseline scenario and prepare your future scenario, you will have to manually delete all the variables that you want to delete except that variable where turtles stored their starting patch (so, for example, you shouldn't use clear-all or clear-turtles in that passage, because such commands would also clear the turtles-own variable that you want to keep).
To show the approach with an example, see the code below:
globals [
; Put here your gobal variables.
]
patches-own [
; Put here your patches' variables.
]
turtles-own [
my-start
my-value ; I only included this to show that you have to manually clear the turtles' variables EXCEPT from 'my-start'.
]
to setup
clear-all
reset-ticks
; Do here what you need to do to prepare the baseline scenario.
create-turtles 20 [
setxy random-xcor random-ycor
set my-value random 10
set my-start patch-here
]
end
to go
run-model
clear-baseline-scenario
prepare-future-scenario
run-model
end
to run-model
; Put here all the things you need to have to run your model,
; including a stop condition (and ticks, if you want them).
end
to clear-baseline-scenario
clear-globals
clear-patches
reset-ticks
; Now, you also have to manually clear all your turtles' variables EXCEPT
; from 'my-start':
ask turtles [
set my-value 0
]
end
to prepare-future-scenario
; Do here what you need to do to prepare the future scenario,
; and also tell your agents to go to their starting patch:
ask turtles [
move-to my-start
]
end
There is another approach which basically is just the same solution but applied to patches instead of turtles.
In this case, you will have a patches-own variable that signals if a patch is or isn't a starting patch (for example by taking 1/0 value, or TRUE/FALSE if you prefer).
Then, when going from the baseline scenario to the future scenario, you will clear all the things you need to clear except from that patches-own variable (i.e. without using clear-all or clear-patches in that passage, because such commands would also clear the patches-own variable that you want to keep).
This approach is doable if you are not interested in having exactly the same turtle starting on that same patch, but you are happy to have any turtle starting on any of the starting patches.
So it will be something like:
globals [
; Put here your gobal variables.
]
patches-own [
slope ; I only included this to show that you have to manually clear the patches' variables EXCEPT from 'starting-patch?'.
starting-patch?
]
turtles-own [
; Put here your turtles' variables.
]
to setup
clear-all
reset-ticks
; Do here what you need to do to prepare the baseline scenario.
create-turtles 20 [
setxy random-xcor random-ycor
set starting-patch? TRUE
]
ask patches [
set slope random 5
if (starting-patch? = 0) [
set starting-patch? FALSE
]
]
end
to go
run-model
clear-baseline-scenario
prepare-future-scenario
run-model
end
to run-model
; Put here all the things you need to have to run your model,
; including a stop condition (and ticks, if you want them).
end
to clear-baseline-scenario
clear-globals
clear-turtles
reset-ticks
; Now, you also have to manually clear all your patches' variables that you
; want to clear EXCEPT from 'my-start':
ask patches [
set slope 0
]
end
to prepare-future-scenario
; Do here what you need to do to prepare the future scenario,
; and also tell your agents to go to an empty starting patch:
create-turtles 20 [
move-to one-of patches with [(starting-patch?) AND (not any? turtles-here)]
]
end
I'm trying to import a raster grid to NetLogo but am encountering many issues. My raster file is only 57x41 pixels (I want each pixel here to represent a patch) and the world envelope is [-382875 -381135 700185 701445]. I am also trying to match my raster-dataset value to the patch variable fuel-code in a .csv file. However when I run the code (below) I encounter errors. I'm not using a set coordinate projection in netlogo since my original raster is not in an acceptable projection type for NetLogo (I removed the .prj file associated with the raster when importing the .asc file). Below is my code (with included error messages to the code I tried to edit):
extensions [ csv table gis]
globals [ fuel-type-40 fuel-code setrial1]
to dictionary-file ;put in the setup procedure
ca
;load the ascii file
set setrial1 gis:load-dataset "setrial_ascii.asc"
;match dimensions of raster to the dimensions of the Netlogo world
;I've tried each of the below codes independently, not together
resize-world 0 gis:width-of setrial1 0 gis:height-of setrial1 ;ERROR: Java Heap space error
gis:set-world-envelope gis:envelope-of setrial1 ;ERROR: can't modify a patch's coordinates
;below is visuals of width and height of setrial1
print gis:height-of setrial1 ;41
print gis:width-of setrial1 ;57
print envelope-of setrial1 ;[-382875 -381135 700185 701445]
; Load the csv
set fuel-type-40 but-first csv:from-file "fuel-type-40.csv"
;print fuel-type-40
; Pull first value (Fuel-code)
set fuel-code map first fuel-type-40
;print fuel-code
ask patches [
; Randomly set patch 'land cover' for this example. change for raster
gis:apply-raster setrial1 fuel-code
]
end
You might report which errors you are having. Remember to always read the stackoverflow guide to asking questions.
I'd suggest you to focus on using a rasterfile with all your data on it (ESRI files have a .dbf file which supports data), and thus avoid using both extensions. By having a raster file with a defined resolution (e.g. 100 x 100 m), the resize-world function should work smoothly. Try following my answer to this question.
I want to export to raster a NetLogo simulation output based on shp files, using:
to export-GIS
let patches_out nobody
ask one-of patches [set patches_out gis:patch-dataset pcolor]
gis:store-dataset patches_out (word "usos" ".asc")
end
but it outputs:
Extension exception: you must define a coordinate transformation before using any other GIS features
error while patch 17 -10 running GIS:PATCH-DATASET
called by procedure EXPORT-GIS
called by Button 'export-GIS'
How can this coordinate transformation be defined?
Solved the issue adding the following lines at the Setup phase:
set envelope gis:load-dataset "data/land.shp"
gis:set-world-envelope gis:envelope-of envelope
I was wondering in what way you can group variables that patches-own to loop over them? I am using NetLogo 5.3.1.
Specifically I am doing this:
patches-own[some-variable other-variables]
to setup
gis:apply-coverage dataset-1 "some-variable" some-variable
;this line above for 1000 other-variables
end
and I would like to do it like this:
globals [group-variables]
patches-own [some-variable other-variables]
to setup
set group-variables (list some-variable other-variables)
foreach group-variables[
gis:apply-coverage dataset-1 "?" ?
]
end
But this seems to be impossible: setup is now turtle/patch only. I also got the message that gis:apply-coverage is expecting something, but got anything instead.
What other way can I use to group these variables somehow, without slowing the program down?
I have looked at lists, arrays and tables but the problem is the gis:apply-coverage demands a patch variable. This excludes arrays and tables. Lists would need to be defined in a patch context, but the gis:apply-coverage needs to be called in an observer context. The read-from-string variable does not support reading a variable and making a string of everything and then calling run on it does not improve execution speed.
I think the main problem is that you use the ? variable as a string ("?"). This cannot work, because it does not refer to the current foreach loop variable.
Maybe there are better solutions, but I got it to work by using the run primitive, which allows to create a command from a combination of strings and variables.
Here is a short example, using the countries dataset from the GIS code examples:
extensions[gis]
globals [group-vars shp]
patches-own [CNTRY_NAME POP_CNTRY]
to load-multiple-vars-from-shp
ca
; Load Data
set shp gis:load-dataset "C:/Program Files/NetLogo 5.3.1/app/models/Code Examples/GIS/data/countries.shp"
; Print properties
print gis:property-names shp
; Select two properties to write to patch-variable
set group-vars (list "CNTRY_NAME" "POP_CNTRY")
; Loop over group-vars
foreach group-vars
[
; Apply coverage of current variable
run (word "gis:apply-coverage shp \"" ? "\"" ?)
]
; Visualize patch variables to check if everything is working
ask patches
[
set plabel substring (word CNTRY_NAME) 0 1
set pcolor POP_CNTRY
]
end
---- Update with what I got so far and what's left to resolve can be found in point 3 below ----
Using Octave I want to create 30 horizontal box and whisker plots without spread (x-axis) from 30 different GeoTIFF's. This is a sketch of how I would like the plot to look like:
Ideally the best solution for me would be an Octave code (workflow) that would allow me to place multiple GeoTIFFs in one directory and then with one click create a box and whisker plot for all GeotIFFs at once - just like the sketch above.
A GeoTIFF-sample with 3 GeoTIFF's can be downloaded here. The file looks like this in QGIS:
It holds elevation values on band 1 (the ones that each box and whisker plot should be based on, and no data values (-999), the no-data values should be excluded from the plot.
Right now this is what I got:
Using img = imread ("filname.tif") gets the file into Octave. Using hist (img(:), 200); shows that all cells are concentrated around 65300. imagesc (img, [65100 65600]) follwed by colorbar displays the image extent but's it's clear that this way simply doesn't import the real cell values. I can't find a working solution to import GeoTIFF's with cell values, therefor my current work-around is exporting the GeoTIFF from QGIS with gdal_translate -of aaigrid which creates a .asc-file that I manually edit to remove header rows, rename to .csv and load into Octave. That .csv can be found here.
To load it and create a box plot I'm currently using this code (thanks to #Andy and #Cris Luengo):
pkg load statistics
s = urlread ("https://drive.google.com/uc?export=download&id=1RzJ-EO0OXgfMmMRG8wiCBz-51RcwSM5h");
o = str2double (strsplit (s, ";"));
o(isnan (o)) = [];
boxplot (o)
set(gca,"xtick",[])
view([-90 90])
print out.png
The results is pretty close but I'm still failing to: A) load GeoTIFF's directly from a folder. If this is not possible I'm gonna have to modify the code to load all *.csv in a directory to the same box plot and label each plot by filename (which I'm unsure how to accomplish. B) to get the x-axis reversed (going from 200-450, not the other way around). This is caused by the view([-90 90]) that I use to make the box plot horizontal instead of vertical which is needed for layout reasons.
Anyone with any ideas on how to resolve the last adjustments?
---- Background info ----
I have 30 GeoTIFFs containing results from a viewshed analysis, for every 2x2 meter square there is a value the tells me how high a building can be (in meters) before it's visible from the viewshed point. The results cover the whole city of Stockholm but the above mentioned 30 GeoTIFFs are smaller clips of an area where new development is planned. The results help planners to understand how new development might effect each of the 30 places (that are important for cultural heritage management).
As part of a bigger PDF-report (where these results are visualized with different maps in different scales) I'm trying to produce a box and whisker plot (as a compliment to the maps) the gives the reader an overview over how much space is there is left at the planned development area, based on each of the 30 viewshed (GeoTIFF) results (one box and whisker for each of the 30 locations). Below is an example of how a map in the report can look like:
Does not directly read GeoTIFF but calls gdal_translate under the hood. Just place all your .tif in the same directory. Make sure gdal_translate is in your PATH:
pkg load statistics
clear all;
fns = glob ("*.tif");
for k=1:numel (fns)
ofn = tmpnam;
cmd = sprintf ('gdal_translate -of aaigrid "%s" "%s"', fns{k}, ofn);
[s, out] = system (cmd);
if (s != 0)
error ('calling gdal_translate failed with "%s"', out);
endif
fid = fopen (ofn, "r");
# read 6 headerlines
hdr = [];
for i=1:6
s = strsplit (fgetl (fid), " ");
hdr.(s{1}) = str2double (s{2});
endfor
d = dlmread (fid);
# check size against header
assert (size (d), [hdr.nrows hdr.ncols])
# set nodata to NA
d (d == hdr.NODATA_value) = NA;
raw{k} = d;
# create copy with existing values
raw_v{k} = d(! isna (d));
fclose (fid);
endfor
## generate plot
boxplot (raw_v)
set (gca, "xtick", 1:numel(fns),
"xticklabel", strrep (fns, ".tif", ""));
view ([-90 90])
zoom (0.95)
print ("out.png")
gives