As Arcgis for server has not a built in download shapefile(or any other format) functionality the "clip and ship" geoprocessing example is being suggested by many users and developers. However I find it quite limiting. As far as I understand, the "Extract Data" tool requires first to be run with a pre-defined set of Layers as a "Parameter" just like the "Zion" example.
What I (and many other developers) need is a script/service that takes an Arcgis Server service as an input (or a relevant js object like featureset) and returns a shapefile (or any other format) as an output. Of course I am referring to a client web application. I am using the Javascript API but if I am not mistaken Flex developers face the same issue. Thanks.
HI Periklis,
You can do what you want with one geoprocessing tool: JSON to Feature . Here is the workflow:
1) Create the python script to Query input Map or Feature Service (send request to Query Endpoint). Pass the output JSON to arcpy.JSONToFeatures_conversion tool. Zip the output shape and expose it as GPDataFIle as an output parameter
2) Share the script as a Geoprocessing Service
Regards,
Adam
Thanks Adam, that simplified things a lot. You actually don't need to use JSON to Feature tool. You can save it directly to shapefile. I will put the code below.
However I am still frustrated that I have to go through the service to get to the file instead of doing that in the background. Geoserver has that functionality built in ![]()
In any case, if anyone wants to use the script below they will probably want to add a return string with the file name according their needs.
import arcpy
from arcpy import env
import zipfile
import sys
import os
import glob
from random import randint
baseURL= arcpy.GetParameterAsText(0)
where = '1=1'
fields ='*'
token = ''
#The above variables construct the query
query = "?where={}&outFields={}&returnGeometry=true&f=json&token={}".format(where, fields, token)
fsURL = baseURL + query
fs = arcpy.FeatureSet()
fs.load(fsURL)
fs.save(arcpy.env.scratchFolder+"\\"+"download_file.shp")
#Randomize file name
def random_with_N_digits(n):
range_start = 10**(n-1)
range_end = (10**n)-1
return randint(range_start, range_end)
#Ziping the shapefile files
def zipShapefile(inShapefile, newZipFN):
if not (os.path.exists(inShapefile)):
print inShapefile + ' Does Not Exist'
return False
if (os.path.exists(newZipFN)):
os.remove(newZipFN)
if (os.path.exists(newZipFN)):
return False
zipobj = zipfile.ZipFile(newZipFN,'w')
for infile in glob.glob( inShapefile.lower().replace(".shp",".*")):
zipobj.write(infile,os.path.basename(infile),zipfile.ZIP_DEFLATED)
zipobj.close()
return True
randomname = str(random_with_N_digits(8))
InputShapeFile = arcpy.env.scratchFolder+"\\"+"download_file.shp"
#Public folder. Probably you will want to change this
OutputZipFile = "C:\\inetpub\\wwwroot\\Shapefiles\\"+randomname+"_file.zip"
zipShapefile(InputShapeFile,OutputZipFile)
print "done!"
Hi,
Python Noob. All I would like is for our users to be able to Download a layer(s) from a Map Service in .shp/,gdb output. I'm not digging the Extract Toolset, mainly because users "might" get inaccurate data via Clip. I would rather use a 'Select' but am not having a bunch of luck. I tried the above code but am getting errors, see below. Any help is Grate-ly appreciated. Thanks!
Runtime error
Traceback (most recent call last):
File "<string>", line 33, in <module>
File "c:\program files (x86)\arcgis\desktop10.5\arcpy\arcpy\arcobjects\arcobjects.py", line 175, in load
return convertArcObjectToPythonObject(self._arc_object.Load(*gp_fixargs(args)))
RuntimeError: RecordSetObject: Cannot open table for Load