Monday 11 April 2016

arcpy - Trace Geometric Network in custom script tool?


I'm trying to make a Python script tool which uses the Trace Geometric Network tool (10.3). My script works in the Python window, but as a script-tool, it runs and NOTHING HAPPENS. Messages state: Executing..., Start time..., Running script..., Completed script... Succeeded at... It acts like the tool executed with no errors, but there's no visible output.


The Trace Geometric Network tool refuses to work inside a Python script tool the way it does in the Python window. I tried playing with the parameters, data types in of parameter settings, and deleting and remaking the tool several times. I even tried using other geometric networks with the tool. Finally, I made a bare-bones script with only the trace tool to troubleshoot, and NOTHING. I get the same action as above.


Here's my bare-bones script:



geoNetwork = arcpy.GetParameterAsText(0)

inflags = arcpy.GetParameterAsText(1)

barriers = arcpy.GetParameterAsText(2)

arcpy.TraceGeometricNetwork_management(geoNetwork, "Trace", inflags, "TRACE_DOWNSTREAM", barriers)

Here's a screen shot of how I'm setting my parameters in the tool properties:


Tool Parameter Properties



How can I to get this to work as a Python script tool?


Here's the actual code. As this tool executes, I can see it looping over the flags and selecting them one by one. No output group layer files are added to the map and no apparent traces are made. Again, these functions work as intended if pasted in the python window, but misbehave as python-script tools.


inflags = arcpy.GetParameterAsText(0)
geoNetwork = arcpy.GetParameterAsText(1)
barriers = arcpy.GetParameterAsText(2)
outPath = arcpy.GetParameterAsText(3)
outName = arcpy.GetParameterAsText(4)

def makeFullPath(path, name):
return path + "\\" + name


def TraceCapture(inflags, geoNetwork, barriers, outPath, outName):
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
flagList = list(arcpy.da.SearchCursor(inflags, 'UNITID'))
trace = 1
segmentCapture = []
for flag in range(1, len(flagList)+1):
try:
outputLayer = "Trace_" + str(trace)

expression = '"OBJECTID" =' + str(trace)
arcpy.SelectLayerByAttribute_management(inflags, "NEW_SELECTION", expression)
arcpy.TraceGeometricNetwork_management(geoNetwork, outputLayer, inflags, "TRACE_DOWNSTREAM", barriers)
arcpy.AddMessage("Trace_" + str(trace) + " complete")

for lyr in arcpy.mapping.ListLayers(mxd, "", df):
if lyr.name == "Sewers":
pipesCursor = arcpy.da.SearchCursor(lyr, 'ASSETID')
for i in pipesCursor:
segmentCapture.append((flagList[trace - 1][0], i[0]))

if lyr.name == outputLayer:
arcpy.mapping.RemoveLayer(df, lyr)
trace += 1
except RuntimeError:
print "Flag " + str(trace) + " was invalid and skipped."
trace += 1
continue

arcpy.CreateTable_management(outPath, outName)
outFile = makeFullPath(outPath, outName)

arcpy.AddField_management(outFile, "manholeID", "TEXT", "", "", 10)
arcpy.AddField_management(outFile, "pipeID", "TEXT", "", "", 10)

with arcpy.da.InsertCursor(outFile, ["manholeID", "pipeID"]) as cursor:
for row in segmentCapture:
cursor.insertRow(row)

TraceCapture(inflags, geoNetowrk, barriers, outPath, outName)

Answer



Odds are it has finished, and finished properly. You don't have any outputs on your tool, thus the script tool wont return anything to your ArcMap session.



In most Trace models/scripts I've seen, you need to Select Data to pull out whatever child element you want, then its good to run Copy Features on that item. The output of CopyFeatures should be passed into one more variable you need to define on the Parameters page you've shown. You can set it as a derived output if you're handling the output location of the data in your script.


Model


See the picture of the model here where you can see Select and Make Feature Layer after the Trace tool (but dont use Make Feature Layer, use Copy Features). Note that the Select tool is a ModelBuilder ONLY tool. The workflow is different in Python.


Python


To select an item out of the group layer, you need to have prior knowledge of what it's name will be. The below code shows you can list the sub items of a group layer to get their name. Having prior knowledge of the names, you just need to build up a path to the output using traceName/subLayerName. (arcpy.mapping code is only added for reference to print out all available item names, in practice you probably wouldn't add this to a production tool)


arcpy.Snap_edit(Flags, "'Primary OH Conductor' VERTEX '30 Meters'")

arcpy.TraceGeometricNetwork_management(El_Paso_Electric, "Storm_Net", Flags, "TRACE_UPSTREAM", "", "", "", "", "", "NO_TRACE_ENDS", "TRACE_INDETERMINATE_FLOW", "", "", "AS_IS", "", "", "", "AS_IS")

network = arcpy.mapping.Layer("Storm_Net")

if network.isGroupLayer:
for sublayer in network:
arcpy.AddMessage(" {} ".format(sublayer.name))

# Process: Select Data
#arcpy.SelectData_management("Storm_Net", "ServiceLocation") # <--- dont use

# Build up the path to the item you want, in this case, "Storm_Net" is my output Trace, and "ServiceLocation" is the item inside I want.
arcpy.CopyFeatures_management("Storm_Net/ServiceLocation", outputFeatureClass)

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...