2016-08-03 1 views
1

Je suis nouveau sur gdal et C++ et j'essaye de créer une fonction qui lit un raster par blocs (en utilisant RasterIO et non ReadBlock) faire quelque chose avec les valeurs et écrit le résultat dans un nouveau fichier rasterGDAL C++ RasterIO par blocs

Je reçois une erreur:

Unhandled exception at 0x00007FFDFB517BC4 (gdal201.dll) in Test.exe: 0xC0000005: Access violation writing location 0x00000230E2593000 at line rasterBand->RasterIO(GDALRWFlag::GF_Read, j * readCols, i * readRows, readCols, readRows, rasterBlock, readCols, readRows, GDALDataType::GDT_CFloat32, 0, 0)

J'ai une fonction très similaire qui fonctionne bien, mais il lit les valeurs de pixels ligne par ligne

Toute aide est appréciée

La fonction est ci-dessous

Merci

#include <iostream> 
#include "gdal_priv.h" 
using namespace std; 

void SlopeBlock() 
{ 
int readRows = 2048; 
int readCols = 2048; 
int nBlockXSize; 
int nBlockYSize; 
int rowOff = 0; 
int colOff = 0; 
int nRows = 0; 
int nCols = 0; 
double noData = -9999; 

GDALAllRegister(); 

GDALDataset* dem = (GDALDataset*)GDALOpen("path/EUD_CP-DEMS_4500025000-AA.tif", GA_ReadOnly); 

GDALDriver *gTIF = GetGDALDriverManager()->GetDriverByName(dem->GetDriverName()); 

double geoTransform[6]; 
dem->GetGeoTransform(geoTransform); 

GDALRasterBand* rasterBand = dem->GetRasterBand(1); 

nCols = rasterBand->GetXSize(); 
nRows = rasterBand->GetYSize(); 
noData = rasterBand->GetNoDataValue(); 

//rasterBand->GetBlockSize(&nBlockXSize, &nBlockYSize); 

int nXBlocks = (rasterBand->GetXSize() + readCols - 1)/readCols; 
int nYBlocks = (rasterBand->GetYSize() + readRows - 1)/readRows; 

cout << nYBlocks << "___" << nXBlocks << "\n"; 


//Slope 
GDALDataset *slope = gTIF->Create("path/slopeBlock.tif", nCols, nRows, 1, GDT_Float32, NULL); 
slope->SetGeoTransform(geoTransform); 

for (int i = 0; i < nYBlocks; i++) 
{ 
    for (int j = 0; j < nXBlocks; j++) 
    { 
     float* rasterBlock = (float*)CPLMalloc(readCols*readRows*sizeof(float)); 
     float* rasterBlockOut = (float*)CPLMalloc(readCols*readRows*sizeof(float)); 

     if (rasterBand != nullptr) 
      rasterBand->RasterIO(GDALRWFlag::GF_Read, j * readCols, i * readRows, readCols, readRows, rasterBlock, readCols, readRows, GDALDataType::GDT_CFloat32, 0, 0); 

     //Not sure if is working 
     for (int jb = 0; jb < readCols; jb++) 
     { 
      if (rasterBlock[jb] == noData) 
      { 
       rasterBlockOut[jb] = noData; 
      } 
      else 
      { 
       rasterBlockOut[jb] = rasterBlock[jb]; 
      } 
     } 

     slope->GetRasterBand(1)->RasterIO(GDALRWFlag::GF_Write, j * readCols, i * readRows, readCols, readRows, rasterBlockOut, readCols, readRows, GDALDataType::GDT_CFloat32, 0, 0); 

     CPLFree(rasterBlock); 
     CPLFree(rasterBlockOut); 
    } 
} 

GDALClose(dem); 
GDALClose(slope); 

}

Répondre

0

Cela peut ne pas être la cause de l'accident, mais vous demandez un 2048 * 2048 bloc même si votre image est plus petite . Ce code ne devrait fonctionner que pour les images avec des multiples de 2048 en taille.

Vous devriez faire quelque chose comme:

nXSize = min(readCols, rasterBand->GetXSize() - j * readCols); 
nYSize = min(readRows, rasterBand->GetYSize() - i * readRows); 

rasterBand->RasterIO(GDALRWFlag::GF_Read, j * readCols, i * readRows, 
    nXSize, nYSize, rasterBlock, nXSize, nYSize, GDALDataType::GDT_CFloat32, 0, 0); 
+0

Merci pour votre aide. Le code ci-dessous fonctionne maintenant, mais cela prend plus de temps que de lire toute l'image à J'ai changé \t float * rasterBlock = (float *) CPLMalloc (nCols * nRows * sizeof (GDT_CFloat32)); \t float * rasterBlockOut = (flottant *) CPLMalloc (nCols * nRows * sizeof (GDT_CFloat32)); –

+0

Le but de travailler avec des blocs n'est pas d'accélérer le traitement (si vous traitez l'image entière) mais de pouvoir gérer une quantité de données qui ne rentrerait pas dans le bélier. Si vous pouvez charger toute l'image en une fois, cela sera certainement plus rapide. – Gwen