Working towards completely depricating the previous insanely stupid array fit
algorithm.
This commit is contained in:
parent
af6dc9bb0d
commit
aec29df1c8
4 changed files with 98 additions and 108 deletions
|
@ -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
|
||||||
|
|
|
@ -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 );
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue