1
0
Fork 0

Genapts: move all elevation-related functions into tg_surface, where they belong.

This commit is contained in:
Christian Schmitt 2014-11-16 19:48:47 +01:00
parent 8aabdbf2ad
commit d8d6f1ace1
3 changed files with 71 additions and 75 deletions

View file

@ -211,58 +211,6 @@ bool Airport::isDebugFeature( int feat )
} }
// TODO : Add somewhere
// Determine node elevations of a point_list based on the provided
// TGAptSurface. Offset is added to the final elevation
static std::vector<SGGeod> calc_elevations( const tgSurface& surf, const std::vector<SGGeod>& geod_nodes, double offset )
{
std::vector<SGGeod> result = geod_nodes;
for ( unsigned int i = 0; i < result.size(); ++i ) {
double elev = surf.query( result[i] );
result[i].setElevationM( elev + offset );
}
return result;
}
static tgContour calc_elevations( const tgSurface& surf, const tgContour& geod_nodes, double offset )
{
tgContour result = geod_nodes;
for ( unsigned int i = 0; i < result.GetSize(); ++i ) {
SGGeod node = result.GetNode(i);
double elev = surf.query( node );
node.setElevationM( elev + offset );
result.SetNode( i, node );
}
return result;
}
static double calc_elevation( const tgSurface& surf, const SGGeod& node, double offset )
{
double elev = surf.query( node );
elev += offset;
return elev;
}
// Determine node elevations of each node of a TGPolygon based on the
// provided TGAptSurface. Offset is added to the final elevation
static tgPolygon calc_elevations( const tgSurface& surf, const tgPolygon& poly, double offset )
{
tgPolygon result;
for ( unsigned int i = 0; i < poly.Contours(); ++i ) {
tgContour contour = poly.GetContour( i );
tgContour elevated = calc_elevations( surf, contour, offset );
result.AddContour( elevated );
}
return result;
}
void Airport::BuildBtg(const std::string& root, const string_list& elev_src ) void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
{ {
@ -887,10 +835,10 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
TG_LOG(SG_GENERAL, SG_INFO, "Adding line nodes and normals"); TG_LOG(SG_GENERAL, SG_INFO, "Adding line nodes and normals");
for ( unsigned int k = 0; k < line_polys.size(); ++k ) for ( unsigned int k = 0; k < line_polys.size(); ++k )
{ {
TG_LOG(SG_GENERAL, SG_INFO, "tri " << k); TG_LOG(SG_GENERAL, SG_DEBUG, "tri " << k);
std::string material = line_polys[k].GetMaterial(); std::string material = line_polys[k].GetMaterial();
TG_LOG(SG_GENERAL, SG_INFO, "material = " << material); TG_LOG(SG_GENERAL, SG_DEBUG, "material = " << material);
TG_LOG(SG_GENERAL, SG_INFO, "triangles = " << line_polys[k].Triangles()); TG_LOG(SG_GENERAL, SG_DEBUG, "triangles = " << line_polys[k].Triangles());
for ( unsigned int i = 0; i < line_polys[k].Triangles(); ++i ) for ( unsigned int i = 0; i < line_polys[k].Triangles(); ++i )
{ {
tgPolygon poly = line_polys[k]; tgPolygon poly = line_polys[k];
@ -1052,7 +1000,6 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
TG_LOG(SG_GENERAL, SG_DEBUG, " max: " << max_deg ); TG_LOG(SG_GENERAL, SG_DEBUG, " max: " << max_deg );
TG_LOG(SG_GENERAL, SG_DEBUG, " average: " << average ); TG_LOG(SG_GENERAL, SG_DEBUG, " average: " << average );
// TODO elevation queries should be performed as member functions of surface
tgRectangle aptBounds(min_deg, max_deg); tgRectangle aptBounds(min_deg, max_deg);
tgSurface apt_surf( root, elev_src, aptBounds, average, slope_max, slope_eps ); tgSurface apt_surf( root, elev_src, aptBounds, average, slope_max, slope_eps );
TG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created"); TG_LOG(SG_GENERAL, SG_DEBUG, "Airport surface created");
@ -1061,7 +1008,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
// pass one, calculate raw elevations from Array // pass one, calculate raw elevations from Array
for ( unsigned int i = 0; i < rwy_lights.size(); ++i ) { for ( unsigned int i = 0; i < rwy_lights.size(); ++i ) {
for ( unsigned int j = 0; j < rwy_lights[i].ContourSize(); j++ ) { for ( unsigned int j = 0; j < rwy_lights[i].ContourSize(); j++ ) {
double light_elevation = calc_elevation( apt_surf, rwy_lights[i].GetNode(j), 0.0 ); double light_elevation = apt_surf.calc_elevation( rwy_lights[i].GetNode(j), 0.0 );
rwy_lights[i].SetElevation(j, light_elevation); rwy_lights[i].SetElevation(j, light_elevation);
} }
} }
@ -1095,8 +1042,8 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
// calculate node elevations // calculate node elevations
TG_LOG(SG_GENERAL, SG_DEBUG, "Computing airport node elevations"); TG_LOG(SG_GENERAL, SG_DEBUG, "Computing airport node elevations");
std::vector<SGGeod> geod_nodes = calc_elevations( apt_surf, nodes.get_list(), 0.0 ); std::vector<SGGeod> geod_nodes = apt_surf.calc_elevations( nodes.get_list(), 0.0 );
divided_base = calc_elevations( apt_surf, divided_base, 0.0 ); divided_base = apt_surf.calc_elevations( divided_base, 0.0 );
// calculate wgs84 mapping of nodes // calculate wgs84 mapping of nodes
std::vector<SGVec3d> wgs84_nodes; std::vector<SGVec3d> wgs84_nodes;
@ -1157,7 +1104,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
for ( unsigned int i = 0; i < windsocks.size(); ++i ) for ( unsigned int i = 0; i < windsocks.size(); ++i )
{ {
SGGeod ref_geod = windsocks[i]->GetLoc(); SGGeod ref_geod = windsocks[i]->GetLoc();
ref_geod.setElevationM( calc_elevation( apt_surf, ref_geod, 0.0 ) ); ref_geod.setElevationM( apt_surf.calc_elevation( ref_geod, 0.0 ) );
if ( windsocks[i]->IsLit() ) if ( windsocks[i]->IsLit() )
{ {
@ -1175,7 +1122,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
for ( unsigned int i = 0; i < beacons.size(); ++i ) for ( unsigned int i = 0; i < beacons.size(); ++i )
{ {
ref_geod = beacons[i]->GetLoc(); ref_geod = beacons[i]->GetLoc();
ref_geod.setElevationM( calc_elevation( apt_surf, ref_geod, 0.0 ) ); ref_geod.setElevationM( apt_surf.calc_elevation( ref_geod, 0.0 ) );
write_index_shared( objpath, b, ref_geod, write_index_shared( objpath, b, ref_geod,
"Models/Airport/beacon.xml", "Models/Airport/beacon.xml",
@ -1186,7 +1133,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
for ( unsigned int i = 0; i < signs.size(); ++i ) for ( unsigned int i = 0; i < signs.size(); ++i )
{ {
ref_geod = signs[i]->GetLoc(); ref_geod = signs[i]->GetLoc();
ref_geod.setElevationM( calc_elevation( apt_surf, ref_geod, 0.0 ) ); ref_geod.setElevationM( apt_surf.calc_elevation( ref_geod, 0.0 ) );
write_object_sign( objpath, b, ref_geod, write_object_sign( objpath, b, ref_geod,
signs[i]->GetDefinition(), signs[i]->GetDefinition(),
signs[i]->GetHeading(), signs[i]->GetHeading(),
@ -1201,7 +1148,7 @@ void Airport::BuildBtg(const std::string& root, const string_list& elev_src )
for ( unsigned int j = 0; j < buoys.GetSize(); ++j ) for ( unsigned int j = 0; j < buoys.GetSize(); ++j )
{ {
ref_geod = buoys.GetNode(j); ref_geod = buoys.GetNode(j);
ref_geod.setElevationM( calc_elevation( apt_surf, ref_geod, 0.0 ) ); ref_geod.setElevationM( apt_surf.calc_elevation( ref_geod, 0.0 ) );
write_index_shared( objpath, b, ref_geod, write_index_shared( objpath, b, ref_geod,
"Models/Airport/water_rw_buoy.xml", "Models/Airport/water_rw_buoy.xml",
0.0 ); 0.0 );

View file

@ -414,7 +414,7 @@ double tgSurface::query( SGGeod query ) const {
// sanity check // sanity check
if ( !_aptBounds.isInside(query) ) if ( !_aptBounds.isInside(query) )
{ {
SG_LOG(SG_GENERAL, SG_WARN, "Warning: query out of bounds for fitted surface!"); SG_LOG(SG_GENERAL, SG_WARN, "Warning: Elevation query out of bounds for fitted surface!");
return -9999.0; return -9999.0;
} }
@ -437,4 +437,50 @@ double tgSurface::query( SGGeod query ) const {
result += area_center.getElevationM(); result += area_center.getElevationM();
return result; return result;
} }
double tgSurface::calc_elevation( const SGGeod& node, double offset )
{
double elev = query( node );
elev += offset;
return elev;
}
tgSurface::PointList tgSurface::calc_elevations( const PointList& geod_nodes, double offset )
{
PointList result = geod_nodes;
for ( unsigned int i = 0; i < result.size(); ++i ) {
double elev = query( result[i] );
result[i].setElevationM( elev + offset );
}
return result;
}
tgContour tgSurface::calc_elevations( const tgContour& geod_nodes, double offset )
{
tgContour result = geod_nodes;
for ( unsigned int i = 0; i < result.GetSize(); ++i ) {
SGGeod node = result.GetNode(i);
double elev = query( node );
node.setElevationM( elev + offset );
result.SetNode( i, node );
}
return result;
}
tgPolygon tgSurface::calc_elevations( const tgPolygon& poly, double offset )
{
tgPolygon result;
for ( unsigned int i = 0; i < poly.Contours(); ++i ) {
tgContour contour = poly.GetContour( i );
tgContour elevated = calc_elevations( contour, offset );
result.AddContour( elevated );
}
return result;
}

View file

@ -96,6 +96,7 @@ private:
* and dips in the airport surface. * and dips in the airport surface.
*/ */
class tgSurface { class tgSurface {
typedef std::vector<SGGeod> PointList;
public: public:
@ -110,14 +111,10 @@ public:
// Destructor // Destructor
~tgSurface(); ~tgSurface();
// Use a linear least squares method to fit a 3d polynomial to the double calc_elevation( const SGGeod& node, double offset );
// sampled surface data PointList calc_elevations( const PointList& geod_nodes, double offset );
void fit(); tgContour calc_elevations( const tgContour& geod_nodes, double offset );
tgPolygon calc_elevations( const tgPolygon& poly, double offset );
// Query the elevation of a point, return -9999 if out of range.
// This routine makes a simplistic assumption that X,Y space is
// proportional to u,v space on the nurbs surface which it isn't.
double query( SGGeod query ) const;
private: private:
// The actual nurbs surface approximation for the airport // The actual nurbs surface approximation for the airport
@ -133,8 +130,14 @@ private:
// externally seeded average airport elevation // externally seeded average airport elevation
double _average_elev_m; double _average_elev_m;
// double slope_max = 0.02; // Use a linear least squares method to fit a 3d polynomial to the
// double slope_eps = 0.00001; // sampled surface data
void fit();
// Query the elevation of a point, return -9999 if out of range.
// This routine makes a simplistic assumption that X,Y space is
// proportional to u,v space on the nurbs surface which it isn't.
double query( SGGeod query ) const;
}; };
#endif // _SURFACE_HXX #endif // _SURFACE_HXX