HOW TO
In some cases, users enable the Feature Access function on map services to allow easy download of data. However, data can be downloaded from a map service in the form of JSON and the JSON code can be converted to a shapefile or Feature Class. This article describes how to do so with a publicly shared map service using ArcPy and other built-in Python libraries.
The following instructions demonstrate how to query a map service for features, write the JSON response to a file, and convert the JSON file to a shapefile using the arcpy.JSONToFeatures_conversion() function. It is possible to use the script as-is, or format them into functions that take a URL argument.
Adjust the query parameters as needed (most, but not all, of the possible parameters are included). Output files are stored in the directory containing the Python script.
# For Python 2 import urllib2, urllib, os, arcpy
# For Python 3 import urllib.parse, urllib.request, os, arcpy, json
username = "adminaccount"
password = "adminpassword"
tokenURL = 'https://machine.domain.com/portal/sharing/rest/generateToken/'
params = {'f': 'pjson', 'username': username, 'password': password, 'referer': 'https://machine.domain.com'}
#For Python 2
req = urllib2.Request(tokenURL, urllib.urlencode(params))
response = urllib2.urlopen(req)
#For Python 3
data = urllib.parse.urlencode(query=params).encode('utf-8')
req = urllib.request.Request(tokenURL, data)
response = urllib.request.urlopen(req)
data = json.loads(response.read())
token = data['token']
url = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3/query?"
#For Python 2
params = urllib.urlencode({'where': '1=1',
'geometryType': 'esriGeometryEnvelope',
'spatialRel': 'esriSpatialRelIntersects',
'relationParam': '',
'outFields': '*',
'returnGeometry': 'true',
'geometryPrecision':'',
'outSR': '',
'returnIdsOnly': 'false',
'returnCountOnly': 'false',
'orderByFields': '',
'groupByFieldsForStatistics': '',
'returnZ': 'false',
'returnM': 'false',
'returnDistinctValues': 'false',
'f': 'pjson'
})
# For Python 3
params = {'where': '1=1',
'geometryType': 'esriGeometryEnvelope',
'spatialRel': 'esriSpatialRelIntersects',
'relationParam': '',
'outFields': '*',
'returnGeometry': 'true',
'geometryPrecision':'',
'outSR': '',
'returnIdsOnly': 'false',
'returnCountOnly': 'false',
'orderByFields': '',
'groupByFieldsForStatistics': '',
'returnZ': 'false',
'returnM': 'false',
'returnDistinctValues': 'false',
'f': 'pjson',
'token': token
}
encode_params = urllib.parse.urlencode(params).encode("utf-8")
# For Python 2 request = urllib2.Request(url, params) response = urllib2.urlopen(request) json = response.read()
# For Python 3 response = urllib.request.urlopen(url, encode_params) json = response.read()
with open("mapservice.json", "wb") as ms_json:
ms_json.write(json)
ws = os.getcwd() + os.sep
arcpy.JSONToFeatures_conversion("mapservice.json", ws + "mapservice.shp")
import urllib2, urllib, os, arcpy
url = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3/query?"
params = urllib.urlencode({'where': '1=1',
'geometryType': 'esriGeometryEnvelope',
'spatialRel': 'esriSpatialRelIntersects',
'relationParam': '',
'outFields': '*',
'returnGeometry': 'true',
'geometryPrecision':'',
'outSR': '',
'returnIdsOnly': 'false',
'returnCountOnly': 'false',
'orderByFields': '',
'groupByFieldsForStatistics': '',
'returnZ': 'false',
'returnM': 'false',
'returnDistinctValues': 'false',
'f': 'pjson'
})
request = urllib2.Request(url, params)
response = urllib2.urlopen(request)
json = response.read()
with open("mapservice.json", "wb") as ms_json:
ms_json.write(json)
ws = os.getcwd() + os.sep
arcpy.JSONToFeatures_conversion("mapservice.json", ws + "mapservice.shp")
import urllib.parse, urllib.request, os, arcpy, json
arcpy.env.overwriteOutput = True
# Specify built-in Portal for ArcGIS account credentials
username = "portaluser"
password = "portalpassword"
tokenURL = 'https://server.domain.com/portal/sharing/rest/generateToken/'
params = {'f': 'pjson', 'username': username, 'password': password, 'referer': 'https://server.domain.com'}
data = urllib.parse.urlencode(query=params).encode('utf-8')
req = urllib.request.Request(tokenURL, data)
response = urllib.request.urlopen(req)
data = json.loads(response.read())
token = data['token']
# Specify REST URL for service JSON to be returned
url = "https://server.domain.com/server/rest/services/servicename/MapServer/0/query?"
params = {'where': '1=1',
'geometryType': 'esriGeometryEnvelope',
'spatialRel': 'esriSpatialRelIntersects',
'relationParam': '',
'outFields': '*',
'returnGeometry': 'true',
'geometryPrecision': '',
'outSR': '',
'returnIdsOnly': 'false',
'returnCountOnly': 'false',
'orderByFields': '',
'groupByFieldsForStatistics': '',
'returnZ': 'false',
'returnM': 'false',
'returnDistinctValues': 'false',
'f': 'pjson',
'token': token
}
encode_params = urllib.parse.urlencode(params).encode("utf-8")
response = urllib.request.urlopen(url, encode_params)
json = response.read()
with open("mapservice.json", "wb") as ms_json:
ms_json.write(json)
ws = os.getcwd() + os.sep
arcpy.JSONToFeatures_conversion("mapservice.json", ws + "mapservice.shp", )
Article ID: 000019645
Get help from ArcGIS experts
Start chatting now