starname.cpp
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:4k
源码类别:

OpenGL

开发平台:

Visual C++

  1. //
  2. // C++ Implementation: starname
  3. //
  4. // Description:
  5. //
  6. //
  7. // Author: Toti <root@totibox>, (C) 2005
  8. //
  9. // Copyright: See COPYING file that comes with this distribution
  10. //
  11. //
  12. #include <celengine/constellation.h>
  13. #include <celengine/starname.h>
  14. using namespace std;
  15. uint32 StarNameDatabase::findCatalogNumberByName(const string& name) const
  16. {
  17.     string priName   = name;
  18.     string altName;
  19.     // See if the name is a Bayer or Flamsteed designation
  20.     string::size_type pos  = name.find(' ');
  21.     if (pos != 0 && pos != string::npos && pos < name.length() - 1)
  22.     {
  23.         string prefix(name, 0, pos);
  24.         string conName(name, pos + 1, string::npos);
  25.         Constellation* con  = Constellation::getConstellation(conName);
  26.         if (con != NULL)
  27.         {
  28.             char digit  = ' ';
  29.             int len     = prefix.length();
  30.             // If the first character of the prefix is a letter
  31.             // and the last character is a digit, we may have
  32.             // something like 'Alpha2 Cen' . . . Extract the digit
  33.             // before trying to match a Greek letter.
  34.             if (len > 2 && isalpha(prefix[0]) && isdigit(prefix[len - 1]))
  35.             {
  36.                 --len;
  37.                 digit   = prefix[len];
  38.             }
  39.             // We have a valid constellation as the last part
  40.             // of the name.  Next, we see if the first part of
  41.             // the name is a greek letter.
  42.             const string& letter = Greek::canonicalAbbreviation(string(prefix, 0, len));
  43.             if (letter != "")
  44.             {
  45.                 // Matched . . . this is a Bayer designation
  46.                 if (digit == ' ')
  47.                 {
  48.                     priName  = letter + ' ' + con->getAbbreviation();
  49.                     // If 'let con' doesn't match, try using
  50.                     // 'let1 con' instead.
  51.                     altName  = letter + '1' + ' ' + con->getAbbreviation();
  52.                 }
  53.                 else
  54.                 {
  55.                     priName  = letter + digit + ' ' + con->getAbbreviation();
  56.                 }
  57.             }
  58.             else
  59.             {
  60.                 // Something other than a Bayer designation
  61.                 priName  = prefix + ' ' + con->getAbbreviation();
  62.             }
  63.         }
  64.     }
  65.     uint32 catalogNumber   = getCatalogNumberByName(priName);
  66.     if (catalogNumber != Star::InvalidCatalogNumber)
  67.         return catalogNumber;
  68.     priName        += " A";  // try by appending an A
  69.     catalogNumber   = getCatalogNumberByName(priName);
  70.     if (catalogNumber != Star::InvalidCatalogNumber)
  71.         return catalogNumber;
  72.     // If the first search failed, try using the alternate name
  73.     if (altName.length() != 0)
  74.     {
  75.         catalogNumber   = getCatalogNumberByName(altName);
  76.         if (catalogNumber == Star::InvalidCatalogNumber)
  77.         {
  78.             altName        += " A";
  79.             catalogNumber   = getCatalogNumberByName(altName);
  80.         }   // Intentional fallthrough.
  81.     }
  82.     return catalogNumber;
  83. }
  84. StarNameDatabase* StarNameDatabase::readNames(istream& in)
  85. {
  86.     StarNameDatabase* db = new StarNameDatabase();
  87.     bool failed = false;
  88.     string s;
  89.     while (!failed)
  90.     {
  91.         uint32 catalogNumber = Star::InvalidCatalogNumber;
  92. in >> catalogNumber;
  93. if (in.eof())
  94.     break;
  95. if (in.bad())
  96.         {
  97.     failed = true;
  98.     break;
  99. }
  100.         // in.get(); // skip a space (or colon);
  101.         string name;
  102.         getline(in, name);
  103.         if (in.bad())
  104.         {
  105.             failed = true;
  106.             break;
  107.         }
  108.         // Iterate through the string for names delimited
  109.         // by ':', and insert them into the star database. Note that
  110.         // db->add() will skip empty names.
  111.         string::size_type startPos = 0; 
  112.         while (startPos != string::npos)
  113.         {
  114.             ++startPos;
  115.             string::size_type next = name.find(':', startPos);
  116.             string::size_type length = string::npos;
  117.             if (next != string::npos)
  118.                 length = next - startPos;
  119.             db->add(catalogNumber, name.substr(startPos, length));
  120.             startPos = next;
  121.         }
  122.     }
  123.     if (failed)
  124.     {
  125.         delete db;
  126.         return NULL;
  127.     }
  128.     else
  129.     {
  130.         return db;
  131.     }
  132. }