14
#include "buildPlanetMap.h"
17
#include "PlanetProperties.h"
18
#include "readOriginFile.h"
21
#include "libannotate/libannotate.h"
22
#include "libdisplay/libdisplay.h"
23
#include "libdisplay/libtimer.h"
24
#include "libplanet/Planet.h"
27
drawMultipleBodies(DisplayBase *display, Planet *target,
28
map<double, Planet *> &planetsFromSunMap,
29
PlanetProperties *planetProperties[]);
32
drawProjection(DisplayBase *display, Planet *target,
33
map<double, Planet *> &planetsFromSunMap,
34
PlanetProperties *planetProperties);
37
readConfigFile(string configFile, PlanetProperties *planetProperties[]);
40
main(int argc, char **argv)
42
if (setlocale(LC_ALL, "") == NULL)
45
errMsg << "Warning: setlocale(LC_ALL, \"\") failed! "
46
<< "Check your LANG environment variable "
48
char *lang = getenv("LANG");
55
errMsg << "\"" << lang << "\"";
57
errMsg << "). Setting to \"C\".\n";
58
setlocale(LC_ALL, "C");
62
Options *options = Options::getInstance();
63
options->parseArgs(argc, argv);
65
PlanetProperties *planetProperties[RANDOM_BODY];
66
for (int i = 0; i < RANDOM_BODY; i++)
67
planetProperties[i] = new PlanetProperties((body) i);
69
// Load the drawing info for each planet
70
readConfigFile(options->ConfigFile(), planetProperties);
73
// Load any SPICE kernels
77
// Load artificial satellite orbital elements
78
if (!planetProperties[EARTH]->SatelliteFiles().empty())
79
loadSatelliteVector(planetProperties[EARTH]);
81
// If an origin file has been specified, read it
82
const bool origin_file = !options->OriginFile().empty();
83
vector<LBRPoint> originVector;
86
readOriginFile(options->OriginFile(), originVector);
87
if (!options->InterpolateOriginFile())
88
options->NumTimes(originVector.size());
91
vector<LBRPoint>::iterator iterOriginVector = originVector.begin();
93
// Initialize the timer
94
Timer *timer = getTimer(options->getWait(), options->Hibernate(),
101
// Set the time for the next update
104
if (!options->PrevCommand().empty())
106
if (system(options->PrevCommand().c_str()) != 0)
108
ostringstream errStr;
109
errStr << "Can't execute " << options->PrevCommand()
111
xpWarn(errStr.str(), __FILE__, __LINE__);
115
// Set the time to the current time, if desired
116
if (options->UseCurrentTime())
119
gettimeofday(&time, NULL);
121
time_t t = time.tv_sec;
122
const double julianDay = toJulian(gmtime(static_cast<time_t *> (&t))->tm_year + 1900,
123
gmtime(static_cast<time_t *> (&t))->tm_mon + 1,
124
gmtime(static_cast<time_t *> (&t))->tm_mday,
125
gmtime(static_cast<time_t *> (&t))->tm_hour,
126
gmtime(static_cast<time_t *> (&t))->tm_min,
127
gmtime(static_cast<time_t *> (&t))->tm_sec);
128
options->setTime(julianDay);
133
if (options->InterpolateOriginFile())
135
// interpolate positions in the origin file to the
137
double thisRad, thisLat, thisLon, thisLocalTime = -1;
138
interpolateOriginFile(options->getJulianDay(),
139
originVector, thisRad,
140
thisLat, thisLon, thisLocalTime);
141
options->setRange(thisRad);
142
options->Latitude(thisLat);
143
options->Longitude(thisLon);
144
options->LocalTime(thisLocalTime);
148
// Use the next time and position in the origin file
149
options->setTime(iterOriginVector->time);
150
options->setRange(iterOriginVector->radius);
151
options->Latitude(iterOriginVector->latitude);
152
options->Longitude(iterOriginVector->longitude);
153
options->LocalTime(iterOriginVector->localTime);
157
if (!options->DynamicOrigin().empty())
159
LBRPoint originPoint;
160
readDynamicOrigin(options->DynamicOrigin(), originPoint);
161
options->setRange(originPoint.radius);
162
options->Latitude(originPoint.latitude);
163
options->Longitude(originPoint.longitude);
164
options->LocalTime(originPoint.localTime);
167
options->setTarget(planetProperties);
168
options->setOrigin(planetProperties);
170
// Rectangular coordinates of the observer
172
options->getOrigin(oX, oY, oZ);
174
// Calculate the positions of the planets & moons. The map
175
// container sorts on the key, so the bodies will be ordered
176
// by heliocentric distance. This makes calculating shadows
178
map<double, Planet *> planetsFromSunMap;
179
buildPlanetMap(options->getJulianDay(), oX, oY, oZ,
180
options->LightTime(), planetsFromSunMap);
182
// Find the target body in the list
183
body target_body = options->getTarget();
184
Planet *target = findPlanetinMap(planetsFromSunMap, target_body);
186
// LOOKAT mode is where the target isn't a planetary body.
187
// (e.g. the Cassini spacecraft)
188
if (options->TargetMode() == LOOKAT)
190
if (options->LightTime()) options->setTarget(planetProperties);
195
xpExit("Can't find target body?\n", __FILE__, __LINE__);
197
if (options->LightTime())
200
target->getPosition(tX, tY, tZ);
201
options->setTarget(tX, tY, tZ);
204
// Find the sub-observer lat & lon
205
double obs_lat, obs_lon;
206
target->XYZToPlanetographic(oX, oY, oZ, obs_lat, obs_lon);
207
options->Latitude(obs_lat);
208
options->Longitude(obs_lon);
210
// Find the sub-solar lat & lon. This is used for the image
212
double sunLat, sunLon;
213
target->XYZToPlanetographic(0, 0, 0, sunLat, sunLon);
214
options->SunLat(sunLat);
215
options->SunLon(sunLon);
218
// delete the markerbounds file, since we'll create a new one
219
string markerBounds(options->MarkerBounds());
220
if (!markerBounds.empty())
221
unlinkFile(markerBounds.c_str());
223
// Initialize display device
224
DisplayBase *display = getDisplay(times_run);
226
if (options->ProjectionMode() == MULTIPLE)
228
drawMultipleBodies(display, target, planetsFromSunMap,
233
drawProjection(display, target, planetsFromSunMap,
234
planetProperties[target->Index()]);
237
display->renderImage(planetProperties);
244
if (!options->PostCommand().empty())
246
if (system(options->PostCommand().c_str()) != 0)
248
ostringstream errStr;
249
errStr << "Can't execute " << options->PostCommand()
251
xpWarn(errStr.str(), __FILE__, __LINE__);
255
if (options->NumTimes() > 0 && times_run >= options->NumTimes())
258
if (origin_file && !options->InterpolateOriginFile())
260
// If we've run through the origin file, break out of the
263
if (iterOriginVector == originVector.end()) break;
266
if (!options->UseCurrentTime())
268
// Set the time to the next update
269
options->incrementTime((time_t) (options->getTimeWarp()
270
* options->getWait()));
273
// Sleep until the next update. If Sleep() returns false,
275
if (!timer->Sleep()) break;
280
for (int i = 0; i < RANDOM_BODY; i++) delete planetProperties[i];
282
return(EXIT_SUCCESS);