|
#Name: Export ArcGIS Server Map Service Layer to Shapefile with Iterate |
|
#Author: Bryan McIntosh |
|
#Description: Python script that connects to an ArcGIS Server Map Service and downloads a single vector layer |
|
# to shapefiles. If there are more features than AGS max allowed, it will iterate to extract all features. |
|
|
|
import urllib2,json,os,arcpy,itertools |
|
ws = os.getcwd() + os.sep |
|
|
|
#Set connection to ArcGIS Server, map service, layer ID, and server max requests (1000 is AGS default if not known). |
|
serviceURL = "https://domain/arcgis/rest/services" |
|
serviceMap = "/Public/Directory/MapServer" |
|
serviceLayerID = 0 |
|
serviceMaxRequest = 1000 |
|
dataOutputName = "MyShapefile" |
|
|
|
def defServiceGetIDs(): |
|
IDsRequest = serviceURL + serviceMap + "/" + str(serviceLayerID) + "/query?where=1%3D1&text=&objectIds=&time=&geometry=&geometryType=esriGeometryEnvelope&inSR=&spatialRel=esriSpatialRelIntersects&relationParam=&outFields=&returnGeometry=true&returnTrueCurves=false&maxAllowableOffset=&geometryPrecision=&outSR=&returnIdsOnly=true&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&outStatistics=&returnZ=false&returnM=false&gdbVersion=&returnDistinctValues=false&resultOffset=&resultRecordCount=&f=pjson" |
|
IDsResponse = urllib2.urlopen(IDsRequest) |
|
IDsJSON = json.loads(IDsResponse.read()) |
|
IDsSorted = sorted(IDsJSON['objectIds']) |
|
return IDsSorted |
|
|
|
def defGroupList(n, iterable): |
|
args = [iter(iterable)] * n |
|
return ([e for e in t if e != None] for t in itertools.izip_longest(*args)) |
|
|
|
def defQueryExtractRequests(idMin, idMax): |
|
myQuery = "&where=objectid+>%3D+" + idMin + "+and+objectid+<%3D+" + idMax |
|
myParams = "query?geometryType=esriGeometryEnvelope&spatialRel=esriSpatialRelIntersects&relationParam=&outFields=*&returnGeometry=true&geometryPrecision=&outSR=&returnIdsOnly=false&returnCountOnly=false&orderByFields=&groupByFieldsForStatistics=&returnZ=false&returnM=false&returnDistinctValues=false&returnTrueCurves=false&f=pjson" |
|
myRequest = serviceURL + serviceMap + "/" + str(serviceLayerID) + "/" + myParams + myQuery |
|
response = urllib2.urlopen(myRequest) |
|
myJSON = response.read() |
|
# Write response to json text file |
|
foo = open(dataOutputName + idMin + ".json", "w+") |
|
foo.write(myJSON); |
|
foo.close() |
|
# Create Feature Class |
|
arcpy.JSONToFeatures_conversion(dataOutputName + idMin + ".json", ws + dataOutputName + idMin + ".shp") |
|
|
|
#**MAIN**# |
|
#Get all objectIDs (OIDs) for the layer (there is no server limit for this request) |
|
AllObjectIDs = defServiceGetIDs() |
|
#Divide the OIDs into chunks since there is a limit to map queries (assumed limit stored in serviceMaxRequest variable) |
|
ObjectID_Groups = list(defGroupList(serviceMaxRequest, AllObjectIDs)) |
|
#Create a shapefile for each chunk |
|
for ObjectID_Group in ObjectID_Groups: |
|
idMin = str(ObjectID_Group[0]) |
|
idMax = str(ObjectID_Group[-1]) |
|
defQueryExtractRequests(idMin, idMax) |
|
#Append all shapefiles if desired |