Mais

-9999 (sem valor de dados) torna-se 0 ao gravar a matriz no arquivo de memória GDAL


Estou tentando reprojetar e reamostrar (1000m - >> 30m) uma imagem raster (forma 238X406) usando a função gdal.ReprojectImage () em Python. O arquivo de entrada tem -9999 células sem valor de dados. O resultado é uma matriz (formato 10834x15055). O tipo de dados é float32.

Quando escrevo o resultado em um arquivo geotiff, tudo é esperado. Nenhum valor de dados é definido como -9999 e a matriz de saída tem -9999 células. No entanto, quando eu gravo o resultado em um arquivo de memória gdal para economizar algum tempo (25 segundos menos tempo de processamento, de 105 segundos para 80 segundos), desta vez todos os -9999s (sem valor de dados) tornam-se 0 (zero) na saída matriz de arquivo de memória. Ambos os resultados são exatamente iguais, mas o arquivo GeoTIFF tem -9999, o arquivo de memória tem 0. Mesmo que o arquivo de memória não tenha valor de dados de -9999, mas a matriz de saída é inicializada para 0,0 em vez de -9999.

Estou usando o mesmo código para produzir os resultados e a única diferença é que eu chamo o driver de memória quando quero escrever o resultado no arquivo de memória (driver = gdal.GetDriverByName ("MEM")), e o driver GeoTIFF quando quero escrever resultado para o arquivo GeoTIFF (driver = gdal.GetDriverByName ("GTiff"))

Minha versão gdal é '1100000' de gdal.VersionInfo (). Meu sistema operacional nos ubuntu 12.04 LTS "preciso".

# Cria um arquivo outFileRead = driver.Create (outFilePath, X, Y, 1, dataType, options) imprime inFileRead.GetRasterBand (1) .GetNoDataValue () imprime inFileRead.GetRasterBand (1) .ReadAsRasterBand () imprime inFileRead.GetRasterBand (1) imprime inFileRead.GetRasterBand (1). ) .ReadAsArray (). Shape # Reproject gdal.ReprojectImage (inFileRead, outFileRead, inProjection, outProjection, reSamplingType) imprimir outFileRead.GetRasterBand (1) .GetNoDataValue () imprimir outFileRead.GetBasterRead (.Read 1) .ReadAsArray (). Forma

o resultado das estampas

-9999.0

[[-9999. -9999. -9999… , -9999. -9999. -9999.]

[-9999. -9999. -9999… , -9999. -9999. -9999.]

[-9999. -9999. -9999… , -9999. -9999. -9999.]

… ,

[-9999. -9999. -9999… , -9999. -9999. -9999.]

[-9999. -9999. -9999… , -9999. -9999. -9999.]

[-9999. -9999. -9999… , -9999. -9999. -9999.]]

(406, 238)

-9999.0

[[ 0. 0. 0… , 0. 0. 0.]

[ 0. 0. 0… , 0. 0. 0.]

[ 0. 0. 0… , 0. 0. 0.]

… ,

[ 0. 0. 0… , 0. 0. 0.]

[ 0. 0. 0… , 0. 0. 0.]

[ 0. 0. 0… , 0. 0. 0.]]

(15055, 10834)

Isso mostra que mesmo se nenhum valor de dados for definido como -9999 no arquivo de memória, a matriz será inicializada com 0,0 em vez de nenhum valor de dados. A matriz em GeoTIFF foi inicializada com nenhum valor de dados, -9999, conforme o esperado. Acho que é um bug no arquivo de memória.


De acordo com o código-fonte, este é um problema que foi corrigido no GDAL 2.0. Quer tenha ou não, você pode contorná-lo preenchendo previamente o novo raster com seu valor de nodata preferido:

outFileRead = driver.Create (outFilePath, X, Y, 1, dataType, options) tmp = gdal.AutoCreateWarpedVRT (outFileRead, src_wkt, dst_wkt) b = outFileRead.GetRasterBand (1) 99 b.SetNoData.ndalue a (shape = (tmp.RasterYSize, tmp.RasterXSize)) a.fill (-9999.0) b.WriteArray (a) gdal.ReprojectImage (inFileRead, outFileRead, inProjection, outProjection, reSamplingType)

Band band = outAlignedRaster.GetRasterBand (1); band.SetNoDataValue (-9999,9); band.Fill (-9999,9, 0,0); Gdal.ReprojectImage (…);

Usei o valor de preenchimento de banda exatamente igual a nenhum valor de dados em meu aplicativo .net e funcionou para mim.


O problema é com o driver de memória gdal, não com a função de reprojetar. O driver de memória Gdal sempre inicializa a matriz com 0 em vez de nenhum valor de dados, mesmo se nenhum valor de dados for definido explicitamente. Veja o exemplo abaixo. No reprojeto, a matriz de saída é inicializada com 0, quando a matriz reprojetada é gravada nesta matriz, os elementos em excesso permanecem 0 em vez de nenhum valor de dados. O array deve ser inicializado sem nenhum valor de dados (somente se estiver definido).

from osgeo import gdal, gdal_array import numpy ds = gdal.GetDriverByName ('MEM'). Create (", 3, 3, 1, gdal.GDT_Float32) ds.GetRasterBand (1) .SetNoDataValue (-9999.0) ar = numpy.array ([[-9999.0]], dtype = numpy.float32) ds.GetRasterBand (1) .WriteArray (ar) print (ds.GetRasterBand (1) .ReadAsArray ()) [[-9999. 0. 0.] [0 . 0. 0.] [0. 0. 0.]]

https://trac.osgeo.org/gdal/ticket/6404