Taxiway signs: support all variants from the apt.dat 850 spec and
read size values from the optional stg column
This commit is contained in:
@@ -288,7 +288,12 @@ ReaderWriterSTG::readStgFile(const std::string& absoluteFileName,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else if ( token == "OBJECT_SIGN" ) {
|
} else if ( token == "OBJECT_SIGN" ) {
|
||||||
signBuilder.addSign(SGGeod::fromDegM(lon, lat, elev), hdg, name);
|
int size(-1);
|
||||||
|
|
||||||
|
if ( hasOptionalValue(in) ){
|
||||||
|
in >> size;
|
||||||
|
}
|
||||||
|
signBuilder.addSign(SGGeod::fromDegM(lon, lat, elev), hdg, name, size);
|
||||||
} else {
|
} else {
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
SG_LOG( SG_TERRAIN, SG_ALERT, absoluteFileName
|
||||||
<< ": Unknown token '" << token << "'" );
|
<< ": Unknown token '" << token << "'" );
|
||||||
|
|||||||
@@ -66,7 +66,10 @@ struct element_info {
|
|||||||
|
|
||||||
typedef std::vector<element_info*> ElementVec;
|
typedef std::vector<element_info*> ElementVec;
|
||||||
|
|
||||||
const double HT[5] = {0.460, 0.610, 0.760, 1.220, 0.760}; // standard panel height sizes
|
// Standard panel height sizes. The first value is unused to
|
||||||
|
// make sure the size value equals 1:1 the value from the apt.dat file:
|
||||||
|
const double HT[6] = {0.1, 0.460, 0.610, 0.760, 1.220, 0.760};
|
||||||
|
|
||||||
const double grounddist = 0.2; // hard-code sign distance from surface for now
|
const double grounddist = 0.2; // hard-code sign distance from surface for now
|
||||||
const double thick = 0.1; // half the thickness of the 3D sign
|
const double thick = 0.1; // half the thickness of the 3D sign
|
||||||
|
|
||||||
@@ -80,14 +83,13 @@ struct pair {
|
|||||||
{"@d", "^d"},
|
{"@d", "^d"},
|
||||||
{"@l", "^l"},
|
{"@l", "^l"},
|
||||||
{"@lu", "^lu"},
|
{"@lu", "^lu"},
|
||||||
{"@ul", "^lu"},
|
|
||||||
{"@ld", "^ld"},
|
{"@ld", "^ld"},
|
||||||
{"@dl", "^ld"},
|
|
||||||
{"@r", "^r"},
|
{"@r", "^r"},
|
||||||
{"@ru", "^ru"},
|
{"@ru", "^ru"},
|
||||||
{"@ur", "^ru"},
|
|
||||||
{"@rd", "^rd"},
|
{"@rd", "^rd"},
|
||||||
{"@dr", "^rd"},
|
{"r1", "^I1"},
|
||||||
|
{"r2", "^I2"},
|
||||||
|
{"r3", "^I3"},
|
||||||
{0, 0},
|
{0, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -274,7 +276,7 @@ AirportSignBuilder::~AirportSignBuilder()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::string& content)
|
void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::string& content, int size)
|
||||||
{
|
{
|
||||||
double sign_height = 1.0; // meter
|
double sign_height = 1.0; // meter
|
||||||
string newmat = "BlackSign";
|
string newmat = "BlackSign";
|
||||||
@@ -285,10 +287,14 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s
|
|||||||
double total_width2 = 0.0;
|
double total_width2 = 0.0;
|
||||||
bool cmd = false;
|
bool cmd = false;
|
||||||
bool isBackside = false;
|
bool isBackside = false;
|
||||||
int size = -1;
|
|
||||||
char oldtype = 0, newtype = 0;
|
char oldtype = 0, newtype = 0;
|
||||||
SGMaterial *material = 0;
|
SGMaterial *material = 0;
|
||||||
|
|
||||||
|
if (size < -1 || size > 5){
|
||||||
|
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "Found illegal sign size value of '" << size << "' for " << content << ".");
|
||||||
|
size = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Part I: parse & measure
|
// Part I: parse & measure
|
||||||
for (const char *s = content.data(); *s; s++) {
|
for (const char *s = content.data(); *s; s++) {
|
||||||
string name;
|
string name;
|
||||||
@@ -315,9 +321,10 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s
|
|||||||
|
|
||||||
for (; *s; s++) {
|
for (; *s; s++) {
|
||||||
name += *s;
|
name += *s;
|
||||||
if (s[1] == ',' || s[1] == '}' || s[1] == '=')
|
if (s[1] == ',' || s[1] == '}' )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!*s) {
|
if (!*s) {
|
||||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
|
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
|
||||||
} else if (s[1] == '=') {
|
} else if (s[1] == '=') {
|
||||||
@@ -330,25 +337,44 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s
|
|||||||
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
|
SG_LOG(SG_TERRAIN, SG_ALERT, SIGN "unclosed { in sign contents");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == "@@") {
|
if (name == "no-entry") {
|
||||||
isBackside = true;
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
continue;
|
newmat = "RedSign";
|
||||||
|
newtype = 'R';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == "@size") {
|
else if (name == "critical") {
|
||||||
sign_height = strtod(value.data(), 0);
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
|
newmat = "SpecialSign";
|
||||||
|
newtype = 'S';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (name == "safety") {
|
||||||
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
|
newmat = "SpecialSign";
|
||||||
|
newtype = 'S';
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (name == "hazard") {
|
||||||
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
|
newmat = "SpecialSign";
|
||||||
|
newtype = 'S';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name == "@@") {
|
||||||
|
isBackside = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name.size() == 2 || name.size() == 3) {
|
if (name.size() == 2 || name.size() == 3) {
|
||||||
string n = name;
|
string n = name;
|
||||||
if (n.size() == 3 && n[2] >= '1' && n[2] <= '5') {
|
if (n.size() == 3 && n[2] >= '1' && n[2] <= '5') {
|
||||||
size = n[2] - '1';
|
size = n[2];
|
||||||
n = n.substr(0, 2);
|
n = n.substr(0, 2);
|
||||||
}
|
}
|
||||||
if (n == "@Y") {
|
if (n == "@Y") {
|
||||||
if (size < 3) {
|
if (size < 3) {
|
||||||
sign_height = HT[size < 0 ? 2 : size];
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
newmat = "YellowSign";
|
newmat = "YellowSign";
|
||||||
newtype = 'Y';
|
newtype = 'Y';
|
||||||
continue;
|
continue;
|
||||||
@@ -356,7 +382,7 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s
|
|||||||
|
|
||||||
} else if (n == "@R") {
|
} else if (n == "@R") {
|
||||||
if (size < 3) {
|
if (size < 3) {
|
||||||
sign_height = HT[size < 0 ? 2 : size];
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
newmat = "RedSign";
|
newmat = "RedSign";
|
||||||
newtype = 'R';
|
newtype = 'R';
|
||||||
continue;
|
continue;
|
||||||
@@ -364,15 +390,15 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s
|
|||||||
|
|
||||||
} else if (n == "@L") {
|
} else if (n == "@L") {
|
||||||
if (size < 3) {
|
if (size < 3) {
|
||||||
sign_height = HT[size < 0 ? 2 : size];
|
sign_height = HT[size < 0 ? 3 : size];
|
||||||
newmat = "FramedSign";
|
newmat = "FramedSign";
|
||||||
newtype = 'L';
|
newtype = 'L';
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (n == "@B") {
|
} else if (n == "@B") {
|
||||||
if (size < 0 || size == 3 || size == 4) {
|
if (size < 0 || size == 4 || size == 5) {
|
||||||
sign_height = HT[size < 0 ? 3 : size];
|
sign_height = HT[size < 0 ? 4 : size];
|
||||||
newmat = "BlackSign";
|
newmat = "BlackSign";
|
||||||
newtype = 'B';
|
newtype = 'B';
|
||||||
continue;
|
continue;
|
||||||
@@ -397,7 +423,7 @@ void AirportSignBuilder::addSign(const SGGeod& pos, double heading, const std::s
|
|||||||
material = d->materials->find(newmat);
|
material = d->materials->find(newmat);
|
||||||
newmat.clear();
|
newmat.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
SGMaterialGlyph *glyph = material->get_glyph(name);
|
SGMaterialGlyph *glyph = material->get_glyph(name);
|
||||||
if (!glyph) {
|
if (!glyph) {
|
||||||
SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph '" << *s << '\'');
|
SG_LOG( SG_TERRAIN, SG_ALERT, SIGN "unsupported glyph '" << *s << '\'');
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
AirportSignBuilder(SGMaterialLib* mats, const SGGeod& center);
|
AirportSignBuilder(SGMaterialLib* mats, const SGGeod& center);
|
||||||
~AirportSignBuilder();
|
~AirportSignBuilder();
|
||||||
|
|
||||||
void addSign(const SGGeod& pos, double heading, const std::string& content);
|
void addSign(const SGGeod& pos, double heading, const std::string& content, int size);
|
||||||
|
|
||||||
osg::Node* getSignsGroup();
|
osg::Node* getSignsGroup();
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user