6 votos

Construir un conjunto de datos de red con python comtypes

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:

http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/How_to_create_a_network_dataset/0001000000w7000000/

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'

4voto

John Kramlich Puntos 286

De acuerdo, voy a intentarlo:

La mayor parte de su código parece estar construyendo un Conjunto de datos de la red pero esta línea

fdx = fdxc.FindExtension(esriGeoDatabase.esriDatasetType(7))  # get error here

intenta devolver un GeometricNetwork ( 7 ), pruebe a devolver un conjunto de datos de red ( 19 )?

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X