I'm sure this is a really elementary solution, I'm just over thinking it. I have this really simple model that takes a feature class and converts it to a GPX.
Ran the model
Then published it successfully after registering the folder where the PY code is.
When I run the GP tool from the GIS Server connection in Arc Cat, I can see that the output GPX file is going to the jobs directory, but how can I get that file? The whole point of this is to have a simple-click-one-button tool so users can get a GPX file back on their hard drive.
try: from xml.etree import cElementTree as ET except: from xml.etree import ElementTree as ET import arcpy, sys, traceback from arcpy import env import time, os from subprocess import call unicode = str OutName = arcpy.GetParameterAsText(0) fms = arcpy.FieldMappings() fms.addTable("\\\\some_server\DATASTORE\GP\\PLACE FISH.sde\\FISH.DBO.FISH_BARRIERS") FLD_STATION_NAME = arcpy.FieldMap() FLD_STREAMNAME = arcpy.FieldMap() FLD_EDITDATE = arcpy.FieldMap() FLD_STATION_NAME.addInputField("\\\\some_server\DATASTORE\GP\\PLACE FISH.sde\\FISH.DBO.FISH_BARRIERS", "STATION_NAME") STATION_NAME_MAP = FLD_STATION_NAME.outputField STATION_NAME_MAP.name = "Name" FLD_STATION_NAME.outputField = STATION_NAME_MAP fms.addFieldMap(FLD_STATION_NAME) FLD_STREAMNAME.addInputField("\\\\some_server\DATASTORE\GP\\PLACE FISH.sde\\FISH.DBO.FISH_BARRIERS", "STREAMNAME") STREAMNAME_MAP = FLD_STREAMNAME.outputField STREAMNAME_MAP.name = "Descript" FLD_STREAMNAME.outputField = STREAMNAME_MAP fms.addFieldMap(FLD_STREAMNAME) FLD_EDITDATE.addInputField("\\\\some_server\DATASTORE\GP\\PLACE FISH.sde\\FISH.DBO.FISH_BARRIERS", "EDITDATE") EDITDATE_MAP = FLD_EDITDATE.outputField EDITDATE_MAP.name = "DateTimeS" EDITDATE_MAP.type = "Text" FLD_EDITDATE.outputField = EDITDATE_MAP fms.addFieldMap(FLD_EDITDATE) arcpy.FeatureClassToFeatureClass_conversion("\\\\some_server\DATASTORE\GP\\PLACE FISH.sde\\FISH.DBO.FISH_BARRIERS", "\\\\some_server\DATASTORE\GP\\", "FISH_BARRIERS.shp", "", fms) gpx = ET.Element("gpx", xmlns="http://www.topografix.com/GPX/1/1", xalan="http://xml.apache.org/xalan", xsi="http://www.w3.org/2001/XMLSchema-instance", creator="Esri", version="1.1") def prettify(elem): """Return a pretty-printed XML string for the Element. """ from xml.dom import minidom rough_string = ET.tostring(elem, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent=" ") def featuresToGPX(inputFC, outGPX, zerodate, pretty): ''' This is called by the __main__ if run from a tool or at the command line ''' descInput = arcpy.Describe(inputFC) if descInput.spatialReference.factoryCode != 4326: arcpy.AddWarning("Input data is not projected in WGS84," " features were reprojected on the fly to create the GPX.") generatePointsFromFeatures(inputFC , descInput, zerodate) # Write the output GPX file try: if pretty: gpxFile = open(outGPX, "w") gpxFile.write(prettify(gpx)) else: gpxFile = open(outGPX, "wb") ET.ElementTree(gpx).write(gpxFile, encoding="UTF-8", xml_declaration=True) except TypeError as e: arcpy.AddError("Error serializing GPX into the file.") finally: gpxFile.close() def generatePointsFromFeatures(inputFC, descInput, zerodate=False): def attHelper(row): # helper function to get/set field attributes for output gpx file pnt = row[1].getPart() valuesDict["PNTX"] = str(pnt.X) valuesDict["PNTY"] = str(pnt.Y) Z = pnt.Z if descInput.hasZ else None if Z or ("ELEVATION" in cursorFields): valuesDict["ELEVATION"] = str(Z) if Z else str(row[fieldNameDict["ELEVATION"]]) else: valuesDict["ELEVATION"] = str(0) valuesDict["NAME"] = row[fieldNameDict["NAME"]] if "NAME" in fields else " " valuesDict["DESCRIPT"] = row[fieldNameDict["DESCRIPT"]] if "DESCRIPT" in fields else " " if "DATETIMES" in fields: row_time = row[fieldNameDict["DATETIMES"]] formatted_time = row_time if row_time else " " elif zerodate and "DATETIMES" not in fields: formatted_time = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(0)) else: formatted_time = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(0)) if zerodate else " " valuesDict["DATETIMES"] = formatted_time return #-------------end helper function----------------- def getValuesFromFC(inputFC, cursorFields ): previousPartNum = 0 startTrack = True # Loop through all features and parts with arcpy.da.SearchCursor(inputFC, cursorFields, spatial_reference="4326", explode_to_points=True) as searchCur: for row in searchCur: if descInput.shapeType == "Polyline": for part in row: newPart = False if not row[0] == previousPartNum or startTrack is True: startTrack = False newPart = True previousPartNum = row[0] attHelper(row) yield "trk", newPart elif descInput.shapeType == "Multipoint" or descInput.shapeType == "Point": # check to see if data was original GPX with "Type" of "TRKPT" or "WPT" trkType = row[fieldNameDict["TYPE"]].upper() if "TYPE" in fields else None attHelper(row) if trkType == "TRKPT": newPart = False if previousPartNum == 0: newPart = True previousPartNum = 1 yield "trk", newPart else: yield "wpt", None # ---------end get values function------------- # Get list of available fields fields = [f.name.upper() for f in arcpy.ListFields(inputFC)] valuesDict = {"ELEVATION": 0, "NAME": "", "DESCRIPT": "", "DATETIMES": "", "TYPE": "", "PNTX": 0, "PNTY": 0} fieldNameDict = {"ELEVATION": 0, "NAME": 1, "DESCRIPT": 2, "DATETIMES": 3, "TYPE": 4, "PNTX": 5, "PNTY": 6} cursorFields = ["OID@", "SHAPE@"] for key, item in valuesDict.items(): if key in fields: fieldNameDict[key] = len(cursorFields) # assign current index cursorFields.append(key) # build up list of fields for cursor else: fieldNameDict[key] = None for index, gpxValues in enumerate(getValuesFromFC(inputFC, cursorFields)): if gpxValues[0] == "wpt": wpt = ET.SubElement(gpx, 'wpt', {'lon':valuesDict["PNTX"], 'lat':valuesDict["PNTY"]}) wptEle = ET.SubElement(wpt, "ele") wptEle.text = valuesDict["ELEVATION"] wptTime = ET.SubElement(wpt, "time") wptTime.text = valuesDict["DATETIMES"] wptName = ET.SubElement(wpt, "name") wptName.text = valuesDict["NAME"] wptDesc = ET.SubElement(wpt, "desc") wptDesc.text = valuesDict["DESCRIPT"] else: #TRKS if gpxValues[1]: # Elements for the start of a new track trk = ET.SubElement(gpx, "trk") trkName = ET.SubElement(trk, "name") trkName.text = valuesDict["NAME"] trkDesc = ET.SubElement(trk, "desc") trkDesc.text = valuesDict["DESCRIPT"] trkSeg = ET.SubElement(trk, "trkseg") trkPt = ET.SubElement(trkSeg, "trkpt", {'lon':valuesDict["PNTX"], 'lat':valuesDict["PNTY"]}) trkPtEle = ET.SubElement(trkPt, "ele") trkPtEle.text = valuesDict["ELEVATION"] trkPtTime = ET.SubElement(trkPt, "time") trkPtTime.text = valuesDict["DATETIMES"] if __name__ == "__main__": ''' Gather tool inputs and pass them to featuresToGPX ''' inputFC = "\\\\some_server\DATASTORE\GP\\FISH_BARRIERS.shp" outGPX = OutName zerodate = "#" pretty = "#" featuresToGPX(inputFC, outGPX, zerodate, pretty) arcpy.Delete_management("\\\\some_server\DATASTORE\GP\\FISH_BARRIERS.shp")
Solved! Go to Solution.
This worked for me when using data drive pages.
output = targetJobname + ".pdf"
Output_File = os.path.join(arcpy.env.scratchFolder, output)
ddp.exportToPDF(Output_File, "CURRENT")
#forgot to add
arcpy.SetParameterAsText(1, Output_File)
This worked for me when using data drive pages.
output = targetJobname + ".pdf"
Output_File = os.path.join(arcpy.env.scratchFolder, output)
ddp.exportToPDF(Output_File, "CURRENT")
#forgot to add
arcpy.SetParameterAsText(1, Output_File)
Thanks. Based on https://community.esri.com/thread/104530#comment-388705 , Custom Geoprocessing Tool Reporting for ArcGIS online , Geoprocessing Service Output File scratch directory path to url , and Geoprocessing Service Output Directory that seems to be the path. But I'm having a hard time figuring out how to a) replicate your example in my specific situation, and b) how to present the file to the user. Where this is all leading to, I'm hoping to embed the GP service in the GP Widget in WAB, with similar functionality as how Tutorial: Publishing additional services for printing—Documentation | ArcGIS for Server works in WAB: delivering a click-to-download pdf. In this case, I need a click-to-download gpx file. But first I have to figure out how to make the underlying logic work. Thanks!
So I've modified the PY as such:
inputFC = "\\\\server\DATASTORE\GP\\FISH_BARRIERS.shp"
outGPX = os.path.join(arcpy.env.scratchFolder, OutName)
zerodate = "#"
pretty = "#"
featuresToGPX(inputFC, outGPX, zerodate, pretty)
arcpy.Delete_management("\\\\server\DATASTORE\GP\\FISH_BARRIERS.shp")
Re-ran the tool, republished it, same result:
Added it to a WAB (developer) GP Widget
Hit execute, same result: nothing.
Am I missing something elementary-obvious or does this workflow only work with the export-web-map-to-pdf task example?
Update...implementing some of your answer, setting the job to asych, and setting "add to display" in the model solved this. You can infer I spent ALL WEEKEND ON THIS.....
Once I polish up the workflow I'll document it in a blog.
Opps looks like I missed this last line in my copy and paste which may do it. Really sorry about that.
arcpy.SetParameterAsText(1, Output_File)