Last active
November 26, 2023 06:04
-
-
Save TheBryanMac/da76aea0b736aa3da99a80408f6db42f to your computer and use it in GitHub Desktop.
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello, Bryan. Thank you very much for those pieces of code! But I'd like to ask you some help. I tried you first code (MapService2Shapefile.py) with success, but this one is not working properly. I changed just the 3 variables that were required:
serviceURL = "https://www.geoservicos1.segeth.df.gov.br/arcgis/rest/services"
serviceMap = "/Luos/LUOS_PLC/MapServer"
serviceLayerID = 0
Am I supposed to do something else?
Thanks again!