00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
00063 inputFilename = string(argv[i]);
00064 fileCount++;
00065 }
00066 else if (fileCount == 1)
00067 {
00068
00069 outputFilename = string(argv[i]);
00070 fileCount++;
00071 }
00072 else
00073 {
00074
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
00123 out.write("CELSTARS", 8);
00124
00125
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
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 }