1
0
Fork 0

Compare commits

...

10 commits

Author SHA1 Message Date
Fabian Lucke
d42a5d6d0d FGEagels patch and strict line code checks for all lines covered by the patch
Signed-off-by: Fabian Lucke <fabian.lucke@uniki.de>
2023-09-16 22:32:23 +02:00
scttgs0
43d8d23343 parse v1300 files 2023-08-27 00:06:35 -05:00
scttgs0
e701da1d4a [taxiway] Maintenance 2023-05-14 17:57:18 -05:00
scttgs0
3f7bb23b38 [scheduler] Maintenance 2023-05-14 17:49:40 -05:00
scttgs0
f98b5cd482 [rwy_simple] Maintenance 2023-05-14 17:37:31 -05:00
scttgs0
cbcbb8c8f6 [rwy_gen] Maintenance, Modernize 2023-05-14 17:35:21 -05:00
scttgs0
dc9a7e494e [runway] Maintenance 2023-05-14 13:24:46 -05:00
scttgs0
efddc3d44c [parser] Maintenance 2023-05-14 13:17:45 -05:00
scttgs0
b83c79f6b0 [output] Maintenance 2023-05-14 13:06:36 -05:00
scttgs0
275d5cc4f6 [object] Maintenance 2023-05-14 12:50:08 -05:00
21 changed files with 1190 additions and 1142 deletions

View file

@ -337,6 +337,39 @@ std::string ClosedPoly::GetMaterial(int surface)
case 15:
break;
case 20: // Light colored asphalt
case 21:
case 22:
case 23:
case 24: // Asphalt
case 25:
case 26:
case 27: // Darker colored asphalt
case 28:
case 29:
case 30:
case 31: // Very dark colored asphalt
case 32:
case 33:
case 34:
case 35: // Near black, new looking asphalt
case 36:
case 37:
case 38:
material = "pa_tiedown";
break;
case 50: // Light “new” looking concrete
case 51:
case 52:
case 53: // Concrete
case 54:
case 55: // Dark concrete
case 56:
case 57:
material = "pc_tiedown";
break;
default:
TG_LOG(SG_GENERAL, SG_ALERT, "ClosedPoly::BuildBtg: unknown surface type " << surface_type);
exit(1);

View file

@ -34,6 +34,11 @@ Helipad::Helipad(char* definition)
std::istringstream ss(definition);
ss >> heli.designator >> heli.lat >> heli.lon >> heli.heading >> heli.length >> heli.width >> heli.surface >> heli.marking >> heli.shoulder >> heli.smoothness >> heli.edge_lights;
if (heli.length <= 0 || heli.width <= 0 || heli.lat < -90 || heli.lat > 90 || heli.lon < -180 || heli.lon > 180 || heli.surface < 1 || heli.surface > 57 || heli.shoulder < 0 || heli.shoulder > 2 || heli.smoothness < 0 || heli.smoothness > 1 || !(heli.edge_lights == 0 || heli.edge_lights == 1)) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid helipad line: " << definition);
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Read helipad: (" << heli.lon << "," << heli.lat << ") heading: " << heli.heading << " length: " << heli.length << " width: " << heli.width);
}

View file

@ -54,12 +54,14 @@ public:
tgcontour_list& slivers,
tgAccumulator& accum);
bool valid {true};
private:
struct TGRunway {
// data for helipad
std::string designator;
double lat;
double lon;
double lat {-9999};
double lon {-9999};
double heading;
double length;
double width;

View file

@ -19,6 +19,7 @@
#define LF_SAFETYZONE_CENTERLINE (7)
#define LF_SINGLE_LANE_QUEUE (8)
#define LF_DOUBLE_LANE_QUEUE (9)
#define LF_SOLID_YELLOW_WIDE (10)
#define LF_TAXI_HOLD_WIDE (11)
#define LF_DOUBLE_HOLD_WIDE (12)

View file

@ -9,6 +9,11 @@ Windsock::Windsock(char* definition)
std::istringstream ss(definition);
ss >> lat >> lon >> lit;
if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid windsock line: " << definition);
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Read Windsock: (" << lon << "," << lat << ") lit: " << lit);
}
@ -17,6 +22,11 @@ Beacon::Beacon(char* definition)
std::istringstream ss(definition);
ss >> lat >> lon >> code;
if (lat < -90 || lat > 90 || lon < -180 || lon > 180) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid beacon line: " << definition);
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Read Beacon: (" << lon << "," << lat << ") code: " << code);
}
@ -28,6 +38,11 @@ Sign::Sign(char* definition)
std::istringstream ss(definition);
ss >> lat >> lon >> def_heading >> reserved >> size >> sgdef;
if (lat < -90 || lat > 90 || lon < -180 || lon > 180 || size < 1 || size > 5) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid sign line: " << definition);
}
// 850 format sign heading is the heading which points away from the visible numbers
// Flightgear wants the heading to be the heading in which the sign is read
heading = -def_heading + 360.0;

View file

@ -10,9 +10,10 @@ class Windsock
public:
explicit Windsock(char* def);
double lat;
double lon;
double lat {-9999};
double lon {-9999};
int lit;
bool valid {true};
SGGeod GetLoc() const
{
@ -33,9 +34,10 @@ class Beacon
public:
explicit Beacon(char* def);
double lat;
double lon;
double lat {-9999};
double lon {-9999};
int code;
bool valid {true};
SGGeod GetLoc() const
{
@ -55,12 +57,13 @@ class Sign
public:
explicit Sign(char* def);
double lat;
double lon;
double lat {-9999};
double lon {-9999};
double heading;
int reserved;
int size;
std::string sgn_def;
bool valid {true};
SGGeod GetLoc() const
{

View file

@ -1,134 +1,124 @@
#include <simgear/math/SGMathFwd.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/SGMathFwd.hxx>
#include "object.hxx"
#include "debug.hxx"
#include "object.hxx"
LightingObj::LightingObj( char* definition )
LightingObj::LightingObj(char* definition)
{
std::istringstream ss(definition);
ss >> lat
>> lon
>> type
>> heading
>> glideslope
>> assoc_rw;
ss >> lat >> lon >> type >> heading >> glideslope >> assoc_rw;
TG_LOG(SG_GENERAL, SG_DEBUG, "Read lighting object: (" << lon << "," << lat << ") heading: " << heading << " type: " << type );
if (lat < -90 || lat > 90 || lon < -180 || lon > 180 || type < 1 || type > 6 || heading < 0 || heading > 360) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid lighting object line: " << definition);
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Read lighting object: (" << lon << "," << lat << ") heading: " << heading << " type: " << type);
}
void LightingObj::BuildBtg( tglightcontour_list& lights )
void LightingObj::BuildBtg(tglightcontour_list& lights)
{
tgLightContour light_contour;
light_contour.SetType( "RWY_VASI_LIGHTS" );
light_contour.SetType("RWY_VASI_LIGHTS");
double left_hdg = SGMiscd::normalizePeriodic(0, 360, heading - 90.0 );
SGGeod ref = SGGeod::fromDeg(lon, lat);
double left_hdg = SGMiscd::normalizePeriodic(0.0, 360.0, heading - 90.0);
SGGeod ref = SGGeod::fromDeg(lon, lat);
// Calculate the light normal with the help of a second point
// in the object heading direction.
// SimGear takes care of the glideslope angle calculation from the normal
SGVec3f cart1 = SGVec3f::fromGeod(SGGeodesy::direct( ref, heading, 10));
SGVec3f cart1 = SGVec3f::fromGeod(SGGeodesy::direct(ref, heading, 10.0));
SGVec3f cart2 = SGVec3f::fromGeod(ref);
SGVec3f normal = normalize(cart2 - cart1);
// We know our normal, now create the lights
SGGeod pt1;
if (type == 1)
{
if (type == 1) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Generating VASI = " << assoc_rw);
// VASI coordinates describe the center between the two bars.
// Space between the bars is 200m
// Go to downwind bar
pt1 = SGGeodesy::direct( ref, heading, -100 );
pt1 = SGGeodesy::direct(ref, heading, -100.0);
// unit1
pt1 = SGGeodesy::direct( pt1, left_hdg, -5 );
light_contour.AddLight( pt1, normal );
pt1 = SGGeodesy::direct(pt1, left_hdg, -5.0);
light_contour.AddLight(pt1, normal);
// unit2+3
for (int i = 0; i < 2; ++i)
{
pt1 = SGGeodesy::direct( pt1, left_hdg, 5 );
light_contour.AddLight( pt1, normal );
for (int i = 0; i < 2; ++i) {
pt1 = SGGeodesy::direct(pt1, left_hdg, 5.0);
light_contour.AddLight(pt1, normal);
}
// Go to upwind bar
pt1 = SGGeodesy::direct( ref, heading, 100 );
pt1 = SGGeodesy::direct(ref, heading, 100.0);
// unit4
pt1 = SGGeodesy::direct( pt1, left_hdg, -5 );
light_contour.AddLight( pt1, normal );
pt1 = SGGeodesy::direct(pt1, left_hdg, -5.0);
light_contour.AddLight(pt1, normal);
// unit5+6
for (int i = 0; i < 2; ++i)
{
pt1 = SGGeodesy::direct( pt1, left_hdg,5 );
light_contour.AddLight( pt1, normal );
for (int i = 0; i < 2; ++i) {
pt1 = SGGeodesy::direct(pt1, left_hdg, 5.0);
light_contour.AddLight(pt1, normal);
}
}
else if (type == 2)
{
} else if (type == 2) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Generating PAPI 4L = " << assoc_rw);
// unit1
pt1 = SGGeodesy::direct( ref, left_hdg, -12 );
light_contour.AddLight( pt1, normal );
pt1 = SGGeodesy::direct(ref, left_hdg, -12.0);
light_contour.AddLight(pt1, normal);
// unit2-4
for (int i = 0; i < 3; ++i)
{
pt1 = SGGeodesy::direct( pt1, left_hdg, 8 );
light_contour.AddLight( pt1, normal );
for (int i = 0; i < 3; ++i) {
pt1 = SGGeodesy::direct(pt1, left_hdg, 8.0);
light_contour.AddLight(pt1, normal);
}
}
else if (type == 3)
{
} else if (type == 3) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Generating PAPI 4R = " << assoc_rw);
// unit1
pt1 = SGGeodesy::direct( ref, left_hdg, 12 );
light_contour.AddLight( pt1, normal );
pt1 = SGGeodesy::direct(ref, left_hdg, 12.0);
light_contour.AddLight(pt1, normal);
// unit2-4
for (int i = 0; i < 3; ++i)
{
pt1 = SGGeodesy::direct( pt1, left_hdg, -8 );
light_contour.AddLight( pt1, normal );
for (int i = 0; i < 3; ++i) {
pt1 = SGGeodesy::direct(pt1, left_hdg, -8.0);
light_contour.AddLight(pt1, normal);
}
}
else if (type == 4)
{
} else if (type == 4) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Space Shuttle PAPI is deprecated. Use the normal PAPI and set the glideslope accordingly");
return;
}
else if (type == 5)
{
} else if (type == 5) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Generating tri-colour VASI = " << assoc_rw);
// only one light here
light_contour.AddLight( ref, normal );
}
else if (type == 6)
{
light_contour.AddLight(ref, normal);
} else if (type == 6) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Generating runway guard light = " << assoc_rw);
light_contour.SetType( "RWY_GUARD_LIGHTS" );
light_contour.SetType("RWY_GUARD_LIGHTS");
// unit 1
light_contour.AddLight( SGGeodesy::direct( ref, left_hdg, 0.2 ), normal );
light_contour.AddLight(SGGeodesy::direct(ref, left_hdg, 0.2), normal);
// unit 2
light_contour.AddLight( SGGeodesy::direct( ref, left_hdg, -0.2 ), normal );
}
else
{
light_contour.AddLight(SGGeodesy::direct(ref, left_hdg, -0.2), normal);
} else {
TG_LOG(SG_GENERAL, SG_ALERT, "Unknown lighting object (PAPI/VASI...) code: " << type);
return;
}
lights.push_back( light_contour);
lights.push_back(light_contour);
}

View file

@ -11,12 +11,13 @@ class LightingObj
public:
explicit LightingObj(char* def);
double lat;
double lon;
double lat {-9999};
double lon {-9999};
int type;
double heading;
double glideslope;
char assoc_rw;
bool valid {true};
void BuildBtg(tglightcontour_list& lights);

View file

@ -24,7 +24,6 @@
#include <config.h>
#endif
#include <cstdlib>
#include <fstream>
#include <set>
#include <string>
@ -33,86 +32,90 @@
#include <simgear/bucket/newbucket.hxx>
#include <simgear/misc/sg_path.hxx>
using std::string;
// update index file (list of objects to be included in final scenery build)
void write_index_object( const string& base, const SGBucket& b, const string& name )
void write_index_object(const std::string& base, const SGBucket& b, const std::string& name)
{
string dir = base + "/" + b.gen_base_path();
SGPath sgp( dir );
sgp.append( "dummy" );
sgp.create_dir( 0755 );
using namespace std::string_literals;
string file = dir + "/" + b.gen_index_str() + ".ind";
SG_LOG( SG_GENERAL, SG_DEBUG, "Writing object to " << file );
std::string dir = base + "/"s + b.gen_base_path();
SGPath sgp(dir);
sgp.append("dummy"s);
sgp.create_dir(0755);
FILE *fp;
if ( (fp = fopen( file.c_str(), "a" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: opening " << file << " for writing!" );
std::string file = dir + "/"s + b.gen_index_str() + ".ind"s;
SG_LOG(SG_GENERAL, SG_DEBUG, "Writing object to " << file);
FILE* fp;
if ((fp = fopen(file.c_str(), "a")) == NULL) {
SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: opening " << file << " for writing!");
exit(-1);
}
fprintf( fp, "OBJECT %s\n", name.c_str() );
fclose( fp );
fprintf(fp, "OBJECT %s\n", name.c_str());
fclose(fp);
}
// update index file (list of shared objects to be included in final scenery build)
void write_index_object_shared( const string &base, const SGBucket &b,
const SGGeod &p, const string& name,
const double &heading )
void write_index_object_shared(const std::string& base, const SGBucket& b,
const SGGeod& p, const std::string& name,
const double& heading)
{
string dir = base + "/" + b.gen_base_path();
SGPath sgp( dir );
sgp.append( "dummy" );
sgp.create_dir( 0755 );
using namespace std::string_literals;
string file = dir + "/" + b.gen_index_str() + ".ind";
SG_LOG( SG_GENERAL, SG_DEBUG, "Writing shared object to " << file );
std::string dir = base + "/"s + b.gen_base_path();
SGPath sgp(dir);
sgp.append("dummy"s);
sgp.create_dir(0755);
FILE *fp;
if ( (fp = fopen( file.c_str(), "a" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: opening " << file << " for writing!" );
std::string file = dir + "/"s + b.gen_index_str() + ".ind"s;
SG_LOG(SG_GENERAL, SG_DEBUG, "Writing shared object to " << file);
FILE* fp;
if ((fp = fopen(file.c_str(), "a")) == NULL) {
SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: opening " << file << " for writing!");
exit(-1);
}
fprintf( fp, "OBJECT_SHARED %s %.6f %.6f %.1f %.2f\n", name.c_str(),
p.getLongitudeDeg(), p.getLatitudeDeg(), p.getElevationM(), heading );
fclose( fp );
fprintf(fp, "OBJECT_SHARED %s %.6f %.6f %.1f %.2f\n", name.c_str(),
p.getLongitudeDeg(), p.getLatitudeDeg(), p.getElevationM(), heading);
fclose(fp);
}
// update index file (list of shared objects to be included in final scenery build)
void write_index_object_sign( const string &base, const SGBucket &b,
const SGGeod &p, const string& sign,
const double &heading, const int &size)
void write_index_object_sign(const std::string& base, const SGBucket& b,
const SGGeod& p, const std::string& sign,
const double& heading, const int& size)
{
string dir = base + "/" + b.gen_base_path();
SGPath sgp( dir );
sgp.append( "dummy" );
sgp.create_dir( 0755 );
using namespace std::string_literals;
string file = dir + "/" + b.gen_index_str() + ".ind";
SG_LOG( SG_GENERAL, SG_DEBUG, "Writing sign to " << file );
std::string dir = base + "/"s + b.gen_base_path();
SGPath sgp(dir);
sgp.append("dummy"s);
sgp.create_dir(0755);
FILE *fp;
if ( (fp = fopen( file.c_str(), "a" )) == NULL ) {
SG_LOG( SG_GENERAL, SG_ALERT, "ERROR: opening " << file << " for writing!" );
std::string file = dir + "/"s + b.gen_index_str() + ".ind"s;
SG_LOG(SG_GENERAL, SG_DEBUG, "Writing sign to " << file);
FILE* fp;
if ((fp = fopen(file.c_str(), "a")) == NULL) {
SG_LOG(SG_GENERAL, SG_ALERT, "ERROR: opening " << file << " for writing!");
exit(-1);
}
fprintf( fp, "OBJECT_SIGN %s %.6f %.6f %.1f %.2f %d\n", sign.c_str(),
p.getLongitudeDeg(), p.getLatitudeDeg(), p.getElevationM(), heading, size );
fclose( fp );
fprintf(fp, "OBJECT_SIGN %s %.6f %.6f %.1f %.2f %d\n", sign.c_str(),
p.getLongitudeDeg(), p.getLatitudeDeg(), p.getElevationM(), heading, size);
fclose(fp);
}
// purge the existing index file when it already exists
void truncate_index_file( const std::string& fileName )
void truncate_index_file(const std::string& fileName)
{
if (static_cast<bool>(std::ifstream(fileName)))
{
SG_LOG( SG_GENERAL, SG_DEBUG, "Truncating file " << fileName );
if (static_cast<bool>(std::ifstream(fileName))) {
SG_LOG(SG_GENERAL, SG_DEBUG, "Truncating file " << fileName);
std::ofstream fsIndex;
fsIndex.open(fileName, std::ofstream::out | std::ofstream::trunc);

View file

@ -25,6 +25,7 @@
#include <config.h>
#endif
// update index file (list of objects to be included in final scenery build)
void write_index_object(const std::string& base, const SGBucket& b, const std::string& name);

View file

@ -6,6 +6,7 @@
#include "parser.hxx"
bool Parser::GetAirportDefinition(char* line, std::string& icao)
{
bool match = false;
@ -44,8 +45,7 @@ void Parser::set_debug(const std::string& path, std::vector<std::string> runway_
debug_path = path;
/* Find any ids for our tile */
for (unsigned int i = 0; i < runway_defs.size(); i++) {
std::string dsd = runway_defs[i];
for (std::string& dsd : runway_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
@ -71,8 +71,7 @@ void Parser::set_debug(const std::string& path, std::vector<std::string> runway_
debug_runways[icao] = shapes;
}
for (unsigned int i = 0; i < pavement_defs.size(); i++) {
std::string dsd = pavement_defs[i];
for (std::string& dsd : pavement_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
@ -98,8 +97,7 @@ void Parser::set_debug(const std::string& path, std::vector<std::string> runway_
debug_pavements[icao] = shapes;
}
for (unsigned int i = 0; i < taxiway_defs.size(); i++) {
std::string dsd = taxiway_defs[i];
for (std::string& dsd : taxiway_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
@ -125,8 +123,7 @@ void Parser::set_debug(const std::string& path, std::vector<std::string> runway_
debug_taxiways[icao] = shapes;
}
for (unsigned int i = 0; i < feature_defs.size(); i++) {
std::string dsd = feature_defs[i];
for (std::string& dsd : feature_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
@ -225,7 +222,11 @@ void Parser::run()
}
log_time = time(0);
TG_LOG(SG_GENERAL, SG_ALERT, "Finished airport " << icao << " : parse " << parse_time << " : build " << build_time << " : clean " << clean_time << " : tesselate " << triangulation_time);
TG_LOG(SG_GENERAL, SG_ALERT, "Finished airport " << icao <<
" : parse " << parse_time <<
" : build " << build_time <<
" : clean " << clean_time <<
" : tesselate " << triangulation_time);
} else {
TG_LOG(SG_GENERAL, SG_INFO, "Not an airport at pos " << pos << " line is: " << line);
}
@ -491,7 +492,7 @@ int Parser::ParseLine(char* line)
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing runway: " << line);
cur_runway = std::make_shared<Runway>(line);
if (cur_airport) {
if (cur_airport && cur_runway->valid) {
cur_airport->AddRunway(cur_runway);
}
break;
@ -499,16 +500,16 @@ int Parser::ParseLine(char* line)
case WATER_RUNWAY_CODE:
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing water runway: " << line);
cur_waterrunway = std::make_shared<WaterRunway>(line);
if (cur_airport) {
cur_airport->AddWaterRunway(cur_waterrunway);
cur_waterRunway = std::make_shared<WaterRunway>(line);
if (cur_airport && cur_waterRunway->valid) {
cur_airport->AddWaterRunway(cur_waterRunway);
}
break;
case HELIPAD_CODE:
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing helipad: " << line);
cur_helipad = std::make_shared<Helipad>(line);
if (cur_airport) {
if (cur_airport && cur_helipad->valid) {
cur_airport->AddHelipad(cur_helipad);
}
break;
@ -517,7 +518,7 @@ int Parser::ParseLine(char* line)
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway: " << line);
cur_taxiway = std::make_shared<Taxiway>(line);
if (cur_airport) {
if (cur_airport && cur_taxiway->valid) {
cur_airport->AddTaxiway(cur_taxiway);
}
break;
@ -642,25 +643,33 @@ int Parser::ParseLine(char* line)
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing light beacon: " << line);
cur_beacon = std::make_shared<Beacon>(line);
cur_airport->AddBeacon(cur_beacon);
if (cur_airport && cur_beacon->valid) {
cur_airport->AddBeacon(cur_beacon);
}
break;
case WINDSOCK_CODE:
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing windsock: " << line);
cur_windsock = std::make_shared<Windsock>(line);
cur_airport->AddWindsock(cur_windsock);
if (cur_airport && cur_windsock->valid) {
cur_airport->AddWindsock(cur_windsock);
}
break;
case TAXIWAY_SIGN:
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing taxiway sign: " << line);
cur_sign = std::make_shared<Sign>(line);
cur_airport->AddSign(cur_sign);
if (cur_airport && cur_sign->valid) {
cur_airport->AddSign(cur_sign);
}
break;
case LIGHTING_OBJECT:
SetState(STATE_PARSE_SIMPLE);
TG_LOG(SG_GENERAL, SG_DEBUG, "Parsing lighting object: " << line);
cur_object = std::make_shared<LightingObj>(line);
cur_airport->AddObj(cur_object);
if (cur_airport && cur_object->valid) {
cur_airport->AddObj(cur_object);
}
break;
case COMM_FREQ1_CODE:

View file

@ -16,103 +16,105 @@
#include "trafficFlow.hxx"
#define STATE_NONE (1)
#define STATE_PARSE_SIMPLE (2)
#define STATE_PARSE_BOUNDARY (3)
#define STATE_PARSE_PAVEMENT (4)
#define STATE_PARSE_FEATURE (5)
#define STATE_DONE (10)
#define STATE_NONE (1)
#define STATE_PARSE_SIMPLE (2)
#define STATE_PARSE_BOUNDARY (3)
#define STATE_PARSE_PAVEMENT (4)
#define STATE_PARSE_FEATURE (5)
#define STATE_DONE (10)
//-------------------------------------
// [[deprecated]]
#define TAXIWAY_CODE (10)
#define TAXIWAY_CODE (10)
// [[deprecated]]
#define AIRPLANE_STARTUP_LOCATION_CODE (15)
#define AIRPLANE_STARTUP_LOCATION_CODE (15)
// [[deprecated]]
#define COMM_FREQ1_CODE (50)
#define COMM_FREQ1_CODE (50)
// [[deprecated]]
#define COMM_FREQ2_CODE (51)
#define COMM_FREQ2_CODE (51)
// [[deprecated]]
#define COMM_FREQ3_CODE (52)
#define COMM_FREQ3_CODE (52)
// [[deprecated]]
#define COMM_FREQ4_CODE (53)
#define COMM_FREQ4_CODE (53)
// [[deprecated]]
#define COMM_FREQ5_CODE (54)
#define COMM_FREQ5_CODE (54)
// [[deprecated]]
#define COMM_FREQ6_CODE (55)
#define COMM_FREQ6_CODE (55)
// [[deprecated]]
#define COMM_FREQ7_CODE (56)
#define COMM_FREQ7_CODE (56)
// [[deprecated]]
#define RWY_ARR_DEP_CONSTRAINTS (1100)
#define RWY_ARR_DEP_CONSTRAINTS (1100)
// [[deprecated]]
#define TAXI_ROUTE_NETWORK_OBSOLETE (1203)
//-------------------------------------
#define LAND_AIRPORT_CODE (1)
#define SEA_AIRPORT_CODE (16)
#define HELIPORT_CODE (17)
#define LAND_AIRPORT_CODE (1)
#define SEA_AIRPORT_CODE (16)
#define HELIPORT_CODE (17)
#define AIRPORT_VIEWPOINT_CODE (14)
#define LIGHT_BEACON_CODE (18)
#define WINDSOCK_CODE (19)
#define TAXIWAY_SIGN (20)
#define LIGHTING_OBJECT (21)
#define AIRPORT_VIEWPOINT_CODE (14)
#define LIGHT_BEACON_CODE (18)
#define WINDSOCK_CODE (19)
#define TAXIWAY_SIGN (20)
#define LIGHTING_OBJECT (21)
#define LAND_RUNWAY_CODE (100)
#define WATER_RUNWAY_CODE (101)
#define HELIPAD_CODE (102)
#define LAND_RUNWAY_CODE (100)
#define WATER_RUNWAY_CODE (101)
#define HELIPAD_CODE (102)
#define PAVEMENT_CODE (110)
#define NODE_CODE (111)
#define BEZIER_NODE_CODE (112)
#define CLOSE_NODE_CODE (113)
#define CLOSE_BEZIER_NODE_CODE (114)
#define TERM_NODE_CODE (115)
#define TERM_BEZIER_NODE_CODE (116)
#define PAVEMENT_CODE (110)
#define NODE_CODE (111)
#define BEZIER_NODE_CODE (112)
#define CLOSE_NODE_CODE (113)
#define CLOSE_BEZIER_NODE_CODE (114)
#define TERM_NODE_CODE (115)
#define TERM_BEZIER_NODE_CODE (116)
#define LINEAR_FEATURE_CODE (120)
#define BOUNDARY_CODE (130)
#define LINEAR_FEATURE_CODE (120)
#define BOUNDARY_CODE (130)
#define END_OF_FILE (99)
#define END_OF_FILE (99)
// TODO: not implemented yet
#define TRAFFIC_FLOW_HEADER (1000)
#define TRAFFIC_FLOW_WIND_RULE (1001)
#define TRAFFIC_FLOW_MIN_CEILING_RULE (1002)
#define TRAFFIC_FLOW_MIN_VISIBILITY_RULE (1003)
#define TRAFFIC_FLOW_TIME_RULE (1004)
#define TRAFFIC_FLOW_HEADER (1000)
#define TRAFFIC_FLOW_WIND_RULE (1001)
#define TRAFFIC_FLOW_MIN_CEILING_RULE (1002)
#define TRAFFIC_FLOW_MIN_VISIBILITY_RULE (1003)
#define TRAFFIC_FLOW_TIME_RULE (1004)
#define COMM_RECORDED (1050) // 8.33 kHz; AWOS, ASOS or ATIS
#define COMM_UNICOM (1051) // 8.33 kHz; Unicom (US), CTAF (US), Radio (UK)
#define COMM_CLD (1052) // 8.33 kHz; Clearance Delivery
#define COMM_GND (1053) // 8.33 kHz; Ground
#define COMM_TWR (1054) // 8.33 kHz; Tower
#define COMM_APP (1055) // 8.33 kHz; Approach
#define COMM_DEP (1056) // 8.33 kHz; Departure
#define COMM_RECORDED (1050) // 8.33 kHz; AWOS, ASOS or ATIS
#define COMM_UNICOM (1051) // 8.33 kHz; Unicom (US), CTAF (US), Radio (UK)
#define COMM_CLD (1052) // 8.33 kHz; Clearance Delivery
#define COMM_GND (1053) // 8.33 kHz; Ground
#define COMM_TWR (1054) // 8.33 kHz; Tower
#define COMM_APP (1055) // 8.33 kHz; Approach
#define COMM_DEP (1056) // 8.33 kHz; Departure
#define VFR_TRAFFIC_PATTERN (1101)
#define RWY_IN_USE_CONSTRAINTS (1110)
#define VFR_TRAFFIC_PATTERN (1101)
#define RWY_IN_USE_CONSTRAINTS (1110)
#define TAXI_ROUTE_NETWORK_HEADER (1200)
#define TAXI_ROUTE_NETWORK_NODE (1201)
#define TAXI_ROUTE_NETWORK_EDGE (1202)
#define TAXI_ROUTE_NETWORK_OBSOLETE (1203)
#define TAXI_ROUTE_EDGE_ACTIVE_ZONE (1204)
#define TAXI_ROUTE_EDGE_CONTROL (1205)
#define TAXI_ROUTE_EDGE_GROUND_VEHICLES (1206)
#define TAXI_ROUTE_NETWORK_HEADER (1200)
#define TAXI_ROUTE_NETWORK_NODE (1201)
#define TAXI_ROUTE_NETWORK_EDGE (1202)
#define TAXI_ROUTE_EDGE_ACTIVE_ZONE (1204)
#define TAXI_ROUTE_EDGE_CONTROL (1205)
#define TAXI_ROUTE_EDGE_GROUND_VEHICLES (1206)
#define START_UP_LOCATION (1300)
#define START_UP_LOCATION_METADATA (1301)
#define AIRPORT_IDENTIFICATION_METADATA (1302)
#define START_UP_LOCATION (1300)
#define START_UP_LOCATION_METADATA (1301)
#define AIRPORT_IDENTIFICATION_METADATA (1302)
#define TRUCK_PARKING_LOCATION (1400)
#define TRUCK_DESTINATION_LOCATION (1401)
#define TRUCK_PARKING_LOCATION (1400)
#define TRUCK_DESTINATION_LOCATION (1401)
#define JETWAY_ACTIVE (1500)
#define JETWAY_CUSTOM (1501)
#define JETWAY_ACTIVE (1500)
#define JETWAY_CUSTOM (1501)
class Parser : public SGThread
@ -125,7 +127,7 @@ public:
cur_airport(nullptr),
cur_taxiway(nullptr),
cur_runway(nullptr),
cur_waterrunway(nullptr),
cur_waterRunway(nullptr),
cur_helipad(nullptr),
cur_pavement(nullptr),
cur_boundary(nullptr),
@ -171,7 +173,7 @@ private:
std::shared_ptr<Airport> cur_airport;
std::shared_ptr<Taxiway> cur_taxiway;
std::shared_ptr<Runway> cur_runway;
std::shared_ptr<WaterRunway> cur_waterrunway;
std::shared_ptr<WaterRunway> cur_waterRunway;
std::shared_ptr<Helipad> cur_helipad;
std::shared_ptr<ClosedPoly> cur_pavement;
std::shared_ptr<ClosedPoly> cur_boundary;

View file

@ -12,6 +12,7 @@
#include "beznode.hxx"
#include "runway.hxx"
extern int nudge;
Runway::Runway(char* definition)
@ -64,14 +65,19 @@ Runway::Runway(char* definition)
>> rwy.tz_lights[1]
>> rwy.reil[1];
if (rwy.width == -9999 || rwy.lat[0] < -90 || rwy.lat[0] > 90 || rwy.lon[0] < -180 || rwy.lon[0] > 180 || rwy.lat[1] < -90 || rwy.lat[1] > 90 || rwy.lon[1] < -180 || rwy.lon[1] > 180 || rwy.smoothness > 1 || rwy.smoothness < 0 || !(rwy.centerline_lights == 0 || rwy.centerline_lights == 1) || rwy.edge_lights < 0 || rwy.edge_lights > 3 || !(rwy.dist_remain_signs == 0 || rwy.dist_remain_signs == 1) || rwy.marking[0] < 0 || rwy.marking[0] > 7 || rwy.marking[1] < 0 || rwy.marking[1] > 7 || rwy.approach_lights[0] < 0 || rwy.approach_lights[0] > 12 || rwy.approach_lights[1] < 0 || rwy.approach_lights[1] > 12 || !(rwy.tz_lights[0] == 0 || rwy.tz_lights[0] == 1) || !(rwy.tz_lights[1] == 0 || rwy.tz_lights[1] == 1) || rwy.reil[0] < 0 || rwy.reil[0] > 2 || rwy.reil[1] < 0 || rwy.reil[1] > 2 || rwy.surface < 1 || rwy.surface > 57) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid runway line: " << definition);
}
// calculate runway heading and length (used a lot)
SGGeodesy::inverse( GetStart(), GetEnd(), rwy.heading, az2, rwy.length );
SGGeodesy::inverse(GetStart(), GetEnd(), rwy.heading, az2, rwy.length);
TG_LOG(SG_GENERAL, SG_DEBUG, "Read runway: (" << rwy.lon[0] << "," << rwy.lat[0] <<
") to (" << rwy.lon[1] << "," << rwy.lat[1] <<
") heading: " << rwy.heading <<
" length: " << rwy.length <<
" width: " << rwy.width );
") to (" << rwy.lon[1] << "," << rwy.lat[1] <<
") heading: " << rwy.heading <<
" length: " << rwy.length <<
" width: " << rwy.width );
}
@ -87,14 +93,22 @@ WaterRunway::WaterRunway(char* definition)
>> lat[1]
>> lon[1];
TG_LOG(SG_GENERAL, SG_DEBUG, "Read water runway: (" << lon[0] << "," << lat[0] << ") to (" << lon[1] << "," << lat[1] << ") width: " << width << " buoys = " << buoys );
if (width == -9999 || lat[0] < -90 || lat[0] > 90 || lon[0] < -180 || lon[0] > 180 || lat[1] < -90 || lat[1] > 90 || lon[1] < -180 || lon[1] > 180 || !(buoys == 0 || buoys == 1)) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid water runway line: " << definition);
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Read water runway: (" << lon[0] << "," << lat[0] <<
") to (" << lon[1] << "," << lat[1] <<
") width: " << width <<
" buoys = " << buoys);
}
tgContour WaterRunway::GetBuoys()
{
tgContour buoys_nodes;
if (buoys){
if (buoys) {
double heading, az2, length;
// calculate runway heading and length
SGGeodesy::inverse(GetStart(), GetEnd(), heading, az2, length);
@ -102,15 +116,16 @@ tgContour WaterRunway::GetBuoys()
// create a contour with points every 100m
tgContour area = gen_wgs84_area(GetStart(), GetEnd(),
0, 0, 0, width, heading, false);
for ( unsigned int i = 0; i < area.GetSize(); ++i ) {
for (unsigned int i = 0; i < area.GetSize(); ++i) {
double dist, course, cs;
SGGeodesy::inverse(area.GetNode(i), area.GetNode(i==3 ? 0 : i+1), course, cs, dist );
SGGeodesy::inverse(area.GetNode(i), area.GetNode(i == 3 ? 0 : i + 1), course, cs, dist);
int divs = (int)(dist / 100.0);
double step = dist/divs;
double step = dist / divs;
SGGeod pt = area.GetNode(i);
for (int j = 0; j < divs; ++j) {
pt = SGGeodesy::direct(pt, course, step );
buoys_nodes.AddNode( pt );
pt = SGGeodesy::direct(pt, course, step);
buoys_nodes.AddNode(pt);
}
}
}
@ -118,114 +133,102 @@ tgContour WaterRunway::GetBuoys()
return buoys_nodes;
}
int Runway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name )
int Runway::BuildBtg(tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name)
{
if ( rwy.surface == 1 /* Asphalt */ )
{
if (rwy.surface == 1 /* Asphalt */) {
material_prefix = "pa_";
}
else if ( rwy.surface == 2 /* Concrete */ )
{
} else if (rwy.surface == 2 /* Concrete */) {
material_prefix = "pc_";
}
else if ( rwy.surface == 3 /* Turf/Grass */ )
{
} else if (rwy.surface == 3 /* Turf/Grass */) {
material_prefix = "grass_rwy";
}
else if ( rwy.surface == 4 /* Dirt */ || rwy.surface == 5 /* Gravel */ )
{
} else if (rwy.surface == 4 /* Dirt */ || rwy.surface == 5 /* Gravel */) {
material_prefix = "dirt_rwy";
}
else if ( rwy.surface == 12 /* Dry Lakebed */ )
{
} else if (rwy.surface == 12 /* Dry Lakebed */) {
material_prefix = "lakebed_taxiway";
}
else if ( rwy.surface == 13 /* Water runway (buoys) */ )
{
} else if (rwy.surface == 13 /* Water runway (buoys) */) {
// water
}
else if ( rwy.surface == 14 /* Snow / Ice */ )
{
} else if (rwy.surface == 14 /* Snow / Ice */) {
// Ice
}
else if ( rwy.surface == 15 /* Transparent */ )
{
} else if (rwy.surface == 15 /* Transparent */) {
//Transparent texture
}
else
{
} else {
TG_LOG(SG_GENERAL, SG_WARN, "surface_code = " << rwy.surface);
throw sg_exception("unknown runway type!");
}
// first, check the surface type - anything but concrete and asphalt are easy
switch( rwy.surface )
{
case 1: // asphalt:
case 2: // concrete
TG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: asphalt or concrete " << rwy.surface);
gen_rwy( rwy_polys, slivers, accum, shapefile_name );
gen_runway_lights( rwy_lights );
break;
switch (rwy.surface) {
case 1: // asphalt:
case 2: // concrete
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway: asphalt or concrete " << rwy.surface);
gen_rwy(rwy_polys, slivers, accum, shapefile_name);
gen_runway_lights(rwy_lights);
break;
case 3: // Grass
case 4: // Dirt
case 5: // Gravel
case 12: // dry lakebed
TG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Grass, Dirt, Gravel or Dry Lakebed " << rwy.surface );
gen_simple_rwy( rwy_polys, slivers, accum );
gen_runway_lights( rwy_lights );
break;
case 3: // Grass
case 4: // Dirt
case 5: // Gravel
case 12: // dry lakebed
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway: Grass, Dirt, Gravel or Dry Lakebed " << rwy.surface);
gen_simple_rwy(rwy_polys, slivers, accum);
gen_runway_lights(rwy_lights);
break;
case 13: // water
TG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Water");
break;
case 13: // water
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway: Water");
break;
case 14: // snow
TG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: Snow");
break;
case 14: // snow
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway: Snow");
break;
case 15: // transparent
TG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: transparent");
break;
case 15: // transparent
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway: transparent");
break;
default: // unknown
TG_LOG( SG_GENERAL, SG_DEBUG, "Build Runway: unknown: " << rwy.surface);
break;
default: // unknown
TG_LOG(SG_GENERAL, SG_DEBUG, "Build Runway: unknown: " << rwy.surface);
break;
}
return 0;
}
int Runway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgpolygon_list& apt_base_polys, tgpolygon_list& apt_clearing_polys, tgAccumulator& accum, std::string& shapefile_name )
int Runway::BuildBtg(tgpolygon_list& rwy_polys,
tglightcontour_list& rwy_lights,
tgcontour_list& slivers,
tgpolygon_list& apt_base_polys,
tgpolygon_list& apt_clearing_polys,
tgAccumulator& accum,
std::string& shapefile_name)
{
tgContour base_contour, safe_base_contour;
tgPolygon base, safe_base;
double shoulder_width = 0.0;
BuildBtg( rwy_polys, rwy_lights, slivers, accum, shapefile_name );
BuildBtg(rwy_polys, rwy_lights, slivers, accum, shapefile_name);
// generate area around runways
if ( (rwy.shoulder > 0) && (rwy.surface < 3) ) {
if ((rwy.shoulder > 0) && (rwy.surface < 3)) {
shoulder_width += 22.0;
} else if ( (rwy.surface == 1) || (rwy.surface == 2) ) {
} else if ((rwy.surface == 1) || (rwy.surface == 2)) {
shoulder_width += 2.0;
}
base_contour = gen_runway_area_w_extend( 20.0, -rwy.overrun[0], -rwy.overrun[1], shoulder_width + 20.0 );
base_contour = tgContour::Snap( base_contour, gSnap );
base.AddContour( base_contour );
base_contour = gen_runway_area_w_extend(20.0, -rwy.overrun[0], -rwy.overrun[1], shoulder_width + 20.0);
base_contour = tgContour::Snap(base_contour, gSnap);
base.AddContour(base_contour);
// also clear a safe area around the runway
safe_base_contour = gen_runway_area_w_extend( 180.0, -rwy.overrun[0], -rwy.overrun[1], shoulder_width + 50.0 );
safe_base_contour = tgContour::Snap( safe_base_contour, gSnap );
safe_base.AddContour( safe_base_contour );
safe_base_contour = gen_runway_area_w_extend(180.0, -rwy.overrun[0], -rwy.overrun[1], shoulder_width + 50.0);
safe_base_contour = tgContour::Snap(safe_base_contour, gSnap);
safe_base.AddContour(safe_base_contour);
// add this to the airport clearing
apt_clearing_polys.push_back( safe_base );
apt_clearing_polys.push_back(safe_base);
// and add the clearing to the base
apt_base_polys.push_back( base );
apt_base_polys.push_back(base);
return 0;
}

View file

@ -14,22 +14,22 @@ class Runway
public:
explicit Runway(char* def);
SGGeod GetStart()
SGGeod GetStart() const
{
return SGGeod::fromDeg(rwy.lon[0], rwy.lat[0]);
}
SGGeod GetEnd()
SGGeod GetEnd() const
{
return SGGeod::fromDeg(rwy.lon[1], rwy.lat[1]);
}
SGGeod GetMidpoint()
SGGeod GetMidpoint() const
{
return SGGeod::fromDeg((rwy.lon[0] + rwy.lon[1]) / 2.0f, (rwy.lat[0] + rwy.lat[1]) / 2.0f);
}
bool GetsShoulder()
bool GetsShoulder() const
{
return (rwy.surface < 3) ? true : false;
}
@ -52,24 +52,26 @@ public:
tgcontour_list& slivers,
tgAccumulator& accum);
bool valid {true};
private:
struct TGRunway {
// data for whole runway
// data for the whole runway
int surface;
int shoulder;
int centerline_lights;
int edge_lights;
int dist_remain_signs;
double width;
double width {-9999};
double length;
double heading;
double smoothness;
// data for each end
char rwnum[2][16];
double lat[2];
double lon[2];
double lat[2] {-9999, -9999};
double lon[2] {-9999, -9999};
double threshold[2];
double overrun[2];
@ -187,21 +189,24 @@ public:
tgContour GetBuoys();
SGGeod GetStart(void)
SGGeod GetStart() const
{
return SGGeod::fromDeg(lon[0], lat[0]);
}
SGGeod GetEnd(void)
SGGeod GetEnd() const
{
return SGGeod::fromDeg(lon[1], lat[1]);
}
bool valid {true};
private:
double width;
double width {-9999};
int buoys;
char rwnum[2][16];
double lat[2];
double lon[2];
double lat[2] {-9999, -9999};
double lon[2] {-9999, -9999};
};
typedef std::vector<std::shared_ptr<WaterRunway>> WaterRunwayList;

File diff suppressed because it is too large Load diff

View file

@ -23,21 +23,20 @@
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include "runway.hxx"
#include "debug.hxx"
#include "runway.hxx"
using std::string;
// generate a simple runway
void Runway::gen_simple_rwy( tgpolygon_list& rwy_polys,
tgcontour_list& slivers,
tgAccumulator& accum )
void Runway::gen_simple_rwy(tgpolygon_list& rwy_polys,
tgcontour_list& slivers,
tgAccumulator& accum)
{
tgContour runway = gen_runway_w_mid( 0.0, 0.0 );
tgContour runway = gen_runway_w_mid(0.0, 0.0);
tgPolygon runway_half;
std::string empty = "";
std::string empty{};
for ( int rwhalf=0; rwhalf<2; ++rwhalf ) {
for (int rwhalf = 0; rwhalf < 2; ++rwhalf) {
double length = rwy.length / 2.0;
double end_pct = 0.0;
double heading = 0.0;
@ -47,52 +46,51 @@ void Runway::gen_simple_rwy( tgpolygon_list& rwy_polys,
//Create the first half of the runway (first entry in apt.dat)
runway_half.Erase();
runway_half.AddNode( 0, runway.GetNode(3) );
runway_half.AddNode( 0, runway.GetNode(4) );
runway_half.AddNode( 0, runway.GetNode(5) );
runway_half.AddNode( 0, runway.GetNode(2) );
}
else {
runway_half.AddNode(0, runway.GetNode(3));
runway_half.AddNode(0, runway.GetNode(4));
runway_half.AddNode(0, runway.GetNode(5));
runway_half.AddNode(0, runway.GetNode(2));
} else {
heading = rwy.heading;
//Create the second runway half from apt.dat
runway_half.Erase();
runway_half.AddNode( 0, runway.GetNode(0) );
runway_half.AddNode( 0, runway.GetNode(1) );
runway_half.AddNode( 0, runway.GetNode(2) );
runway_half.AddNode( 0, runway.GetNode(5) );
runway_half.AddNode(0, runway.GetNode(0));
runway_half.AddNode(0, runway.GetNode(1));
runway_half.AddNode(0, runway.GetNode(2));
runway_half.AddNode(0, runway.GetNode(5));
}
TG_LOG( SG_GENERAL, SG_DEBUG, "runway marking = " << rwy.marking[rwhalf] );
TG_LOG(SG_GENERAL, SG_DEBUG, "runway marking = " << rwy.marking[rwhalf]);
// Displaced threshold if it exists
if ( rwy.threshold[rwhalf] > 0.0 ) {
TG_LOG( SG_GENERAL, SG_DEBUG, "Displaced threshold for RW side " << rwhalf << " is " << rwy.threshold[rwhalf] );
if (rwy.threshold[rwhalf] > 0.0) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Displaced threshold for RW side " << rwhalf << " is " << rwy.threshold[rwhalf]);
double start_pct = end_pct;
end_pct = start_pct + ( rwy.threshold[rwhalf] / length );
Runway::gen_runway_section( runway_half,
start_pct, end_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
heading,
"",
rwy_polys,
slivers,
accum,
empty );
end_pct = start_pct + (rwy.threshold[rwhalf] / length);
Runway::gen_runway_section(runway_half,
start_pct, end_pct,
0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
heading,
"",
rwy_polys,
slivers,
accum,
empty);
}
// Generate runway
Runway::gen_runway_section( runway_half,
end_pct, 1.0,
0.0, 1.0,
0.0, 0.28, 0.0, 1.0,
heading,
"",
rwy_polys,
slivers,
accum,
empty );
Runway::gen_runway_section(runway_half,
end_pct, 1.0,
0.0, 1.0,
0.0, 0.28, 0.0, 1.0,
heading,
"",
rwy_polys,
slivers,
accum,
empty);
}
}

View file

@ -1,9 +1,9 @@
#ifdef _MSC_VER
# include <windows.h>
# define sleep(x) Sleep(x*1000)
#include <windows.h>
#define sleep(x) Sleep(x * 1000)
#endif
#include <cstring>
//#//include <cstring>
#include <memory>
#include <simgear/debug/logstream.hxx>
@ -13,14 +13,15 @@
#include "parser.hxx"
#include "scheduler.hxx"
extern double gSnap;
SGLockedQueue<AirportInfo> global_workQueue;
std::ostream& operator<< (std::ostream &out, const AirportInfo &ai)
std::ostream& operator<<(std::ostream& out, const AirportInfo& ai)
{
char snap_string[32];
sprintf( snap_string, "%1.8lf", ai.snap );
sprintf(snap_string, "%1.8lf", ai.snap);
out << ai.icao;
out << ",";
@ -40,43 +41,42 @@ std::ostream& operator<< (std::ostream &out, const AirportInfo &ai)
out << ",";
out << ai.tessTime;
out << ",";
out << ai.parseTime+ai.buildTime+ai.cleanTime+ai.tessTime;
out << ai.parseTime + ai.buildTime + ai.cleanTime + ai.tessTime;
out << ",";
out << snap_string,
out << ",";
out << ",";
out << ai.errString;
return out; // MSVC
return out; // MSVC
}
void Scheduler::set_debug( const std::string& path, std::vector<std::string> runway_defs,
std::vector<std::string> pavement_defs,
std::vector<std::string> taxiway_defs,
std::vector<std::string> feature_defs )
void Scheduler::set_debug(const std::string& path,
std::vector<std::string> runway_defs,
std::vector<std::string> pavement_defs,
std::vector<std::string> taxiway_defs,
std::vector<std::string> feature_defs)
{
TG_LOG(SG_GENERAL, SG_ALERT, "Set debug Path " << path);
debug_path = path;
/* Find any ids for our tile */
for (unsigned int i=0; i< runway_defs.size(); i++) {
std::string dsd = runway_defs[i];
size_t d_pos = dsd.find(":");
for (std::string dsd : runway_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
dsd.erase(0, d_pos + 1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
if (dsd == "all") {
shapes.push_back(std::numeric_limits<int>::max());
} else {
std::stringstream ss(dsd);
int idx;
while (ss >> idx)
{
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug runway " << idx << " for " << icao );
while (ss >> idx) {
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug runway " << idx << " for " << icao);
shapes.push_back(idx);
@ -84,27 +84,26 @@ void Scheduler::set_debug( const std::string& path, std::vector<std::string> run
ss.ignore();
}
}
debug_runways[icao] = shapes;
}
for (unsigned int i=0; i< pavement_defs.size(); i++) {
std::string dsd = pavement_defs[i];
size_t d_pos = dsd.find(":");
for (std::string dsd : pavement_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
dsd.erase(0, d_pos + 1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
if (dsd == "all") {
shapes.push_back(std::numeric_limits<int>::max());
} else {
std::stringstream ss(dsd);
int idx;
while (ss >> idx)
{
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug pavement " << idx << " for " << icao );
while (ss >> idx) {
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug pavement " << idx << " for " << icao);
shapes.push_back(idx);
@ -112,27 +111,26 @@ void Scheduler::set_debug( const std::string& path, std::vector<std::string> run
ss.ignore();
}
}
debug_pavements[icao] = shapes;
}
for (unsigned int i=0; i< taxiway_defs.size(); i++) {
std::string dsd = taxiway_defs[i];
size_t d_pos = dsd.find(":");
for (std::string dsd : taxiway_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
dsd.erase(0, d_pos + 1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
if (dsd == "all") {
shapes.push_back(std::numeric_limits<int>::max());
} else {
std::stringstream ss(dsd);
int idx;
while (ss >> idx)
{
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug taxiway " << idx << " for " << icao );
while (ss >> idx) {
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug taxiway " << idx << " for " << icao);
shapes.push_back(idx);
@ -140,27 +138,26 @@ void Scheduler::set_debug( const std::string& path, std::vector<std::string> run
ss.ignore();
}
}
debug_taxiways[icao] = shapes;
}
for (unsigned int i=0; i< feature_defs.size(); i++) {
std::string dsd = feature_defs[i];
size_t d_pos = dsd.find(":");
for (std::string dsd : feature_defs) {
size_t d_pos = dsd.find(":");
std::string icao = dsd.substr(0, d_pos);
std::string icao = dsd.substr(0, d_pos);
std::vector<int> shapes;
shapes.clear();
dsd.erase(0, d_pos+1);
dsd.erase(0, d_pos + 1);
if ( dsd == "all" ) {
shapes.push_back( std::numeric_limits<int>::max() );
if (dsd == "all") {
shapes.push_back(std::numeric_limits<int>::max());
} else {
std::stringstream ss(dsd);
int idx;
while (ss >> idx)
{
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug feature " << idx << " for " << icao );
while (ss >> idx) {
TG_LOG(SG_GENERAL, SG_ALERT, "Adding debug feature " << idx << " for " << icao);
shapes.push_back(idx);
@ -168,154 +165,138 @@ void Scheduler::set_debug( const std::string& path, std::vector<std::string> run
ss.ignore();
}
}
debug_features[icao] = shapes;
}
}
bool Scheduler::IsAirportDefinition( char* line, const std::string& icao )
bool Scheduler::IsAirportDefinition(char* line, const std::string& icao)
{
bool match = false;
// Get the number code
char* tok = strtok(line, " \t\r\n");
if (tok)
{
line += strlen(tok)+1;
if (tok) {
line += strlen(tok) + 1;
int code = atoi(tok);
switch(code)
{
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
case HELIPORT_CODE:
{
Airport ap( code, line );
switch (code) {
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
case HELIPORT_CODE: {
Airport ap(code, line);
if ( ap.GetIcao() == icao )
{
match = true;
}
}
break;
if (ap.GetIcao() == icao) {
match = true;
}
} break;
default:
break;
default:
break;
}
}
return match;
}
void Scheduler::AddAirport( std::string icao )
void Scheduler::AddAirport(std::string icao)
{
char line[2048];
bool found = false;
AirportInfo ai;
char line[2048];
bool found = false;
AirportInfo ai;
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
TG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
std::ifstream in(filename.c_str());
if (!in.is_open()) {
TG_LOG(SG_GENERAL, SG_ALERT, "Cannot open file: " << filename);
exit(-1);
}
TG_LOG( SG_GENERAL, SG_INFO, "Adding airport " << icao << " to parse list");
while ( !in.eof() && !found )
{
TG_LOG(SG_GENERAL, SG_INFO, "Adding airport " << icao << " to parse list");
while (!in.eof() && !found) {
// remember the position of this line
long cur_pos = in.tellg();
// get a line
in.getline(line, 2048);
in.getline(line, 2048);
// this is an airport definition - remember it
if ( IsAirportDefinition( line, icao ) )
{
TG_LOG( SG_GENERAL, SG_DEBUG, "Found airport " << icao << " at " << cur_pos );
if (IsAirportDefinition(line, icao)) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Found airport " << icao << " at " << cur_pos);
ai = AirportInfo( icao, cur_pos, gSnap );
global_workQueue.push( ai );
ai = AirportInfo(icao, cur_pos, gSnap);
global_workQueue.push(ai);
found = true;
}
}
}
long Scheduler::FindAirport( const std::string& icao )
long Scheduler::FindAirport(const std::string& icao)
{
char line[2048];
long cur_pos = 0;
bool found = false;
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
TG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
std::ifstream in(filename.c_str());
if (!in.is_open()) {
TG_LOG(SG_GENERAL, SG_ALERT, "Cannot open file: " << filename);
exit(-1);
}
TG_LOG( SG_GENERAL, SG_DEBUG, "Finding airport " << icao );
while ( !in.eof() && !found )
{
TG_LOG(SG_GENERAL, SG_DEBUG, "Finding airport " << icao);
while (!in.eof() && !found) {
// remember the position of this line
cur_pos = in.tellg();
// get a line
in.getline(line, 2048);
in.getline(line, 2048);
// this is and airport definition - remember it
if ( IsAirportDefinition( line, icao ) )
{
TG_LOG( SG_GENERAL, SG_DEBUG, "Found airport " << line << " at " << cur_pos );
if (IsAirportDefinition(line, icao)) {
TG_LOG(SG_GENERAL, SG_DEBUG, "Found airport " << line << " at " << cur_pos);
found = true;
}
}
if (found)
{
return cur_pos;
}
else
{
return 0;
}
if (found) {
return cur_pos;
} else {
return 0;
}
}
void Scheduler::RetryAirport( AirportInfo* pai )
void Scheduler::RetryAirport(AirportInfo* pai)
{
// retryList.push_back( *pai );
}
bool Scheduler::AddAirports( long start_pos, tgRectangle* boundingBox )
bool Scheduler::AddAirports(long start_pos, tgRectangle* boundingBox)
{
char line[2048];
long cur_apt_pos = 0;
std::string cur_apt_name;
int code;
bool match;
bool done;
char line[2048];
long cur_apt_pos = 0;
std::string cur_apt_name;
int code;
bool match;
bool done;
done = false;
done = false;
match = false;
// start from current position, and push all airports where a runway start or end
// lies within the given min/max coordinates
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
TG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
std::ifstream in(filename.c_str());
if (!in.is_open()) {
TG_LOG(SG_GENERAL, SG_ALERT, "Cannot open file: " << filename);
exit(-1);
}
if (start_pos)
{
if (start_pos) {
in.seekg(start_pos, std::ios::beg);
}
while (!done)
{
while (!done) {
// remember the position of this line
long cur_pos = in.tellg();
@ -326,115 +307,104 @@ bool Scheduler::AddAirports( long start_pos, tgRectangle* boundingBox )
// Get the number code
char* tok = strtok(def, " \t\r\n");
if (tok)
{
def += strlen(tok)+1;
if (tok) {
def += strlen(tok) + 1;
code = atoi(tok);
switch(code)
{
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
case HELIPORT_CODE:
{
auto airport = std::make_unique<Airport>( code, def );
if (match)
{
// Start off with given snap value
AirportInfo ai = AirportInfo( cur_apt_name, cur_apt_pos, gSnap );
global_workQueue.push( ai );
}
// remember this new apt pos and name, and clear match
cur_apt_pos = cur_pos;
cur_apt_name = airport->GetIcao();
switch (code) {
case LAND_AIRPORT_CODE:
case SEA_AIRPORT_CODE:
case HELIPORT_CODE: {
auto airport = std::make_unique<Airport>(code, def);
if (match) {
// Start off with given snap value
AirportInfo ai = AirportInfo(cur_apt_name, cur_apt_pos, gSnap);
global_workQueue.push(ai);
}
// remember this new apt pos and name, and clear match
cur_apt_pos = cur_pos;
cur_apt_name = airport->GetIcao();
match = false;
match = false;
} break;
case END_OF_FILE:
if (match) {
// Start off with given snap value
AirportInfo ai = AirportInfo(cur_apt_name, cur_apt_pos, gSnap);
global_workQueue.push(ai);
}
done = true;
break;
case LAND_RUNWAY_CODE:
// if the the runway start / end coords are within the rect,
// we have a winner
{
auto runway = std::make_unique<Runway>(def);
if (boundingBox->isInside(runway->GetStart())) {
match = true;
} else if (boundingBox->isInside(runway->GetEnd())) {
match = true;
}
}
break;
case END_OF_FILE:
if (match)
{
// Start off with given snap value
AirportInfo ai = AirportInfo( cur_apt_name, cur_apt_pos, gSnap );
global_workQueue.push( ai );
case WATER_RUNWAY_CODE:
// if the the runway start / end coords are within the rect,
// we have a winner
{
auto runway = std::make_unique<WaterRunway>(def);
if (boundingBox->isInside(runway->GetStart())) {
match = true;
} else if (boundingBox->isInside(runway->GetEnd())) {
match = true;
}
done = true;
break;
}
break;
case LAND_RUNWAY_CODE:
// if the the runway start / end coords are within the rect,
// we have a winner
{
auto runway = std::make_unique<Runway>(def);
if ( boundingBox->isInside(runway->GetStart()) ) {
match = true;
}
else if ( boundingBox->isInside(runway->GetEnd()) ) {
match = true;
}
case HELIPAD_CODE:
// if the heliport coords are within the rect, we have
// a winner
{
auto helipad = std::make_unique<Helipad>(def);
if (boundingBox->isInside(helipad->GetLoc())) {
match = true;
}
break;
}
break;
case WATER_RUNWAY_CODE:
// if the the runway start / end coords are within the rect,
// we have a winner
{
auto runway = std::make_unique<WaterRunway>(def);
if ( boundingBox->isInside(runway->GetStart()) ) {
match = true;
}
else if ( boundingBox->isInside(runway->GetEnd()) ) {
match = true;
}
}
break;
case HELIPAD_CODE:
// if the heliport coords are within the rect, we have
// a winner
{
auto helipad = std::make_unique<Helipad>(def);
if ( boundingBox->isInside(helipad->GetLoc()) ) {
match = true;
}
}
break;
default:
break;
default:
break;
}
}
}
// did we add airports to the parse list?
if ( global_workQueue.size() ) {
if (global_workQueue.size())
return true;
} else {
return false;
}
return false;
}
Scheduler::Scheduler(std::string& datafile, const std::string& root, const string_list& elev_src) :
filename(datafile),
elevation(elev_src),
work_dir(root)
Scheduler::Scheduler(std::string& datafile, const std::string& root, const string_list& elev_src) : filename(datafile),
elevation(elev_src),
work_dir(root)
{
std::ifstream in( filename.c_str() );
if ( !in.is_open() )
{
TG_LOG( SG_GENERAL, SG_ALERT, "Cannot open file: " << filename );
std::ifstream in(filename.c_str());
if (!in.is_open()) {
TG_LOG(SG_GENERAL, SG_ALERT, "Cannot open file: " << filename);
exit(-1);
}
}
void Scheduler::Schedule( int num_threads, std::string& summaryfile )
void Scheduler::Schedule(int num_threads, std::string& summaryfile)
{
std::vector<std::shared_ptr<Parser>> parsers;
for (int i=0; i<num_threads; i++) {
auto parser = std::make_shared<Parser>( filename, work_dir, elevation );
for (int i = 0; i < num_threads; i++) {
auto parser = std::make_shared<Parser>(filename, work_dir, elevation);
parser->start();
parsers.push_back( parser );
parsers.push_back(parser);
}
while (!global_workQueue.empty()) {
@ -442,7 +412,7 @@ void Scheduler::Schedule( int num_threads, std::string& summaryfile )
}
// Then wait until they are finished
for (unsigned int i=0; i<parsers.size(); i++) {
for (unsigned int i = 0; i < parsers.size(); i++) {
parsers[i]->join();
parsers[i] = nullptr;
}

View file

@ -1,15 +1,17 @@
#pragma once
#include <string>
#include <iostream>
#include <fstream>
#include <iostream>
#include <string>
#include <simgear/compiler.h>
#include <simgear/math/sg_types.hxx>
#include <simgear/timing/timestamp.hxx>
#include <simgear/threads/SGThread.hxx>
#include <simgear/threads/SGQueue.hxx>
#include <simgear/threads/SGThread.hxx>
#include <simgear/timing/timestamp.hxx>
#include <terragear/tg_rectangle.hxx>
#include "airport.hxx"
@ -21,10 +23,10 @@
#define P_STATE_DONE (8)
#define P_STATE_KILLED (9)
#define P_STATE_INIT_TIME (1*60)
#define P_STATE_PARSE_TIME (1*60)
#define P_STATE_INIT_TIME (60)
#define P_STATE_PARSE_TIME (60)
#define P_STATE_BUILD_TIME (30*60)
#define P_STATE_TRIANGULATE_TIME (1*60)
#define P_STATE_TRIANGULATE_TIME (60)
#define P_STATE_OUTPUT_TIME (10*60)
#define GENAPT_PORT (12397)
@ -56,21 +58,21 @@ public:
numTaxiways = -1;
}
std::string GetIcao(void) { return icao; }
long GetPos(void) { return pos; }
double GetSnap(void) { return snap; }
std::string GetIcao() const { return icao; }
long GetPos() const { return pos; }
double GetSnap() const { return snap; }
void SetRunways(int r) { numRunways = r; }
void SetPavements(int p) { numPavements = p; }
void SetFeats(int f) { numFeats = f; }
void SetTaxiways(int t) { numTaxiways = t; }
void SetParseTime(SGTimeStamp t) { parseTime = t; }
void SetBuildTime(SGTimeStamp t) { buildTime = t; }
void SetCleanTime(SGTimeStamp t) { cleanTime = t; }
void SetTessTime(SGTimeStamp t) { tessTime = t; }
void SetErrorString(char* e) { errString = e; }
void SetRunways(int r) { numRunways = r; }
void SetPavements(int p) { numPavements = p; }
void SetFeats(int f) { numFeats = f; }
void SetTaxiways(int t) { numTaxiways = t; }
void SetParseTime(SGTimeStamp t) { parseTime = t; }
void SetBuildTime(SGTimeStamp t) { buildTime = t; }
void SetCleanTime(SGTimeStamp t) { cleanTime = t; }
void SetTessTime(SGTimeStamp t) { tessTime = t; }
void SetErrorString(char* e) { errString = e; }
void IncreaseSnap(void) { snap *= 2.0f; }
void IncreaseSnap() { snap *= 2.0f; }
friend std::ostream& operator<<(std::ostream& output, const AirportInfo& ai);

View file

@ -1,14 +1,14 @@
#include <simgear/compiler.h>
#include <simgear/structure/exception.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/exception.hxx>
#include <terragear/tg_shapefile.hxx>
#include "global.hxx"
#include "apt_math.hxx"
#include "beznode.hxx"
#include "global.hxx"
#include "taxiway.hxx"
extern int nudge;
@ -16,16 +16,16 @@ extern int nudge;
Taxiway::Taxiway(char* definition)
{
// variables for adjusting 810 rwy format to 850 rwy format
double lon = 0, lat = 0;
double lon = -9999, lat = -9999;
// variables to store unused parameters
char designation[16];
char designation[16];
double threshold;
double overrun;
int shoulder;
int markings;
int shoulder;
int markings;
double smoothness;
int signs;
int signs;
// taxiway format:
// lat lon designation heading length threshold overrun
@ -38,31 +38,33 @@ Taxiway::Taxiway(char* definition)
// 44.38085600 -074.20606200 xxx 79.29 3384 0.0 0.0 60 161161 1 0 0 0.35 0
std::istringstream ss(definition);
ss >> lat
>> lon
>> designation
>> heading
>> length
>> threshold
>> overrun
>> width
>> lighting
>> surface
>> shoulder
>> markings
>> smoothness
>> signs;
ss >> lat >> lon >>
designation >>
heading >> length >>
threshold >> overrun >>
width >>
lighting >>
surface >>
shoulder >>
markings >>
smoothness >>
signs;
TG_LOG(SG_GENERAL, SG_DEBUG, "Read taxiway: (" << lon << "," << lat << ") heading: " << heading << " length: " << length << " width: " << width );
if (width == -9999 || length == -9999 || lat < -90 || lat > 90 || lon < -180 || lon > 180) {
valid = false;
TG_LOG(SG_GENERAL, SG_ALERT, "Invalid taxiway line: " << definition);
}
TG_LOG(SG_GENERAL, SG_DEBUG, "Read taxiway: (" << lon << "," << lat << ") heading: " << heading << " length: " << length << " width: " << width);
// adjust length and width from feet to meters
length *= SG_FEET_TO_METER;
width *= SG_FEET_TO_METER;
// adjust lat / lon to the start of the taxiway, not the middle
origin = SGGeodesy::direct( SGGeod::fromDeg(lon, lat), heading, -length/2 );
origin = SGGeodesy::direct(SGGeod::fromDeg(lon, lat), heading, -length / 2.0);
taxi_contour = gen_wgs84_rect( origin, heading, length, width );
taxi_contour = gen_wgs84_rect(origin, heading, length, width);
}
void Taxiway::GenLights(tglightcontour_list& rwy_lights)
@ -74,122 +76,112 @@ void Taxiway::GenLights(tglightcontour_list& rwy_lights)
SGVec3f vec = normalize(SGVec3f::fromGeod(taxi_contour.GetNode(0)));
tgLightContour blue;
blue.SetType( "RWY_BLUE_TAXIWAY_LIGHTS" );
blue.SetType("RWY_BLUE_TAXIWAY_LIGHTS");
for ( unsigned int i = 0; i < taxi_contour.GetSize(); ++i ) {
for (unsigned int i = 0; i < taxi_contour.GetSize(); ++i) {
double dist, course, cs;
SGGeodesy::inverse(taxi_contour.GetNode(i), taxi_contour.GetNode(i+1), course, cs, dist );
int divs = (int)(dist / 10.0);
double step = dist/divs;
SGGeod pt = taxi_contour.GetNode(i);
for (int j = 0; j < divs; ++j) {
pt = SGGeodesy::direct(pt, course, step );
blue.AddLight( pt, vec );
}
i++;
}
rwy_lights.push_back( blue );
SGGeodesy::inverse(taxi_contour.GetNode(i), taxi_contour.GetNode(i + 1), course, cs, dist);
int divs = (int)(dist / 10.0);
double step = dist / divs;
SGGeod pt = taxi_contour.GetNode(i);
for (int j = 0; j < divs; ++j) {
pt = SGGeodesy::direct(pt, course, step);
blue.AddLight(pt, vec);
}
++i;
}
rwy_lights.push_back(blue);
}
int Taxiway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name )
int Taxiway::BuildBtg(tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgAccumulator& accum, std::string& shapefile_name)
{
using namespace std::string_literals;
std::string material;
if ( surface == 1 /* Asphalt */ )
{
if ( (width <= 50) && (lighting[1] == '6') ) {
material = "pa_taxiway";
if (surface == 1 /* Asphalt */) {
if ((width <= 50) && (lighting[1] == '6')) {
material = "pa_taxiway"s;
GenLights(rwy_lights);
} else {
material = "pa_tiedown";
material = "pa_tiedown"s;
}
}
else if ( surface == 2 /* Concrete */ )
{
if ( (width <= 50) && (lighting[1] == '6') ) {
material = "pc_taxiway";
} else if (surface == 2 /* Concrete */) {
if ((width <= 50) && (lighting[1] == '6')) {
material = "pc_taxiway"s;
GenLights(rwy_lights);
} else {
material = "pc_tiedown";
material = "pc_tiedown"s;
}
}
else if ( surface == 3 /* Turf/Grass */ )
{
material = "grass_rwy";
}
else if ( surface == 4 /* Dirt */ || surface == 5 /* Gravel */ )
{
material = "dirt_rwy";
}
else if ( surface == 12 /* Dry Lakebed */ )
{
material = "lakebed_taxiway";
}
else if ( surface == 13 /* Water runway (buoy's?) */ )
{
} else if (surface == 3 /* Turf/Grass */) {
material = "grass_rwy"s;
} else if (surface == 4 /* Dirt */ || surface == 5 /* Gravel */) {
material = "dirt_rwy"s;
} else if (surface == 12 /* Dry Lakebed */) {
material = "lakebed_taxiway"s;
} else if (surface == 13 /* Water runway (buoy's?) */) {
// water
}
else if ( surface == 14 /* Snow / Ice */ )
{
} else if (surface == 14 /* Snow / Ice */) {
// Ice
}
else if ( surface == 15 /* Transparent */ )
{
} else if (surface == 15 /* Transparent */) {
//Transparent texture
}
else
{
} else {
TG_LOG(SG_GENERAL, SG_WARN, "surface_code = " << surface);
throw sg_exception("unknown runway type!");
}
if( shapefile_name.size() ) {
if (shapefile_name.size()) {
tgPolygon taxi_poly;
taxi_poly.AddContour( taxi_contour );
taxi_poly.AddContour(taxi_contour);
tgShapefile::FromPolygon( taxi_poly, "./airport_dbg", std::string("preclip"), shapefile_name );
accum.ToShapefiles( "./airport_dbg", "accum", true );
tgShapefile::FromPolygon(taxi_poly, "./airport_dbg"s, "preclip"s, shapefile_name);
accum.ToShapefiles("./airport_dbg"s, "accum"s, true);
}
tgPolygon clipped = accum.Diff( taxi_contour );
tgPolygon split = tgPolygon::SplitLongEdges( clipped, 100 );
tgPolygon clipped = accum.Diff(taxi_contour);
tgPolygon split = tgPolygon::SplitLongEdges(clipped, 100);
tgPolygon::RemoveSlivers( split, slivers );
tgPolygon::RemoveSlivers(split, slivers);
split.SetMaterial( material );
split.SetTexParams( taxi_contour.GetNode(0), width, 25*SG_FEET_TO_METER, heading );
split.SetTexLimits( 0.0, 0.0, 1.0, 1.0 );
split.SetTexMethod( TG_TEX_BY_TPS_CLIPU, -1.0, -1.0, 1.0, 1.0 );
rwy_polys.push_back( split );
split.SetMaterial(material);
split.SetTexParams(taxi_contour.GetNode(0), width, 25 * SG_FEET_TO_METER, heading);
split.SetTexLimits(0.0, 0.0, 1.0, 1.0);
split.SetTexMethod(TG_TEX_BY_TPS_CLIPU, -1.0, -1.0, 1.0, 1.0);
rwy_polys.push_back(split);
if( shapefile_name.size() ) {
tgShapefile::FromPolygon( split, "./airport_dbg", std::string("postclip"), shapefile_name );
if (shapefile_name.size()) {
tgShapefile::FromPolygon(split, "./airport_dbg"s, "postclip"s, shapefile_name);
}
accum.Add( taxi_contour );
accum.Add(taxi_contour);
return 0;
}
int Taxiway::BuildBtg( tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgpolygon_list& apt_base_polys, tgpolygon_list& apt_clearing_polys, tgAccumulator& accum, std::string& shapefile_name )
int Taxiway::BuildBtg(tgpolygon_list& rwy_polys, tglightcontour_list& rwy_lights, tgcontour_list& slivers, tgpolygon_list& apt_base_polys, tgpolygon_list& apt_clearing_polys, tgAccumulator& accum, std::string& shapefile_name)
{
tgContour base_contour, safe_base_contour;
tgPolygon base, safe_base;
BuildBtg( rwy_polys, rwy_lights, slivers, accum, shapefile_name );
BuildBtg(rwy_polys, rwy_lights, slivers, accum, shapefile_name);
base_contour = tgContour::Expand( taxi_contour, 20.0);
base.AddContour( base_contour );
base_contour = tgContour::Expand(taxi_contour, 20.0);
base.AddContour(base_contour);
safe_base_contour = tgContour::Expand(taxi_contour, 50.0);
safe_base.AddContour(safe_base_contour);
safe_base_contour = tgContour::Expand( taxi_contour, 50.0);
safe_base.AddContour( safe_base_contour );
// add this to the airport clearing
apt_clearing_polys.push_back( safe_base );
apt_clearing_polys.push_back(safe_base);
// and add the clearing to the base
apt_base_polys.push_back( base );
apt_base_polys.push_back(base);
return 0;
}

View file

@ -8,6 +8,7 @@
#include "apt_math.hxx"
class Taxiway
{
public:
@ -27,11 +28,13 @@ public:
tgAccumulator& accum,
std::string& shapefile_name);
bool valid {true};
private:
SGGeod origin;
double heading;
double length;
double width;
double length {-9999};
double width {-9999};
int surface;
char lighting[6];

View file

@ -269,6 +269,7 @@ tgSurface::tgSurface( const std::string& path,
// Build the extra res input grid (shifted SW by half (dlon,dlat)
// with an added major row column on the NE sides.)
int mult = 10;
SG_LOG(SG_GENERAL, SG_ALERT, "creating tgMatrix with nPts x=" << ((xdivs + 1) * mult + 1) << " y=" << ((ydivs + 1) * mult + 1));
tgMatrix dPts( (xdivs + 1) * mult + 1, (ydivs + 1) * mult + 1 );
for ( int j = 0; j < dPts.rows(); ++j ) {
for ( int i = 0; i < dPts.cols(); ++i ) {