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()
83 QString name, full_name, orbit_id, orbit_class, dimensions;
85 double q, a, e, dble_i, dble_w, dble_N, dble_M, H, G, earth_moid;
87 float diameter, albedo, rot_period, period;
91 qCInfo(KSTARS) <<
"Loading asteroids";
95 KSUtils::JPLParser ast_parser(filepath_txt);
96 auto fieldMap = ast_parser.fieldMap();
97 bool isString = fieldMap.count(
"epoch_mjd") == 1;
100 [&](
const auto & get)
102 full_name = get(
"full_name").toString();
103 full_name = full_name.
trimmed();
105 name = full_name.
section(
' ', 1, -1);
108 if (name ==
i18nc(
"Asteroid name (optional)",
"Europa") ||
109 name ==
i18nc(
"Asteroid name (optional)",
"Io") ||
110 name ==
i18nc(
"Asteroid name (optional)",
"Asterope"))
111 name +=
i18n(
" (Asteroid)");
117 mJD = get(
"epoch_mjd").toString().toInt();
118 period = get(
"per_y").toString().toDouble();
123 mJD =
get(
"epoch.mjd").toInt();
124 period =
get(
"per.y").toDouble();
127 q =
get(
"q").toString().toDouble();
128 a =
get(
"a").toString().toDouble();
129 e =
get(
"e").toString().toDouble();
130 dble_i =
get(
"i").toString().toDouble();
131 dble_w =
get(
"w").toString().toDouble();
132 dble_N =
get(
"om").toString().toDouble();
133 dble_M =
get(
"ma").toString().toDouble();
134 orbit_id =
get(
"orbit_id").toString();
135 H =
get(
"H").toString().toDouble();
136 G =
get(
"G").toString().toDouble();
137 neo =
get(
"neo").toString() ==
"Y";
138 diameter =
get(
"diameter").toString().toFloat();
139 dimensions =
get(
"extent").toString();
140 albedo =
get(
"albedo").toString().toFloat();
141 rot_period =
get(
"rot_per").toString().toFloat();
142 earth_moid =
get(
"moid").toString().toDouble();
143 orbit_class =
get(
"class").toString();
145 JD =
static_cast<double>(mJD) + 2400000.5;
150 if (name ==
i18nc(
"Asteroid name (optional)",
"Pluto"))
155 dms(dble_w),
dms(dble_N),
dms(dble_M), H, G);
159 new_asteroid->
setNEO(neo);
173 objectNames(SkyObject::ASTEROID).append(name);
174 objectLists(SkyObject::ASTEROID)
175 .append(QPair<QString, const SkyObject *>(name, new_asteroid));
178 catch (
const std::runtime_error &e)
180 qCInfo(KSTARS) <<
"Loading asteroid objects failed.";
181 qCInfo(KSTARS) <<
" -> was trying to read " + filepath_txt;
193 bool hideLabels = !Options::showAsteroidNames() || (SkyMap::Instance()->isSlewing() && Options::hideLabels());
195 double labelMagLimit = Options::asteroidLabelDensity();
196 const double showMagLimit = Options::magLimitAsteroid();
197 const double lgmin = log10(MINZOOM);
198 const double lgmax = log10(MAXZOOM);
199 const double lgz = log10(Options::zoomFactor());
200 const double densityLabelFactor = 10.0;
202 const double zoomLimit = (lgz - lgmin) / (lgmax - lgmin);
205 labelMagLimit = std::max(1e-3, labelMagLimit) / densityLabelFactor;
209 labelMagLimit = showMagLimit - 20.0 / densityLabelFactor + std::max(zoomLimit, labelMagLimit);
215 if (!ast->
toDraw() || std::isnan(ast->
mag()) || ast->
mag() > showMagLimit)
225 if (drawn && !hideLabels && ast->
mag() <= labelMagLimit)
238 for (
auto o : m_ObjectList)
240 if (!((
dynamic_cast<KSAsteroid*
>(o)->toDraw())))
254void AsteroidsComponent::updateDataFile(
bool isAutoUpdate)
256 delete (downloadJob);
257 downloadJob =
new FileDownloader();
259 if (isAutoUpdate ==
false)
260 downloadJob->setProgressDialogEnabled(
true,
i18n(
"Asteroid Update"),
261 i18n(
"Downloading asteroids updates..."));
262 downloadJob->registerDataVerification([&](
const QByteArray & data)
267 QObject::connect(downloadJob, SIGNAL(downloaded()),
this, SLOT(downloadReady()));
268 if (isAutoUpdate ==
false)
272 QUrl url =
QUrl(
"https://ssd-api.jpl.nasa.gov/sbdb_query.api");
276 KSUtils::getJPLQueryString(
"a",
277 "full_name,neo,H,G,diameter,extent,albedo,rot_per,"
278 "orbit_id,epoch_mjd,e,a,q,i,om,w,ma,per_y,moid,class",
280 downloadJob->post(url, post_data);
283void AsteroidsComponent::downloadReady()
286 QByteArray data = downloadJob->downloadedData();
290 .filePath(
"asteroids.dat"));
297 qCWarning(KSTARS) <<
"Failed writing asteroid data to" << file.fileName();
303 if (foc && foc->
type() == SkyObject::ASTEROID)
305 focusedAstroid = foc->
name();
310 if (foc && foc->
type() == SkyObject::ASTEROID)
312 focusedAstroid = foc->
name();
331 downloadJob->deleteLater();
334void AsteroidsComponent::downloadError(
const QString &errorString)
336 KSNotification::error(
i18n(
"Error downloading asteroids data: %1", errorString));
337 qDebug() << Q_FUNC_INFO <<
i18n(
"Error downloading asteroids data: %1", errorString);
338 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.
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
The solar system composite manages all planets, asteroids and comets.
An angle, stored as degrees, but expressible in many ways.
const double & Degrees() const
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