Problem Set 4 - GIS in Python
Task | Description |
---|---|
Set up | Fetching the data for the exercise, instructions, & tips |
Task 1 | Using geoprocessing tools in Python |
Task 2 | Using geoprocessing tools in a loop |
Task 3 | Using ArcPy functions, classes, and geoprocessing tools |
Task 4 | Describing data in ArcPy; Creating script tools in ArcGIS Pro |
Task 5 | Working with ArcPy geometry objects |
Submission | Submitting your assignment |
Set up
The following tasks refer to data in the zip file “ENV859_PS4.zip
”, available here. This zip file should be uncompressed to your V:
drive to create a V:\ENV859_PS4
workspace. This workspace contains the familiar Data
, Scripts
, Scratch
, and Docs
folders. Within the Data
folder are the datasets needed to do the assignment. Save all scripts in the `Scripts` folder and write your code to send output files to the *scratch* folder unless otherwise specified.
When writing scripts in this exercise, there’s no need to include extensive front matter (e.g., the script name, description, name, date, etc.), but it may be helpful to add comments that briefly describe each step in your script so that we can offer partial credit.
When you’ve completed this assignment, compress your entire workspace folder into a single zip file, being sure to include any requested screen captures in your Docs folder. Rename the zip file using your NetID followed by “_PS4” (e.g. jpfay_PS4.zip
), and submit it via the Assignments section on Canvas.
Some general tips to contemplate as you tackle this assignment:
Use intuitive names for your variables, and use lots of variables.
If you comment out lines for debugging, clean them up before submitting your final scripts.
The construction of a compound if statement requires fully written tests for all conditions.
- Incorrect:
If x == "something" or "another thing"
- Correct:
If x == "something" or x == "another thing"
For multiple tests in an if statement, consider when and where to use parentheses. The following yield different results!
if (x>1 or x<10 and x!=4)
vsif (x>1 or x<10) and (x!=4)
vsif (x>1) or (x<10 and x!=4)
Logic - thinking through the different results from
and
,or
,==
,!=
:
if x != "A" or x != "B"
→ when x is “C” how does this test evaluate? What if x is “A”?if x != "A" and x!= "B"
→ when x is “C” how does this test evaluate? What if x is “A”?
Task 1
Task 1 is a sequence of steps that lead you toward building an interactive Python scripts that implements the ArcGIS’s Buffer tool. Each step is used as a building block to the next step.
References:
- http://pro.arcgis.com/en/pro-app/arcpy/get-started/setting-paths-to-data.htm
- http://pro.arcgis.com/en/pro-app/arcpy/geoprocessing_and_python/using-tools-in-python.htm
- http://pro.arcgis.com/en/pro-app/arcpy/geoprocessing_and_python/using-environment-settings.htm
1a. (5 pts.) Creating the initial buffer script
Write a Python script (Task1a.py
) in your Scripts folder that buffers the Streams.shp
feature class 1000 meters, writing the output to a new feature class called StrmBuff1km.shp
located in the Scratch folder. Include in this script statements that do the following:
-
Creates a string variable that includes the path to the
streams.shp
feature class -
Creates a second string variable that specifies the buffer distance as “1000 meters”
-
Creates a third string variable that sets the path and filename of where the buffer tool should write its output. This should be a file named
StrmBuff1km.shp
located in the Scratch folder. -
Executes the buffer command such that the streams are buffered set buffer distance, in planar (not geodesic) terms, on both sides (the default), with a round end type (the default), and dissolved into a single feature (not the default).
-
At the end of your script, add the following line to display any messages, warnings, or errors to your Python interactive console:
print(arcpy.GetMessages())
NOTE: All inputs and output data references can be ‘hard-coded’ (meaning full pathnames can be typed in the code itself, not passed as user input variables).
1b. (3 pts.) Setting environment values in your script
Copy (or “Save as…”) the above script to a new file (Task1b.py
) and modify it so that it includes the ArcPy environment settings that:
- Sets the ArcPy workspace environment to the
Data
folder in theENV859_PS4
folder; - Allows script outputs to be overwritten.
Also, since the workspace environment variable has been set to the data folder, you should also be able to just specify the stream feature class file name in the buffer tool, not the full path. Make that edit to your script, but keep the output file hard-coded to go to the scratch folder just as in the previous script.
NOTE: When testing new scripts, it’s always wise to restart your interactive session or clear existing variables before running them.
1c. (5 pts.) Enabling user input
Copy the above script to a new file (Task1c.py
) and restart your interactive session. Modify the new script so that:
- The buffer distance and the output feature class values are both specified as user input variables rather than hard wired. (e.g.
distance = sys.argv[]
ordistance = arcpy.GetParameterAsText()
). - The user knows to enter buffer distance input in meters such that he/she can simply enter a numeric value (e.g. “1000”). But code your script so that this number is interpreted as meters, not decimal degrees, miles, km, etc. In other words, convert the user input integer into string that reflects a “linear unit” data type: “
1000
” becomes “1000 meters
”.
The filename of the input stream feature class can remain static as in the previous Task2b.py
script. You can assume that the user will input values without making a mistake (i.e., no need to do any error trapping).
You can also assume that the output filename supplied by the user will include the full file path, e.g. “V:\ENV859_PS4\Scratch\StrmBuff1km.shp
”
NOTE: Recall that to test scripts using parameters for user input, as above, you need to create a “
launch.json
” file and add a line to the “configurations” dictionary with the key of “args” and your input values as strings inside a list (e.g.,"args": ["1000", "V:/ENV859_PS4/Scratch/StrmBuff1km.shp"]
). Also recall, that the script needs to be run in debug mode for the values in thelaunch.json
file to be read into your script.
1d. (4 pts.) Adding auto-generated output names
Copy the above script to a new file (Task1d.py
) and modify it so that the user continues to input the buffer distance as above. This time, however, the output feature class will be generated by the script. (In other words, remove it as a user input in your code.)
Set the buffer output to be saved into the Scratch folder and named buff_1000m.shp
, where the “1000
” in the name reflects whatever the user inputs as a distance. For example, if the user input 550
as the input buffer distance, the output shapefile would be buff_550m.shp
. Again, you can assume that the user will enter a valid input so that no error trapping is required.
1e. (3 pts.) Iterating through buffer distances
Copy your Task1d.py
to a new script called Task1e.py
and tweak it so that, instead of asking the user for a single buffer distance, it buffers the streams distances of 100, 200, 300, 400, and 500 meters, each time renaming the outputs as above, i.e., with the distance in the file names. Continue to use the ArcPy Buffer command (not the “MultipleRing Buffer” tool), and strive for efficiency in your script, meaning avoid simply copying and pasting the Buffer command 5 times in your code. (Really this tweak should take very view edits to your previous script…)
Task 2
(20 pts) The data
folder in the workspace provided contains a feature class of roads (roads.shp
). In this exercise you will write a script that iterates through a set of road type codes, and for each code, extracts the road features having that code and writes them to a new output file using the Select_analysis
tool.
The catch here is that the list of road types to process is supplied as a “multi-value string” (see link below). Thus, you need to parse this string into a list of road code items before you can iterate through them.
The following steps will guide you through the workflow, though you may want to construct (and debug) your script incrementally and not necessarily in the order described below.
References:
- http://pro.arcgis.com/en/pro-app/arcpy/get-started/working-with-multivalue-inputs.htm
- http://pro.arcgis.com/en/pro-app/tool-reference/analysis/select.htm
► Write a script (Task2.py
) that:
- Enables any existing ArcPy outputs to be overwritten
- Creates a string variable containing the path to the
Roads.shp
feature class. - Simulates a ‘multi-value input’ by creating a string variable with the value “
0;201;203
” (i.e. a “multi-value string”) of the road type class values to be processed. - Creates a list variable by splitting the values between the semi-colons in the string created above so the three values each become an item in the list.
- Loops through each item (i.e. each road type value) in this list, and in each iteration:
- Selects features in the
roads.shp
feature class with theROAD_TYPE
attribute matching the value in the list, writing these selected features to a new, separate feature class, ideally with the “road type” value in the name, in theScratch
folder.
(For example, the first iteration will select roads with aROAD_TYPE
= 0 and write them to a new file called “roads_0.shp
”.) - Prints geoprocessing messages to the console (e.g. with
arcpy.GetMessages()
- see the last step in1a.
)
- Selects features in the
Use a ‘for’ loop to accomplish this, and ensure that each result produces a unique output (i.e. so that three distinct shapefiles are created). All outputs should be written to the Scratch folder.
Tip: You may want to begin by writing code that runs the Select tool first, and when that runs well, then put that into a loop…
Also: To get the proper syntax for a query expression, I find it easy to run the tool (e.g. the Select tool) in ArcGIS Pro and then examine the expression in SQL mode. That will reveal what needs to be in single, double, or no quotes….
Lastly: Check your output: you should have three new feature classes in your
Scratch
folder…
🎖️CHALLENGE - 0 pts (bragging rights)
For full credit, use thePath
object (from thepathlib
package) to allow your code to use relative paths. Be sure, however, to convert these Path objects to strings before using them in any ArcPy geoprocessing tool. You will not lose any points by not doing this, but you will lose “bragging rights”.
Additional Tasks in Progress