1
0
Fork 0

Added Airport boundary support.

- needs testing on lots of airports.  I'm uncomfortable with expanding
  concave polys by 20 meters.  I really need to find a safe polygon expander.
This commit is contained in:
PSadrozinski 2011-10-08 09:46:23 -04:00 committed by Christian Schmitt
parent 33c92f60f6
commit 3ba27cd481
10 changed files with 267 additions and 125 deletions

View file

@ -35,14 +35,12 @@ Airport::Airport( int c, char* def)
code = c;
SG_LOG(SG_GENERAL, SG_DEBUG, "sscanf " << def);
numParams = sscanf(def, "%d %d %d %s %ls", &altitude, &x, &y, tmp, d);
SG_LOG(SG_GENERAL, SG_DEBUG, "done ");
SG_LOG(SG_GENERAL, SG_DEBUG, "got " << altitude << ", " << tmp << ", " << d);
altitude *= SG_FEET_TO_METER;
icao = tmp;
description = d;
boundary = NULL;
}
// TODO: fix OSG - it was nice, but unnecesary...
@ -379,10 +377,17 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
for (i=0; i<runways.size(); i++ )
{
if ( runways[i]->IsPrecision() )
{
if (boundary)
{
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
}
else
{
runways[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
}
}
}
if (lightobjects.size())
{
@ -396,18 +401,32 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
if (helipads.size())
{
for (i=0; i<helipads.size(); i++ )
{
if (boundary)
{
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, NULL, NULL );
}
else
{
helipads[i]->BuildBtg( altitude, &rwy_polys, &rwy_tps, &rwy_lights, &accum, &apt_base, &apt_clearing );
}
}
}
// Build the pavements
if (pavements.size())
{
for ( i=0; i<pavements.size(); i++ )
{
SG_LOG(SG_GENERAL, SG_ALERT, "Build Pavement Poly " << i << ": " << pavements[i]->GetDescription());
if (boundary)
{
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, NULL, NULL );
}
else
{
pavements[i]->BuildBtg( altitude, &pvmt_polys, &pvmt_tps, &accum, &apt_base, &apt_clearing );
// AddFeatures( pavements[i]->GetMarkings() );
}
}
}
else
@ -415,6 +434,12 @@ void Airport::BuildBtg(const string& root, const string_list& elev_src )
SG_LOG(SG_GENERAL, SG_ALERT, "no pavements");
}
// build the base and clearing if there's a boundary
if (boundary)
{
boundary->BuildBtg( altitude, &apt_base, &apt_clearing );
}
if ( apt_base.total_size() == 0 )
{
SG_LOG(SG_GENERAL, SG_ALERT, "no airport points generated");

View file

@ -57,6 +57,11 @@ public:
}
}
void SetBoundary( ClosedPoly* bndry )
{
boundary = bndry;
}
void AddWindsock( Windsock* windsock )
{
windsocks.push_back( windsock );
@ -90,6 +95,7 @@ private:
BeaconList beacons;
SignList signs;
HelipadList helipads;
ClosedPoly* boundary;
};
typedef std::vector <Airport *> AirportList;

View file

@ -14,12 +14,31 @@
#include "convex_hull.hxx"
#include "closedpoly.hxx"
ClosedPoly::ClosedPoly( char* desc )
{
is_pavement = false;
if ( desc )
{
description = desc;
}
else
{
description = "none";
}
boundary = NULL;
cur_contour = NULL;
cur_feature = NULL;
}
ClosedPoly::ClosedPoly( int st, float s, float th, char* desc )
{
surface_type = st;
smoothness = s;
texture_heading = th;
is_pavement = true;
if ( desc )
{
description = desc;
@ -43,15 +62,11 @@ void ClosedPoly::AddNode( BezNode* node )
}
cur_contour->push_back( node );
SG_LOG(SG_GENERAL, SG_DEBUG, "CLOSEDPOLY::ADDNODE : (" << node->GetLoc().x() << "," << node->GetLoc().y() << ")");
// TODO: Create ONE linear feature for each contour.
// Parse the polys in linear feature
// if recording a linear feature on the pavement, add this node
// to it as well
// TODO: just doing marking now, need lighting as well
// For pavement polys, add a linear feature for each contour
if (is_pavement)
{
if (!cur_feature)
{
string feature_desc = description + ":";
@ -68,6 +83,7 @@ void ClosedPoly::AddNode( BezNode* node )
cur_feature = new LinearFeature(feature_desc, 1.0f );
}
cur_feature->AddNode( node );
}
}
void ClosedPoly::CreateConvexHull( void )
@ -77,17 +93,20 @@ void ClosedPoly::CreateConvexHull( void )
Point3D p;
int i;
if (boundary->size() > 2){
if (boundary->size() > 2)
{
for (i=0; i<boundary->size(); i++)
{
p = boundary->at(i)->GetLoc();
nodes.push_back( p );
}
convexHull = convex_hull( nodes );
hull = convexHull.get_contour(0);
} else
}
else
{
SG_LOG(SG_GENERAL, SG_ALERT, "Boundary size too small: " << boundary->size() << ". Ignoring..." );
}
}
int ClosedPoly::CloseCurContour()
@ -281,9 +300,6 @@ void ClosedPoly::ConvertContour( BezContour* src, point_list *dst )
SG_LOG(SG_GENERAL, SG_DEBUG, "adding Linear Anchor node at (" << curLoc.x() << "," << curLoc.y() << ")");
}
}
// Add the first point again?
// dst->push_back( src->at(0)->GetLoc() );
}
void ExpandPoint( Point3D *prev, Point3D *cur, Point3D *next, double expand_by, double *heading, double *offset )
@ -459,7 +475,7 @@ int ClosedPoly::Finish()
// error handling
if (boundary == NULL)
{
SG_LOG(SG_GENERAL, SG_DEBUG, "no boundary");
SG_LOG(SG_GENERAL, SG_ALERT, "no boundary");
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Converting a poly with " << holes.size() << " holes");
@ -485,7 +501,7 @@ int ClosedPoly::Finish()
delete boundary;
boundary = NULL;
// The convert the hole contours
// and the hole contours
holes.clear();
}
@ -579,6 +595,8 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
string material;
int j, k;
if (is_pavement)
{
switch( surface_type )
{
case 1:
@ -592,7 +610,8 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
case 3:
material = "grass_rwy";
break;
// TODO Differentiate more here:
// TODO Differentiate more here:
case 4:
case 5:
case 12:
@ -645,6 +664,8 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
tp = TGTexParams( pre_tess.get_pt(0,0), 5.0, 5.0, texture_heading );
texparams->push_back( tp );
if ( apt_base )
{
ExpandContour( hull, base, 20.0 );
ExpandContour( hull, safe_base, 50.0 );
@ -654,9 +675,29 @@ int ClosedPoly::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list
// and add the clearing to the base
*apt_base = tgPolygonUnion( base, *apt_base );
}
}
}
// clean up to save ram : we're done here...
return 1;
}
int ClosedPoly::BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing )
{
TGPolygon base, safe_base;
// verify the poly has been generated
if ( pre_tess.contours() )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "BuildBtg: original poly has " << pre_tess.contours() << " contours");
hull = pre_tess.get_contour(0);
ExpandContour( hull, safe_base, 20.0 );
// add this to the airport clearing
*apt_clearing = tgPolygonUnion( safe_base, *apt_clearing);
// and add the clearing to the base
*apt_base = tgPolygonUnion( pre_tess, *apt_base );
}
}

View file

@ -18,13 +18,20 @@ using std::string;
class ClosedPoly
{
public:
ClosedPoly( char* desc );
ClosedPoly( int st, float s, float th, char* desc );
inline string GetDescription() { return description; }
void AddNode( BezNode* node );
int CloseCurContour();
int Finish();
int BuildOsg( osg::Group* airport );
// Build BTG for airport base for airports with boundary
int BuildBtg( float alt_m, TGPolygon* apt_base, TGPolygon* apt_clearing );
// Build BTG for pavements for airports with no boundary
int BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* texparams, TGPolygon* accum, TGPolygon* apt_base, TGPolygon* apt_clearing );
FeatureList* GetFeatures()
@ -40,6 +47,7 @@ private:
osg::DrawArrays* CreateOsgPrimitive( point_list contour, osg::Vec3Array* vpave );
void ExpandContour( point_list& src, TGPolygon& dst, double dist );
bool is_pavement;
int surface_type;
float smoothness;
float texture_heading;

View file

@ -114,6 +114,8 @@ void Helipad::BuildBtg( float alt_m,
// generate area around helipad
if (apt_base)
{
TGPolygon base, safe_base;
base = gen_runway_area_w_extend( 0.0, maxsize * 0.25 , 0.0, 0.0, maxsize * 0.25 );
@ -125,6 +127,7 @@ void Helipad::BuildBtg( float alt_m,
// and add the clearing to the base
*apt_base = tgPolygonUnion( base, *apt_base );
}
// Now generate the helipad lights
superpoly_list s = gen_helipad_lights();

View file

@ -2578,7 +2578,7 @@ superpoly_list Runway::gen_malsx( float alt_m, const string& kind, bool recip )
// top level runway light generator
void Runway::gen_runway_lights( float alt_m, superpoly_list *lights, TGPolygon *apt_base ) {
void Runway::gen_runway_lights( float alt_m, superpoly_list *lights ) {
unsigned int i;

View file

@ -211,6 +211,30 @@ ClosedPoly* Parser::ParsePavement( char* line )
return poly;
}
ClosedPoly* Parser::ParseBoundary( char* line )
{
ClosedPoly* poly;
char desc[256];
char *d = NULL;
int numParams;
numParams = sscanf(line, "%ls", desc);
if (numParams == 1)
{
d = strstr(line,desc);
}
else
{
d = "none";
}
SG_LOG(SG_GENERAL, SG_DEBUG, "Creating Closed Poly for airport boundary : " << d);
poly = new ClosedPoly(d);
return poly;
}
int Parser::SetState( int state )
{
// if we are currently parsing pavement, the oly way we know we are done
@ -223,6 +247,14 @@ int Parser::SetState( int state )
cur_pavement = NULL;
}
if ( cur_airport && cur_state == STATE_PARSE_BOUNDARY )
{
SG_LOG(SG_GENERAL, SG_DEBUG, "Closing and Adding boundary");
cur_boundary->Finish();
cur_airport->SetBoundary( cur_boundary );
cur_boundary = NULL;
}
cur_state = state;
}
@ -297,8 +329,7 @@ int Parser::ParseLine(char* line)
case BOUNDRY_CODE:
SetState( STATE_PARSE_BOUNDARY );
SG_LOG(SG_GENERAL, SG_DEBUG, "Parsing airport boundary: " << line);
// ParseBoundry(line);
cur_boundary = ParseBoundary( line );
break;
case NODE_CODE:
@ -317,6 +348,10 @@ int Parser::ParseLine(char* line)
{
cur_feat->AddNode( prev_node );
}
else if ( cur_state == STATE_PARSE_BOUNDARY )
{
cur_boundary->AddNode( prev_node );
}
}
prev_node = cur_node;
@ -340,6 +375,19 @@ int Parser::ParseLine(char* line)
}
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)

View file

@ -59,8 +59,16 @@ public:
{
filename = f;
cur_airport = NULL;
cur_runway = NULL;
cur_waterrunway = NULL;
cur_helipad = NULL;
cur_pavement = NULL;
cur_boundary = NULL;
cur_feat = NULL;
cur_object = NULL;
cur_windsock = NULL;
cur_beacon = NULL;
cur_sign = NULL;
prev_node = NULL;
cur_state = STATE_NONE;
}
@ -76,10 +84,12 @@ private:
LinearFeature* ParseFeature( char* line );
ClosedPoly* ParsePavement( char* line );
osg::Geode* ParseRunway(char* line );
ClosedPoly* ParseBoundary( char* line );
int ParseLine( char* line );
// int ParseBoundry(char* line, Node* airport);
BezNode* prev_node;
int cur_state;
string filename;
// a polygon conists of an array of contours
@ -89,16 +99,14 @@ private:
WaterRunway* cur_waterrunway;
Helipad* cur_helipad;
ClosedPoly* cur_pavement;
ClosedPoly* cur_boundary;
LinearFeature* cur_feat;
BezNode* prev_node;
LightingObj* cur_object;
Windsock* cur_windsock;
Beacon* cur_beacon;
Sign* cur_sign;
AirportList airports;
int cur_state;
};
#endif

View file

@ -170,7 +170,7 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
case 2: // concrete
SG_LOG( SG_GENERAL, SG_ALERT, "Build Runway: asphalt or concrete" << rwy.surface);
gen_rwy( alt_m, material, rwy_polys, texparams, accum );
gen_runway_lights( alt_m, rwy_lights, apt_base );
gen_runway_lights( alt_m, rwy_lights );
break;
case 3: // Grass
@ -178,7 +178,7 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
case 5: // Gravel
SG_LOG( SG_GENERAL, SG_ALERT, "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, apt_base );
gen_runway_lights( alt_m, rwy_lights );
break;
case 12: // dry lakebed
@ -202,6 +202,8 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
break;
}
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);
@ -213,4 +215,5 @@ int Runway::BuildBtg( float alt_m, superpoly_list* rwy_polys, texparams_list* te
// and add the clearing to the base
*apt_base = tgPolygonUnion( base, *apt_base );
}
}

View file

@ -130,7 +130,7 @@ private:
texparams_list* texparams,
TGPolygon* accum, int marking);
void gen_runway_lights( float alt_m, superpoly_list* lights, TGPolygon* apt_base );
void gen_runway_lights( float alt_m, superpoly_list* lights );
Point3D gen_runway_light_vector( double angle, bool recip );
superpoly_list gen_runway_edge_lights( bool recip );