1
0
Fork 0

Working towards completely depricating the previous insanely stupid array fit

algorithm.
This commit is contained in:
curt 2003-08-19 02:24:38 +00:00
parent af6dc9bb0d
commit aec29df1c8
4 changed files with 98 additions and 108 deletions

View file

@ -27,23 +27,6 @@
#include <simgear/compiler.h> #include <simgear/compiler.h>
// #include <ctype.h> // isspace()
// #include <stdlib.h> // atoi()
// #include <math.h> // rint()
// #include <stdio.h>
// #include <string.h>
// #ifdef HAVE_SYS_STAT_H
// # include <sys/stat.h> // stat()
// #endif
// #ifdef SG_HAVE_STD_INCLUDES
// # include <cerrno>
// #else
// # include <errno.h>
// #endif
// #ifdef HAVE_UNISTD_H
// # include <unistd.h> // stat()
// #endif
#include STL_STRING #include STL_STRING
#include <simgear/constants.h> #include <simgear/constants.h>
@ -96,6 +79,10 @@ bool TGArray::open( const string& file_base ) {
string fitted_name = file_base + ".fit.gz"; string fitted_name = file_base + ".fit.gz";
fitted_in = new sg_gzifstream( fitted_name ); fitted_in = new sg_gzifstream( fitted_name );
if ( ! fitted_in->is_open() ) { if ( ! fitted_in->is_open() ) {
// not having a .fit file is unfortunate, but not fatal. We
// 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.
cout << " Cannot open " << fitted_name << endl; cout << " Cannot open " << fitted_name << endl;
} else { } else {
cout << " Opening fitted data file: " << fitted_name << endl; cout << " Opening fitted data file: " << fitted_name << endl;
@ -140,84 +127,6 @@ TGArray::parse( SGBucket& b ) {
} }
cout << " Done parsing\n"; cout << " Done parsing\n";
#if 0
// need two passes to ensure that all voids are removed (unless entire
// array is a void.)
bool have_void = true;
int last_elev = -32768;
for ( int pass = 0; pass < 2 && have_void; ++pass ) {
// attempt to fill in any void data horizontally
for ( int i = 0; i < cols; i++ ) {
// fill in front ways
last_elev = -32768;
have_void = false;
for ( int j = 0; j < rows; j++ ) {
if ( in_data[i][j] > -9000 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9000 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
// fill in back ways
last_elev = -32768;
have_void = false;
for ( int j = rows - 1; j >= 0; j-- ) {
if ( in_data[i][j] > -9000 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9000 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
}
// attempt to fill in any void data vertically
for ( int j = 0; j < rows; j++ ) {
// fill in front ways
last_elev = -32768;
have_void = false;
for ( int i = 0; i < cols; i++ ) {
if ( in_data[i][j] > -9999 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9999 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
// fill in back ways
last_elev = -32768;
have_void = false;
for ( int i = cols - 1; i >= 0; i-- ) {
if ( in_data[i][j] > -9999 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9999 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
}
}
if ( have_void ) {
// after all that work we still have a void, likely the
// entire array is void. Fill in the void areas with zero
// as a panic fall back.
for ( int i = 0; i < cols; i++ ) {
for ( int j = 0; j < rows; j++ ) {
if ( in_data[i][j] <= -9999 ) {
in_data[i][j] = 0;
}
}
}
}
#endif
} else { } else {
// file not open (not found?), fill with zero'd data // file not open (not found?), fill with zero'd data
@ -246,14 +155,13 @@ TGArray::parse( SGBucket& b ) {
cout << " File not open, so using zero'd data" << endl; cout << " File not open, so using zero'd data" << endl;
} }
// Parse/load the array data file // Parse/load the fitted data file
if ( fitted_in->is_open() ) { if ( fitted_in->is_open() ) {
fit_on_the_fly = false;
int fitted_size; int fitted_size;
double x, y, z, error; double x, y, z, error;
*fitted_in >> fitted_size; *fitted_in >> fitted_size;
for ( int i = 0; i < fitted_size; ++i ) { for ( int i = 0; i < fitted_size; ++i ) {
*fitted_in >> x >> y >> z >> error; *fitted_in >> x >> y >> z;
if ( i < 4 ) { if ( i < 4 ) {
// skip first 4 corner nodes // skip first 4 corner nodes
} else { } else {
@ -261,8 +169,6 @@ TGArray::parse( SGBucket& b ) {
cout << " loading fitted = " << Point3D(x, y, z) << endl; cout << " loading fitted = " << Point3D(x, y, z) << endl;
} }
} }
} else {
fit_on_the_fly = true;
} }
return true; return true;
@ -271,6 +177,86 @@ TGArray::parse( SGBucket& b ) {
// do our best to remove voids by picking data from the nearest neighbor.
void TGArray::remove_voids( ) {
// need two passes to ensure that all voids are removed (unless entire
// array is a void.)
bool have_void = true;
int last_elev = -32768;
for ( int pass = 0; pass < 2 && have_void; ++pass ) {
// attempt to fill in any void data horizontally
for ( int i = 0; i < cols; i++ ) {
// fill in front ways
last_elev = -32768;
have_void = false;
for ( int j = 0; j < rows; j++ ) {
if ( in_data[i][j] > -9000 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9000 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
// fill in back ways
last_elev = -32768;
have_void = false;
for ( int j = rows - 1; j >= 0; j-- ) {
if ( in_data[i][j] > -9000 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9000 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
}
// attempt to fill in any void data vertically
for ( int j = 0; j < rows; j++ ) {
// fill in front ways
last_elev = -32768;
have_void = false;
for ( int i = 0; i < cols; i++ ) {
if ( in_data[i][j] > -9999 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9999 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
// fill in back ways
last_elev = -32768;
have_void = false;
for ( int i = cols - 1; i >= 0; i-- ) {
if ( in_data[i][j] > -9999 ) {
last_elev = in_data[i][j];
} else if ( last_elev > -9999 ) {
in_data[i][j] = last_elev;
} else {
have_void = true;
}
}
}
}
if ( have_void ) {
// after all that work we still have a void, likely the
// entire array is void. Fill in the void areas with zero
// as a panic fall back.
for ( int i = 0; i < cols; i++ ) {
for ( int j = 0; j < rows; j++ ) {
if ( in_data[i][j] <= -9999 ) {
in_data[i][j] = 0;
}
}
}
}
}
// add a node to the output corner node list // add a node to the output corner node list
void TGArray::add_corner_node( int i, int j, double val ) { void TGArray::add_corner_node( int i, int j, double val ) {
@ -291,6 +277,7 @@ void TGArray::add_fit_node( int i, int j, double val ) {
} }
#if 0
// Use least squares to fit a simpler data set to dem data. Return // Use least squares to fit a simpler data set to dem data. Return
// the number of fitted nodes. This is a horrible approach that // the number of fitted nodes. This is a horrible approach that
// doesn't really work, but it's better than nothing if you've got // doesn't really work, but it's better than nothing if you've got
@ -453,6 +440,7 @@ int TGArray::fit( double error ) {
// return fit nodes + 4 corners // return fit nodes + 4 corners
return fitted_list.size() + 4; return fitted_list.size() + 4;
} }
#endif
// Return the elevation of the closest non-void grid point to lon, lat // Return the elevation of the closest non-void grid point to lon, lat

View file

@ -77,7 +77,7 @@ private:
point_list fitted_list; point_list fitted_list;
// bool // bool
bool fit_on_the_fly; // CLO 8/18/2003 // bool fit_on_the_fly;
public: public:
@ -97,13 +97,17 @@ public:
// parse a Array file // parse a Array file
bool parse( SGBucket& b ); bool parse( SGBucket& b );
// do our best to remove voids by picking data from the nearest
// neighbor.
void remove_voids();
// Use least squares to fit a simpler data set to dem data. // Use least squares to fit a simpler data set to dem data.
// Return the number of fitted nodes. This is a horrible approach // Return the number of fitted nodes. This is a horrible approach
// that doesn't really work, but it's better than nothing if // that doesn't really work, but it's better than nothing if
// you've got nothing. Using src/Prep/ArrayFit to create .fit // you've got nothing. Using src/Prep/ArrayFit to create .fit
// files from the .arr files is a *much* better approach, but it // files from the .arr files is a *much* better approach, but it
// is slower which is why it needs to be done "offline". // is slower which is why it needs to be done "offline".
int fit( double error ); // CLO 8/18/2003 // int fit( double error );
// add a node to the output corner node list // add a node to the output corner node list
void add_corner_node( int i, int j, double val ); void add_corner_node( int i, int j, double val );

View file

@ -32,7 +32,5 @@ int main( int argc, char **argv ) {
lat *= 3600; lat *= 3600;
cout << " " << a.altitude_from_grid(lon, lat) << endl; cout << " " << a.altitude_from_grid(lon, lat) << endl;
a.fit( 100 );
return 0; return 0;
} }

View file

@ -92,10 +92,10 @@ int main( int argc, char **argv ) {
a.parse( b ); a.parse( b );
// Old fit // Old fit
cout << "Old fit(200) = " << a.fit(200) << endl; // cout << "Old fit(200) = " << a.fit(200) << endl;
cout << "Old fit(100) = " << a.fit(100) << endl; // cout << "Old fit(100) = " << a.fit(100) << endl;
cout << "Old fit(50) = " << a.fit(50) << endl; // cout << "Old fit(50) = " << a.fit(50) << endl;
cout << "Old fit(25) = " << a.fit(25) << endl; // cout << "Old fit(25) = " << a.fit(25) << endl;
// Test libgts (gnu triangulation library functions) // Test libgts (gnu triangulation library functions)