Populating the feature class
In the previous section, you learned how to create a Python Toolbox and add tools. You created a new toolbox called InsertWildfires and added a tool called USGS Download. However, in that exercise, you didn't complete the geoprocessing operations that connect to an ArcGIS Server map service, query the service for current wildfires, and populate the feature class from the data pulled from the map service query. You'll complete these steps in the following section.
Installing pip and the requests module
This section of the application uses the Python requests module. If you don't already have this module installed on your computer, you will need to do this at this time using pip.
The pip is a package manager that serves as a repository and installation manager for Python modules. It makes finding and installing Python modules much easier. There are several steps that you'll need to follow in order to install pip and the requests module. Instructions to install pip and the requests module are provided in the first few steps:
- Open the Environment Variables dialog box in Windows. The easiest way to display this dialog box is to go to Start and then type Environment Variables in the search box. This should display an Edit environment variables for your account entry. Select this item.
- If you don't see a variable called PATH, click on the New button to create one. If you already have a PATH variable, you can just add to the existing content. Select the PATH variable, and click on Edit, and then set the value to
C:\Python27\ArcGIS10.3
;C:\Python27\ArcGIS10.3\Scripts
. The first path will provide a reference to the location of the Python executable and the second will reference the location of pip when it is installed. This makes it possible to run Python and pip from the Command Prompt in Windows. - Click on OK and then click on OK again to save the changes.
- Next, we'll install pip if you haven't already done so in the past. You need to install pip before you can install requests. In a web browser, go to https://pip.pypa.io/en/latest/installing.html and scroll down to the install pip section. Right-click on
get-pip.py
and select Save Link As or something similar. This will vary depending upon the browser you are using. Save it to yourC:\ArcGIS_Blueprint_Python
folder. - Open the Command Prompt in Windows, type python
C:\ArcGIS_Blueprint_Python\get-pip.py
, and press Enter on your keyboard. This will install pip. - In the Command Prompt, type
pip install requests
and press Enter on your keyboard. This will install the requests module. - Close the Command Prompt.
Requesting data from ArcGIS Server
In the following steps, we will learn how to request data from ArcGIS Server:
- Open ArcCatalog and navigate to the location where you've created your Python Toolbox, it would look like following screenshot:
- Right-click on InsertWildfires.pyt and select Edit to display the code for the toolbox.
- First, we'll clean up a little by removing the AddMessage() functions. Clean up your execute() method so that it appears as follows:
def execute(self, parameters, messages): inFeatures = parameters[0].valueAsText outFeatureClass = parameters[1].valueAsText
- Next, add the code that connects to the wildfire map service, to perform a query. In this step, you will also define the
QueryString
parameters that will be passed into the query of the map service. First, import therequests
andjson
modules:import arcpy import requests, json class Toolbox(object): def __init__(self): """Define the toolbox (the name of the toolbox is the name of the .pyt file).""" self.label = "Toolbox" self.alias = "" # List of tool classes associated with this toolbox self.tools = [USGSDownload]
- Then, create the
agisurl
andjson_payload
variables that will hold theQueryString
parameters. Note that, in this case, we have defined aWHERE
clause so that only wildfires where the acres are greater than 5 will be returned. TheinFeatures
variable holds the ArcGIS Server Wildfire URL:def execute(self, parameters, messages): inFeatures = parameters[0].valueAsText outFeatureClass = parameters[1].valueAsText agisurl = inFeatures json_payload = { 'where': 'acres > 5', 'f': 'pjson', 'outFields': 'latitude,longitude,incidentname,acres' }
- Submit the request to the ArcGIS Server instance; the response should be stored in a variable called
r
. Print a message to the dialog box indicating the response as:def execute(self, parameters, messages): inFeatures = parameters[0].valueAsText outFeatureClass = parameters[1].valueAsText agisurl = inFeatures json_payload = { 'where': 'acres > 5', 'f': 'pjson', 'outFields': 'latitude,longitude,incidentname,acres' } r = requests.get(agisurl, params=json_payload) arcpy.AddMessage("The response: " + r.text)
- Test the code to make sure that we're on the right track. Save the file and refresh
InsertWildfires
in ArcCatalog. Execute the tool and leave the default URL. If everything is working as expected, you should see a JSON object output to the progress dialog box. Your output will probably vary from the following screenshot: - Return to the
execute()
method and convert the JSON object to a Python dictionary using thejson.loads()
method:def execute(self, parameters, messages): inFeatures = parameters[0].valueAsText outFeatureClass = parameters[1].valueAsText agisurl = inFeatures json_payload = { 'where': 'acres > 5', 'f': 'pjson', 'outFields': 'latitude,longitude,incidentname,acres' } r = requests.get(inFeatures, params=json_payload) arcpy.AddMessage("The response: " + r.text) decoded = json.loads(r.text)
Inserting data in a feature class with the ArcPy data access module
The following steps will guide you, to insert data in a feature class with the help of the ArcPy
data access module:
- Now, we'll use the
ArcPy
data access module, that isArcpy.da
, to create anInsertCursor
object by passing the output feature class defined in the tool dialog box along with the fields that will be populated:def execute(self, parameters, messages): inFeatures = parameters[0].valueAsText outFeatureClass = parameters[1].valueAsText agisurl = inFeatures json_payload = { 'where': 'acres > 5', 'f': 'pjson', 'outFields': 'latitude,longitude,fire_name,acres' } r = requests.get(inFeatures, params=json_payload) arcpy.AddMessage("The response: " + r.text) decoded = json.loads(r.text) cur = arcpy.da.InsertCursor(outFeatureClass, ("SHAPE@XY", "NAME", "ACRES"))
- Create a
For
loop that you can see in the following code, and then we'll discuss what this section of code accomplishes:def execute(self, parameters, messages): inFeatures = parameters[0].valueAsText outFeatureClass = parameters[1].valueAsText agisurl = inFeatures json_payload = { 'where': 'acres > 5', 'f': 'pjson', 'outFields': 'latitude,longitude,fire_name,acres' } r = requests.get(inFeatures, params=json_payload) arcpy.AddMessage("The response: " + r.text) decoded = json.loads(r.text) cur = arcpy.da.InsertCursor(outFeatureClass, ("SHAPE@XY", "NAME", "ACRES")) cntr = 1 for rslt in decoded['features']: fireName = rslt['attributes']['incidentname'] latitude = rslt['attributes']['latitude'] longitude = rslt['attributes']['longitude'] acres = rslt['attributes']['acres'] cur.insertRow([(longitude,latitude),fireName, acres]) arcpy.AddMessage("Record number: " + str(cntr) + " written to feature class") cntr = cntr + 1 del cur
The first line simply creates a
counter
that will be used to display the progress information in the Progress Dialog box. We then start aFor
loop that loops through each of the features (wildfires) that have been returned. The decoded variable is a Python dictionary. Inside theFor
loop, we retrieve the wildfire name, latitude, longitude, and acres from the attributes dictionary. Finally, we call theinsertRow()
method to insert a new row into the feature class along with the wildfire name and acres as attributes. The progress information is written to the Progress Dialog box and the counter is updated. - Save the file and refresh your Python Toolbox.
- Double-click on the USGS Download tool.
- Leave the default URL and select the
CurrentFires
feature class in theWildlandFires
geodatabase. TheCurrentFires
feature class is empty and has fields forNAMES
andACRES
: - Click on OK to execute the tool. The number of features written to the feature class will vary depending upon the current wildfire activity. Most of the time, there is at least a little activity, but it is possible that there wouldn't be any wildfires in the U.S. as shown in the following screenshot:
- View the feature class in ArcMap. To view the feature class in the following screenshot, I've plotted the points along with a Basemap topography layer. Your data will almost certainly be different than mine as we are pulling real-time data: