Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

makestardb.cpp

Go to the documentation of this file.
00001 // makestardb.cpp
00002 //
00003 // Copyright (C) 2004, Chris Laurel <claurel@shatters.net>
00004 //
00005 // This program is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU General Public License
00007 // as published by the Free Software Foundation; either version 2
00008 // of the License, or (at your option) any later version.
00009 //
00010 // Convert a file with ASCII star records to a Celestia star database
00011 
00012 #include <iostream>
00013 #include <fstream>
00014 #include <iomanip>
00015 #include <cctype>
00016 #include <cassert>
00017 #include <celutil/basictypes.h>
00018 #include <celutil/bytes.h>
00019 #include <celengine/astro.h>
00020 #include <celengine/star.h>
00021 
00022 using namespace std;
00023 
00024 
00025 static string inputFilename;
00026 static string outputFilename;
00027 static bool useSphericalCoords = false;
00028 
00029 
00030 void Usage()
00031 {
00032     cerr << "Usage: makestardb [options] <input file> <output star database>\n";
00033     cerr << "  Options:\n";
00034     cerr << "    --spherical (or -s) : input file has spherical coords (RA/dec/distance\n";
00035 }
00036 
00037 
00038 bool parseCommandLine(int argc, char* argv[])
00039 {
00040     int i = 1;
00041     int fileCount = 0;
00042 
00043     while (i < argc)
00044     {
00045         if (argv[i][0] == '-')
00046         {
00047             if (!strcmp(argv[i], "--spherical") || !strcmp(argv[i], "-s"))
00048             {
00049                 useSphericalCoords = true;
00050             }
00051             else
00052             {
00053                 cerr << "Unknown command line switch: " << argv[i] << '\n';
00054                 return false;
00055             }
00056             i++;
00057         }
00058         else
00059         {
00060             if (fileCount == 0)
00061             {
00062                 // input filename first
00063                 inputFilename = string(argv[i]);
00064                 fileCount++;
00065             }
00066             else if (fileCount == 1)
00067             {
00068                 // output filename second
00069                 outputFilename = string(argv[i]);
00070                 fileCount++;
00071             }
00072             else
00073             {
00074                 // more than two filenames on the command line is an error
00075                 return false;
00076             }
00077             i++;
00078         }
00079     }
00080 
00081     return true;
00082 }
00083 
00084 
00085 static void writeUint(ostream& out, uint32 n)
00086 {
00087     LE_TO_CPU_INT32(n, n);
00088     out.write(reinterpret_cast<char*>(&n), sizeof n);
00089 }
00090 
00091 static void writeFloat(ostream& out, float f)
00092 {
00093     LE_TO_CPU_FLOAT(f, f);
00094     out.write(reinterpret_cast<char*>(&f), sizeof f);
00095 }
00096 
00097 static void writeUshort(ostream& out, uint16 n)
00098 {
00099     LE_TO_CPU_INT16(n, n);
00100     out.write(reinterpret_cast<char*>(&n), sizeof n);
00101 }
00102 
00103 static void writeShort(ostream& out, int16 n)
00104 {
00105     LE_TO_CPU_INT16(n, n);
00106     out.write(reinterpret_cast<char*>(&n), sizeof n);
00107 }
00108 
00109 
00110 bool WriteStarDatabase(istream& in, ostream& out, bool sphericalCoords)
00111 {
00112     unsigned int record = 0;
00113     unsigned int nStarsInFile = 0;
00114 
00115     in >> nStarsInFile;
00116     if (!in.good())
00117     {
00118         cerr << "Error reading star count at beginning of input file.\n";
00119         return 1;
00120     }
00121 
00122     // Write the header
00123     out.write("CELSTARS", 8);
00124 
00125     // Write the version
00126     writeShort(out, 0x0100);
00127 
00128     writeUint(out, nStarsInFile);
00129 
00130     for (unsigned int record = 0; record < nStarsInFile; record++)
00131     {
00132         unsigned int catalogNumber;
00133         float x, y, z;
00134         float absMag;
00135 
00136         in >> catalogNumber;
00137         if (in.eof())
00138             return true;
00139 
00140         if (!in.good())
00141         {
00142             cerr << "Error parsing catalog number for record #" << record << '\n';
00143             return false;
00144         }
00145 
00146         if (sphericalCoords)
00147         {
00148             float RA, dec, distance;
00149             float appMag;
00150 
00151             in >> RA >> dec >> distance;
00152             if (!in.good())
00153             {
00154                 cerr << "Error parsing position of star " << catalogNumber << '\n';
00155                 return false;
00156             }
00157 
00158             in >> appMag;
00159             if (!in.good())
00160             {
00161                 cerr << "Error parsing magnitude of star " << catalogNumber << '\n';
00162                 return false;
00163             }
00164 
00165             Point3d pos =
00166                 astro::equatorialToCelestialCart((double) RA * 24.0 / 360.0,
00167                                                  (double) dec,
00168                                                  (double) distance);
00169             x = (float) pos.x;
00170             y = (float) pos.y;
00171             z = (float) pos.z;
00172             absMag = (float) (appMag + 5 - 5 * log10(distance / 3.26));
00173         }
00174         else
00175         {
00176             in >> x >> y >> z;
00177             if (!in.good())
00178             {
00179                 cerr << "Error parsing position of star " << catalogNumber << '\n';
00180                 return false;
00181             }
00182 
00183             in >> absMag;
00184             if (!in.good())
00185             {
00186                 cerr << "Error parsing magnitude of star " << catalogNumber << '\n';
00187                 return false;
00188             }
00189         }
00190 
00191         string scString;
00192         in >> scString;
00193         StellarClass sc = StellarClass::parse(scString);
00194 #if 0
00195         StarDetails* details = StarDetails::GetStarDetails(sc);
00196         if (details == NULL)
00197         {
00198             cerr << "Error parsing spectral type of star " << catalogNumber << '\n';
00199             return false;
00200         }
00201 
00202         // For spectral type parser debugging . . .
00203         cout << scString << ' ' << details->getSpectralType() << '\n';
00204 #endif
00205 
00206         writeUint(out, catalogNumber);
00207         writeFloat(out, x);
00208         writeFloat(out, y);
00209         writeFloat(out, z);
00210         writeShort(out, (int16) (absMag * 256.0f));
00211         writeUshort(out, sc.pack());
00212     }
00213 
00214     return true;
00215 }
00216 
00217 
00218 int main(int argc, char* argv[])
00219 {
00220     if (!parseCommandLine(argc, argv) || inputFilename.empty())
00221     {
00222         Usage();
00223         return 1;
00224     }
00225 
00226     ifstream inputFile(inputFilename.c_str(), ios::in);
00227     if (!inputFile.good())
00228     {
00229         cerr << "Error opening input file " << inputFilename << '\n';
00230         return 1;
00231     }
00232 
00233     ofstream stardbFile(outputFilename.c_str(), ios::out | ios::binary);
00234     if (!stardbFile.good())
00235     {
00236         cerr << "Error opening star database file " << outputFilename << '\n';
00237         return 1;
00238     }
00239 
00240     bool success = WriteStarDatabase(inputFile, stardbFile, useSphericalCoords);
00241 
00242     return success ? 0 : 1;
00243 }

Generated on Sat Jan 14 22:30:32 2006 for Celestia by  doxygen 1.4.1