The map below is based on test data generated by the code that follows.
That code:
- Creates a file geodatabase (test.gdb), with a feature dataset (TestFD), and in that feature dataset there are two point feature classes (ValveTypeA and ValveTypeB) and a line feature class (TestLines)
- ValveTypeA, ValveTypeB and TestLines are used to create a geometric network (TestFD_Net) with its flow direction set by its digitized direction
- ValveTypeA and ValveTypeB both have a field "Type" with values "A" and "B" respectively and these are concatenated with the OBJECTID to see the labels in the map above.
- Another point feature class (FlagFC) is in the feature dataset but does not participate in the geometric network. Instead it is used as the flag to run two geometric network traces that are designed to find the isolation valves from FlagFC by first disabling ValveTypeA, and then disabling ValveTypeB
- Running the code correctly finds A1 and A2 as being the isolation valves when ValveTypeA is disabled; and correctly finds B1 and B4 as being the isolation valves when ValveTypeB is disabled
- The last line of the code merges ValveTypeA and ValveTypeB into a single feature class ValveTypesCombined
I think I have shown how I can find isolation valves for a valve type when those valve types are kept in separate feature classes within the feature dataset used to create the geometric network.
However, in the much more complicated geometric network which I am working on for a water utility, they have modelled their valve types in the same point feature class with an attribute to distinguish their types i.e. like in my ValveTypesCombined.
Is it possible to perform an isolation valve trace that can "pass through" one valve type and look for the other valve type to stop it?
In the example below I would like to be able to use ValvesCombined to find the valves of type "B" that can isolate FlagFC without the trace being stopped first by the valves of type "A".
`>>>`
====== RESTART: C:\Temp\CreateTestGeometricNetwork.py =====
Isolation Valves for ValveTypeA: ['A1', 'A2']
Isolation Valves for ValveTypeB: ['B1', 'B4']
`>>>`
import arcpy
if arcpy.Exists("C:/Temp/test.gdb"):
arcpy.Delete_management("C:/Temp/test.gdb")
arcpy.CreateFileGDB_management("C:/Temp","test")
arcpy.CreateFeatureDataset_management("C:/Temp/test.gdb","TestFD","#")
arcpy.CreateFeatureclass_management("C:/Temp/test.gdb/TestFD","TestLines","POLYLINE","#","DISABLED","DISABLED","#","#","0","0","0")
cursor = arcpy.da.InsertCursor("C:/Temp/test.gdb/TestFD/TestLines", ["SHAPE@"])
array = arcpy.Array([arcpy.Point(2,0),arcpy.Point(2,1)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
array = arcpy.Array([arcpy.Point(2,1),arcpy.Point(1,2)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
array = arcpy.Array([arcpy.Point(2,1),arcpy.Point(3,2)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
array = arcpy.Array([arcpy.Point(1,2),arcpy.Point(1,3)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
array = arcpy.Array([arcpy.Point(1,3),arcpy.Point(0,4)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
array = arcpy.Array([arcpy.Point(1,3),arcpy.Point(2,4)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
array = arcpy.Array([arcpy.Point(3,2),arcpy.Point(3,3),arcpy.Point(4,4)])
polyline = arcpy.Polyline(array)
cursor.insertRow([polyline])
del cursor
arcpy.CreateFeatureclass_management("C:/Temp/test.gdb/TestFD","ValveTypeA","POINT","#","DISABLED","DISABLED","#","#","0","0","0")
cursor = arcpy.da.InsertCursor("C:/Temp/test.gdb/TestFD/ValveTypeA", ["SHAPE@XY"])
cursor.insertRow([[1,2]])
cursor.insertRow([[3,2]])
del cursor
arcpy.AddField_management("C:/Temp/test.gdb/TestFD/ValveTypeA","Type","TEXT","","","1")
arcpy.CalculateField_management("C:/Temp/test.gdb/TestFD/ValveTypeA","Type",'"A"',"PYTHON_9.3")
arcpy.CreateFeatureclass_management("C:/Temp/test.gdb/TestFD","ValveTypeB","POINT","#","DISABLED","DISABLED","#","#","0","0","0")
cursor = arcpy.da.InsertCursor("C:/Temp/test.gdb/TestFD/ValveTypeB", ["SHAPE@XY"])
cursor.insertRow([[1,3]])
cursor.insertRow([[0,4]])
cursor.insertRow([[2,4]])
cursor.insertRow([[4,4]])
del cursor
arcpy.AddField_management("C:/Temp/test.gdb/TestFD/ValveTypeB","Type","TEXT","","","1")
arcpy.CalculateField_management("C:/Temp/test.gdb/TestFD/ValveTypeB","Type",'"B"',"PYTHON_9.3")
arcpy.CreateFeatureclass_management("C:/Temp/test.gdb/TestFD","FlagFC","POINT","#","DISABLED","DISABLED","#","#","0","0","0")
cursor = arcpy.da.InsertCursor("C:/Temp/test.gdb/TestFD/FlagFC", ["SHAPE@XY"])
cursor.insertRow([[2,0]])
del cursor
arcpy.CreateGeometricNetwork_management("C:/Temp/test.gdb/TestFD","TestFD_Net",
"TestLines SIMPLE_EDGE NO;ValveTypeA SIMPLE_JUNCTION NO;ValveTypeB SIMPLE_JUNCTION NO",
"#","#","#","#","PRESERVE_ENABLED")
arcpy.SetFlowDirection_management("C:/Temp/test.gdb/TestFD/TestFD_Net","WITH_DIGITIZED_DIRECTION")
arcpy.TraceGeometricNetwork_management(
"C:/Temp/test.gdb/TestFD/TestFD_Net",
r"in_memory\{0}".format("TestFD_Net_group_layer"),
"C:/Temp/test.gdb/TestFD/FlagFC",
"FIND_CONNECTED","","","","","ValveTypeA",
"TRACE_ENDS","","","","AS_IS","","","","AS_IS")
isolationValves = []
for layer in arcpy.mapping.Layer(r"in_memory\{0}".format("TestFD_Net_group_layer")):
for x in arcpy.mapping.ListLayers(layer):
if x.name == "ValveTypeA":
with arcpy.da.SearchCursor("ValveTypeA", ['Type','OBJECTID']) as rows:
for row in rows:
isolationValves.append("{0}{1}".format(row[0],row[1]))
print("Isolation Valves for ValveTypeA: {0}".format(isolationValves))
arcpy.Delete_management(r"in_memory\{0}".format("TestFD_Net_group_layer"))
arcpy.TraceGeometricNetwork_management(
"C:/Temp/test.gdb/TestFD/TestFD_Net",
r"in_memory\{0}".format("TestFD_Net_group_layer"),
"C:/Temp/test.gdb/TestFD/FlagFC",
"FIND_CONNECTED","","","","","ValveTypeB",
"TRACE_ENDS","","","","AS_IS","","","","AS_IS")
isolationValves = []
for layer in arcpy.mapping.Layer(r"in_memory\{0}".format("TestFD_Net_group_layer")):
for x in arcpy.mapping.ListLayers(layer):
if x.name == "ValveTypeB":
with arcpy.da.SearchCursor("ValveTypeB", ['Type','OBJECTID']) as rows:
for row in rows:
isolationValves.append("{0}{1}".format(row[0],row[1]))
print("Isolation Valves for ValveTypeB: {0}".format(isolationValves))
arcpy.Merge_management("C:/Temp/test.gdb/TestFD/ValveTypeA;C:/Temp/test.gdb/TestFD/ValveTypeB",
"C:/Temp/test.gdb/TestFD/ValveTypesCombined")
I am using a Standard Level license of ArcGIS Desktop 10.5.1 for my testing away from the site, but onsite I am using a Standard Level license of ArcGIS Desktop 10.2.1.