261 lines
6.5 KiB
C++
261 lines
6.5 KiB
C++
#include <iostream>
|
|
#include <string>
|
|
#include <fstream>
|
|
#include <vector>
|
|
#include <stdio.h>
|
|
#include "GDALAccessor.h"
|
|
|
|
using namespace std;
|
|
void
|
|
GDALAccessor::init (void * poly)
|
|
{
|
|
return;
|
|
}
|
|
void
|
|
GDALAccessor::finalize ()
|
|
{
|
|
if (FileObject != NULL)
|
|
{
|
|
std::cout << "GDAL close: " << Filename << std::endl;
|
|
GDALClose ((GDALDatasetH) FileObject);
|
|
}
|
|
if (!(Data == NULL))
|
|
{
|
|
delete[] Data;
|
|
}
|
|
}
|
|
void
|
|
GDALAccessor::init (string filename, string accessMode, int sizeV, int Bands,
|
|
int LineWidth)
|
|
{
|
|
init (filename, accessMode,sizeV);
|
|
}
|
|
void
|
|
GDALAccessor::init (string filename, string accessMode, int sizeV)
|
|
{
|
|
setAccessMode (accessMode);
|
|
|
|
Filename = filename;
|
|
openFile (Filename, AccessMode, &FileObject);
|
|
LineWidth = FileObject->GetRasterXSize ();
|
|
NumberOfLines = FileObject->GetRasterYSize ();
|
|
DataType = (GDALDataType) sizeV;
|
|
Bands = FileObject->GetRasterCount ();
|
|
SizeV = GDALGetDataTypeSize (DataType) / 8; //the function returns # bits
|
|
FileSize = LineWidth * NumberOfLines * Bands * SizeV;
|
|
}
|
|
|
|
void
|
|
GDALAccessor::rewindAccessor ()
|
|
{
|
|
LastPosition = 0;
|
|
EofFlag = 0;
|
|
}
|
|
int
|
|
GDALAccessor::getFileLength ()
|
|
{
|
|
return NumberOfLines;
|
|
}
|
|
void
|
|
GDALAccessor::createFile (int numberOfLines)
|
|
{
|
|
//TODO
|
|
}
|
|
|
|
void
|
|
GDALAccessor::openFile (string filename, string accessMode, GDALDataset ** fd)
|
|
{
|
|
|
|
if (accessMode == "read" || accessMode == "READ")
|
|
{
|
|
std::cout << "GDAL open (R): " << filename << std::endl;
|
|
(*fd) = (GDALDataset *) GDALOpenShared (filename.c_str (), GA_ReadOnly);
|
|
if ((*fd) == NULL)
|
|
{
|
|
cout << "Error. Cannot open the file " << filename << " in "
|
|
<< accessMode << " mode." << endl;
|
|
ERR_MESSAGE
|
|
;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
cout << "Error. Only read mode is available and not " << accessMode
|
|
<< " mode." << endl;
|
|
ERR_MESSAGE
|
|
;
|
|
}
|
|
|
|
}
|
|
//The IORaster can read all the bands at once but the data is read one band at the time.
|
|
//This means that one has to know the interleaved scheme and reassemble the data into a stream.
|
|
//Just assume that is one band image or that the user created the appropriate vrt file to read all at once
|
|
void
|
|
GDALAccessor::getStream (char * dataLine, int & numEl)
|
|
{
|
|
//NOTE: arguments 4 and 5 (nXSize and nYSize) are one based
|
|
|
|
int ypos0 = LastPosition / LineWidth;
|
|
int xpos0 = LastPosition % LineWidth;
|
|
LastPosition += numEl;
|
|
int ypos1 = (LastPosition - std::streampos(1)) / LineWidth;
|
|
if (LastPosition * SizeV >= FileSize)
|
|
{
|
|
numEl -= LastPosition % LineWidth;
|
|
LastPosition = 0;
|
|
ypos1 = NumberOfLines - 1;
|
|
|
|
}
|
|
|
|
char buf[SizeV * (ypos1 - ypos0 + 1) * LineWidth];
|
|
FileObject->RasterIO (GF_Read, 0, ypos0, LineWidth, ypos1 - ypos0 + 1, buf,
|
|
LineWidth, ypos1 - ypos0 + 1, DataType, 1, NULL, 0, 0,
|
|
0, NULL);
|
|
for (int i = 0; i < numEl; ++i)
|
|
{
|
|
for (int j = 0; j < SizeV; ++j)
|
|
{
|
|
dataLine[i * SizeV + j] = buf[xpos0 * SizeV + i * SizeV + j];
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
GDALAccessor::getStreamAtPos (char * dataLine, int & pos, int & numEl)
|
|
{
|
|
if (pos * SizeV >= FileSize)
|
|
{
|
|
numEl = 0;
|
|
}
|
|
else
|
|
{
|
|
//put pos in npos since it changes and pos is by reference.
|
|
//should not have passed by reference since it is not modified
|
|
int npos = pos;
|
|
int ypos0 = npos / LineWidth;
|
|
int xpos0 = npos % LineWidth;
|
|
npos += numEl;
|
|
int ypos1 = (npos - 1) / LineWidth;
|
|
if (npos * SizeV >= FileSize)
|
|
{
|
|
numEl -= npos % LineWidth;
|
|
ypos1 = NumberOfLines - 1;
|
|
}
|
|
char buf[SizeV * (ypos1 - ypos0 + 1) * LineWidth];
|
|
FileObject->RasterIO (GF_Read, 0, ypos0, LineWidth, ypos1 - ypos0 + 1,
|
|
buf, LineWidth, ypos1 - ypos0 + 1, DataType, 1,
|
|
NULL, 0, 0, 0, NULL);
|
|
for (int i = 0; i < numEl; ++i)
|
|
{
|
|
for (int j = 0; j < SizeV; ++j)
|
|
{
|
|
dataLine[i * SizeV + j] = buf[xpos0 * SizeV + i * SizeV + j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
void
|
|
GDALAccessor::setData (char * buf, int row, int col, int numEl)
|
|
{
|
|
//TO DO once we start with new formats
|
|
return;
|
|
}
|
|
|
|
void
|
|
GDALAccessor::setDataBand (char* buf, int row, int col, int numEl, int band)
|
|
{
|
|
//TO DO once we start with new formats
|
|
return;
|
|
}
|
|
|
|
//Since GDAL RasterIO returns the data in BSQ (band sequential) no matter what the underlying scheme is
|
|
//we don't need a reader for each interleaved scheme
|
|
void
|
|
GDALAccessor::getData (char * buf, int row, int col, int & numEl)
|
|
{
|
|
int ypos0 = row;
|
|
int xpos0 = col;
|
|
int ypos1 = ypos0 + (xpos0 + numEl - 1) / LineWidth;
|
|
|
|
//make sure we don't go over
|
|
if (ypos1 >= NumberOfLines)
|
|
{
|
|
ypos1 = NumberOfLines - 1;
|
|
//adjust number of elements read
|
|
numEl -= (xpos0 + numEl - 1) % LineWidth;
|
|
EofFlag = -1;
|
|
}
|
|
|
|
//B. Riel: 05/19/17: additional check for ypos0 to prevent negative allocation size
|
|
if (ypos0 > ypos1)
|
|
{
|
|
ypos0 = ypos1;
|
|
}
|
|
|
|
//get every band at once. Read enough line to fit all the data. GDAL read one band after the other
|
|
//i.e. band sequential scheme
|
|
char dataLine[SizeV * (ypos1 - ypos0 + 1) * LineWidth * Bands];
|
|
CPLErr err = FileObject->RasterIO (GF_Read, 0, ypos0, LineWidth, ypos1 - ypos0 + 1,
|
|
dataLine, LineWidth, ypos1 - ypos0 + 1, DataType,
|
|
Bands, NULL, 0, 0, 0, NULL);
|
|
|
|
for (int i = 0; i < numEl; ++i)
|
|
{
|
|
for (int j = 0; j < Bands; ++j)
|
|
{
|
|
|
|
for (int k = 0; k < SizeV; ++k)
|
|
{
|
|
|
|
buf[i * Bands * SizeV + j * SizeV + k] = dataLine[xpos0 * SizeV
|
|
+ i * SizeV
|
|
+ j * SizeV * (ypos1 - ypos0 + 1) * LineWidth + k];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//Similarly as above the RasterIO already returns the band. Just put it into the buffer
|
|
void
|
|
GDALAccessor::getDataBand (char * buf, int row, int col, int &numEl, int band)
|
|
{
|
|
GDALRasterBand *poBand;
|
|
//NOTE GDAL band counting is 1 based
|
|
poBand = FileObject->GetRasterBand (band + 1);
|
|
int ypos0 = row;
|
|
int xpos0 = col;
|
|
int ypos1 = ypos0 + (xpos0 + numEl - 1) / LineWidth;
|
|
//make sure we don't go over
|
|
if (ypos1 >= NumberOfLines)
|
|
{
|
|
ypos1 = NumberOfLines - 1;
|
|
//adjust number of elements read
|
|
numEl -= (xpos0 + numEl - 1) % LineWidth;
|
|
EofFlag = -1;
|
|
}
|
|
//get every band at once. Read enough line to fit all the data. GDAL read one band after the other
|
|
//i.e. band sequential scheme
|
|
char dataLine[SizeV * (ypos1 - ypos0 + 1) * LineWidth];
|
|
poBand->RasterIO (GF_Read, 0, ypos0, LineWidth, ypos1 - ypos0 + 1, dataLine,
|
|
LineWidth, ypos1 - ypos0 + 1, DataType, 0, 0);
|
|
|
|
for (int i = 0; i < numEl; ++i)
|
|
{
|
|
for (int k = 0; k < SizeV; ++k)
|
|
{
|
|
buf[i * SizeV + k] = dataLine[xpos0 * SizeV + i * SizeV + k];
|
|
}
|
|
|
|
}
|
|
}
|
|
void
|
|
GDALAccessor::setStream (char * dataLine, int numEl)
|
|
{
|
|
|
|
}
|
|
void
|
|
GDALAccessor::setStreamAtPos (char * dataLine, int & pos, int & numEl)
|
|
{
|
|
|
|
}
|
|
|