2016-08-03 38 views
1

我是gdal和C++的新手,我試圖創建一個按塊(使用RasterIO而不是ReadBlock)讀取柵格的函數,並將結果寫入新的柵格文件GDAL C++ RasterIO的塊

我得到一個錯誤:

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)

我有一個非常類似的功能工作正常,但按行

任何幫助表示讚賞讀取的像素值排

功能是波紋管

謝謝

#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); 

}

回答

0

這可能不是飛機墜毀的原因,但你問一個2048 * 2048塊就算你的形象是較小。此代碼只適用於尺寸爲2048的倍數的圖像。

你應該這樣做:

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

謝謝您的幫助。下面的代碼正在工作,但是這樣做比讀取整個圖像需要更多時間。 我改變了 \t float * rasterBlock =(float *)CPLMalloc(nCols * nRows * sizeof(GDT_CFloat32)); \t float * rasterBlockOut =(float *)CPLMalloc(nCols * nRows * sizeof(GDT_CFloat32)); –

+0

使用塊的目的不是加速處理(如果處理整個圖像),而是要處理大量不適合內存的數據。如果你可以在RAM中一次加載整個圖像,它肯定會更快。 – Gwen