Compare commits
10 commits
fba4f3634d
...
d42a5d6d0d
Author | SHA1 | Date | |
---|---|---|---|
|
d42a5d6d0d | ||
|
43d8d23343 | ||
|
e701da1d4a | ||
|
3f7bb23b38 | ||
|
f98b5cd482 | ||
|
cbcbb8c8f6 | ||
|
dc9a7e494e | ||
|
efddc3d44c | ||
|
b83c79f6b0 | ||
|
275d5cc4f6 |
21 changed files with 1190 additions and 1142 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
Loading…
Add table
Reference in a new issue