7#include "asteroidscomponent.h"
13#include "ksfilereader.h"
14#include "kstarsdata.h"
15#include "kstars_debug.h"
17#include "solarsystemcomposite.h"
18#include "skycomponent.h"
19#include "skylabeler.h"
23#include "kstarslite.h"
25#include "skypainter.h"
26#include "auxiliary/kspaths.h"
27#include "auxiliary/ksnotification.h"
28#include "auxiliary/filedownloader.h"
29#include "projections/projector.h"
31#include <KLocalizedString>
34#include <QStandardPaths>
35#include <QHttpMultiPart>
48 return Options::showAsteroids();
81void AsteroidsComponent::loadDataFromText()
84 objectNames(SkyObject::ASTEROID).
clear();
85 objectLists(SkyObject::ASTEROID).
clear();
87 QString name, full_name, orbit_id, orbit_class, dimensions;
89 double q, a, e, dble_i, dble_w, dble_N, dble_M, H, G, earth_moid;
91 float diameter, albedo, rot_period, period;
95 qCInfo(KSTARS) <<
"Loading asteroids";
99 KSUtils::JPLParser ast_parser(filepath_txt);
100 auto fieldMap = ast_parser.fieldMap();
101 bool isString = fieldMap.count(
"epoch_mjd") == 1;
104 [&](
const auto & get)
106 full_name = get(
"full_name").toString();
107 full_name = full_name.
trimmed();
109 name = full_name.
section(
' ', 1, -1);
112 if (name ==
i18nc(
"Asteroid name (optional)",
"Europa") ||
113 name ==
i18nc(
"Asteroid name (optional)",
"Io") ||
114 name ==
i18nc(
"Asteroid name (optional)",
"Asterope"))
115 name +=
i18n(
" (Asteroid)");
121 mJD = get(
"epoch_mjd").toString().toInt();
122 period = get(
"per_y").toString().toDouble();
127 mJD =
get(
"epoch.mjd").toInt();
128 period =
get(
"per.y").toDouble();
131 q =
get(
"q").toString().toDouble();
132 a =
get(
"a").toString().toDouble();
133 e =
get(
"e").toString().toDouble();
134 dble_i =
get(
"i").toString().toDouble();
135 dble_w =
get(
"w").toString().toDouble();
136 dble_N =
get(
"om").toString().toDouble();
137 dble_M =
get(
"ma").toString().toDouble();
138 orbit_id =
get(
"orbit_id").toString();
139 H =
get(
"H").toString().toDouble();
140 G =
get(
"G").toString().toDouble();
141 neo =
get(
"neo").toString() ==
"Y";
142 diameter =
get(
"diameter").toString().toFloat();
143 dimensions =
get(
"extent").toString();
144 albedo =
get(
"albedo").toString().toFloat();
145 rot_period =
get(
"rot_per").toString().toFloat();
146 earth_moid =
get(
"moid").toString().toDouble();
147 orbit_class =
get(
"class").toString();
149 JD =
static_cast<double>(mJD) + 2400000.5;
154 if (name ==
i18nc(
"Asteroid name (optional)",
"Pluto"))
159 dms(dble_w),
dms(dble_N),
dms(dble_M), H, G);
163 new_asteroid->
setNEO(neo);
177 objectNames(SkyObject::ASTEROID).append(name);
178 objectLists(SkyObject::ASTEROID)
179 .append(QPair<QString, const SkyObject *>(name, new_asteroid));
182 catch (
const std::runtime_error &e)
184 qCInfo(KSTARS) <<
"Loading asteroid objects failed.";
185 qCInfo(KSTARS) <<
" -> was trying to read " + filepath_txt;
197 bool hideLabels = !Options::showAsteroidNames() || (SkyMap::Instance()->isSlewing() && Options::hideLabels());
199 double labelMagLimit = Options::asteroidLabelDensity();
200 const double showMagLimit = Options::magLimitAsteroid();
201 const double lgmin = log10(MINZOOM);
202 const double lgmax = log10(MAXZOOM);
203 const double lgz = log10(Options::zoomFactor());
204 const double densityLabelFactor = 10.0;
206 const double zoomLimit = (lgz - lgmin) / (lgmax - lgmin);
209 labelMagLimit = std::max(1e-3, labelMagLimit) / densityLabelFactor;
213 labelMagLimit = showMagLimit - 20.0 / densityLabelFactor + std::max(zoomLimit, labelMagLimit);
219 if (!ast->
toDraw() || std::isnan(ast->
mag()) || ast->
mag() > showMagLimit)
229 if (drawn && !hideLabels && ast->
mag() <= labelMagLimit)
242 for (
auto o : m_ObjectList)
244 if (!((
dynamic_cast<KSAsteroid*
>(o)->toDraw())))
247 double r = o->angularDistanceTo(p).Degrees();
258void AsteroidsComponent::updateDataFile(
bool isAutoUpdate)
260 delete (downloadJob);
261 downloadJob =
new FileDownloader();
263 if (isAutoUpdate ==
false)
264 downloadJob->setProgressDialogEnabled(
true,
i18n(
"Asteroid Update"),
265 i18n(
"Downloading asteroids updates..."));
266 downloadJob->registerDataVerification([&](
const QByteArray & data)
271 QObject::connect(downloadJob, SIGNAL(downloaded()),
this, SLOT(downloadReady()));
272 if (isAutoUpdate ==
false)
276 QUrl url =
QUrl(
"https://ssd-api.jpl.nasa.gov/sbdb_query.api");
280 KSUtils::getJPLQueryString(
"a",
281 "full_name,neo,H,G,diameter,extent,albedo,rot_per,"
282 "orbit_id,epoch_mjd,e,a,q,i,om,w,ma,per_y,moid,class",
284 downloadJob->post(url, post_data);
287void AsteroidsComponent::downloadReady()
290 QByteArray data = downloadJob->downloadedData();
294 .filePath(
"asteroids.dat"));
301 qCWarning(KSTARS) <<
"Failed writing asteroid data to" << file.fileName();
307 if (foc && foc->
type() == SkyObject::ASTEROID)
309 focusedAstroid = foc->
name();
314 if (foc && foc->
type() == SkyObject::ASTEROID)
316 focusedAstroid = foc->
name();
335 downloadJob->deleteLater();
338void AsteroidsComponent::downloadError(
const QString &errorString)
340 KSNotification::error(
i18n(
"Error downloading asteroids data: %1", errorString));
341 qDebug() << Q_FUNC_INFO <<
i18n(
"Error downloading asteroids data: %1", errorString);
342 downloadJob->deleteLater();
AsteroidsComponent(SolarSystemComposite *parent)
Default constructor.
void draw(SkyPainter *skyp) override
Draw the object on the SkyMap skyp a pointer to the SkyPainter to use.
SkyObject * objectNearest(SkyPoint *p, double &maxrad) override
Find the SkyObject nearest the given SkyPoint.
provides functionality for loading the component data from Binary
A subclass of KSPlanetBase that implements asteroids.
void setPerihelion(double perihelion)
Sets the asteroid's perihelion distance.
void setPeriod(float per)
Sets the asteroid's period.
void setDiameter(float diam)
Sets the asteroid's diameter.
void setDimensions(QString dim)
Sets the asteroid's dimensions.
void setEarthMOID(double earth_moid)
Sets the asteroid's earth minimum orbit intersection distance.
void setNEO(bool neo)
Sets if the comet is a near earth object.
void setOrbitID(QString orbit_id)
Sets the asteroid's orbit solution ID.
void setAlbedo(float albedo)
Sets the asteroid's albedo.
void setRotationPeriod(float rot_per)
Sets the asteroid's rotation period.
void setOrbitClass(QString orbit_class)
Sets the asteroid's orbit class.
void setPhysicalSize(double size)
set the planet's physical size, in km.
const QImage & image() const
void setFullTimeUpdate()
The Sky is updated more frequently than the moon, which is updated more frequently than the planets.
static KStarsLite * Instance()
KStarsData * data() const
static KStars * Instance()
KStarsData * data() const
void appendListObject(SkyObject *object)
Add an object to the Object list.
virtual void emitProgressText(const QString &message)
Emit signal about progress.
static void AddLabel(SkyObject *obj, label_t type)
static version of addLabel() below.
void setFocusObject(SkyObject *o)
Set the FocusObject pointer to the argument.
SkyObject * focusObject() const
Retrieve the object which is centered in the sky map.
void setFocusObject(SkyObject *o)
Set the FocusObject pointer to the argument.
SkyObject * focusObject() const
Retrieve the object which is centered in the sky map.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
virtual QString name(void) const
Draws things on the sky, without regard to backend.
virtual bool drawPlanet(KSPlanetBase *planet)=0
Draw a planet.
virtual bool drawAsteroid(KSAsteroid *ast)=0
Draw an asteroid in the sky.
The sky coordinates of a point in the sky.
The solar system composite manages all planets, asteroids and comets.
An angle, stored as degrees, but expressible in many ways.
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
KIOCORE_EXPORT TransferJob * get(const QUrl &url, LoadType reload=NoReload, JobFlags flags=DefaultFlags)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
bool startsWith(QByteArrayView bv) const const
bool isNull() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool isEmpty() const const
QString number(double n, char format, int precision)
QString section(QChar sep, qsizetype start, qsizetype end, SectionFlags flags) const const
int toInt(bool *ok, int base) const const
QByteArray toUtf8() const const
QString trimmed() const const