1
0
Fork 0

Stability checkpoint for genapt850

- break up and expand shoulder polys, so they overlap runways.
  This keeps cracks from forming between the shoulder and runway
  do to roundoff error
- Add verbose option to polygon_tesselate functions to aid in debugging
  can set at runtime to produce triangulation output for just 1 poly.
- add remove_small_cycles to poly cleanup routines before triangulation
- more warnings cleanup in ClosePoly.cxx
- add more output in normal execution path, as some airports can go for
  hours without printing any status.  Hard to tell if it's locked up
This commit is contained in:
Peter Sadrozinski 2012-01-22 13:15:02 -05:00 committed by Christian Schmitt
parent 27c31404ca
commit 37a46c4075
17 changed files with 559 additions and 404 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@ Makefile.in
.deps
*.o
*.a
*~
COPYING
INSTALL
VERSION

View file

@ -828,7 +828,7 @@ void build_airport( string airport_id, float alt_m,
TGPolygon poly = rwy_polys[i].get_poly();
SG_LOG(SG_GENERAL, SG_DEBUG, "total size before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly );
TGPolygon tri = polygon_tesselate_alt( poly, false );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc;
@ -844,7 +844,7 @@ void build_airport( string airport_id, float alt_m,
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating base");
TGPolygon base_tris = polygon_tesselate_alt( base_poly );
TGPolygon base_tris = polygon_tesselate_alt( base_poly, false );
#if 0
// dump more debugging output

View file

@ -325,6 +325,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
int i, j, k;
Point3D p;
bool verbose_triangulation = false;
// parse main airport information
double apt_lon = 0.0, apt_lat = 0.0;
@ -334,16 +336,24 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
struct timeval cleanup_end;
struct timeval triangulation_start;
struct timeval triangulation_end;
struct timeval log_time;
// Find the average of all the runway long / lats
// TODO : Need runway object...
// Find the average of all the runway and heliport long / lats
int num_samples = 0;
for (i=0; i<runways.size(); i++)
{
apt_lon += runways.at(i)->GetMidpoint().x();
apt_lat += runways.at(i)->GetMidpoint().y();
apt_lon += runways[i]->GetMidpoint().x();
apt_lat += runways[i]->GetMidpoint().y();
num_samples++;
}
apt_lon = apt_lon / (double)runways.size();
apt_lat = apt_lat / (double)runways.size();
for (i=0; i<helipads.size(); i++)
{
apt_lon += helipads[i]->GetLoc().x();
apt_lat += helipads[i]->GetLoc().y();
num_samples++;
}
apt_lon = apt_lon / (double)num_samples;
apt_lat = apt_lat / (double)num_samples;
SGBucket b( apt_lon, apt_lat );
SG_LOG(SG_GENERAL, SG_DEBUG, b.gen_base_path() << "/" << b.gen_index_str());
@ -368,7 +378,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
{
for ( i=0; i<features.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Feature Poly " << i << ": " << features[i]->GetDescription() );
SG_LOG(SG_GENERAL, SG_INFO, "Build Feature Poly " << i << " of " << features.size() << " : " << features[i]->GetDescription() );
// cut the linear feature in until we get the geometry right...
// features[i]->BuildBtg( altitude, &line_polys, &line_tps, &line_accum );
@ -380,9 +390,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "no markings");
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building Linear Features for " << icao << " at " << ctime(&log_time.tv_sec) );
// Build runways next
for (i=0; i<runways.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build Runway " << i << " of " << runways.size());
if ( runways[i]->IsPrecision() )
{
if (boundary)
@ -393,13 +408,18 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
{
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
}
}
}
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building runways for " << icao << " at " << ctime(&log_time.tv_sec) );
if (lightobjects.size())
{
for ( i=0; i<lightobjects.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_INFO, "Build runway light " << i << " of " << lightobjects.size());
lightobjects[i]->BuildBtg( altitude, &rwy_lights );
}
}
@ -407,6 +427,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// Build helipads (use runway poly- and texture list for this)
if (helipads.size())
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build helipad " << i << " of " << helipads.size());
for (i=0; i<helipads.size(); i++ )
{
if (boundary)
@ -419,12 +441,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
}
}
}
// Build the pavements
if (pavements.size())
{
for ( i=0; i<pavements.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Pavement " << i << " of " << pavements.size() << " : " << pavements[i]->GetDescription());
if (boundary)
{
@ -441,9 +464,14 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "no pavements");
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished building pavements for " << icao << " at " << ctime(&log_time.tv_sec) );
// Build runway shoulders here
for (i=0; i<runways.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway shoulder " << i << " of " << runways.size());
if ( runways[i]->GetsShoulder() )
{
runways[i]->BuildShoulder( altitude, &rwy_polys, &rwy_tps, &accum );
@ -453,10 +481,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// build the base and clearing if there's a boundary
if (boundary)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Build user defined boundary " );
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
}
if ( apt_base.total_size() == 0 )
if ( apt_base.total_size() == 0 )
{
SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");
return;
@ -464,7 +494,6 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
TGPolygon filled_base = tgPolygonStripHoles( apt_base );
TGPolygon divided_base = tgPolygonSplitLongEdges( filled_base, 200.0 );
//TGPolygon base_poly = tgPolygonDiff( filled_base, accum );
TGPolygon base_poly = tgPolygonDiff( divided_base, accum );
gettimeofday(&build_end, NULL);
@ -477,6 +506,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
TGTriNodes tmp_nodes;
// build temporary node list from runways...
SG_LOG(SG_GENERAL, SG_INFO, "Build Node List " );
for ( k = 0; k < (int)rwy_polys.size(); ++k )
{
TGPolygon poly = rwy_polys[k].get_poly();
@ -484,7 +515,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
{
for ( j = 0; j < poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( poly.get_pt(i, j) );
tmp_nodes.unique_add( poly.get_pt(i, j) );
//tmp_nodes.course_add( poly.get_pt(i, j) );
}
}
}
@ -498,6 +530,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( j = 0; j < poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( poly.get_pt(i, j) );
//tmp_nodes.course_add( poly.get_pt(i, j) );
}
}
}
@ -511,6 +544,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( j = 0; j < poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( poly.get_pt(i, j) );
//tmp_nodes.course_add( poly.get_pt(i, j) );
}
}
}
@ -521,6 +555,7 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( j = 0; j < base_poly.contour_size( i ); ++j )
{
tmp_nodes.unique_add( base_poly.get_pt(i, j) );
//tmp_nodes.course_add( base_poly.get_pt(i, j) );
}
}
@ -531,9 +566,13 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( j = 0; j < divided_base.contour_size( i ); ++j )
{
tmp_nodes.unique_add( divided_base.get_pt(i, j) );
//tmp_nodes.course_add( divided_base.get_pt(i, j) );
}
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished collecting nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
// second pass : runways
for ( k = 0; k < (int)rwy_polys.size(); ++k )
{
@ -564,6 +603,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
line_polys[k].set_poly( poly );
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished adding intermediate nodes for " << icao << " at " << ctime(&log_time.tv_sec) );
// One more pass to try to get rid of other yukky stuff
for ( k = 0; k < (int)rwy_polys.size(); ++k )
@ -572,12 +613,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
poly = remove_cycles( poly );
poly = remove_dups( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
poly = remove_bad_contours( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
poly = remove_tiny_contours( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
rwy_polys[k].set_poly( poly );
}
@ -588,12 +627,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
poly = remove_cycles( poly );
poly = remove_dups( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
poly = remove_bad_contours( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
poly = remove_tiny_contours( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
pvmt_polys[k].set_poly( poly );
}
@ -604,17 +641,16 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_DEBUG, "total size of section " << k << " before =" << poly.total_size());
poly = remove_cycles( poly );
poly = remove_dups( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_dups() = " << poly.total_size());
poly = remove_bad_contours( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_bad() = " << poly.total_size());
poly = remove_tiny_contours( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after remove_tiny_contours() = " << poly.total_size());
line_polys[k].set_poly( poly );
}
gettimeofday(&log_time, NULL);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished cleaning poly for " << icao << " at " << ctime(&log_time.tv_sec) );
SG_LOG(SG_GENERAL, SG_DEBUG, "add nodes base ");
SG_LOG(SG_GENERAL, SG_DEBUG, " before: " << base_poly);
@ -623,15 +659,10 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
base_poly = add_nodes_to_poly( base_poly, tmp_nodes );
SG_LOG(SG_GENERAL, SG_DEBUG, " after adding tmp_nodes: " << base_poly);
// write_polygon( base_poly, "base-add" );
SG_LOG(SG_GENERAL, SG_DEBUG, "remove dups base ");
base_poly = remove_cycles( base_poly );
base_poly = remove_dups( base_poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "remove bad contours base");
base_poly = remove_bad_contours( base_poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "remove small contours base");
base_poly = remove_tiny_contours( base_poly );
// write_polygon( base_poly, "base-fin" );
SG_LOG(SG_GENERAL, SG_DEBUG, " after clean up: " << base_poly);
gettimeofday(&cleanup_end, NULL);
timersub(&cleanup_end, &cleanup_start, &cleanup_time);
@ -641,11 +672,19 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// tesselate the polygons and prepair them for final output
for ( i = 0; i < (int)rwy_polys.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << rwy_polys[i].get_flag());
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating runway poly = " << i << " of " << rwy_polys.size() << " : flag = " << rwy_polys[i].get_flag());
TGPolygon poly = rwy_polys[i].get_poly();
#if 0
if ( i == 62 ) {
tgChopNormalPolygon( "/home/pete", "Base", poly, false );
verbose_triangulation = true;
}
#endif
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly );
TGPolygon tri = polygon_tesselate_alt( poly, verbose_triangulation );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc;
@ -658,11 +697,11 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// tesselate the polygons and prepair them for final output
for ( i = 0; i < (int)pvmt_polys.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << pvmt_polys[i].get_flag());
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating pavement poly = " << i << " of " << pvmt_polys.size() << " : flag = " << pvmt_polys[i].get_flag());
TGPolygon poly = pvmt_polys[i].get_poly();
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly );
TGPolygon tri = polygon_tesselate_alt( poly, false );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc;
@ -682,27 +721,30 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// tesselate the polygons and prepair them for final output
for ( i = 0; i < (int)line_polys.size(); ++i )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Tesselating section = " << i << " flag = " << line_polys[i].get_flag());
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating line poly = " << i << " of " << line_polys.size() << " : flag = " << line_polys[i].get_flag());
TGPolygon poly = line_polys[i].get_poly();
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
SG_LOG(SG_GENERAL, SG_DEBUG, "contours before " << poly.contours() << " total points before = " << poly.total_size());
TGPolygon tri = polygon_tesselate_alt( poly, false );
SG_LOG(SG_GENERAL, SG_DEBUG, "total size after = " << tri.total_size());
TGPolygon tc;
tc = linear_feature_tex_coords( tri, line_tps[i] );
line_polys[i].set_tris( tri );
line_polys[i].set_texcoords( tc );
line_polys[i].set_tris( tri );
line_polys[i].set_texcoords( tc );
}
#if 0
{
string polypath = root + "/AirportArea";
tgChopNormalPolygon( polypath, "Base", base_poly, false );
}
#if 1
{
tgChopNormalPolygon( "/home/pete", "Base", base_poly, false );
verbose_triangulation = true;
}
#endif
TGPolygon base_tris = polygon_tesselate_alt( base_poly );
SG_LOG(SG_GENERAL, SG_INFO, "Tesselating base poly ");
TGPolygon base_tris = polygon_tesselate_alt( base_poly, verbose_triangulation );
gettimeofday(&triangulation_end, NULL);
timersub(&triangulation_end, &triangulation_start, &triangulation_time);
@ -776,6 +818,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( j = 0; j < tri_poly.contour_size(i); ++j )
{
p = tri_poly.get_pt( i, j );
SG_LOG(SG_GENERAL, SG_DEBUG, "adding runway point = " << p);
index = nodes.unique_add( p );
tri_v.push_back( index );
@ -878,6 +922,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for ( j = 0; j < base_tris.contour_size(i); ++j )
{
p = base_tris.get_pt( i, j );
SG_LOG(SG_GENERAL, SG_DEBUG, "adding base point " << p);
index = nodes.unique_add( p );
tri_v.push_back( index );
@ -916,6 +962,8 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
{
for ( j = 0; j < divided_base.contour_size( i ); ++j )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "adding divided base point " << p);
nodes.unique_add( divided_base.get_pt(i, j) );
}
}
@ -927,7 +975,22 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
// it avoids biases introduced from the surrounding area if the
// airport is located in a bowl or on a hill.
SG_LOG(SG_GENERAL, SG_DEBUG, " calcaverage elevation");
{
point_list dbg = nodes.get_node_list();
// dump the node list
SG_LOG(SG_GENERAL, SG_DEBUG, " node list size is " << dbg.size() );
for (unsigned int w = 0; w<dbg.size(); w++)
{
SG_LOG(SG_GENERAL, SG_DEBUG, " node " << w << " is " << dbg[w] );
}
}
double average = tgAverageElevation( root, elev_src, nodes.get_node_list() );
SG_LOG(SG_GENERAL, SG_DEBUG, " done");
// cout << "average airport elevation = " << average << endl;
// Now build the fitted airport surface ...

View file

@ -51,7 +51,7 @@ public:
void AddFeatures( FeatureList* feature_list )
{
for (int i=0; i<feature_list->size(); i++)
for (unsigned int i=0; i<feature_list->size(); i++)
{
features.push_back( feature_list->at(i) );
}

View file

@ -172,6 +172,39 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
return result_list;
}
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width )
{
TGPolygon result_list;
double ptlat, ptlon, r;
Point3D p;
// starting point is in the middle of the rectangle width, at the beginning - stretch to heading
// Point 1 is -90deg, 1/2 width away
double left_hdg = heading -90;
if ( left_hdg < 0 ) { left_hdg += 360.0; }
geo_direct_wgs_84 ( 0.0, lat, lon, left_hdg, width / 2.0, &ptlat, &ptlon, &r );
p = Point3D( ptlon, ptlat, 0.0 );
result_list.add_node( 0, p );
// Point 2 is heading, length away from point 1
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, length, &ptlat, &ptlon, &r );
p = Point3D( ptlon, ptlat, 0.0 );
result_list.add_node( 0, p );
// Point 3 is -90deg, -width away from point 2
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, left_hdg, -width, &ptlat, &ptlon, &r );
p = Point3D( ptlon, ptlat, 0.0 );
result_list.add_node( 0, p );
// last point is heading, -length from point 3
geo_direct_wgs_84 ( 0.0, ptlat, ptlon, heading, -length, &ptlat, &ptlon, &r );
p = Point3D( ptlon, ptlat, 0.0 );
result_list.add_node( 0, p );
return result_list;
}
// generate a section of texture
void gen_tex_section( const TGPolygon& runway,

View file

@ -25,6 +25,9 @@ TGPolygon gen_wgs84_area( Point3D end1, Point3D end2,
double alt_m,
bool add_mid );
TGPolygon gen_wgs84_rect( double lat, double lon, double heading, double length, double width );
void gen_tex_section( const TGPolygon& runway,
double startl_pct, double endl_pct,
double startw_pct, double endw_pct,

View file

@ -10,6 +10,15 @@
#include "convex_hull.hxx"
#include "closedpoly.hxx"
static void stringPurifier( string& s )
{
for ( string::iterator it = s.begin(), itEnd = s.end(); it!=itEnd; ++it) {
if ( static_cast<unsigned int>(*it) < 32 || static_cast<unsigned int>(*it) > 127 ) {
(*it) = ' ';
}
}
}
ClosedPoly::ClosedPoly( char* desc )
{
is_pavement = false;
@ -17,6 +26,7 @@ ClosedPoly::ClosedPoly( char* desc )
if ( desc )
{
description = desc;
stringPurifier(description);
}
else
{
@ -38,6 +48,7 @@ ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
if ( desc )
{
description = desc;
stringPurifier(description);
}
else
{
@ -65,7 +76,7 @@ void ClosedPoly::AddNode( BezNode* node )
{
if (!cur_feature)
{
string feature_desc = description + ":";
string feature_desc = description + " - ";
if (boundary)
{
feature_desc += "hole";
@ -84,10 +95,10 @@ void ClosedPoly::AddNode( BezNode* node )
void ClosedPoly::CreateConvexHull( void )
{
TGPolygon convexHull;
point_list nodes;
Point3D p;
int i;
TGPolygon convexHull;
point_list nodes;
Point3D p;
unsigned int i;
if (boundary->size() > 2)
{
@ -105,7 +116,7 @@ void ClosedPoly::CreateConvexHull( void )
}
}
int ClosedPoly::CloseCurContour()
void ClosedPoly::CloseCurContour()
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Close Contour");
@ -151,7 +162,7 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
Point3D cp2;
int curve_type = CURVE_LINEAR;
int i;
unsigned int i;
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating a contour with " << src->size() << " nodes");
@ -346,7 +357,7 @@ void ClosedPoly::ExpandContour( point_list& src, TGPolygon& dst, double dist )
double h1;
double o1;
double az2;
int i;
unsigned int i;
// iterate through each bezier node in the contour
for (i=0; i<src.size(); i++)
@ -427,7 +438,7 @@ void ClosedPoly::ExpandContour( point_list& src, TGPolygon& dst, double dist )
}
// finish the poly - convert to TGPolygon, and tesselate
int ClosedPoly::Finish()
void ClosedPoly::Finish()
{
point_list dst_contour;
@ -448,7 +459,7 @@ int ClosedPoly::Finish()
pre_tess.add_contour( dst_contour, 0 );
// The convert the hole contours
for (int i=0; i<holes.size(); i++)
for (unsigned int i=0; i<holes.size(); i++)
{
dst_contour.clear();
ConvertContour( holes[i], &dst_contour );
@ -574,4 +585,6 @@ int ClosedPoly::BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clear
// and add the clearing to the base
*apt_base = tgPolygonUnion( pre_tess, *apt_base );
}
return 1;
}

View file

@ -24,8 +24,8 @@ public:
inline string GetDescription() { return description; }
void AddNode( BezNode* node );
int CloseCurContour();
int Finish();
void CloseCurContour();
void Finish();
// Build BTG for airport base for airports with boundary
int BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing );

View file

@ -68,21 +68,23 @@ double tgAverageElevation( const string &root, const string_list elev_src,
}
while ( !done ) {
// find first node with -9999 elevation
// find first node with -9999 elevation
Point3D first(0.0);
bool found_one = false;
for ( i = 0; i < points.size(); ++i ) {
if ( points[i].z() < -9000.0 && !found_one ) {
first = points[i];
SG_LOG( SG_GENERAL, SG_DEBUG, "founf first = " << first );
found_one = true;
}
}
if ( found_one ) {
SGBucket b( first.x(), first.y() );
string base = b.gen_base_path();
if ( found_one ) {
SGBucket b( first.x(), first.y() );
string base = b.gen_base_path();
// try the various elevation sources
// try the various elevation sources
i = 0;
bool found_file = false;
while ( !found_file && i < elev_src.size() ) {
@ -98,7 +100,7 @@ double tgAverageElevation( const string &root, const string_list elev_src,
// this will fill in a zero structure if no array data
// found/opened
array.parse( b );
array.parse( b );
// this will do a hasty job of removing voids by inserting
// data from the nearest neighbor (sort of)

View file

@ -125,7 +125,7 @@ int main(int argc, char **argv)
setup_default_elevation_sources(elev_src);
// Set verbose
// sglog().setLogLevels( SG_GENERAL, SG_BULK );
// sglog().setLogLevels( SG_GENERAL, SG_BULK );
sglog().setLogLevels( SG_GENERAL, SG_INFO );
SG_LOG(SG_GENERAL, SG_INFO, "Run genapt");

View file

@ -345,6 +345,8 @@ void Parser::Parse()
}
gettimeofday(&parse_end, NULL);
timersub(&parse_end, &parse_start, &parse_time);
SG_LOG( SG_GENERAL, SG_ALERT, "Finished parsing airport " << airport_icaos[i] << " at " << ctime(&parse_end.tv_sec) );
// write the airport BTG
if (cur_airport)
@ -536,9 +538,13 @@ ClosedPoly* Parser::ParsePavement( char* line )
if (numParams == 4)
{
d = strstr(line,desc);
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th << " and description " << d);
}
else
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th );
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly with st " << st << " smoothness " << s << " thexture heading " << th << " and description " << d);
poly = new ClosedPoly(st, s, th, d);
return poly;
@ -599,178 +605,146 @@ int Parser::ParseLine(char* line)
BezNode* cur_node = NULL;
// Get the number code
tok = strtok(line, " \t\r\n");
if (tok)
if (*line != '#')
{
line += strlen(tok)+1;
code = atoi(tok);
// Get the number code
tok = strtok(line, " \t\r\n");
switch(code)
if (tok)
{
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
if (cur_state == STATE_NONE)
{
line += strlen(tok)+1;
code = atoi(tok);
switch(code)
{
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
if (cur_state == STATE_NONE)
{
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing land airport: " << line);
cur_airport = new Airport( code, line );
}
else
{
SetState( STATE_DONE );
}
break;
case HELIPORT_CODE:
if (cur_state == STATE_NONE)
{
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing heliport: " << line);
cur_airport = new Airport( code, line );
}
else
{
SetState( STATE_DONE );
}
break;
case LAND_RUNWAY_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing land airport: " << line);
cur_airport = new Airport( code, line );
}
else
{
SetState( STATE_DONE );
}
break;
case HELIPORT_CODE:
if (cur_state == STATE_NONE)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
cur_runway = new Runway(line);
if (cur_airport)
{
cur_airport->AddRunway( cur_runway );
}
break;
case WATER_RUNWAY_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing heliport: " << line);
cur_airport = new Airport( code, line );
}
else
{
SetState( STATE_DONE );
}
break;
case LAND_RUNWAY_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
cur_runway = new Runway(line);
if (cur_airport)
{
cur_airport->AddRunway( cur_runway );
}
break;
case WATER_RUNWAY_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
cur_waterrunway = new WaterRunway(line);
if (cur_airport)
{
cur_airport->AddWaterRunway( cur_waterrunway );
}
break;
case HELIPAD_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
cur_helipad = new Helipad(line);
if (cur_airport)
{
cur_airport->AddHelipad( cur_helipad );
}
break;
case PAVEMENT_CODE:
SetState( STATE_PARSE_PAVEMENT );
cur_pavement = ParsePavement( line );
break;
case LINEAR_FEATURE_CODE:
SetState( STATE_PARSE_FEATURE );
cur_feat = ParseFeature( line );
break;
case BOUNDRY_CODE:
SetState( STATE_PARSE_BOUNDARY );
cur_boundary = ParseBoundary( line );
break;
case NODE_CODE:
case BEZIER_NODE_CODE:
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing node: " << line);
cur_node = ParseNode( code, line, prev_node );
if ( prev_node && (cur_node != prev_node) )
{
// prev node is done - process it\n");
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
cur_waterrunway = new WaterRunway(line);
if (cur_airport)
{
cur_airport->AddWaterRunway( cur_waterrunway );
}
break;
case HELIPAD_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
cur_helipad = new Helipad(line);
if (cur_airport)
{
cur_airport->AddHelipad( cur_helipad );
}
break;
case PAVEMENT_CODE:
SetState( STATE_PARSE_PAVEMENT );
cur_pavement = ParsePavement( line );
break;
case LINEAR_FEATURE_CODE:
SetState( STATE_PARSE_FEATURE );
cur_feat = ParseFeature( line );
break;
case BOUNDRY_CODE:
SetState( STATE_PARSE_BOUNDARY );
cur_boundary = ParseBoundary( line );
break;
case NODE_CODE:
case BEZIER_NODE_CODE:
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing node: " << line);
cur_node = ParseNode( code, line, prev_node );
if ( prev_node && (cur_node != prev_node) )
{
// prev node is done - process it\n");
if ( cur_state == STATE_PARSE_PAVEMENT )
{
cur_pavement->AddNode( prev_node );
}
else if ( cur_state == STATE_PARSE_FEATURE )
{
cur_feat->AddNode( prev_node );
}
else if ( cur_state == STATE_PARSE_BOUNDARY )
{
cur_boundary->AddNode( prev_node );
}
}
prev_node = cur_node;
break;
case CLOSE_NODE_CODE:
case CLOSE_BEZIER_NODE_CODE:
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing close loop node: " << line);
cur_node = ParseNode( code, line, prev_node );
if ( cur_state == STATE_PARSE_PAVEMENT )
{
cur_pavement->AddNode( prev_node );
}
else if ( cur_state == STATE_PARSE_FEATURE )
{
cur_feat->AddNode( prev_node );
if (cur_node != prev_node)
{
cur_pavement->AddNode( prev_node );
cur_pavement->AddNode( cur_node );
}
else
{
cur_pavement->AddNode( cur_node );
}
cur_pavement->CloseCurContour();
}
else if ( cur_state == STATE_PARSE_BOUNDARY )
{
cur_boundary->AddNode( prev_node );
if (cur_node != prev_node)
{
cur_boundary->AddNode( prev_node );
cur_boundary->AddNode( cur_node );
}
else
{
cur_boundary->AddNode( cur_node );
}
cur_boundary->CloseCurContour();
}
}
prev_node = cur_node;
break;
case CLOSE_NODE_CODE:
case CLOSE_BEZIER_NODE_CODE:
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing close loop node: " << line);
cur_node = ParseNode( code, line, prev_node );
if ( cur_state == STATE_PARSE_PAVEMENT )
{
if (cur_node != prev_node)
else if ( cur_state == STATE_PARSE_FEATURE )
{
cur_pavement->AddNode( prev_node );
cur_pavement->AddNode( cur_node );
}
else
{
cur_pavement->AddNode( cur_node );
}
cur_pavement->CloseCurContour();
}
else if ( cur_state == STATE_PARSE_BOUNDARY )
{
if (cur_node != prev_node)
{
cur_boundary->AddNode( prev_node );
cur_boundary->AddNode( cur_node );
}
else
{
cur_boundary->AddNode( cur_node );
}
cur_boundary->CloseCurContour();
}
else if ( cur_state == STATE_PARSE_FEATURE )
{
if (cur_node != prev_node)
{
cur_feat->AddNode( prev_node );
cur_feat->AddNode( cur_node );
}
else
{
cur_feat->AddNode( cur_node );
}
if (cur_airport)
{
cur_feat->Finish();
cur_airport->AddFeature( cur_feat );
}
cur_feat = NULL;
SetState( STATE_NONE );
}
prev_node = NULL;
cur_node = NULL;
break;
case TERM_NODE_CODE:
case TERM_BEZIER_NODE_CODE:
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing termination node: " << line);
if ( cur_state == STATE_PARSE_FEATURE )
{
// we have some bad data - termination nodes right after the
// linear feature declaration - can't do anything with a
// single point - detect and delete.
if ( prev_node )
{
cur_node = ParseNode( code, line, prev_node );
if (cur_node != prev_node)
{
cur_feat->AddNode( prev_node );
@ -785,87 +759,122 @@ int Parser::ParseLine(char* line)
cur_feat->Finish();
cur_airport->AddFeature( cur_feat );
}
cur_feat = NULL;
SetState( STATE_NONE );
}
else
prev_node = NULL;
cur_node = NULL;
break;
case TERM_NODE_CODE:
case TERM_BEZIER_NODE_CODE:
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing termination node: " << line);
if ( cur_state == STATE_PARSE_FEATURE )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Parsing termination node with no previous nodes!!!" );
// this feature is bogus...
delete cur_feat;
// we have some bad data - termination nodes right after the
// linear feature declaration - can't do anything with a
// single point - detect and delete.
if ( prev_node )
{
cur_node = ParseNode( code, line, prev_node );
if (cur_node != prev_node)
{
cur_feat->AddNode( prev_node );
cur_feat->AddNode( cur_node );
}
else
{
cur_feat->AddNode( cur_node );
}
if (cur_airport)
{
cur_feat->Finish();
cur_airport->AddFeature( cur_feat );
}
}
else
{
SG_LOG(SG_GENERAL, SG_ALERT, "Parsing termination node with no previous nodes!!!" );
// this feature is bogus...
delete cur_feat;
}
cur_feat = NULL;
SetState( STATE_NONE );
}
cur_feat = NULL;
SetState( STATE_NONE );
}
prev_node = NULL;
cur_node = NULL;
break;
case AIRPORT_VIEWPOINT_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing viewpoint: " << line);
break;
case AIRPLANE_STARTUP_LOCATION_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airplane startup location: " << line);
break;
case LIGHT_BEACON_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
cur_beacon = new Beacon(line);
cur_airport->AddBeacon( cur_beacon );
break;
case WINDSOCK_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
cur_windsock = new Windsock(line);
cur_airport->AddWindsock( cur_windsock );
break;
case TAXIWAY_SIGN:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
cur_sign = new Sign(line);
cur_airport->AddSign( cur_sign );
break;
case LIGHTING_OBJECT:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
cur_object = new LightingObj(line);
cur_airport->AddObj( cur_object );
break;
case COMM_FREQ1_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 1: " << line);
break;
case COMM_FREQ2_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 2: " << line);
break;
case COMM_FREQ3_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 3: " << line);
break;
case COMM_FREQ4_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 4: " << line);
break;
case COMM_FREQ5_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 5: " << line);
break;
case COMM_FREQ6_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 6: " << line);
break;
case COMM_FREQ7_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 7: " << line);
break;
case END_OF_FILE :
SG_LOG(SG_GENERAL, SG_DEBUG, "Reached end of file");
SetState( STATE_DONE );
break;
prev_node = NULL;
cur_node = NULL;
break;
case AIRPORT_VIEWPOINT_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing viewpoint: " << line);
break;
case AIRPLANE_STARTUP_LOCATION_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airplane startup location: " << line);
break;
case LIGHT_BEACON_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
cur_beacon = new Beacon(line);
cur_airport->AddBeacon( cur_beacon );
break;
case WINDSOCK_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
cur_windsock = new Windsock(line);
cur_airport->AddWindsock( cur_windsock );
break;
case TAXIWAY_SIGN:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
cur_sign = new Sign(line);
cur_airport->AddSign( cur_sign );
break;
case LIGHTING_OBJECT:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
cur_object = new LightingObj(line);
cur_airport->AddObj( cur_object );
break;
case COMM_FREQ1_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 1: " << line);
break;
case COMM_FREQ2_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 2: " << line);
break;
case COMM_FREQ3_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 3: " << line);
break;
case COMM_FREQ4_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 4: " << line);
break;
case COMM_FREQ5_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 5: " << line);
break;
case COMM_FREQ6_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 6: " << line);
break;
case COMM_FREQ7_CODE:
SetState( STATE_PARSE_SIMPLE );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing commfreq 7: " << line);
break;
case END_OF_FILE :
SG_LOG(SG_GENERAL, SG_DEBUG, "Reached end of file");
SetState( STATE_DONE );
break;
}
}
}
return cur_state;
}

View file

@ -136,8 +136,8 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
case 4: // Dirt
case 5: // Gravel
SG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Turf, Dirt or Gravel" << rwy.surface );
gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
gen_runway_lights( alt_m, rwy_lights );
gen_simple_rwy( alt_m, material, rwy_polys, texparams, accum );
gen_runway_lights( alt_m, rwy_lights );
break;
case 12: // dry lakebed
@ -164,10 +164,10 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
if (apt_base)
{
// generate area around runways
base = gen_runway_area_w_extend( 0.0, rwy.width * 0.25, -rwy.overrun[0], -rwy.overrun[1], rwy.width * 0.25);
base = gen_runway_area_w_extend( 0.0, 20.0, -rwy.overrun[0], -rwy.overrun[1], 20.0);
// also clear a safe area around the runway
safe_base = gen_runway_area_w_extend( 0.0, rwy.width, -rwy.overrun[0], -rwy.overrun[1], rwy.width );
safe_base = gen_runway_area_w_extend( 0.0, 180.0, -rwy.overrun[0], -rwy.overrun[1], 50.0 );
// add this to the airport clearing
*apt_clearing = tgPolygonUnion(safe_base, *apt_clearing);

View file

@ -354,7 +354,7 @@ void Runway::BuildShoulder( float alt_m,
} else SG_LOG(SG_GENERAL, SG_ALERT, "Unknown shoulder surface code = " << rwy.shoulder );
} else if (rwy.shoulder == 0){ // We add a fake shoulder if the runway has an asphalt or concrete surface
shoulder_width = 1;
shoulder_width = 1.0;
if (rwy.surface == 1){
shoulder_surface = "pa_shoulder_f";
} else if (rwy.surface == 2){
@ -365,6 +365,13 @@ void Runway::BuildShoulder( float alt_m,
SG_LOG(SG_GENERAL, SG_DEBUG, "Shoulder surface is: " << shoulder_surface );
if (shoulder_width > 0.0f) {
// we need to break these shoulders up into managable pieces, as we're asked to triangulate
// 3-4 km long by 1m wide strips - jrs-can't handle it.
double max_dist = (double)shoulder_width * 50.0f;
int numSegs = (rwy.length / max_dist) + 1;
double dist = rwy.length / (double)numSegs;
// Create both shoulder sides
for (int i=0; i<2; ++i){
double step;
@ -374,44 +381,40 @@ void Runway::BuildShoulder( float alt_m,
/* If the are 'equal' there's a good chance roundoff error can create a */
/* REALY thin long polygon, which causes a segfault */
if (i == 0){
step= (rwy.width + shoulder_width)*0.5 - 0.00001;
step= (rwy.width + shoulder_width)*0.5;
} else if (i == 1) {
step= -(rwy.width + shoulder_width)*0.5 + 0.00001;
step= -(rwy.width + shoulder_width)*0.5;
}
double left_hdg = rwy.heading - 90.0;
if ( left_hdg < 0 ) { left_hdg += 360.0; }
geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg,
step, &lat, &lon, &r );
geo_direct_wgs_84 ( alt_m, rwy.lat[0], rwy.lon[0], left_hdg, step, &lat, &lon, &r );
Point3D ref = Point3D( lon, lat, 0.0f );
Point3D shoulder1 = Point3D( lon, lat, 0.0f );
for (int j=0; j<numSegs; j++)
{
geo_direct_wgs_84 ( alt_m, ref.y(), ref.x(), rwy.heading, (j*dist), &lat, &lon, &r );
TGPolygon shoulderSegment = gen_wgs84_rect( lat, lon, rwy.heading, dist+0.2, shoulder_width+0.5 );
geo_direct_wgs_84 ( alt_m, rwy.lat[1], rwy.lon[1], left_hdg,
step, &lat, &lon, &r );
TGSuperPoly sp;
TGTexParams tp;
TGPolygon clipped = tgPolygonDiff( shoulderSegment, *accum );
Point3D shoulder2 = Point3D( lon, lat, 0.0f );
sp.erase();
sp.set_poly( clipped );
sp.set_material( shoulder_surface );
rwy_polys->push_back( sp );
TGPolygon shoulder = gen_wgs84_area( shoulder1, shoulder2, 0.0, 0.0, 0.0, shoulder_width, rwy.heading, alt_m, false);
*accum = tgPolygonUnion( shoulderSegment, *accum );
TGSuperPoly sp;
TGTexParams tp;
TGPolygon clipped = tgPolygonDiff( shoulder, *accum );
TGPolygon split = tgPolygonSplitLongEdges( clipped, 400.0 );
sp.erase();
sp.set_poly( split );
sp.set_material( shoulder_surface );
rwy_polys->push_back( sp );
*accum = tgPolygonUnion( shoulder, *accum );
tp = TGTexParams( shoulder.get_pt(0,0), shoulder_width , rwy.length + 2, rwy.heading );
if (i == 1){
tp.set_maxu(0);
tp.set_minu(1);
tp = TGTexParams( shoulderSegment.get_pt(0,0), -shoulder_width, dist, rwy.heading );
if (i == 0){
tp.set_maxu(0);
tp.set_minu(1);
}
texparams->push_back( tp );
}
texparams->push_back( tp );
}
}
}

View file

@ -63,6 +63,8 @@ TGArray::TGArray( const string &file ):
for (int i = 0; i < ARRAY_SIZE_1; i++)
in_data[i] = new int[ARRAY_SIZE_1];
SG_LOG(SG_GENERAL, SG_ALERT, "ps TGArray CONstructor called." );
TGArray::open(file);
}
@ -75,7 +77,7 @@ bool TGArray::open( const string& file_base ) {
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, " Cannot open " << array_name );
SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << array_name );
success = false;
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, " Opening array data file: " << array_name );
@ -89,7 +91,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, " Cannot open " << fitted_name );
SG_LOG(SG_GENERAL, SG_DEBUG, " ps: Cannot open " << fitted_name );
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, " Opening fitted data file: " << fitted_name );
}

View file

@ -50,8 +50,6 @@ extern "C" {
#include "trisegs.hxx"
using std::copy;
using std::cout;
using std::endl;
using std::ostream_iterator;
using std::sort;
using std::vector;
@ -117,7 +115,7 @@ static bool intersects( Point3D p0, Point3D p1, double x, Point3D *result ) {
// basic triangulation of a polygon with out adding points or
// splitting edges, this should triangulate around interior holes.
void polygon_tesselate( const TGPolygon &p,
int polygon_tesselate( const TGPolygon &p,
const point_list &extra_nodes,
triele_list &elelist,
point_list &out_pts,
@ -125,8 +123,7 @@ void polygon_tesselate( const TGPolygon &p,
{
struct triangulateio in, out, vorout;
int i;
tri_flags = "pzqenXYYQ";
int success = 0;
// make sure all elements of these structs point to "NULL"
zero_triangulateio( &in );
@ -272,7 +269,7 @@ void polygon_tesselate( const TGPolygon &p,
// no new points on boundary (Y), no internal segment
// splitting (YY), no quality refinement (q)
// Quite (Q)
triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
success = triangulate( (char *)tri_flags.c_str(), &in, &out, &vorout );
// TEMPORARY
// write_tri_data(&out);
@ -280,33 +277,36 @@ void polygon_tesselate( const TGPolygon &p,
// now copy the results back into the corresponding TGTriangle
// structures
// triangles
elelist.clear();
int n1, n2, n3;
double attribute;
for ( i = 0; i < out.numberoftriangles; ++i ) {
n1 = out.trianglelist[i * 3];
n2 = out.trianglelist[i * 3 + 1];
n3 = out.trianglelist[i * 3 + 2];
if ( out.numberoftriangleattributes > 0 ) {
attribute = out.triangleattributelist[i];
} else {
attribute = 0.0;
if (success >= 0) {
// triangles
elelist.clear();
int n1, n2, n3;
double attribute;
for ( i = 0; i < out.numberoftriangles; ++i ) {
n1 = out.trianglelist[i * 3];
n2 = out.trianglelist[i * 3 + 1];
n3 = out.trianglelist[i * 3 + 2];
if ( out.numberoftriangleattributes > 0 ) {
attribute = out.triangleattributelist[i];
} else {
attribute = 0.0;
}
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
}
// output points
out_pts.clear();
double x, y, z;
for ( i = 0; i < out.numberofpoints; ++i ) {
x = out.pointlist[i * 2 ];
y = out.pointlist[i * 2 + 1];
z = out.pointattributelist[i];
out_pts.push_back( Point3D(x, y, z) );
}
// cout << "triangle = " << n1 << " " << n2 << " " << n3 << endl;
elelist.push_back( TGTriEle( n1, n2, n3, attribute ) );
}
// output points
out_pts.clear();
double x, y, z;
for ( i = 0; i < out.numberofpoints; ++i ) {
x = out.pointlist[i * 2 ];
y = out.pointlist[i * 2 + 1];
z = out.pointattributelist[i];
out_pts.push_back( Point3D(x, y, z) );
}
// free mem allocated to the "Triangle" structures
free(in.pointlist);
free(in.pointattributelist);
@ -327,6 +327,8 @@ void polygon_tesselate( const TGPolygon &p,
free(vorout.pointattributelist);
free(vorout.edgelist);
free(vorout.normlist);
return success;
}
@ -336,7 +338,7 @@ void polygon_tesselate( const TGPolygon &p,
// wrapper for the polygon_tesselate() function. Note, this routine
// will modify the points_inside list for your polygon.
TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose ) {
TGPolygon result;
point_list extra_nodes;
result.erase();
@ -358,25 +360,42 @@ TGPolygon polygon_tesselate_alt( TGPolygon &p ) {
// 2. Do a final triangulation of the entire polygon
triele_list trieles;
point_list nodes;
// polygon_tesselate( p, extra_nodes, trieles, nodes, "pzYYenQ" );
polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
string flags;
if (verbose) {
flags = "pzqenXYY";
} else {
flags = "pzqenXYYQ";
}
// 3. Convert the tesselated output to a list of tringles.
// basically a polygon with a contour for every triangle
for ( i = 0; i < (int)trieles.size(); ++i ) {
TGTriEle t = trieles[i];
Point3D p1 = nodes[ t.get_n1() ];
Point3D p2 = nodes[ t.get_n2() ];
Point3D p3 = nodes[ t.get_n3() ];
result.add_node( i, p1 );
result.add_node( i, p2 );
result.add_node( i, p3 );
if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
// 3. Convert the tesselated output to a list of tringles.
// basically a polygon with a contour for every triangle
for ( i = 0; i < (int)trieles.size(); ++i ) {
TGTriEle t = trieles[i];
Point3D p1 = nodes[ t.get_n1() ];
Point3D p2 = nodes[ t.get_n2() ];
Point3D p3 = nodes[ t.get_n3() ];
result.add_node( i, p1 );
result.add_node( i, p2 );
result.add_node( i, p3 );
}
}
// check the result for nan point
for (int c = 0; c < result.contours(); c++) {
point_list contour = result.get_contour( c );
for ( int d = 0; d < (int)contour.size(); ++d ) {
if ( isnan( contour[d].x() ) || isnan( contour[d].y() ) ) {
printf("Uh-oh - got nan from tesselation\n");
exit(0);
}
}
}
return result;
}
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes ) {
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extra_nodes, bool verbose ) {
TGPolygon result;
result.erase();
int i;
@ -394,18 +413,25 @@ TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p, const point_list& extr
// 2. Do a final triangulation of the entire polygon
triele_list trieles;
point_list nodes;
polygon_tesselate( p, extra_nodes, trieles, nodes, "pzenQ" );
string flags;
if (verbose) {
flags = "VVpzqenXYY";
} else {
flags = "pzqenXYYQ";
}
// 3. Convert the tesselated output to a list of tringles.
// basically a polygon with a contour for every triangle
for ( i = 0; i < (int)trieles.size(); ++i ) {
TGTriEle t = trieles[i];
Point3D p1 = nodes[ t.get_n1() ];
Point3D p2 = nodes[ t.get_n2() ];
Point3D p3 = nodes[ t.get_n3() ];
result.add_node( i, p1 );
result.add_node( i, p2 );
result.add_node( i, p3 );
if ( polygon_tesselate( p, extra_nodes, trieles, nodes, flags ) >= 0 ) {
// 3. Convert the tesselated output to a list of tringles.
// basically a polygon with a contour for every triangle
for ( i = 0; i < (int)trieles.size(); ++i ) {
TGTriEle t = trieles[i];
Point3D p1 = nodes[ t.get_n1() ];
Point3D p2 = nodes[ t.get_n2() ];
Point3D p3 = nodes[ t.get_n3() ];
result.add_node( i, p1 );
result.add_node( i, p2 );
result.add_node( i, p3 );
}
}
return result;
@ -598,7 +624,7 @@ static void calc_point_inside( TGContourNode *node, TGPolygon &p ) {
}
static void print_contour_tree( TGContourNode *node, string indent ) {
cout << indent << node->get_contour_num() << endl;
// cout << indent << node->get_contour_num() << endl;
indent += " ";
for ( int i = 0; i < node->get_num_kids(); ++i ) {
@ -997,7 +1023,7 @@ static point_list reduce_contour_degeneracy( const point_list& contour ) {
// remove bad node from contour. But only remove one node. If
// the 'badness' is caused by coincident adjacent nodes, we don't
// want to remove both of them, just one (either will do.)
cout << "found a bad node = " << bad_node << endl;
// cout << "found a bad node = " << bad_node << endl;
point_list tmp; tmp.clear();
bool found_one = false;
for ( int j = 0; j < (int)result.size(); ++j ) {
@ -1045,11 +1071,11 @@ static point_list remove_small_cycles( const point_list& contour ) {
result.push_back( contour[i] );
for ( unsigned int j = i + 1; j < contour.size(); ++j ) {
if ( contour[i] == contour[j] && i + 4 > j ) {
cout << "detected a small cycle: i = "
<< i << " j = " << j << endl;
for ( unsigned int k = i; k <= j; ++k ) {
cout << " " << contour[k] << endl;
}
// cout << "detected a small cycle: i = "
// << i << " j = " << j << endl;
//for ( unsigned int k = i; k <= j; ++k ) {
// cout << " " << contour[k] << endl;
//}
i = j;
}
}

View file

@ -53,7 +53,7 @@ inline double triangle_area( const Point3D p1,
// basic triangulation of a polygon with out adding points or
// splitting edges
void polygon_tesselate( const TGPolygon &p,
int polygon_tesselate( const TGPolygon &p,
const point_list &extra_nodes,
triele_list &elelist,
point_list &out_pts,
@ -64,10 +64,10 @@ void polygon_tesselate( const TGPolygon &p,
// with one contour per tesselated triangle. This is mostly just a
// wrapper for the polygon_tesselate() function. Note, this routine
// will modify the points_inside list for your polygon.
TGPolygon polygon_tesselate_alt( TGPolygon &p );
TGPolygon polygon_tesselate_alt( TGPolygon &p, bool verbose );
TGPolygon polygon_tesselate_alt_with_extra( TGPolygon &p,
const point_list &extra_nodes );
const point_list &extra_nodes, bool verbose );
// calculate some "arbitrary" point inside each of the polygons contours
void calc_points_inside( TGPolygon& p );

View file

@ -36,8 +36,8 @@
#define FG_PROXIMITY_EPSILON 0.000001
#define FG_COURSE_EPSILON 0.0003
//#define FG_COURSE_EPSILON 0.0003
#define FG_COURSE_EPSILON 0.0001
class TGTriNodes {