00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <iostream>
00019
00020 #include <kglobal.h>
00021 #include <kstandarddirs.h>
00022 #include <qpoint.h>
00023 #include <qregexp.h>
00024 #include <qfile.h>
00025 #include <qtextstream.h>
00026
00027 #include "skyobject.h"
00028 #include "starobject.h"
00029 #include "ksnumbers.h"
00030 #include "dms.h"
00031 #include "geolocation.h"
00032 #include "kstarsdatetime.h"
00033
00034 QString SkyObject::emptyString = QString("");
00035 QString SkyObject::unnamedString = QString(i18n("unnamed"));
00036 QString SkyObject::unnamedObjectString = QString(i18n("unnamed object"));
00037 QString SkyObject::starString = QString("star");
00038
00039 SkyObject::SkyObject( SkyObject &o ) : SkyPoint( o ) {
00040 setType( o.type() );
00041 Magnitude = o.mag();
00042 setName(o.name());
00043 setName2(o.name2());
00044 setLongName(o.longname());
00045 ImageList = o.ImageList;
00046 ImageTitle = o.ImageTitle;
00047 InfoList = o.InfoList;
00048 InfoTitle = o.InfoTitle;
00049 }
00050
00051 SkyObject::SkyObject( int t, dms r, dms d, float m,
00052 QString n, QString n2, QString lname ) : SkyPoint( r, d) {
00053 setType( t );
00054 Magnitude = m;
00055 Name = 0;
00056 setName(n);
00057 Name2 = 0;
00058 setName2(n2);
00059 LongName = 0;
00060 setLongName(lname);
00061 }
00062
00063 SkyObject::SkyObject( int t, double r, double d, float m,
00064 QString n, QString n2, QString lname ) : SkyPoint( r, d) {
00065 setType( t );
00066 Magnitude = m;
00067 Name = 0;
00068 setName(n);
00069 Name2 = 0;
00070 setName2(n2);
00071 LongName = 0;
00072 setLongName(lname);
00073 }
00074
00075 SkyObject::~SkyObject() {
00076 delete Name;
00077 delete Name2;
00078 delete LongName;
00079 }
00080
00081 void SkyObject::setLongName( const QString &longname ) {
00082 delete LongName;
00083 if ( longname.isEmpty() ) {
00084 if ( hasName() )
00085 LongName = new QString(translatedName());
00086 else if ( hasName2() )
00087 LongName = new QString(*Name2);
00088 else
00089 LongName = 0;
00090 } else {
00091 LongName = new QString(longname);
00092 }
00093 }
00094
00095 QTime SkyObject::riseSetTime( const KStarsDateTime &dt, const GeoLocation *geo, bool rst ) {
00096
00097 if ( checkCircumpolar(geo->lat()) )
00098 return QTime( 25, 0, 0 );
00099
00100
00101
00102 KStarsDateTime dt2 = dt;
00103 SkyPoint p = recomputeCoords( dt, geo );
00104 p.EquatorialToHorizontal( &(geo->GSTtoLST( dt.gst() )), geo->lat() );
00105 if ( p.alt()->Degrees() < 0.0 ) {
00106 if ( p.az()->Degrees() < 180.0 ) {
00107 dt2 = dt.addSecs( 12.*3600. );
00108 } else {
00109 dt2 = dt.addSecs( -12.*3600. );
00110 }
00111 }
00112
00113 return geo->UTtoLT( KStarsDateTime( dt2.date(), riseSetTimeUT( dt2, geo, rst ) ) ).time();
00114 }
00115
00116 QTime SkyObject::riseSetTimeUT( const KStarsDateTime &dt, const GeoLocation *geo, bool riseT ) {
00117
00118 QTime UT = auxRiseSetTimeUT( dt, geo, ra(), dec(), riseT );
00119
00120
00121
00122
00123 KStarsDateTime dt0 = dt;
00124 dt0.setTime( UT );
00125 if ( riseT && dt0 > dt ) {
00126 dt0 = dt0.addDays( -1 );
00127 } else if ( ! riseT && dt0 < dt ) {
00128 dt0 = dt0.addDays( 1 );
00129 }
00130
00131 SkyPoint sp = recomputeCoords( dt0, geo );
00132 UT = auxRiseSetTimeUT( dt0, geo, sp.ra(), sp.dec(), riseT );
00133
00134
00135
00136 dt0.setTime( UT );
00137 sp = recomputeCoords( dt0, geo );
00138 UT = auxRiseSetTimeUT( dt0, geo, sp.ra(), sp.dec(), riseT );
00139 return UT;
00140 }
00141
00142 dms SkyObject::riseSetTimeLST( const KStarsDateTime &dt, const GeoLocation *geo, bool riseT ) {
00143 KStarsDateTime rst( dt.date(), riseSetTimeUT( dt, geo, riseT) );
00144 return geo->GSTtoLST( rst.gst() );
00145 }
00146
00147 QTime SkyObject::auxRiseSetTimeUT( const KStarsDateTime &dt, const GeoLocation *geo,
00148 const dms *righta, const dms *decl, bool riseT) {
00149 dms LST = auxRiseSetTimeLST( geo->lat(), righta, decl, riseT );
00150 return dt.GSTtoUT( geo->LSTtoGST( LST ) );
00151 }
00152
00153 dms SkyObject::auxRiseSetTimeLST( const dms *gLat, const dms *righta, const dms *decl, bool riseT ) {
00154 dms h0 = elevationCorrection();
00155 double H = approxHourAngle ( &h0, gLat, decl );
00156 dms LST;
00157
00158 if ( riseT )
00159 LST.setH( 24.0 + righta->Hours() - H/15.0 );
00160 else
00161 LST.setH( righta->Hours() + H/15.0 );
00162
00163 return LST.reduce();
00164 }
00165
00166
00167 dms SkyObject::riseSetTimeAz( const KStarsDateTime &dt, const GeoLocation *geo, bool riseT ) {
00168 dms Azimuth;
00169 double AltRad, AzRad;
00170 double sindec, cosdec, sinlat, coslat, sinHA, cosHA;
00171 double sinAlt, cosAlt;
00172
00173 QTime UT = riseSetTimeUT( dt, geo, riseT );
00174 KStarsDateTime dt0 = dt;
00175 dt0.setTime( UT );
00176 SkyPoint sp = recomputeCoords( dt0, geo );
00177 const dms *ram = sp.ra0();
00178 const dms *decm = sp.dec0();
00179
00180 dms LST = auxRiseSetTimeLST( geo->lat(), ram, decm, riseT );
00181 dms HourAngle = dms( LST.Degrees() - ram->Degrees() );
00182
00183 geo->lat()->SinCos( sinlat, coslat );
00184 dec()->SinCos( sindec, cosdec );
00185 HourAngle.SinCos( sinHA, cosHA );
00186
00187 sinAlt = sindec*sinlat + cosdec*coslat*cosHA;
00188 AltRad = asin( sinAlt );
00189 cosAlt = cos( AltRad );
00190
00191 AzRad = acos( ( sindec - sinlat*sinAlt )/( coslat*cosAlt ) );
00192 if ( sinHA > 0.0 ) AzRad = 2.0*dms::PI - AzRad;
00193 Azimuth.setRadians( AzRad );
00194
00195 return Azimuth;
00196 }
00197
00198 QTime SkyObject::transitTimeUT( const KStarsDateTime &dt, const GeoLocation *geo ) {
00199 dms LST = geo->GSTtoLST( dt.gst() );
00200
00201
00202 dms HourAngle = dms( LST.Degrees() - ra()->Degrees() );
00203 int dSec = int( -3600.*HourAngle.Hours() );
00204
00205
00206 KStarsDateTime dt0 = dt.addSecs( dSec );
00207
00208
00209
00210 SkyPoint sp = recomputeCoords( dt0, geo );
00211 const dms *ram = sp.ra0();
00212
00213 HourAngle = dms ( LST.Degrees() - ram->Degrees() );
00214 dSec = int( -3600.*HourAngle.Hours() );
00215
00216 return dt.addSecs( dSec ).time();
00217 }
00218
00219 QTime SkyObject::transitTime( const KStarsDateTime &dt, const GeoLocation *geo ) {
00220 return geo->UTtoLT( KStarsDateTime( dt.date(), transitTimeUT( dt, geo ) ) ).time();
00221 }
00222
00223 dms SkyObject::transitAltitude( const KStarsDateTime &dt, const GeoLocation *geo ) {
00224 KStarsDateTime dt0 = dt;
00225 QTime UT = transitTimeUT( dt, geo );
00226 dt0.setTime( UT );
00227 SkyPoint sp = recomputeCoords( dt0, geo );
00228 const dms *decm = sp.dec0();
00229
00230 dms delta;
00231 delta.setRadians( asin ( sin (geo->lat()->radians()) *
00232 sin ( decm->radians() ) +
00233 cos (geo->lat()->radians()) *
00234 cos (decm->radians() ) ) );
00235
00236 return delta;
00237 }
00238
00239 double SkyObject::approxHourAngle( const dms *h0, const dms *gLat, const dms *dec ) {
00240
00241 double sh0 = sin ( h0->radians() );
00242 double r = (sh0 - sin( gLat->radians() ) * sin(dec->radians() ))
00243 / (cos( gLat->radians() ) * cos( dec->radians() ) );
00244
00245 double H = acos( r )/dms::DegToRad;
00246
00247 return H;
00248 }
00249
00250 dms SkyObject::elevationCorrection(void) {
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 if ( name() == "Sun" || name() == "Moon" )
00272 return dms(-0.8333);
00273
00274
00275 else
00276 return dms(-0.5667);
00277 }
00278
00279 SkyPoint SkyObject::recomputeCoords( const KStarsDateTime &dt, const GeoLocation *geo ) {
00280
00281 SkyPoint original( ra(), dec() );
00282
00283
00284 KSNumbers num( dt.djd() );
00285 if ( isSolarSystem() && geo ) {
00286 dms LST = geo->GSTtoLST( dt.gst() );
00287 updateCoords( &num, true, geo->lat(), &LST );
00288 } else {
00289 updateCoords( &num );
00290 }
00291
00292
00293 SkyPoint sp = SkyPoint( ra(), dec() );
00294
00295
00296 setRA( original.ra()->Hours() );
00297 setDec( original.dec()->Degrees() );
00298
00299 return sp;
00300 }
00301
00302 bool SkyObject::checkCircumpolar( const dms *gLat ) {
00303 double r = -1.0 * tan( gLat->radians() ) * tan( dec()->radians() );
00304 if ( r < -1.0 || r > 1.0 )
00305 return true;
00306 else
00307 return false;
00308 }
00309
00310 QString SkyObject::typeName( void ) const {
00311 if ( Type==0 ) return i18n( "Star" );
00312 else if ( Type==1 ) return i18n( "Catalog Star" );
00313 else if ( Type==2 ) return i18n( "Planet" );
00314 else if ( Type==3 ) return i18n( "Open Cluster" );
00315 else if ( Type==4 ) return i18n( "Globular Cluster" );
00316 else if ( Type==5 ) return i18n( "Gaseous Nebula" );
00317 else if ( Type==6 ) return i18n( "Planetary Nebula" );
00318 else if ( Type==7 ) return i18n( "Supernova Remnant" );
00319 else if ( Type==8 ) return i18n( "Galaxy" );
00320 else if ( Type==9 ) return i18n( "Comet" );
00321 else if ( Type==10 ) return i18n( "Asteroid" );
00322 else return i18n( "Unknown Type" );
00323 }
00324 void SkyObject::setName( const QString &name ) {
00325
00326 delete Name;
00327 if (!name.isEmpty())
00328 Name = new QString(name);
00329 else
00330 { Name = 0; }
00331 }
00332
00333 void SkyObject::setName2( const QString &name2 ) {
00334 delete Name2;
00335 if (!name2.isEmpty())
00336 Name2 = new QString(name2);
00337 else
00338 { Name2 = 0; }
00339 }
00340
00341 QString SkyObject::messageFromTitle( const QString &imageTitle ) {
00342 QString message = imageTitle;
00343
00344
00345 if ( imageTitle == i18n( "Show HST Image" ) || imageTitle.contains("HST") ) {
00346 message = i18n( "%1: Hubble Space Telescope, operated by STScI for NASA [public domain]" ).arg( longname() );
00347
00348
00349 } else if ( imageTitle.contains( i18n( "Show Spitzer Image" ) ) ) {
00350 message = i18n( "%1: Spitzer Space Telescope, courtesy NASA/JPL-Caltech [public domain]" ).arg( longname() );
00351
00352
00353 } else if ( imageTitle == i18n( "Show SEDS Image" ) ) {
00354 message = i18n( "%1: SEDS, http://www.seds.org [free for non-commercial use]" ).arg( longname() );
00355
00356
00357 } else if ( imageTitle == i18n( "Show KPNO AOP Image" ) ) {
00358 message = i18n( "%1: Advanced Observing Program at Kitt Peak National Observatory [free for non-commercial use; no physical reproductions]" ).arg( longname() );
00359
00360
00361 } else if ( imageTitle.contains( i18n( "Show NOAO Image" ) ) ) {
00362 message = i18n( "%1: National Optical Astronomy Observatories and AURA [free for non-commercial use]" ).arg( longname() );
00363
00364
00365 } else if ( imageTitle.contains( "VLT" ) ) {
00366 message = i18n( "%1: Very Large Telescope, operated by the European Southern Observatory [free for non-commercial use; no reproductions]" ).arg( longname() );
00367
00368
00369 } else if ( imageTitle.startsWith( i18n( "Show" ) ) ) {
00370 message = imageTitle.mid( imageTitle.find( " " ) + 1 );
00371 message = longname() + ": " + message;
00372 }
00373
00374 return message;
00375 }
00376
00377
00378
00379
00380 void SkyObject::saveUserLog( const QString &newLog ) {
00381 QFile file;
00382 QString logs;
00383
00384
00385
00386 if ( newLog == (i18n("Record here observation logs and/or data on %1.").arg(name())) || newLog.isEmpty() )
00387 return;
00388
00389
00390 QString KSLabel ="[KSLABEL:" + name() + "]";
00391
00392 if ( type() == STAR ) {
00393 StarObject *star = (StarObject*)this;
00394 if ( name() == star->gname() )
00395 KSLabel = "[KSLABEL:" + star->gname( false ) + "]";
00396 }
00397
00398 file.setName( locateLocal( "appdata", "userlog.dat" ) );
00399 if ( file.open( IO_ReadOnly)) {
00400 QTextStream instream(&file);
00401
00402 logs = instream.read();
00403 file.close();
00404 }
00405
00406
00407 if ( ! userLog.isEmpty() ) {
00408 int startIndex, endIndex;
00409 QString sub;
00410
00411 startIndex = logs.find(KSLabel);
00412 sub = logs.mid (startIndex);
00413 endIndex = sub.find("[KSLogEnd]");
00414
00415 logs.remove(startIndex, endIndex + 11);
00416 }
00417
00418
00419
00420 if ( ! newLog.stripWhiteSpace().isEmpty() )
00421 logs.append( KSLabel + "\n" + newLog + "\n[KSLogEnd]\n" );
00422
00423
00424
00425 if ( !file.open( IO_WriteOnly ) ) {
00426 kdDebug() << i18n( "user log file could not be opened." ) << endl;
00427 return;
00428 }
00429
00430
00431 QTextStream outstream(&file);
00432 outstream << logs;
00433
00434
00435 userLog = newLog;
00436
00437 file.close();
00438 }