1 votos

Obtener la ruta de las clases de características en los conjuntos de datos de características sin arcpy

Estoy buscando una manera de obtener la ruta completa de una clase de característica dentro de los conjuntos de datos de características (ya sea en bases de datos personales o de archivos) sin usar arcpy. Mi primer intento fue utilizar ogr, que funciona bien si las clases de características se almacenan en la geodatabase directamente. Pero no conseguí obtener la ruta completa si se trata de un conjunto de datos de características. Probé el controlador "OpenFileGDB" así como el controlador "FileGDB". Mi geodatabase de prueba almacena cinco clases de características, cuatro de ellas están dentro del conjunto de datos de características y una directamente en la geodatabase.

Mi código hasta ahora:

gdb_path = r"C:\my_path\test_gdb_fd.gdb"
gdb_driver = ogr.GetDriverByName("FileGDB")
gdb = gdb_driver.Open(gdb_path)
for featsClass_idx in range(gdb.GetLayerCount()):
    featsClass = gdb.GetLayerByIndex(featsClass_idx)
    print featsClass.GetName()

esto imprime los nombres base de todas las clases de características sin ninguna información sobre si la clase de característica está dentro del conjunto de datos de características o no. Estoy usando GDAL 2.2.4, FileGDB API 1.3, Python 2.7 32 bit

2voto

Vasya Novikov Puntos 111

No estoy muy familiarizado con el trabajo con GDBs en el contexto de GDAL. Si es posible hacerlo a través de las APIs reales que obviamente sería ideal, pero no puedo comentar sobre eso.

Dicho esto, si no es posible y te apetece ponerte en plancha, puedes rebuscar en el a00000004.gdbtable del propio GDB. Ver aquí para una ingeniería inversa parcial de la especificación, pero el resultado es que el archivo mencionado contiene fragmentos de XML que describen el contenido de GDB.

Aquí hay un parser rápido y sucio para volcar las rutas completas a todas las clases de características:

import mmap
import os
from xml.etree import cElementTree as cET

gdb = r'C:\Users\gberard\Documents\ArcGIS\New File Geodatabase.gdb'
table = os.path.join(gdb, 'a00000004.gdbtable')

tag_a = '<DEFeatureClassInfo'
tag_b = '</DEFeatureClassInfo>'

with open(table, 'r') as f:
    mm = mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ)

    off_b = 0
    while True:
        off_a = mm.find(tag_a, off_b)
        off_b = mm.find(tag_b, off_a) + len(tag_b)
        if off_a < 0 or off_b < 0:
            break

        tree = cET.fromstring(mm[off_a:off_b])
        elem = tree.find('CatalogPath')
        print os.path.join(gdb, elem.text[1:])

Lo que daría como resultado:

C:\Users\gberard\Documents\ArcGIS\New File Geodatabase.gdb\SomeFeatureDataset\SomeFC
C:\Users\gberard\Documents\ArcGIS\New File Geodatabase.gdb\OtherFeatureDataset\OtherFC 
C:\Users\gberard\Documents\ArcGIS\New File Geodatabase.gdb\JustAFeatureClass

Otra vez, utilice las APIs si puede . Lo anterior es burdo, pero es una opción.

1 votos

Este método es mucho más rápido que el uso de arcpy.walk o incluso ogr, pero tenga en cuenta que las tablas y conjuntos de datos de características, presumiblemente otros objetos también, que se han eliminado de la gdb todavía se registran en el archivo a00000004.gdbtable. Todavía no he descubierto cómo identificarlos.

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