2 votos

python se bloquea con el objeto gdal band devuelto por una función

Escribí estas dos funciones en un módulo cuando quiero leer la banda en archivos NetCDF o HDF y devolver la banda fuera de la función. Cada HDF y NetCDF tiene muchos subconjuntos de datos. Cada subconjunto de datos de un archivo NetCDF tiene 365 bandas, mientras que el subconjunto de datos HDF sólo tiene una banda. Cuando ejecuto readFile1, no hay ningún problema. Sin embargo, cuando ejecuto readFile2 y devuelvo la banda, escribo out.GetNoDataValue() (u otras funciones adjuntas) en el intérprete o en otra función, python se bloquea. En la función readFile1, out.GetNoDataValue() no devuelve ningún valor de datos de la banda con éxito. Cuando devuelve la banda como en readFile2, no se puede hacer nada con ella. Cuando lo haces, python se bloquea.

mi versión de gdal es '1100000' (gdal.VersionInfo()) Mi sistema operativo es ubuntu 12.04 LTS

Creo que esto podría ser un error en gdal, no estoy seguro de ello.

from osgeo import gdal

def readFile1(inputFile,variableNo,bandNo):

    filereadtemp=gdal.Open(inputFile)

    fileread=gdal.Open(filereadtemp.GetSubDatasets()[variableNo][0])

    out=fileread.GetRasterBand(bandNo)
    nodatavalue=out.GetNoDataValue()

    return nodatavalue

def readFile2(inputFile,variableNo,bandNo):

    filereadtemp=gdal.Open(inputFile)

    fileread=gdal.Open(filereadtemp.GetSubDatasets()[variableNo][0])

    out=fileread.GetRasterBand(bandNo)

    return out

5voto

Lucas Puntos 128

El conjunto de datos está siendo desreferenciado cuando devuelves sólo la banda de tu función.

La solución es devolver el conjunto de datos desde la función.

Desde el GDAL Python Gotchas página:

Python se bloquea si se utiliza un objeto después de eliminar un objeto con el que tiene una relación

Considere este ejemplo:

from osgeo import gdal
dataset = gdal.Open('C:\\RandomData.img')
band = dataset.GetRasterBand(1)
print band.Checksum()
31212

En este ejemplo, band tiene una relación con dataset que requiere conjunto de datos permanezca asignado para que banda funcione. Si eliminamos dataset y luego intentamos usar band, Python se bloqueará:

from osgeo import gdal
dataset = gdal.Open('C:\\RandomData.img')
band = dataset.GetRasterBand(1)
del dataset           # This will cause the Python garbage collector to deallocate dataset
band.GetChecksum()    # This will now crash Python because the band's dataset is gone
< Python crashes >

Este problema puede manifestarse de formas sutiles. Por ejemplo, puede ocurrir si se intenta instanciar una instancia temporal de un conjunto de datos dentro de un archivo una sola línea de código:

from osgeo import gdal
print gdal.Open('C:\\RandomData.img').GetRasterBand(1).Checksum()
< Python crashes >

En este ejemplo, la instancia del conjunto de datos ya no era necesaria después de la llamada a llamada a GetRasterBand() por lo que Python la desasignó antes de llamar a Checksum().

Este problema se produce porque los objetos GDAL y OGR se implementan en C++ y las relaciones entre ellos se mantienen en C++ utilizando punteros. Cuando se elimina la instancia del conjunto de datos en Python, el objeto objeto C++ que hay detrás de él. Pero el objeto C++ detrás del no sabe que esto ha ocurrido, por lo que contiene un puntero al objeto C++ dataset que ya no existe. Cuando la banda intenta acceder al objeto inexistente, el proceso se bloquea.

El equipo de GDAL sabe que este diseño no es lo que los programadores de Python esperan. Por desgracia, el diseño es difícil de corregir, por lo que es probable que permanezca durante algún tiempo.

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