Sé que esto no es posible en arcpy, así que pensé en intentarlo usando comtypes. Estoy tratando de traducir parte del código VB.NET para crear un conjunto de datos de red de los documentos de ayuda:
Estoy intentando automatizar este proceso para un ingeniero, ya que no tiene mucha experiencia con los SIG. Siempre utilizará una base de datos de archivos con una clase de característica de línea como características de borde (el nombre fc variará) y dos clases de características de punto como características de unión (fuentes y sumideros para actuar como orígenes y destinos). Una vez construida la red, puede utilizar otras herramientas script que le proporciono para realizar todo el análisis.
Creo que estoy bastante cerca, ya que puedo crear las características de borde y de unión, pero mi código falla en uno de los últimos pasos, que es obtener la extensión para la interfaz IFeatureDatasetExtensionContainer a través del método FindExtension. La documentación de ayuda dice que puedo utilizar la constante esriGeoDatabase.esriDatasetType, pero esto parece causar un error:
http://resources.arcgis.com/en/help/arcobjects-net/componenthelp/index.html#//0025000002ww000000
aquí es donde está fallando:
# 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)
Este es mi 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))
Y aquí está mi código completo si eso ayuda:
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'