Published on NGA Advanced Python Programming for GIS, GLGI 3001-1 (https://www.e-education.psu.edu/ngapython)

Home > Lessons > Lesson 2: Open Source Data > Accessing and working with web data > Accessing GIS Data via REST

Accessing GIS Data via REST

Now that we know some methods for parsing JSON data, let’s look at the REST and how we can use it to generate a url for our code. There are four parameters that we need to fill out for it to return a result.  These four parameters are the Where, Out Fields, and Return Geometry, and return format.  If you need a more specific result, you can enter more parameters as needed.  

The base url for the query is looks like this from Query: BLM California Active Fires 2023 (ID: 0) [1]. 

With the query at the end followed by the ?.  The ? separates the url into sections.  This ? is starting the passing of the parameters, which are separated by & sign.  Note that the url does not contain spaces  

The complete request’s parameters are added to the URL when the request is submitted: 

?where=1=1&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&resultType=none&distance=0.0&units=esriSRUnit_Meter&relationParam=&returnGeodetic=false&outFields=*&returnGeometry=true&featureEncoding=esriDefault&multipatchOption=xyFootprint&maxAllowableOffset=&geometryPrecision=&outSR=&defaultSR=&datumTransformation=&applyVCSProjection=false&returnIdsOnly=false&returnUniqueIdsOnly=false&returnCountOnly=false&returnExtentOnly=false&returnQueryGeometry=false&returnDistinctValues=false&cacheHint=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&having=&resultOffset=&resultRecordCount=&returnZ=false&returnM=false&returnExceededLimitFeatures=true&quantizationParameters=&sqlFormat=none&f=json&token= 

Building our query that will return all features, all fields in json format will look like:

https://www.arcgis.com/apps/mapviewer/index.html?url=https://services3.arcgis.com/T4QMspbfLg3qTGWY/ArcGIS/rest/services/Boulder_Fire_Tax_District/FeatureServer/0/query?where=1=1&outFields=*&returnGeometry=true &f=json  

With this url string, can use request to retrieve data from services and save them locally.  There are a few ways of doing this such as using pandas to read the url, converting the json to a dataframe and then to a featureclass, converting the JSON result to a dictionary and using an insert/update cursor, or creating a new featureclass using the arcpy method JSONToFeatures_conversion(…) method.  It is important to note an important aspect of this method noted in the Summary section of the documentation: 

Converts feature collections in an Esri JSON formatted file (.json) or a GeoJSON formatted file (.geojson) to a feature class. 

This means that the method is expecting a file as the input and trying to pass the response json will results in an error and if you do not need to manipulate the data before outputting to a featureclass, this method might be the simplest to implement with the least amount of packages. If you need to work on the data, such as convert the datetimes for a field, converting the JSON to a dataframe or dictionary would be the preferred process. 

Below is an example of the process.

import arcpy 
import requests 
import json 

arcpy.env.overwriteOutput = True 

url = " https://services3.arcgis.com/T4QMspbfLg3qTGWY/ArcGIS/rest/services/Boulder_Fire_Tax_District/FeatureServer/0/query?where=1=1&returnGeometry=true&outFields=*&f=json" 

# send the request to the url and store the reply as response
response = requests.get(url) 

# Get result as json
jsonCode = response.json() 

jsonFile = r"C:\NGA\Lesson 3\response.json" 

# write the response json to a file
with open(jsonFile, "w") as outfile: 
    json.dump(jsonCode, outfile) 

# JSONToFeatures requires a file as input
arcpy.JSONToFeatures_conversion(jsonFile, r'C:\NGA\Lesson 3\Geog489.gdb\Boulder_Fire_Tax_Dist', 'POLYGON') 

# Clean up
if os.path.exists(jsonFile): 
    os.remove(jsonFile) 

You can also separate the parameters into a dictionary and let requests do the url formatting, making for a cleaner code and this method seems to also format the returned date fields, if there are any:

params = {'where': '1=1', 'outFields': '*', 'f': 'pjson', 'returnGeometry': True} 
response = requests.get(url, params) 

Source URL:https://www.e-education.psu.edu/ngapython/node/858

Links
[1] https://services3.arcgis.com/T4QMspbfLg3qTGWY/ArcGIS/rest/services/_BLM_California_Active_Fires_2023_View_Layer/FeatureServer/0/query?