I know this isn't possible in arcpy, so I thought I'd give it a stab using comtypes. I am trying to translate some of the VB.NET code to create a network dataset from the help docs:
I'm trying to automate this process for an engineer as he is not very experienced with GIS. He will always be using a file geodatabase with one line feature class as edge features (fc name will vary) and two point feature classes as junction features (sources and sinks to act as origins and destinations). Once the network is built, he can use other script tools I am providing him to do the whole analysis.
I think I am pretty close as I am able to create the edge and junction features, but my code is failing at one of the last steps which is getting the extension for the IFeatureDatasetExtensionContainer interface via the FindExtension method. The help docs say I can use the esriGeoDatabase.esriDatasetType constant but this seems to be causing an error:
http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/index.html#//0025000002ww000000
here is where it is failing:
# create network data set based on data element
fdxc = CType(fdsGDS, esriGeoDatabase.IFeatureDatasetExtensionContainer)
fdx = fdxc.FindExtension(esriGeoDatabase.esriDatasetType(7)) # get error here
dsc = CType(fdx, esriGeoDatabase.IDatasetContainer2)
netds = CType(dsc.CreateDataset(nd), esriGeoDatabase.INetworkDataset)
Here is my error:
Traceback (most recent call last):
File "\\arcserver1\GIS\_Resources\ESRI\Python\BMI_Library\arcobjects\network_dataset.py", line 114, in <module>
create_nd(gdb)
File "\\arcserver1\GIS\_Resources\ESRI\Python\BMI_Library\arcobjects\network_dataset.py", line 98, in create_nd
fdx = fdxc.FindExtension(esriGeoDatabase.esriDatasetType(7))
COMError: (-2147220729, None, (u'The specified feature dataset extension type was not found.', u'Esri GeoDatabase', u'esri_csGeoDatabase.hlp', 0, None))
And here is my full code if that helps:
def create_nd(gdb):
arcpy.CheckOutExtension('Network')
getModule('esriGeoDatabase.olb')
getModule('esriDataSourcesGDB.olb')
import comtypes.gen.esriGeoDatabase as esriGeoDatabase
import comtypes.gen.esriDataSourcesGDB as esriDataSourcesGDB
# create new empty data element for buildable network dataset
nd = NewObj(esriGeoDatabase.DENetworkDataset,
esriGeoDatabase.IDENetworkDataset2)
nd.Buildable = True
nd.NetworkType = esriGeoDatabase.esriNetworkDatasetType(1)
# open feature dataset and create IGeoDataset interface
pWSF = NewObj(esriDataSourcesGDB.FileGDBWorkspaceFactory, esriGeoDatabase.IWorkspaceFactory)
gdbWSF = CType(pWSF, esriGeoDatabase.IWorkspaceFactory)
print gdbWSF.WorkspaceDescription, gdbWSF.WorkspaceType
gdbFWS = CType(gdbWSF.OpenFromFile(gdb, 0), esriGeoDatabase.IFeatureWorkspace)
print gdbFWS
openFWS = gdbFWS.OpenFeatureDataset('FlowNet')
fdsGDS = CType(openFWS, esriGeoDatabase.IGeoDataset)
print fdsGDS
# copy feature dataset's extent and spatial reference to network dataset element
deGDS = CType(nd, esriGeoDatabase.IDEGeoDataset)
deGDS.Extent = fdsGDS.Extent
deGDS.SpatialReference = fdsGDS.SpatialReference
print deGDS.Extent
# get flow lines
arcpy.env.workspace = os.path.join(gdb, 'FlowNet')
lines = arcpy.ListFeatureClasses('*', 'Polyline')[0]
# create data element
dataElement = CType(nd, esriGeoDatabase.IDataElement)
dataElement.Name = 'FlowNetwork'
print dataElement.Name
# specify edge features
edgeNet = NewObj(esriGeoDatabase.EdgeFeatureSource,
esriGeoDatabase.INetworkSource)
edgeNet.Name = lines
edgeNet.ElementType = esriGeoDatabase.esriNetworkElementType(2)
## edgeNet.SourceType = esriGeoDatabase.esriNetworkSourceType(3)
## edgeNet.UsesGeometryInConnectivity = True
#set edge feature's connectivity (Any Vertex)
edgeFS = CType(edgeNet, esriGeoDatabase.IEdgeFeatureSource)
edgeFS.UsesSubtypes = False
edgeFS.ClassConnectivityGroup = 1
edgeFS.ClassConnectivityPolicy = esriGeoDatabase.esriNetworkEdgeConnectivityPolicy(0) # any vertex
# add sources and sinks as junctions
# make origins
sinkNet = NewObj(esriGeoDatabase.JunctionFeatureSource,
esriGeoDatabase.INetworkSource)
sinkNet.Name = 'Sinks'
sinkNet.ElementType = esriGeoDatabase.esriNetworkElementType(1)
## sinkNet.SourceType = esriGeoDatabase.esriNetworkSourceType(2)
## sinkNet.UsesGeometryInConnectivity = True
# set connectivity
sinkElm = CType(sinkNet, esriGeoDatabase.IJunctionFeatureSource)
sinkElm.UsesSubtypes = False
sinkElm.ClassConnectivityGroup = 1
sinkElm.ClassConnectivityPolicy = esriGeoDatabase.esriNetworkJunctionConnectivityPolicy(0) # honor
# make destinations
sourceNet = NewObj(esriGeoDatabase.JunctionFeatureSource,
esriGeoDatabase.INetworkSource)
sourceNet.Name = 'Sources'
sourceNet.ElementType = esriGeoDatabase.esriNetworkElementType(1)
## sourceNet.SourceType = esriGeoDatabase.esriNetworkSourceType(2)
## sourceNet.UsesGeometryInConnectivity = True
# set connectivity
sourceElm = CType(sourceNet, esriGeoDatabase.IJunctionFeatureSource)
sourceElm.UsesSubtypes = False
sourceElm.ClassConnectivityGroup = 1
sourceElm.ClassConnectivityPolicy = esriGeoDatabase.esriNetworkJunctionConnectivityPolicy(0) # honor
# add attributes (Length, Cost, Units)
evalNetAttr = NewObj(esriGeoDatabase.EvaluatedNetworkAttribute,
esriGeoDatabase.IEvaluatedNetworkAttribute)
newAttr2 = CType(evalNetAttr, esriGeoDatabase.INetworkAttribute2)
newAttr2.Name = 'Length'
newAttr2.UsageType = esriGeoDatabase.esriNetworkAttributeUsageType(0) # cost
newAttr2.DataType = esriGeoDatabase.esriNetworkAttributeDataType(2) # double
newAttr2.Units = esriGeoDatabase.esriNetworkAttributeUnits(3) # feet
newAttr2.UseByDefault = True
# create network data set based on data element
fdxc = CType(fdsGDS, esriGeoDatabase.IFeatureDatasetExtensionContainer)
fdx = fdxc.FindExtension(esriGeoDatabase.esriDatasetType(7)) # fails here
dsc = CType(fdx, esriGeoDatabase.IDatasetContainer2)
netds = CType(dsc.CreateDataset(nd), esriGeoDatabase.INetworkDataset)
# build network dataset now that it's created
netBuild = CType(netds, esriGeoDatabase.INetworkBuild)
for item in [edgeNet, sinkNet, sourceNet]:
netBuild.AddSource(item)
netBuild.AddAttribute(newAttr2)
netBuild.BuildNetwork(fsdGDS.Extent)
arcpy.CheckInExtension('Network')
return
if __name__ == '__main__':
gdb = r'C:\Users\calebma\Desktop\NA_Testing\test2.gdb'
create_nd(gdb)
print 'done'
arcpy
, it is using the comtypes module which is a third party module that generates python bindings to COM based libraries. This is used to access ArcObjects from Python. The code above got me 3/4 of the way there, but I never actually got around to finishing it. You would need to follow the ArcObjects help docs to set up the networks according to your specific needs.