A couple small tweaks to the airport generator to try to eliminate
surface artifacts.
This commit is contained in:
parent
ae939e2e44
commit
80a1b1ef23
4 changed files with 61 additions and 227 deletions
|
@ -40,133 +40,58 @@
|
||||||
SG_USING_NAMESPACE( PLib );
|
SG_USING_NAMESPACE( PLib );
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
static bool limit_slope( Matrix_Point3Dd &Pts, int i1, int j1, int i2, int j2,
|
||||||
// fix node elevations. Offset is added to the final elevation,
|
double average_elev_m )
|
||||||
// returns average of all points.
|
{
|
||||||
static double calc_elevations( const string &root, const string_list elev_src,
|
bool slope_error = false;
|
||||||
Matrix_Point3Dd &Pts ) {
|
|
||||||
bool done = false;
|
|
||||||
int i, j;
|
|
||||||
TGArray array;
|
|
||||||
|
|
||||||
// just bail if no work to do
|
Point3Dd p1, p2;
|
||||||
if ( Pts.rows() == 0 || Pts.cols() == 0 ) {
|
p1 = Pts(j1,i1);
|
||||||
return 0.0;
|
p2 = Pts(j2,i2);
|
||||||
}
|
|
||||||
|
|
||||||
// set all elevations to -9999
|
double az1, az2, dist;
|
||||||
for ( i = 0; i < Pts.cols(); ++i ) {
|
double slope;
|
||||||
for ( j = 0; j < Pts.rows(); ++j ) {
|
|
||||||
Point3Dd p = Pts(j,i);
|
|
||||||
p.z() = -9999.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while ( !done ) {
|
geo_inverse_wgs_84( 0, p1.y(), p1.x(), p2.y(), p2.x(),
|
||||||
// find first node with -9999 elevation
|
&az1, &az2, &dist );
|
||||||
Point3Dd first;
|
slope = (p2.z() - p1.z()) / dist;
|
||||||
bool found_one = false;
|
|
||||||
for ( i = 0; i < Pts.cols(); ++i ) {
|
|
||||||
for ( j = 0; j < Pts.rows(); ++j ) {
|
|
||||||
Point3Dd p = Pts(j,i);
|
|
||||||
if ( p.z() < -9000.0 && !found_one ) {
|
|
||||||
first = p;
|
|
||||||
found_one = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( found_one ) {
|
if ( fabs(slope) > (slope_max + slope_eps) ) {
|
||||||
SGBucket b( first.x(), first.y() );
|
// need to throttle slope, let's move the point
|
||||||
string base = b.gen_base_path();
|
// furthest away from average towards the center.
|
||||||
|
|
||||||
// try the various elevation sources
|
slope_error = true;
|
||||||
j = 0;
|
|
||||||
bool found_file = false;
|
|
||||||
while ( !found_file && j < (int)elev_src.size() ) {
|
|
||||||
string array_path = root + "/" + elev_src[j] + "/" + base
|
|
||||||
+ "/" + b.gen_index_str();
|
|
||||||
if ( array.open(array_path) ) {
|
|
||||||
found_file = true;
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Using array_path = " << array_path);
|
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this will fill in a zero structure if no array data
|
SG_LOG( SG_GENERAL, SG_DEBUG, " (a) detected slope of "
|
||||||
// found/opened
|
<< slope << " dist = " << dist );
|
||||||
array.parse( b );
|
|
||||||
|
|
||||||
// this will do a hasty job of removing voids by inserting
|
double e1 = fabs(average_elev_m - p1.z());
|
||||||
// data from the nearest neighbor (sort of)
|
double e2 = fabs(average_elev_m - p2.z());
|
||||||
array.remove_voids();
|
// cout << " z1 = " << p1.z() << " z2 = " << p2.z() << endl;
|
||||||
|
// cout << " e1 = " << e1 << " e2 = " << e2 << endl;
|
||||||
|
|
||||||
// update all the non-updated elevations that are inside
|
if ( e1 > e2 ) {
|
||||||
// this array file
|
// cout << " p1 error larger" << endl;
|
||||||
double elev;
|
if ( slope > 0 ) {
|
||||||
done = true;
|
p1.z() = p2.z() - (dist * slope_max);
|
||||||
for ( i = 0; i < Pts.cols(); ++i ) {
|
|
||||||
for ( j = 0; j < Pts.rows(); ++j ) {
|
|
||||||
Point3Dd p = Pts(j,i);
|
|
||||||
if ( p.z() < -9000.0 ) {
|
|
||||||
done = false;
|
|
||||||
elev = array.altitude_from_grid( p.x() * 3600.0,
|
|
||||||
p.y() * 3600.0 );
|
|
||||||
if ( elev > -9000 ) {
|
|
||||||
p.z() = elev;
|
|
||||||
Pts(j,i) = p;
|
|
||||||
// cout << "interpolating for " << p << endl;
|
|
||||||
// cout << p.x() << " " << p.y() << " " << p.z()
|
|
||||||
// << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
array.close();
|
|
||||||
} else {
|
} else {
|
||||||
done = true;
|
p1.z() = p2.z() + (dist * slope_max);
|
||||||
}
|
}
|
||||||
|
Pts(j1,i1) = p1;
|
||||||
|
} else {
|
||||||
|
// cout << " p2 error larger" << endl;
|
||||||
|
if ( slope > 0 ) {
|
||||||
|
p2.z() = p1.z() + (dist * slope_max);
|
||||||
|
} else {
|
||||||
|
p2.z() = p1.z() - (dist * slope_max);
|
||||||
|
}
|
||||||
|
Pts(j2,i2) = p2;
|
||||||
|
}
|
||||||
|
// cout << " z1 = " << p1.z() << " z2 = " << p2.z() << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do some post processing for sanity's sake
|
return slope_error;
|
||||||
|
|
||||||
// find the average height of the queried points
|
|
||||||
double total = 0.0;
|
|
||||||
int count = 0;
|
|
||||||
for ( i = 0; i < Pts.cols(); ++i ) {
|
|
||||||
for ( j = 0; j < Pts.rows(); ++j ) {
|
|
||||||
Point3Dd p = Pts(j,i);
|
|
||||||
total += p.z();
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
double average = total / (double) count;
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height = " << average);
|
|
||||||
|
|
||||||
// now go through the elevations and clamp them all to within
|
|
||||||
// +/-50m (164') of the average.
|
|
||||||
for ( i = 0; i < Pts.cols(); ++i ) {
|
|
||||||
for ( j = 0; j < Pts.rows(); ++j ) {
|
|
||||||
Point3Dd p = Pts(j,i);
|
|
||||||
if ( p.z() < average - max_clamp ) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " clamping " << p.z()
|
|
||||||
<< " to " << average - max_clamp );
|
|
||||||
p.z() = average - max_clamp;
|
|
||||||
Pts(j,i) = p;
|
|
||||||
}
|
|
||||||
if ( p.z() > average + max_clamp ) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " clamping " << p.z()
|
|
||||||
<< " to " << average + max_clamp );
|
|
||||||
p.z() = average + max_clamp;
|
|
||||||
Pts(j,i) = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return average;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Constructor, specify min and max coordinates of desired area in
|
// Constructor, specify min and max coordinates of desired area in
|
||||||
|
@ -226,7 +151,7 @@ TGAptSurface::TGAptSurface( const string& path,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup the elevations of all the grid points
|
// Lookup the elevations of all the grid points
|
||||||
tgCalcElevations( path, elev_src, dPts );
|
tgCalcElevations( path, elev_src, dPts, 0.0 );
|
||||||
|
|
||||||
// Clamp the elevations against the externally provided average
|
// Clamp the elevations against the externally provided average
|
||||||
// elevation.
|
// elevation.
|
||||||
|
@ -273,83 +198,14 @@ TGAptSurface::TGAptSurface( const string& path,
|
||||||
// Add some "slope" sanity to the resulting surface grid points
|
// Add some "slope" sanity to the resulting surface grid points
|
||||||
for ( int i = 0; i < Pts.cols() - 1; ++i ) {
|
for ( int i = 0; i < Pts.cols() - 1; ++i ) {
|
||||||
for ( int j = 0; j < Pts.rows() - 1; ++j ) {
|
for ( int j = 0; j < Pts.rows() - 1; ++j ) {
|
||||||
Point3Dd p1, p2;
|
if ( limit_slope( Pts, i, j, i+1, j, average_elev_m ) ) {
|
||||||
double az1, az2, dist;
|
|
||||||
double slope;
|
|
||||||
|
|
||||||
p1 = Pts(j,i);
|
|
||||||
p2 = Pts(j,i+1);
|
|
||||||
geo_inverse_wgs_84( 0, p1.y(), p1.x(), p2.y(), p2.x(),
|
|
||||||
&az1, &az2, &dist );
|
|
||||||
slope = (p2.z() - p1.z()) / dist;
|
|
||||||
|
|
||||||
if ( fabs(slope) > (slope_max + slope_eps) ) {
|
|
||||||
// need to throttle slope, let's move the point
|
|
||||||
// furthest away from average towards the center.
|
|
||||||
|
|
||||||
slope_error = true;
|
slope_error = true;
|
||||||
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, " (a) detected slope of "
|
|
||||||
<< slope << " dist = " << dist );
|
|
||||||
|
|
||||||
double e1 = average_elev_m - p1.z();
|
|
||||||
double e2 = average_elev_m - p2.z();
|
|
||||||
// cout << " z1 = " << p1.z() << " z2 = " << p2.z() << endl;
|
|
||||||
// cout << " e1 = " << e1 << " e2 = " << e2 << endl;
|
|
||||||
|
|
||||||
if ( fabs(e1) > fabs(e2) ) {
|
|
||||||
// cout << " p1 error larger" << endl;
|
|
||||||
if ( slope > 0 ) {
|
|
||||||
p1.z() = p2.z() - (dist * slope_max);
|
|
||||||
} else {
|
|
||||||
p1.z() = p2.z() + (dist * slope_max);
|
|
||||||
}
|
}
|
||||||
Pts(j,i) = p1;
|
if ( limit_slope( Pts, i, j, i, j+1, average_elev_m ) ) {
|
||||||
} else {
|
|
||||||
// cout << " p2 error larger" << endl;
|
|
||||||
if ( slope > 0 ) {
|
|
||||||
p2.z() = p1.z() + (dist * slope_max);
|
|
||||||
} else {
|
|
||||||
p2.z() = p1.z() - (dist * slope_max);
|
|
||||||
}
|
|
||||||
Pts(j,i+1) = p2;
|
|
||||||
}
|
|
||||||
// cout << " z1 = " << p1.z() << " z2 = " << p2.z() << endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
p1 = Pts(j,i);
|
|
||||||
p2 = Pts(j+1,i);
|
|
||||||
geo_inverse_wgs_84( 0, p1.y(), p1.x(), p2.y(), p2.x(),
|
|
||||||
&az1, &az2, &dist );
|
|
||||||
slope = ( p2.z() - p1.z() ) / dist;
|
|
||||||
|
|
||||||
if ( fabs(slope) > (slope_max+slope_eps) ) {
|
|
||||||
// need to throttle slope, let's move the point
|
|
||||||
// furthest away from average towards the center.
|
|
||||||
|
|
||||||
slope_error = true;
|
slope_error = true;
|
||||||
|
|
||||||
SG_LOG( SG_GENERAL, SG_DEBUG, " (b) detected slope of "
|
|
||||||
<< slope << " dist = " << dist );
|
|
||||||
|
|
||||||
double e1 = average_elev_m - p1.z();
|
|
||||||
double e2 = average_elev_m - p2.z();
|
|
||||||
|
|
||||||
if ( fabs(e1) > fabs(e2) ) {
|
|
||||||
if ( slope > 0 ) {
|
|
||||||
p1.z() = p2.z() - (dist * slope_max);
|
|
||||||
} else {
|
|
||||||
p1.z() = p2.z() + (dist * slope_max);
|
|
||||||
}
|
|
||||||
Pts(j,i) = p1;
|
|
||||||
} else {
|
|
||||||
if ( slope > 0 ) {
|
|
||||||
p2.z() = p1.z() + (dist * slope_max);
|
|
||||||
} else {
|
|
||||||
p2.z() = p1.z() - (dist * slope_max);
|
|
||||||
}
|
|
||||||
Pts(j+1,i) = p2;
|
|
||||||
}
|
}
|
||||||
|
if ( limit_slope( Pts, i, j, i+1, j+1, average_elev_m ) ) {
|
||||||
|
slope_error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,15 +141,15 @@ double tgAverageElevation( const string &root, const string_list elev_src,
|
||||||
// lookup node elevations for each point in the specified nurbs++
|
// lookup node elevations for each point in the specified nurbs++
|
||||||
// matrix. Returns average of all points.
|
// matrix. Returns average of all points.
|
||||||
|
|
||||||
double tgCalcElevations( const string &root, const string_list elev_src,
|
void tgCalcElevations( const string &root, const string_list elev_src,
|
||||||
Matrix_Point3Dd &Pts ) {
|
Matrix_Point3Dd &Pts, const double average ) {
|
||||||
bool done = false;
|
bool done = false;
|
||||||
int i, j;
|
int i, j;
|
||||||
TGArray array;
|
TGArray array;
|
||||||
|
|
||||||
// just bail if no work to do
|
// just bail if no work to do
|
||||||
if ( Pts.rows() == 0 || Pts.cols() == 0 ) {
|
if ( Pts.rows() == 0 || Pts.cols() == 0 ) {
|
||||||
return 0.0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set all elevations to -9999
|
// set all elevations to -9999
|
||||||
|
@ -240,31 +240,9 @@ double tgCalcElevations( const string &root, const string_list elev_src,
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double average = total / (double) count;
|
double grid_average = total / (double) count;
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height of nurbs matrix = "
|
SG_LOG(SG_GENERAL, SG_DEBUG, "Average surface height of nurbs matrix = "
|
||||||
<< average);
|
<< grid_average);
|
||||||
|
|
||||||
// now go through the elevations and clamp them all to within
|
|
||||||
// +/-50m (164') of the average.
|
|
||||||
for ( i = 0; i < Pts.cols(); ++i ) {
|
|
||||||
for ( j = 0; j < Pts.rows(); ++j ) {
|
|
||||||
Point3Dd p = Pts(j,i);
|
|
||||||
if ( p.z() < average - max_clamp ) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " clamping " << p.z()
|
|
||||||
<< " to " << average - max_clamp );
|
|
||||||
p.z() = average - max_clamp;
|
|
||||||
Pts(j,i) = p;
|
|
||||||
}
|
|
||||||
if ( p.z() > average + max_clamp ) {
|
|
||||||
SG_LOG(SG_GENERAL, SG_DEBUG, " clamping " << p.z()
|
|
||||||
<< " to " << average + max_clamp );
|
|
||||||
p.z() = average + max_clamp;
|
|
||||||
Pts(j,i) = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return average;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,9 @@ double tgAverageElevation( const string &root, const string_list elev_src,
|
||||||
const point_list points_source );
|
const point_list points_source );
|
||||||
|
|
||||||
// lookup node elevations for each point in the specified nurbs++
|
// lookup node elevations for each point in the specified nurbs++
|
||||||
// matrix. Returns average of all points.
|
// matrix.
|
||||||
double tgCalcElevations( const string &root, const string_list elev_src,
|
void tgCalcElevations( const string &root, const string_list elev_src,
|
||||||
Matrix_Point3Dd &Pts );
|
Matrix_Point3Dd &Pts, double average );
|
||||||
|
|
||||||
// clamp all elevations to the specified range
|
// clamp all elevations to the specified range
|
||||||
void tgClampElevations( Matrix_Point3Dd &Pts,
|
void tgClampElevations( Matrix_Point3Dd &Pts,
|
||||||
|
|
|
@ -36,7 +36,7 @@ const double coarse_grid = 700.0;
|
||||||
const double max_clamp = 100.0;
|
const double max_clamp = 100.0;
|
||||||
|
|
||||||
// maximum slope (rise/run) allowed on an airport surface
|
// maximum slope (rise/run) allowed on an airport surface
|
||||||
const double slope_max = 0.01;
|
const double slope_max = 0.009;
|
||||||
const double slope_eps = 0.00001;
|
const double slope_eps = 0.00001;
|
||||||
|
|
||||||
#endif // _GEN_AIRPORT_GLOBAL_HXX
|
#endif // _GEN_AIRPORT_GLOBAL_HXX
|
||||||
|
|
Loading…
Reference in a new issue