/* 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 #include #include #include #include #include #include #include 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(static_cast(&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(&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(&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(&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(&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(¤tEsriHDR, -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((1/originEsriHDR.cellsize)+0.5); } currentEsriHDR.cellsize = getDoubleValue(name, valuepos); currentEsriHDR.extend = static_cast((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::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::min(); } bool checkRasterOffset(int XOffset, int YOffset){ bool offsetOK = true; if((XOffset == std::numeric_limits::min()) || (YOffset == std::numeric_limits::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 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