- Made name lists in .stc files replace existing names when overriding a star

- Moved improved spectral type parser from makestardb into the core celestia engine so it can be used by the .stc loader
ver1_5_1
Chris Laurel 2004-10-09 20:25:19 +00:00
parent c9a186130d
commit fb20b87727
4 changed files with 386 additions and 151 deletions

View File

@ -1073,6 +1073,10 @@ bool StarDatabase::load(istream& in, const string& resourcePath)
if (names != NULL && !name.empty())
{
// List of names will replace any that already exist for
// this star.
names->erase(catalogNumber);
// Iterate through the string for names delimited
// by ':', and insert them into the star database.
// Note that db->add() will skip empty names.
@ -1099,3 +1103,4 @@ bool StarDatabase::load(istream& in, const string& resourcePath)
return true;
}

View File

@ -38,12 +38,21 @@ void StarNameDatabase::add(uint32 catalogNumber, const string& name)
DPRINTF(2,"Duplicated name '%s' on HIP %d and %d\n", name.c_str(),
tmp, catalogNumber);
#endif
nameIndex.insert(NameIndex::value_type(name, catalogNumber));
// Add the new name
//nameIndex.insert(NameIndex::value_type(name, catalogNumber));
nameIndex[name] = catalogNumber;
numberIndex.insert(NumberIndex::value_type(catalogNumber, name));
}
}
void StarNameDatabase::erase(uint32 catalogNumber)
{
numberIndex.erase(catalogNumber);
}
uint32 StarNameDatabase::findCatalogNumber(const string& name) const
{
NameIndex::const_iterator iter = nameIndex.find(name);

View File

@ -28,6 +28,10 @@ class StarNameDatabase
typedef std::multimap<uint32, std::string> NumberIndex;
void add(uint32, const std::string&);
// Delete all names associated with the specified catalog number
void erase(uint32);
uint32 findCatalogNumber(const std::string& name) const;
uint32 findName(std::string name) const;
std::vector<std::string> getCompletion(const std::string& name) const;

View File

@ -204,174 +204,391 @@ bool operator<(const StellarClass& sc0, const StellarClass& sc1)
}
StellarClass StellarClass::parse(const std::string& s)
// The following code implements a state machine for parsing spectral
// types. It is a very forgiving parser, returning unknown for any of the
// spectral type fields it can't find, and silently ignoring any extra
// characters in the spectral type. The parser is written this way because
// the spectral type strings from the Hipparcos catalog are quite irregular.
enum ParseState
{
const char* starType = s.c_str();
StellarClass::StarType type = StellarClass::NormalStar;
StellarClass::SpectralClass specClass = StellarClass::Spectral_A;
StellarClass::LuminosityClass lum = StellarClass::Lum_Unknown;
unsigned short number = Subclass_Unknown;
int i = 0;
BeginState,
EndState,
NormalStarState,
WolfRayetTypeState,
NormalStarClassState,
NormalStarSubclassState,
NormalStarSubclassDecimalState,
NormalStarSubclassFinalState,
LumClassBeginState,
LumClassIState,
LumClassIIState,
LumClassVState,
LumClassIdashState,
LumClassIaState,
WDTypeState,
WDExtendedTypeState,
WDSubclassState,
SubdwarfPrefixState,
};
// Subdwarves (luminosity class VI) may be prefixed with sd
if (starType[i] == 's' && starType[i + 1] == 'd')
{
lum = StellarClass::Lum_VI;
i += 2;
}
switch (starType[i])
StellarClass
StellarClass::parse(const string& st)
{
uint32 i = 0;
ParseState state = BeginState;
StellarClass::StarType starType = StellarClass::NormalStar;
StellarClass::SpectralClass specClass = StellarClass::Spectral_Unknown;
StellarClass::LuminosityClass lumClass = StellarClass::Lum_Unknown;
unsigned int subclass = StellarClass::Subclass_Unknown;
while (state != EndState)
{
case 'O':
specClass = StellarClass::Spectral_O;
break;
case 'B':
specClass = StellarClass::Spectral_B;
break;
case 'A':
specClass = StellarClass::Spectral_A;
break;
case 'F':
specClass = StellarClass::Spectral_F;
break;
case 'G':
specClass = StellarClass::Spectral_G;
break;
case 'K':
specClass = StellarClass::Spectral_K;
break;
case 'M':
specClass = StellarClass::Spectral_M;
break;
case 'R':
specClass = StellarClass::Spectral_R;
break;
case 'N':
specClass = StellarClass::Spectral_S;
break;
case 'S':
specClass = StellarClass::Spectral_N;
break;
case 'C':
specClass = StellarClass::Spectral_C;
break;
case 'W':
i++;
if (starType[i] == 'C')
specClass = StellarClass::Spectral_WC;
else if (starType[i] == 'N')
specClass = StellarClass::Spectral_WN;
char c;
if (i < st.length())
c = st[i];
else
i--;
break;
case 'L':
specClass = StellarClass::Spectral_L;
break;
case 'T':
specClass = StellarClass::Spectral_T;
break;
case 'D':
type = StellarClass::WhiteDwarf;
i++;
switch (starType[i])
{
case 'A':
specClass = Spectral_DA;
break;
case 'B':
specClass = Spectral_DB;
break;
case 'C':
specClass = Spectral_DC;
break;
case 'O':
specClass = Spectral_DO;
break;
case 'Q':
specClass = Spectral_DQ;
break;
case 'Z':
specClass = Spectral_DZ;
break;
default:
specClass = Spectral_D;
break;
}
c = '\0';
if (specClass != Spectral_D)
i++;
if (starType[i] != '\0')
switch (state)
{
if (isdigit(starType[i]))
case BeginState:
switch (c)
{
number = starType[i] - '0';
case 'Q':
starType = StellarClass::NeutronStar;
state = EndState;
break;
case 'X':
starType = StellarClass::BlackHole;
state = EndState;
break;
case 'D':
starType = StellarClass::WhiteDwarf;
specClass = StellarClass::Spectral_D;
state = WDTypeState;
i++;
break;
case 's':
// Hipparcos uses sd prefix for stars with luminosity
// class VI ('subdwarfs')
state = SubdwarfPrefixState;
i++;
break;
case '?':
state = EndState;
break;
default:
state = NormalStarClassState;
break;
}
break;
case WolfRayetTypeState:
switch (c)
{
case 'C':
specClass = StellarClass::Spectral_WC;
state = NormalStarSubclassState;
i++;
break;
case 'N':
specClass = StellarClass::Spectral_WN;
state = NormalStarSubclassState;
i++;
break;
default:
specClass = StellarClass::Spectral_WC;
state = NormalStarSubclassState;
break;
}
break;
case SubdwarfPrefixState:
if (c == 'd')
{
lumClass = StellarClass::Lum_VI;
state = NormalStarClassState;
i++;
break;
}
else
{
// Some white dwarf types have two spectral class letters;
// skip past the second one to look for a subclass digit
i++;
if (isdigit(starType[i]))
number = starType[i] - '0';
state = EndState;
}
}
return StellarClass(type, specClass, number, lum);
break;
case 'Q':
type = StellarClass::NeutronStar;
return StellarClass(type, specClass, 0, lum);
case 'X':
type = StellarClass::BlackHole;
return StellarClass(type, specClass, 0, lum);
default:
specClass = StellarClass::Spectral_Unknown;
break;
}
i++;
if (starType[i] >= '0' && starType[i] <= '9')
{
number = starType[i] - '0';
}
if (lum != StellarClass::Lum_VI)
{
i++;
lum = StellarClass::Lum_V;
while (i < 13 && starType[i] != '\0') {
if (starType[i] == 'I') {
if (starType[i + 1] == 'I') {
if (starType[i + 2] == 'I') {
lum = StellarClass::Lum_III;
} else {
lum = StellarClass::Lum_II;
}
} else if (starType[i + 1] == 'V') {
lum = StellarClass::Lum_IV;
} else if (starType[i + 1] == 'a') {
if (starType[i + 2] == '0')
lum = StellarClass::Lum_Ia0;
else
lum = StellarClass::Lum_Ia;
} else if (starType[i + 1] == 'b') {
lum = StellarClass::Lum_Ib;
} else {
lum = StellarClass::Lum_Ib;
}
case NormalStarClassState:
switch (c)
{
case 'W':
state = WolfRayetTypeState;
break;
} else if (starType[i] == 'V') {
if (starType[i + 1] == 'I')
lum = StellarClass::Lum_VI;
else
lum = StellarClass::Lum_V;
case 'O':
specClass = StellarClass::Spectral_O;
state = NormalStarSubclassState;
break;
case 'B':
specClass = StellarClass::Spectral_B;
state = NormalStarSubclassState;
break;
case 'A':
specClass = StellarClass::Spectral_A;
state = NormalStarSubclassState;
break;
case 'F':
specClass = StellarClass::Spectral_F;
state = NormalStarSubclassState;
break;
case 'G':
specClass = StellarClass::Spectral_G;
state = NormalStarSubclassState;
break;
case 'K':
specClass = StellarClass::Spectral_K;
state = NormalStarSubclassState;
break;
case 'M':
specClass = StellarClass::Spectral_M;
state = NormalStarSubclassState;
break;
case 'R':
specClass = StellarClass::Spectral_R;
state = NormalStarSubclassState;
break;
case 'S':
specClass = StellarClass::Spectral_S;
state = NormalStarSubclassState;
break;
case 'N':
specClass = StellarClass::Spectral_N;
state = NormalStarSubclassState;
break;
case 'L':
specClass = StellarClass::Spectral_L;
state = NormalStarSubclassState;
break;
case 'T':
specClass = StellarClass::Spectral_T;
state = NormalStarSubclassState;
break;
case 'C':
specClass = StellarClass::Spectral_C;
state = NormalStarSubclassState;
break;
default:
state = EndState;
break;
}
i++;
break;
case NormalStarSubclassState:
if (isdigit(c))
{
subclass = (unsigned int) c - (unsigned int) '0';
state = NormalStarSubclassDecimalState;
i++;
}
else
{
state = LumClassBeginState;
}
break;
case NormalStarSubclassDecimalState:
if (c == '.')
{
state = NormalStarSubclassFinalState;
i++;
}
else
{
state = LumClassBeginState;
}
break;
case NormalStarSubclassFinalState:
if (isdigit(c))
state = LumClassBeginState;
else
state = EndState;
i++;
break;
case LumClassBeginState:
switch (c)
{
case 'I':
state = LumClassIState;
break;
case 'V':
state = LumClassVState;
break;
default:
state = EndState;
break;
}
i++;
break;
case LumClassIState:
switch (c)
{
case 'I':
state = LumClassIIState;
break;
case 'V':
lumClass = StellarClass::Lum_IV;
state = EndState;
break;
case 'a':
state = LumClassIaState;
break;
case 'b':
lumClass = StellarClass::Lum_Ib;
state = EndState;
break;
case '-':
state = LumClassIdashState;
break;
default:
lumClass = StellarClass::Lum_Ib;
state = EndState;
break;
}
i++;
break;
case LumClassIIState:
switch (c)
{
case 'I':
lumClass = StellarClass::Lum_III;
state = EndState;
break;
default:
lumClass = StellarClass::Lum_II;
state = EndState;
break;
}
break;
case LumClassIdashState:
switch (c)
{
case 'a':
state = LumClassIaState;
break;
case 'b':
lumClass = StellarClass::Lum_Ib;
state = EndState;
break;
default:
lumClass = StellarClass::Lum_Ib;
state = EndState;
break;
}
break;
case LumClassIaState:
switch (c)
{
case '0':
lumClass = StellarClass::Lum_Ia0;
state = EndState;
break;
default:
lumClass = StellarClass::Lum_Ia;
state = EndState;
break;
}
break;
case LumClassVState:
switch (c)
{
case 'I':
lumClass = StellarClass::Lum_VI;
state = EndState;
break;
default:
lumClass = StellarClass::Lum_V;
state = EndState;
break;
}
break;
case WDTypeState:
switch (c)
{
case 'A':
specClass = StellarClass::Spectral_DA;
i++;
break;
case 'B':
specClass = StellarClass::Spectral_DB;
i++;
break;
case 'C':
specClass = StellarClass::Spectral_DC;
i++;
break;
case 'O':
specClass = StellarClass::Spectral_DO;
i++;
break;
case 'Q':
specClass = StellarClass::Spectral_DQ;
i++;
break;
case 'Z':
specClass = StellarClass::Spectral_DZ;
i++;
break;
default:
specClass = StellarClass::Spectral_D;
break;
}
state = WDExtendedTypeState;
break;
case WDExtendedTypeState:
switch (c)
{
case 'A':
case 'B':
case 'C':
case 'O':
case 'Q':
case 'Z':
case 'V': // variable
case 'P': // magnetic stars with polarized light
case 'H': // magnetic stars without polarized light
case 'E': // emission lines
i++;
break;
default:
state = WDSubclassState;
break;
}
break;
case WDSubclassState:
if (isdigit(c))
{
subclass = (unsigned int) c - (unsigned int) '0';
i++;
}
state = EndState;
break;
default:
assert(0);
state = EndState;
break;
}
}
return StellarClass(type, specClass, number, lum);
return StellarClass(starType, specClass, subclass, lumClass);
}