diff --git a/src/Lib/Array/array.cxx b/src/Lib/Array/array.cxx index ed2b186c..737ebcdc 100644 --- a/src/Lib/Array/array.cxx +++ b/src/Lib/Array/array.cxx @@ -30,6 +30,7 @@ #include #include #include +#include #include "array.hxx" @@ -38,22 +39,18 @@ using std::string; TGArray::TGArray( void ): array_in(NULL), - fitted_in(NULL) + fitted_in(NULL), + in_data(NULL) { - SG_LOG(SG_GENERAL, SG_DEBUG, "class TGArray CONstructor called." ); - in_data = new int[ARRAY_SIZE_1 * ARRAY_SIZE_1]; + } TGArray::TGArray( const string &file ): array_in(NULL), - fitted_in(NULL) + fitted_in(NULL), + in_data(NULL) { - SG_LOG(SG_GENERAL, SG_DEBUG, "class TGArray CONstructor called." ); - in_data = new int[ARRAY_SIZE_1 * ARRAY_SIZE_1]; - - SG_LOG(SG_GENERAL, SG_ALERT, "ps TGArray CONstructor called." ); - TGArray::open(file); } @@ -62,13 +59,10 @@ TGArray::TGArray( const string &file ): bool TGArray::open( const string& file_base ) { // open array data file string array_name = file_base + ".arr.gz"; - array_in = new sg_gzifstream( array_name ); - if ( !array_in->is_open() ) { - SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << array_name ); - delete array_in; - array_in = NULL; - } else { - SG_LOG(SG_GENERAL, SG_DEBUG, " Opening array data file: " << array_name ); + + array_in = gzopen( array_name.c_str(), "rb" ); + if (array_in == NULL) { + return false; } // open fitted data file @@ -79,7 +73,7 @@ bool TGArray::open( const string& file_base ) { // can do a really stupid/crude fit on the fly, but it will // not be nearly as nice as what the offline terrafit utility // would have produced. - SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << fitted_name ); + SG_LOG(SG_GENERAL, SG_DEBUG, " Cannot open " << fitted_name ); delete fitted_in; fitted_in = NULL; } else { @@ -94,8 +88,7 @@ bool TGArray::open( const string& file_base ) { bool TGArray::close() { if (array_in) { - array_in->close(); - delete array_in; + gzclose(array_in); array_in = NULL; } @@ -114,23 +107,8 @@ TGArray::close() { bool TGArray::parse( SGBucket& b ) { // Parse/load the array data file - if ( array_in && array_in->is_open() ) { - // file open, parse - *array_in >> originx >> originy; - *array_in >> cols >> col_step; - *array_in >> rows >> row_step; - - SG_LOG(SG_GENERAL, SG_DEBUG, " origin = " << originx << " " << originy ); - SG_LOG(SG_GENERAL, SG_DEBUG, " cols = " << cols << " rows = " << rows ); - SG_LOG(SG_GENERAL, SG_DEBUG, " col_step = " << col_step << " row_step = " << row_step ); - - for ( int i = 0; i < cols; i++ ) { - for ( int j = 0; j < rows; j++ ) { - *array_in >> in_data[(i * ARRAY_SIZE_1) + j]; - } - } - - SG_LOG(SG_GENERAL, SG_DEBUG, " Done parsing" ); + if ( array_in ) { + parse_bin(); } else { // file not open (not found?), fill with zero'd data @@ -149,7 +127,9 @@ TGArray::parse( SGBucket& b ) { SG_LOG(SG_GENERAL, SG_DEBUG, " cols = " << cols << " rows = " << rows ); SG_LOG(SG_GENERAL, SG_DEBUG, " col_step = " << col_step << " row_step = " << row_step ); - memset(in_data, 0, sizeof(int) * cols * rows); + + in_data = new short[cols * rows]; + memset(in_data, 0, sizeof(short) * cols * rows); SG_LOG(SG_GENERAL, SG_DEBUG, " File not open, so using zero'd data" ); } @@ -168,6 +148,33 @@ TGArray::parse( SGBucket& b ) { return true; } +void TGArray::parse_bin() +{ + int32_t header; + sgReadLong(array_in, &header); + if (header != 0x54474152) { + SG_LOG(SG_GENERAL, SG_ALERT, "\nThe .arr file is not in the correct binary format." + << "\nPlease rebuild it using the latest TerraGear HGT tools."); + exit(1); + } + + int minX, minY, intColStep, intRowStep; + sgReadInt(array_in, &minX); + sgReadInt(array_in, &minY); + originx = minX; + originy = minY; + + sgReadInt(array_in, &cols); + sgReadInt(array_in, &intColStep); + sgReadInt(array_in, &rows); + sgReadInt(array_in, &intRowStep); + + col_step = intColStep; + row_step = intRowStep; + + in_data = new short[cols * rows]; + sgReadShort(array_in, cols * rows, in_data); +} // write an Array file bool TGArray::write( const string root_dir, SGBucket& b ) { @@ -287,26 +294,6 @@ void TGArray::remove_voids( ) { } -// add a node to the output corner node list -void TGArray::add_corner_node( int i, int j, double val ) { - - double x = (originx + i * col_step) / 3600.0; - double y = (originy + j * row_step) / 3600.0; - SG_LOG(SG_GENERAL, SG_DEBUG, "originx = " << originx << " originy = " << originy ); - SG_LOG(SG_GENERAL, SG_DEBUG, "corner = " << Point3D(x, y, val) ); - corner_list.push_back( Point3D(x, y, val) ); -} - - -// add a node to the output fitted node list -void TGArray::add_fit_node( int i, int j, double val ) { - double x = (originx + i * col_step) / 3600.0; - double y = (originy + j * row_step) / 3600.0; - SG_LOG(SG_GENERAL, SG_DEBUG, Point3D(x, y, val) ); - fitted_list.push_back( Point3D(x, y, val) ); -} - - // Return the elevation of the closest non-void grid point to lon, lat double TGArray::closest_nonvoid_elev( double lon, double lat ) const { double mindist = 99999999999.9; @@ -335,8 +322,8 @@ double TGArray::closest_nonvoid_elev( double lon, double lat ) const { } -// return the current altitude based on grid data. We should rewrite -// this to interpolate exact values, but for now this is good enough +// return the current altitude based on grid data. +// TODO: We should rewrite this to interpolate exact values, but for now this is good enough double TGArray::altitude_from_grid( double lon, double lat ) const { // we expect incoming (lon,lat) to be in arcsec for now @@ -445,15 +432,24 @@ double TGArray::altitude_from_grid( double lon, double lat ) const { TGArray::~TGArray( void ) { - delete in_data; + delete[] in_data; } int TGArray::get_array_elev( int col, int row ) const { - return in_data[(col * ARRAY_SIZE_1) + row]; + return in_data[(col * rows) + row]; } void TGArray::set_array_elev( int col, int row, int val ) { - in_data[(col * ARRAY_SIZE_1) + row] = val; + in_data[(col * rows) + row] = val; +} + +bool TGArray::is_open() const +{ + if ( array_in != NULL ) { + return true; + } else { + return false; + } } diff --git a/src/Lib/Array/array.hxx b/src/Lib/Array/array.hxx index 3e1ae8d5..fd62edf6 100644 --- a/src/Lib/Array/array.hxx +++ b/src/Lib/Array/array.hxx @@ -23,31 +23,21 @@ #ifndef _ARRAY_HXX #define _ARRAY_HXX - -#ifndef __cplusplus -# error This library requires C++ -#endif - #ifdef HAVE_CONFIG_H # include #endif #include - #include -#include #include #include -#define ARRAY_SIZE_1 20000 - +#include class TGArray { private: - - // array file pointer - sg_gzifstream *array_in; + gzFile array_in; // fitted file pointer sg_gzifstream *fitted_in; @@ -62,13 +52,13 @@ private: double col_step, row_step; // pointers to the actual grid data allocated here - int *in_data; - // float (*out_data)[ARRAY_SIZE_1]; + short *in_data; // output nodes point_list corner_list; point_list fitted_list; + void parse_bin(); public: // Constructor @@ -82,13 +72,7 @@ public: bool open ( const std::string& file_base ); // return if array was successfully opened or not - inline bool is_open() { - if ( array_in != NULL ) { - return array_in->is_open(); - } else { - return false; - } - } + bool is_open() const; // close a Array file bool close(); @@ -103,12 +87,6 @@ public: // neighbor. void remove_voids(); - // add a node to the output corner node list - void add_corner_node( int i, int j, double val ); - - // add a node to the output fitted node list - void add_fit_node( int i, int j, double val ); - // Return the elevation of the closest non-void grid point to lon, lat double closest_nonvoid_elev( double lon, double lat ) const; @@ -130,14 +108,7 @@ public: int get_array_elev( int col, int row ) const; void set_array_elev( int col, int row, int val ); - - - inline Point3D get_fitted_pt( int i ) { - return fitted_list[i]; - } }; #endif // _ARRAY_HXX - - diff --git a/src/Lib/Geometry/TNT/tnt_array1d.h b/src/Lib/Geometry/TNT/tnt_array1d.h index 2473f874..c4c155fe 100644 --- a/src/Lib/Geometry/TNT/tnt_array1d.h +++ b/src/Lib/Geometry/TNT/tnt_array1d.h @@ -258,7 +258,7 @@ inline int Array1D::ref_count() const template inline Array1D Array1D::subarray(int i0, int i1) { - if ((i0 >= 0) && (i1 < n_) || (i0 <= i1)) + if (((i0 >= 0) && (i1 < n_)) || (i0 <= i1)) { Array1D X(*this); /* create a new instance of this array. */ X.n_ = i1-i0+1; diff --git a/src/Lib/HGT/CMakeLists.txt b/src/Lib/HGT/CMakeLists.txt index 7d3bf27d..b120f7fa 100644 --- a/src/Lib/HGT/CMakeLists.txt +++ b/src/Lib/HGT/CMakeLists.txt @@ -1,13 +1,4 @@ - - -add_library(HGT STATIC +add_library(HGT STATIC hgt.cxx hgt.hxx srtmbase.cxx srtmbase.hxx ) - -add_executable(test_hgt testhgt.cxx) - -target_link_libraries(test_hgt - HGT - ${SIMGEAR_CORE_LIBRARIES} - ${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}) diff --git a/src/Lib/HGT/srtmbase.cxx b/src/Lib/HGT/srtmbase.cxx index 09c9c7fc..947a5a45 100644 --- a/src/Lib/HGT/srtmbase.cxx +++ b/src/Lib/HGT/srtmbase.cxx @@ -25,12 +25,13 @@ # include #endif -#include - #include #include #include +#include +#include + #include "srtmbase.hxx" using std::cout; @@ -57,7 +58,7 @@ TGSrtmBase::write_area( const string& root, SGBucket& b ) { double max_y = ( b.get_center_lat() + 0.5 * b.get_height() ) * 3600.0; cout << b << endl; - cout << "width = " << b.get_width() << " height = " << b.get_height() + cout << "width = " << b.get_width() << " height = " << b.get_height() << endl; cout << "min = " << min_x << "," << min_y << " max = " << max_x << "," << max_y << endl; @@ -99,51 +100,38 @@ TGSrtmBase::write_area( const string& root, SGBucket& b ) { string array_file = path + "/" + b.gen_index_str() + ".arr.gz"; cout << "array_file = " << array_file << endl; - // write the file + write_area_bin(array_file, start_x, start_y, min_x, min_y, + span_x, span_y, col_step, row_step); + + return true; +} + +bool TGSrtmBase::write_area_bin(const SGPath& aPath, int start_x, int start_y, + int min_x, int min_y, + int span_x, int span_y, int col_step, int row_step) +{ gzFile fp; - if ( (fp = gzopen( array_file.c_str(), "wb9" )) == NULL ) { - cout << "ERROR: cannot open " << array_file << " for writing!" << endl; - exit(-1); + if ( (fp = gzopen( aPath.c_str(), "wb9" )) == NULL ) { + cout << "ERROR: cannot open " << aPath.str() << " for writing!" << endl; + return false; } - gzprintf( fp, "%d %d\n", (int)min_x, (int)min_y ); - gzprintf( fp, "%d %d %d %d\n", span_x + 1, (int)col_step, - span_y + 1, (int)row_step ); + int32_t header = 0x54474152; // 'TGAR' + sgWriteLong(fp, header); + sgWriteInt(fp, min_x); sgWriteInt(fp, min_y); + sgWriteInt(fp, span_x + 1); sgWriteInt(fp, col_step); + sgWriteInt(fp, span_y + 1); sgWriteInt(fp, row_step); + for ( int i = start_x; i <= start_x + span_x; ++i ) { - for ( int j = start_y; j <= start_y + span_y; ++j ) { - gzprintf( fp, "%d ", (int)height(i,j) ); - } - gzprintf( fp, "\n" ); + for ( int j = start_y; j <= start_y + span_y; ++j ) { + sgWriteShort(fp, height(i,j)); + } } - gzclose(fp); + gzclose(fp); return true; } - -// write the entire area out in a simple ascii format -bool TGSrtmBase::write_whole_ascii( const string& file ) { - cout << "writing to " << file << endl; - // write the file - gzFile fp; - if ( (fp = gzopen( file.c_str(), "wb9" )) == NULL ) { - cout << "ERROR: cannot open " << file << " for writing!" << endl; - exit(-1); - } - - gzprintf( fp, "%d\n%d\n", rows, cols ); - for ( int row = rows - 1; row >= 0; row-- ) { - for ( int col = 0; col < cols; col++ ) { - gzprintf( fp, "%d\n", (int)height(col,row) ); - } - } - gzclose(fp); - - return true; -} - - - bool TGSrtmBase::has_non_zero_elev (int start_x, int span_x, int start_y, int span_y) const diff --git a/src/Lib/HGT/srtmbase.hxx b/src/Lib/HGT/srtmbase.hxx index d735c395..88849a8f 100644 --- a/src/Lib/HGT/srtmbase.hxx +++ b/src/Lib/HGT/srtmbase.hxx @@ -38,15 +38,15 @@ class TGSrtmBase { protected: TGSrtmBase() : remove_tmp_file(false) {} - + ~TGSrtmBase(); // coordinates (in arc seconds) of south west corner double originx, originy; - + // number of columns and rows int cols, rows; - + // Distance between column and row data points (in arc seconds) double col_step, row_step; @@ -60,8 +60,9 @@ public: // hand corner. bool write_area( const std::string& root, SGBucket& b ); - // write the entire area out in a simple ascii format - bool write_whole_ascii( const std::string& file ); + bool write_area_bin(const SGPath& aPath, + int start_x, int start_y, int min_x, int min_y, + int span_x, int span_y, int col_step, int row_step); // Informational methods inline double get_originx() const { return originx; } diff --git a/src/Lib/HGT/testhgt.cxx b/src/Lib/HGT/testhgt.cxx deleted file mode 100644 index 9f1f5f20..00000000 --- a/src/Lib/HGT/testhgt.cxx +++ /dev/null @@ -1,18 +0,0 @@ -#include - -#include "hgt.hxx" - -int main() { - // SGPath path3( "/stage/fgfs03/SRTM/United_States/N38W124/3arcsec/N38W124.hgt.gz" ); - SGPath path3( "/home/curt/trash/N38W124.hgt.gz" ); - - // TGHgt hgt1( 1, path1 ); - TGHgt hgt3( 3, path3 ); - - // hgt1.load(); - hgt3.load(); - - // SGBucket b(-79.5, 33.5); - // hgt1.write_area( ".", b ); - hgt3.write_whole_ascii( "w124n38.txt.gz" ); -} diff --git a/src/Prep/TerraFit/terrafit.cc b/src/Prep/TerraFit/terrafit.cc index d7f8c60c..d025e475 100644 --- a/src/Prep/TerraFit/terrafit.cc +++ b/src/Prep/TerraFit/terrafit.cc @@ -27,7 +27,7 @@ #include #include #include - + #ifndef _MSC_VER # include # ifdef __APPLE__ @@ -41,7 +41,7 @@ # include # define sleep(x) Sleep(x*1000) #endif - + #include #include @@ -52,7 +52,7 @@ #include #include #include - + #include #include #include @@ -81,7 +81,7 @@ public: min=30000; max=-30000; for (int i=0;i"); - SG_LOG(SG_GENERAL,SG_INFO, "\t -h | --help "); + SG_LOG(SG_GENERAL,SG_INFO, "\t -h | --help"); SG_LOG(SG_GENERAL,SG_INFO, "\t -m | --minnodes 50"); SG_LOG(SG_GENERAL,SG_INFO, "\t -x | --maxnodes 1000"); SG_LOG(SG_GENERAL,SG_INFO, "\t -e | --maxerror 40"); SG_LOG(SG_GENERAL,SG_INFO, "\t -f | --force"); - SG_LOG(SG_GENERAL,SG_INFO, "\t -j | --threads"); + SG_LOG(SG_GENERAL,SG_INFO, "\t -j | --threads "); SG_LOG(SG_GENERAL,SG_INFO, "\t -v | --version"); SG_LOG(SG_GENERAL,SG_INFO, ""); SG_LOG(SG_GENERAL,SG_INFO, "Algorithm will produce at least fitted nodes, but no"); @@ -303,10 +303,10 @@ struct option options[]={ }; int main(int argc, char** argv) { - sglog().setLogLevels( SG_ALL, SG_DEBUG ); + sglog().setLogLevels( SG_ALL, SG_INFO ); int option; - while ((option=getopt_long(argc,argv,"h:m:x:e:f:v:j:",options,NULL))!=-1) { + while ((option=getopt_long(argc,argv,"hm:x:e:fvj:",options,NULL))!=-1) { switch (option) { case 'h': usage(argv[0],""); @@ -336,7 +336,7 @@ int main(int argc, char** argv) { } } - SG_LOG(SG_GENERAL, SG_INFO, "TerraFit version " << getTGVersion()); + SG_LOG(SG_GENERAL, SG_INFO, "TerraFit version " << getTGVersion() << " using " << num_threads << " threads"); SG_LOG(SG_GENERAL, SG_INFO, "Min points = " << min_points); SG_LOG(SG_GENERAL, SG_INFO, "Max points = " << point_limit); SG_LOG(SG_GENERAL, SG_INFO, "Max error = " << error_threshold); @@ -350,21 +350,21 @@ int main(int argc, char** argv) { SG_LOG(SG_GENERAL, SG_INFO, "Use 'terrafit --help' for commands"); exit(1); } - + std::vector threads; for (unsigned int t=0; tstart(); threads.push_back(thread); } - + while (!global_workQueue.empty()) { sleep(1); } - + for (unsigned int t=0; tjoin(); } - + SG_LOG(SG_GENERAL, SG_INFO, "Work queue is empty\n"); }