Files
secondo/Algebras/Raster2/Import/Import.h

1219 lines
31 KiB
C
Raw Normal View History

2026-01-23 17:03:45 +08:00
/*
This file is part of SECONDO.
Copyright (C) 2011, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RASTER2_IMPORT_H
#define RASTER2_IMPORT_H
#include "FileSystem.h"
#include "WinUnix.h"
#include "satof.h"
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <limits>
#include <cmath>
namespace raster2
{
class RasterData
{
public:
// constructors
RasterData(bool earthOrigin){
origin.north = -1;
origin.south = -1;
origin.east = -1;
origin.west = -1;
useEarthOrigin = earthOrigin;
endianTypeLittle = isLittleEndian();
undefValueHGT = -32768; //given by HGT file format
// minimum signed 32bit integer
// nodata values taken from gdal library
// frmts/aigrid/aigrid.h, line 37
undefValueEsriGrid = -2147483647;
undefValueEsriGridFloat =
-340282346638528859811704183484516925440.0;
ImportHGTExtend = -1; //HGT extend only 3601x3601 or 1201x1201
}
// destructor
virtual ~RasterData(){};
// getter
int getPageSize(){
return PageSize;
}
int getGridSize(){
return GridSize;
}
bool getEndianTypeLittle() {
return endianTypeLittle;
}
/*This section covers common functions*/
bool endsWith(const std::string& a1, const std::string& a2){
size_t len1 = a1.length();
size_t len2 = a2.length();
if(len2 > len1){
return false;
}
return a1.substr(len1-len2)==a2;
}
bool isLittleEndian() {
int endian_detect = 1;
return *(char *)&endian_detect == 1;
}
float convertFloat(const float inFloat)
{
float retVal;
char *floatToConvert = ( char* ) & inFloat;
char *returnFloat = ( char* ) & retVal;
// swap the bytes into a temporary buffer
returnFloat[0] = floatToConvert[3];
returnFloat[1] = floatToConvert[2];
returnFloat[2] = floatToConvert[1];
returnFloat[3] = floatToConvert[0];
return retVal;
}
uint64_t convertEndian(const uint64_t n){
uint64_t x = n;
return (x>>56) |
((x<<40) & 0x00FF000000000000ull) |
((x<<24) & 0x0000FF0000000000ull) |
((x<<8) & 0x000000FF00000000ull) |
((x>>8) & 0x00000000FF000000ull) |
((x>>24) & 0x0000000000FF0000ull) |
((x>>40) & 0x000000000000FF00ull) |
(x<<56);
}
int16_t convertEndian(int16_t x){
return (( x & 0x00FF) << 8) | ( ( x & 0xFF00) >> 8);
}
int16_t convert16BitEndian(const int16_t n) {
int16_t value = n;
return ((value << 8) | ((value >> 8) & 0xFF));
}
int32_t convertEndian(int32_t val)
{
int32_t tmp = val;
return (tmp << 24) |
((tmp << 8) & 0x00ff0000) |
((tmp >> 8) & 0x0000ff00) |
((tmp >> 24) & 0x000000ff);
}
uint32_t convertEndian(const uint32_t n)
{
uint32_t x = n;
return ((x & 0xFF) << 24) |
((x & 0xFF00) << 8) |
((x & 0xFF0000) >> 8) |
((x & 0xFF000000)>> 24);
}
/*This section covers Functions related to HGT import*/
int getImportHGTExtend(){
return ImportHGTExtend;
}
int getOriginNorth() {
return origin.north;
}
int getOriginSouth() {
return origin.south;
}
int getOriginEast() {
return origin.east;
}
int getOriginWest() {
return origin.west;
}
int getOffsetNorth() {
return offset.north;
}
int getOffsetSouth() {
return offset.south;
}
int getOffsetEast() {
return offset.east;
}
int getOffsetWest() {
return offset.west;
}
int getHGTUndef() {
return undefValueHGT;
}
void calculateCoordinates(std::string LengthOrientation,
int LengthOrientationValue,
std::string WidthOrientation,
int WidthOrientationValue){
if(WidthOrientation.compare("N") == 0){ //OK
if(origin.north == -1){
if(origin.south == -1) {
useEarthOrigin ?
origin.north = 0 :
origin.north = WidthOrientationValue;
useEarthOrigin ?
offset.north = WidthOrientationValue :
offset.north = 0;
} else
offset.south = origin.south + WidthOrientationValue;
} else
offset.north = WidthOrientationValue - origin.north;
}
if(WidthOrientation.compare("S") == 0){ //OK
if(origin.south == -1){
if(origin.north == -1){
useEarthOrigin ?
origin.south = 0 :
origin.south = WidthOrientationValue;
useEarthOrigin ?
offset.south = 0 - WidthOrientationValue :
offset.south = 0;
} else
offset.north = 0 - (origin.north + WidthOrientationValue);
} else
offset.south = origin.south - WidthOrientationValue;
}
if(LengthOrientation.compare("E") == 0){ //OK
if(origin.east == -1){
if(origin.west == -1) {
useEarthOrigin ?
origin.east = 0 :
origin.east = LengthOrientationValue;
useEarthOrigin ?
offset.east = LengthOrientationValue :
offset.east = 0;
} else
offset.west = origin.west + LengthOrientationValue;
} else
offset.east = LengthOrientationValue - origin.east;
}
if(LengthOrientation.compare("W") == 0){ //OK
if(origin.west == -1){
if(origin.east == -1) {
useEarthOrigin ?
origin.west = 0 :
origin.west = LengthOrientationValue;
useEarthOrigin ?
offset.west = 0 - LengthOrientationValue :
offset.west = 0;
} else
offset.east = 0 - (origin.east + LengthOrientationValue);
} else
offset.west = origin.west - LengthOrientationValue;
}
}
int getYOffset() {
if( origin.north != -1)
return offset.north;
if(origin.south != -1)
return offset.south;
return 0;
}
int getXOffset() {
if(origin.east != -1)
return offset.east;
if(origin.west != -1)
return offset.west;
return 0;
}
void setOriginNorth(int originNorth) {
origin.north = originNorth;
}
void setOriginSouth(int originSouth) {
origin.south = originSouth;
}
void setOriginEast(int originEast) {
origin.east = originEast;
}
void setOriginWest(int originWest) {
origin.west = originWest;
}
std::string getWidthOrientationFromFileName(const std::string HGTFile){
std::string filename = HGTFile.substr(HGTFile.find_last_of("/") + 1);
transform(filename.begin(), filename.end(),
filename.begin(), ::toupper);
return filename.substr(0, 1);
}
std::string getLengthOrientationFromFileName(const std::string HGTFile){
std::string filename = HGTFile.substr(HGTFile.find_last_of("/") + 1);
transform(filename.begin(), filename.end(),
filename.begin(), ::toupper);
return filename.substr(3, 1);
}
int getWidthOrientationValueFromFileName(const std::string HGTFile){
std::string filename = HGTFile.substr(HGTFile.find_last_of("/") + 1);
return atoi(filename.substr(1, 2).c_str());
}
int getLengthOrientationValueFromFileName(const std::string HGTFile){
std::string filename = HGTFile.substr(HGTFile.find_last_of("/") + 1);
return atoi(filename.substr(4, 3).c_str());
}
int getHGTExtendfromFile(const std::string currentHGTFile) {
double currentHGTFileSize =
FileSystem::GetFileSize(currentHGTFile.c_str());
if(currentHGTFileSize == -1){
std::cout << "Error accessing file " << currentHGTFile.c_str() << std::endl;
return -1;
}
// HGT Files are written in 16bit signed integer, gives two bytes
int currentValueCount = currentHGTFileSize / 2;
return sqrt(currentValueCount);
}
bool checkHGTFile(std::string currentHGTFile, int currentHGTExtend) {
if(checkHGTExtend(currentHGTExtend)){
std::cout << "Grid extend : " << currentHGTExtend -1
<< "x" << currentHGTExtend - 1 << std::endl;
} else {
std::cout << "Wrong grid extend, skipping file" << std::endl;
return false;
}
if(!checkGeoCoordinates(
getLengthOrientationFromFileName(currentHGTFile),
getLengthOrientationValueFromFileName(currentHGTFile),
getWidthOrientationFromFileName(currentHGTFile),
getWidthOrientationValueFromFileName(currentHGTFile))){
return false;
}
if(!checkHGTFileExtension(currentHGTFile))
return false;
return true;
}
bool checkHGTExtend(int currentHGTExtend){
if(currentHGTExtend != 3601 && currentHGTExtend != 1201)
return false;
if(ImportHGTExtend == -1)
ImportHGTExtend = currentHGTExtend;
if(currentHGTExtend == ImportHGTExtend)
return true;
else
return false;
}
bool checkGeoCoordinates(std::string LengthOrientation,
int LengthOrientationValue,
std::string WidthOrientation,
int WidthOrientationValue){
if(LengthOrientationValue > 180){
std::cout << "Length orientation value is out of range"
<< std::endl << std::endl;
return false;
}
if(WidthOrientationValue > 90){
std::cout << "Width orientation value is out of range"
<< std::endl << std::endl;
return false;
}
if((WidthOrientation.compare("N") != 0) &&
(WidthOrientation.compare("S") != 0)) {
std::cout << "Width orientation not valid" << std::endl << std::endl;
return false;
}
if((LengthOrientation.compare("E") != 0) &&
(LengthOrientation.compare("W") != 0)) {
std::cout << "Length orientation not valid" << std::endl << std::endl;
return false;
}
return true;
}
bool checkHGTFileExtension(std::string currentHGTFile){
transform(currentHGTFile.begin(), currentHGTFile.end(),
currentHGTFile.begin(), ::tolower);
if(!endsWith(currentHGTFile.c_str(),".hgt")){
std::cout << "Wrong file type, skipping file" << std::endl;
return false;
}
return true;
}
int16_t* getHGTData(const std::string HGTFile) {
std::ifstream* f =
new std::ifstream(HGTFile.c_str(),
std::ios::in|std::ios::binary|std::ios::ate);
if(!f->is_open()){
delete f;
f = 0;
std::cerr << "Failed to open HGT File" << std::endl;
return NULL;
}
// go to begin of file
f->seekg (0, std::ios::beg);
int16_t* buffer = new int16_t[ImportHGTExtend*ImportHGTExtend];
// read the complete file into buffer
f->read( (char*) buffer, ImportHGTExtend*ImportHGTExtend*2);
if(!f->good()){
std::cerr << "error in reading from file" << std::endl;
f->close();
delete f;
delete[] buffer;
return NULL;
}
f->close();
delete f;
f = 0;
return buffer;
}
/*
This section covers Functions related to Esri Grid import
*/
struct EsriGridHDRData {
std::string HMagic;
int32_t HCellType;
int32_t CompFlag;
int32_t HTilesPerRow;
int32_t HTilesPerColumn;
int32_t HTileXSize;
int32_t HTileYSize;
double HPixelSizeX;
double HPixelSizeY;
double XRef;
double YRef;
} currentGridHDR;
/*
Esri Grid Config Data from the Esri config files.
*/
struct EsriGridConfigData {
std::string filePath; // the esri grid file path
double llxCoord; // Lower left X (easting) of the grid.
double llyCoord; // Lower left Y (northing) of the grid.
double urxCoord; // Upper right X (easting) of the grid.
double uryCoord; // Upper right Y (northing) of the grid.
size_t fileSize;
size_t numTiles;
size_t actualNumberOfColumns;
size_t actualNumberOfRows;
// Minimum value of a raster cell in this grid.
double esriGridMinimum;
// Maximum value of a raster cell in this grid.
double esriGridMaxmimum;
} esriGridConfigData;
int getEsriGridUndef() {
return undefValueEsriGrid;
}
float getEsriGridFloatUndef() {
return undefValueEsriGridFloat;
}
/*
Delivers the integer value for bit data value RTileTypes
0x01 and 0x04.
*/
int getIntBitDataValueByRTileType(
std::ifstream *fileStream,
const uint8_t *rTileType,
int pixelCounter)
{
int bitDataValue = 0;
const uint8_t tileType = *rTileType;
char valueBlock[1];
fileStream->read(valueBlock, 1);
unsigned char *byteValue =
&(*(unsigned char*)&(valueBlock));
// (raw 1bit data)
if (tileType == 0x01)
{
// algorithm taken from gdal library
// frmts/aigrid/gridlib.c, line 214
if(byteValue[pixelCounter>>3] &
(0x80 >> (pixelCounter & 0x7)))
{
bitDataValue = 1;
}
else
{
bitDataValue = 0;
}
}
// (raw 4bit data)
else if (tileType == 0x04)
{
// algorithm taken from gdal library
// frmts/aigrid/gridlib.c, line 180
if (pixelCounter % 2 == 0)
{
bitDataValue = ((*(byteValue) & 0xf0) >> 4);
}
else {
bitDataValue = (*(byteValue++) & 0xf);
}
}
else
{
std::cout << std::endl;
std::cout << "Could not determine bit data value";
std::cout << " from rTileType";
std::cout << std::endl;
}
return bitDataValue;
}
/*
Delivers the integer value for length encoded RTileTypes.
*/
int getIntValueByRTileType(
std::ifstream *fileStream,
const uint8_t *rTileType,
int pixelCounter)
{
int intValue = 0;
const uint8_t tileType = *rTileType;
// (run length encoded 32bit)
if (
(tileType == 0xE0) ||
(tileType == 0x20))
{
int32_t int32 = getInt32FromFileStream(fileStream);
intValue = (int)int32;
if (isLittleEndian())
{
intValue = ((int) convertEndian(int32));
}
}
// (run length encoded 16bit)
else if (
(tileType == 0xF0) ||
(tileType == 0x10))
{
int16_t int16 = getInt16FromFileStream(fileStream);
if (isLittleEndian())
{
int16 = convert16BitEndian(int16);
}
intValue = (int)int16;
}
// (run length encoded 8bit)
else if (
(tileType == 0x08) ||
(tileType == 0xFC) ||
(tileType == 0xF8))
{
intValue =
(int)getUInt8FromFileStream(fileStream);
}
// (raw 1bit/4bit data)
else if (
(tileType == 0x01) ||
(tileType == 0x04))
{
intValue = getIntBitDataValueByRTileType(
fileStream, rTileType, pixelCounter);
}
else
{
std::cout << std::endl;
std::cout << "Could not determine intValue from rTileType";
std::cout << std::endl;
}
return intValue;
}
double getDouble(char* buffer, int offset){
uint64_t i = *( uint64_t*)&(buffer[offset]);
if(endianTypeLittle){
i = convertEndian(i);
}
double res = 0;
double* pres = static_cast<double*>(static_cast<void*>(&i));
if(pres != 0)
{
res = *pres;
}
return res;
}
int32_t getInt32(char* buffer, int offset){
int32_t i = *( int32_t*)&(buffer[offset]);
if(endianTypeLittle){
i = convertEndian(i);
}
return i;
}
uint32_t getUInt32(char* buffer, int offset){
uint32_t i = *( uint32_t*)&(buffer[offset]);
if(endianTypeLittle){
i = convertEndian(i);
}
return i;
}
/*
Reads a 4 byte block from the current position
of a given fileStream.
*/
int32_t getInt32FromFileStream(std::ifstream *fileStream)
{
int32_t Int32 = 0;
char valueBlock[4];
fileStream->read(valueBlock, 4);
int32_t* pInt32 = reinterpret_cast<int32_t*>(&valueBlock);
if(pInt32 != 0)
{
Int32 = *pInt32;
}
return Int32;
}
/*
Reads short signed int from the current position
of a given fileStream.
*/
int16_t getInt16FromFileStream(std::ifstream *fileStream)
{
int16_t Int16 = 0;
char valueBlock[2];
fileStream->read(valueBlock, 2);
int16_t* pInt16 = reinterpret_cast<int16_t*>(&valueBlock);
if(pInt16 != 0)
{
Int16 = *pInt16;
}
return Int16;
}
/*
Reads an unsigned char integer from the current position
of a given fileStream.
*/
uint8_t getUInt8FromFileStream(std::ifstream *fileStream) {
uint8_t uint8 = 0;
char valueBlock[1];
fileStream->read(valueBlock, 1);
uint8_t* puInt8 = reinterpret_cast<uint8_t*>(&valueBlock);
if(puInt8 != 0)
{
uint8 = *puInt8;
}
return uint8;
}
/*
Reads a signed char integer from the current position
of a given fileStream.
*/
int8_t getInt8FromFileStream(std::ifstream *fileStream) {
int8_t int8 = 0;
char valueBlock[1];
fileStream->read(valueBlock, 1);
int8_t* pInt8 = reinterpret_cast<int8_t*>(&valueBlock);
if(pInt8 != 0)
{
int8 = *pInt8;
}
return int8;
}
/*
Reads a signed int from the current position
of a given fileStream and a given number of bytes.
*/
int getIntFromFileStream(std::ifstream *fileStream, const uint8_t byteSize)
{
int result = 0;
if ((int)byteSize == 0)
{
result = 0;
}
else if ((int)byteSize == 1)
{
result = (int)getInt8FromFileStream(fileStream);
}
else if ((int)byteSize == 2)
{
int16_t int16 = getInt16FromFileStream(fileStream);
if (isLittleEndian())
{
int16 = convert16BitEndian(int16);
}
result = (int)int16;
}
else if ((int)byteSize == 4)
{
int32_t int32 = getInt32FromFileStream(fileStream);
if (isLittleEndian())
{
int32 = convertEndian(int32);
}
result = (int)int32;
}
return result;
}
bool CellTypeReal(){
return currentGridHDR.HCellType == 2;
}
int32_t getCellTypeFromFile(std::string HDRFile){
int32_t celltype = -1;
int celltypeOffset = 16;
if(endsWith(HDRFile, "/"))
HDRFile.append("hdr.adf");
else
HDRFile.append("/hdr.adf");
std::ifstream* f =
new std::ifstream(HDRFile.c_str(),
std::ios::in|std::ios::binary|std::ios::ate);
if(!f->is_open()){
delete f;
f = 0;
return -1;
}
char buffer[sizeof(int32_t)];
f->seekg(celltypeOffset, std::ios::beg);
f->read(buffer, sizeof(int32_t));
celltype = getInt32(buffer,0);
if(!f->good()){
f->close();
delete f;
return -1;
}
f->close();
delete f;
f = 0;
return celltype;
}
int getEsriGridHDR(std::string HDRFile) {
esriGridConfigData.filePath = HDRFile;
if(endsWith(HDRFile, "/")) {
HDRFile.append("hdr.adf");
}
else {
esriGridConfigData.filePath.append("/");
HDRFile.append("/hdr.adf");
}
size_t HDRFileSize =
FileSystem::GetFileSize(HDRFile.c_str());
std::ifstream* f =
new std::ifstream(HDRFile.c_str(),
std::ios::in|std::ios::binary|std::ios::ate);
if(!f->is_open()){
delete f;
f = 0;
std::cerr << "Failed to open HDR File" << std::endl;
return 1;
}
// read the complete file into buffer
char buffer[HDRFileSize];
f->seekg (0, std::ios::beg);
f->read( buffer, HDRFileSize);
if(!f->good()){
std::cerr << "error in reading from file" << std::endl;
f->close();
delete f;
return 1;
}
std::string HMagic(buffer,8);
currentGridHDR.HMagic = HMagic;
currentGridHDR.HCellType = getInt32(buffer,16);
currentGridHDR.CompFlag = getInt32(buffer,20);
currentGridHDR.HPixelSizeX = getDouble(buffer,256);
currentGridHDR.HPixelSizeY = getDouble(buffer,264);
currentGridHDR.XRef = getDouble(buffer,272);
currentGridHDR.YRef = getDouble(buffer,280);
currentGridHDR.HTilesPerRow = getInt32(buffer,288);
currentGridHDR.HTilesPerColumn = getInt32(buffer,292);
currentGridHDR.HTileXSize = getInt32(buffer,296);
currentGridHDR.HTileYSize = getInt32(buffer,304);
f->close();
delete f;
f = 0;
return 0;
}
/*
This section covers Functions related to Esri Raster import
*/
struct EsriRasterHDRData {
int ncols;
int nrows;
double xllcorner;
double xllcenter;
double yllcorner;
double yllcenter;
double cellsize;
int extend;
int nodata_value;
size_t posValues;
size_t filesize;
} originEsriHDR, currentEsriHDR;
int getIntValue(std::string line, size_t offset){
int value = -1;
size_t posA = line.find_first_of(" ");
size_t pos=line.find_first_not_of(" ", posA);
if(pos!=std::string::npos){
std::string buffer = line.substr(pos, (line.length() - pos));
value = atoi(buffer.c_str());
}
return value;
}
double getDoubleValue(std::string line, size_t offset){
double value = -1.0;
size_t posA = line.find_first_of(" ");
size_t pos=line.find_first_not_of(" ", posA);
if(pos!=std::string::npos){
std::string buffer = line.substr(pos, (line.length() - pos));
value = satof(buffer.c_str());
}
return value;
}
int getEsriRasterHDR(std::string RasterFile, bool init) {
std::ifstream* f =
new std::ifstream(RasterFile.c_str(), std::ios::in);
if(!f->is_open()){
delete f;
f = 0;
std::cerr << "Failed to open Esri Raster File" << std::endl;
return 1;
}
size_t header = 0;
size_t valuepos;
char buffer[1000];
//initialize data structs
if(init)
memset(&originEsriHDR, -1, sizeof (originEsriHDR));
memset(&currentEsriHDR, -1, sizeof (currentEsriHDR));
//get filesize
if(init)
originEsriHDR.filesize =
FileSystem::GetFileSize(RasterFile.c_str());
currentEsriHDR.filesize =
FileSystem::GetFileSize(RasterFile.c_str());
//default, will be overwritten if differs
if(init)
originEsriHDR.nodata_value = -9999;
currentEsriHDR.nodata_value = -9999;
//reading the header
while((header != std::string::npos)) {
f->getline(buffer, 1000, '\n');
std::string name = buffer;
transform(name.begin(), name.end(),
name.begin(), ::tolower);
valuepos = name.find("ncols");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.ncols = getIntValue(name, valuepos);
currentEsriHDR.ncols = getIntValue(name, valuepos);
}
valuepos = name.find("nrows");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.nrows = getIntValue(name, valuepos);
currentEsriHDR.nrows = getIntValue(name, valuepos);
}
valuepos = name.find("xllcorner");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.xllcorner = getDoubleValue(name, valuepos);
currentEsriHDR.xllcorner = getDoubleValue(name, valuepos);
}
valuepos = name.find("xllcenter");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.xllcenter = getDoubleValue(name, valuepos);
currentEsriHDR.xllcenter = getDoubleValue(name, valuepos);
}
valuepos = name.find("yllcorner");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.yllcorner = getDoubleValue(name, valuepos);
currentEsriHDR.yllcorner = getDoubleValue(name, valuepos);
}
valuepos = name.find("yllcenter");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.yllcenter = getDoubleValue(name, valuepos);
currentEsriHDR.yllcenter = getDoubleValue(name, valuepos);
}
valuepos = name.find("cellsize");
if (valuepos != std::string::npos){
if(init){
originEsriHDR.cellsize = getDoubleValue(name, valuepos);
originEsriHDR.extend =
static_cast<int>((1/originEsriHDR.cellsize)+0.5);
}
currentEsriHDR.cellsize = getDoubleValue(name, valuepos);
currentEsriHDR.extend =
static_cast<int>((1/currentEsriHDR.cellsize)+0.5);
}
valuepos = name.find("nodata_value");
if (valuepos != std::string::npos){
if(init)
originEsriHDR.nodata_value = getIntValue(name, valuepos);
currentEsriHDR.nodata_value = getIntValue(name, valuepos);
}
header =
name.find_first_of("abcdefghijklmnopqrstuvwxyz", 0);
if(header == 0){
if(init)
originEsriHDR.posValues = 1 + f->tellg();
currentEsriHDR.posValues = 1 + f->tellg();
}
}
f->close();
delete f;
f = 0;
if(!validateHeaderData()){
std::cout << "Wrong header information." << std::endl;
return 1;
}
return 0;
}
bool validateHeaderData(){
return (currentEsriHDR.ncols != -1) &&
(currentEsriHDR.nrows != -1) &&
!std::isnan(currentEsriHDR.cellsize) &&
(getUseCorner() || getUseCenter());
}
bool getUseCorner(){
return std::isnan(originEsriHDR.xllcenter) &&
std::isnan(currentEsriHDR.xllcenter) &&
std::isnan(originEsriHDR.yllcenter) &&
std::isnan(currentEsriHDR.yllcenter);
}
bool getUseCenter(){
return std::isnan(originEsriHDR.xllcorner) &&
std::isnan(currentEsriHDR.xllcorner) &&
std::isnan(originEsriHDR.yllcorner) &&
std::isnan(currentEsriHDR.yllcorner);
}
bool checkRasterExtend(){
bool extendOK = true;
if(originEsriHDR.cellsize != currentEsriHDR.cellsize){
std::cout << "Wrong Raster extend, skipping file" << std::endl;
extendOK = false;
} else {
std::cout << "Grid extend : " << currentEsriHDR.extend
<< "x" << currentEsriHDR.extend << std::endl;
}
return extendOK;
}
int getRasterXOffset() {
if(getUseCorner())
return (currentEsriHDR.xllcorner - originEsriHDR.xllcorner)
* originEsriHDR.extend;
if(getUseCenter())
return (currentEsriHDR.xllcenter - originEsriHDR.xllcenter)
* originEsriHDR.extend;
return std::numeric_limits<int>::min();
}
int getRasterYOffset() {
if(getUseCorner())
return (currentEsriHDR.yllcorner - originEsriHDR.yllcorner)
* originEsriHDR.extend;
if(getUseCenter())
return (currentEsriHDR.yllcenter - originEsriHDR.yllcenter)
* originEsriHDR.extend;
return std::numeric_limits<int>::min();
}
bool checkRasterOffset(int XOffset, int YOffset){
bool offsetOK = true;
if((XOffset == std::numeric_limits<int>::min()) ||
(YOffset == std::numeric_limits<int>::min())){
std::cout << "Invalid offset, skipping file" << std::endl;
offsetOK = false;
}
return offsetOK;
}
bool checkNumber(char *value){
bool numberOK = true;
std::string number = value;
size_t pos = number.find_first_not_of("-0123456789.\n\r", 0);
if(number.empty() || pos != std::string::npos)
numberOK = false;
return numberOK;
}
double* getEsriRasterData(const std::string EsriRasterFile) {
std::ifstream* f =
new std::ifstream(EsriRasterFile.c_str(), std::ios::in);
if(!f->is_open()){
delete f;
f = 0;
std::cerr << "Failed to open ASCII File" << std::endl;
return NULL;
}
long allValues = currentEsriHDR.nrows * currentEsriHDR.ncols;
long unit = allValues/100;
double* buffer = new double[allValues];
char value[50];
f->seekg(currentEsriHDR.posValues, std::ios::beg);
std::cout << "Consistency : ";
for(int row = 0; row < currentEsriHDR.nrows; row++){
for(int col = 0; col < currentEsriHDR.ncols; col++){
f->getline(value, 50, ' ');
//If end of file is reached, something is wrong with the file.
if(checkNumber(value)){
buffer[(row*currentEsriHDR.ncols) + col] = satof(value);
if(f->eof()){
if((row != currentEsriHDR.nrows-1) ||
col != currentEsriHDR.ncols-1){
std::cout << "\rConsistency : failed, skipping file" << std::endl;
row = currentEsriHDR.nrows;
col = currentEsriHDR.ncols;
buffer = NULL;
} else
std::cout << "\rConsistency : OK " << std::endl;
} else {
//calculate percentage of progress
if(allValues > 99){
if(((row == 0) && (col == 0)) ||
((((row * currentEsriHDR.ncols)+(col+1)) % unit == 0) &&
(((row * currentEsriHDR.ncols)+(col+1)) >= unit))){
std::cout << "\rConsistency : "
<< ((row * currentEsriHDR.ncols)+(col+1))
/ unit << "%";
fflush (stdout);
}
}
}
} else {
std::cout << "\rConsistency : failed, skipping file" << std::endl;
row = currentEsriHDR.nrows;
col = currentEsriHDR.ncols;
buffer = NULL;
}
}
}
f->close();
delete f;
f = 0;
return buffer;
}
/*This section covers interim Functions*/
std::vector<std::string> buildFilesVector(std::string HGTDataRoot);
bool checkRootIsValid(std::string HGTDataRoot);
int ImportHGT(const std::string HGTDataRoot);
int processFile(std::string HGTFile);
private:
RasterData(){}
int PageSize;
int GridSize;
int ImportHGTExtend;
int undefValueHGT;
int undefValueEsriGrid;
float undefValueEsriGridFloat;
bool useEarthOrigin;
bool endianTypeLittle;
struct GeoCoordinates {
int north;
int south;
int east;
int west;
} origin, offset;
};
}
#endif // RASTER2_IMPORT_H