8#include "catalogscomponent.h"
11#include "kstarsdata.h"
13#include "MeshIterator.h"
14#include "projections/projector.h"
15#include "skylabeler.h"
16#include "kstars_debug.h"
18#include "skymapcomposite.h"
20#include "import_skycomp.h"
22#include <QtConcurrent>
26constexpr std::size_t expectedKnownMagObjectsPerTrixel = 500;
27constexpr std::size_t expectedUnknownMagObjectsPerTrixel = 1500;
32 , m_db_manager(db_filename)
33 , m_skyMesh{
SkyMesh::Create(m_db_manager.htmesh_level()) }
34 , m_mainCache(m_skyMesh->size(), calculateCacheSize(Options::dSOCachePercentage()))
35 , m_unknownMagCache(m_skyMesh->size(), calculateCacheSize(Options::dSOCachePercentage()))
40 Options::dSODefaultCatalogFilename());
42 if (
QFile(default_file).exists())
44 m_db_manager.import_catalog(default_file,
false);
48 m_catalog_colors = m_db_manager.get_catalog_colors();
49 tryImportSkyComponents();
50 qCInfo(KSTARS) <<
"Loaded DSO catalogs.";
53double compute_maglim()
55 double maglim = Options::magLimitDrawDeepSky();
58 static const double lgmin{ log10(MINZOOM) };
59 static const double lgmax{ log10(MAXZOOM) };
60 double lgz = log10(Options::zoomFactor());
61 if (lgz <= 0.75 * lgmax)
63 (Options::magLimitDrawDeepSky() - Options::magLimitDrawDeepSkyZoomOut()) *
64 (0.75 * lgmax - lgz) / (0.75 * lgmax - lgmin);
71 if (!
selected() || Options::zoomFactor() < Options::dSOMinZoomFactor())
76 skyp->
setPen(default_color);
79 bool showUnknownMagObjects = Options::showUnknownMagObjects();
80 auto maglim = compute_maglim();
82 auto &labeler = *SkyLabeler::Instance();
84 QColor(KStarsData::Instance()->colorScheme()->colorNamed(
"DSNameColor")));
85 const auto &color_scheme = KStarsData::Instance()->colorSchemeFileName();
87 auto &map = *SkyMap::Instance();
88 auto hideLabels = (map.isSlewing() && Options::hideOnSlew()) ||
89 !(Options::showDeepSkyMagnitudes() || Options::showDeepSkyNames());
91 const auto label_padding{ 1 + (1 - (Options::deepSkyLabelDensity() / 100)) * 50 };
92 auto &proj = *map.projector();
96 size_t num_trixels{ 0 };
97 const auto zoomFactor = Options::zoomFactor();
98 const double sizeScale =
dms::PI * zoomFactor / 10800.0;
133 auto fillCache = [&](
139 if (!cacheElement.
is_set())
143 cacheElement = (m_db_manager.*fillFunction)(trixel);
148 <<
"Could not load catalog objects in trixel: " << trixel <<
", "
152 nullptr,
i18n(
"Could not load catalog objects in trixel: %1", trixel),
161 auto drawObjects = [&](std::vector<CatalogObject*> &objects)
169 auto &color = m_catalog_colors[
object->catalogId()][color_scheme];
170 if (!color.isValid())
172 color = m_catalog_colors[
object->catalogId()][
"default"];
174 if (!color.isValid())
176 color = default_color;
182 if (Options::showInlineImages())
183 object->load_image();
187 labeler.drawNameLabel(
object, proj.toScreen(
object), label_padding);
192 std::vector<CatalogObject*> drawListKnownMag;
193 drawListKnownMag.reserve(expectedKnownMagObjectsPerTrixel);
199 Trixel trixel = region.
next();
203 auto &objectsKnownMag = m_mainCache[trixel];
205 drawListKnownMag.clear();
208 for (
const auto &
object : objectsKnownMag.data())
210 const auto mag =
object.mag();
211 const auto a =
object.a();
212 const double size = a * sizeScale;
213 const bool magCriterion = (mag < maglim);
222 (size > 1.0 || size == 0 || zoomFactor > 2000.);
227 drawListKnownMag.push_back(
const_cast<CatalogObject*
>(&
object));
231 drawObjects(drawListKnownMag);
235 if (showUnknownMagObjects)
237 std::vector<CatalogObject*> drawListUnknownMag;
238 drawListUnknownMag.reserve(expectedUnknownMagObjectsPerTrixel);
239 QMutex drawListUnknownMagLock;
244 Trixel trixel = region.
next();
245 drawListUnknownMag.clear();
248 auto &objectsUnknownMag = m_unknownMagCache[trixel];
253 objectsUnknownMag.data(),
254 [&](
const auto &
object)
257 double size = a * sizeScale;
263 bool magCriterion = (a <= 0.0 || (13.1 - 5 * log10(a)) < maglim);
269 (size > 1.0 || (size == 0 && object.type() != SkyObject::GALAXY) || zoomFactor > 10000.);
274 QMutexLocker _{&drawListUnknownMagLock};
275 drawListUnknownMag.push_back(
const_cast<CatalogObject*
>(&
object));
279 drawObjects(drawListUnknownMag);
286 m_mainCache.prune(num_trixels * 1.2);
287 m_unknownMagCache.prune(num_trixels * 1.2);
290void CatalogsComponent::updateSkyMesh(
SkyMap &map, MeshBufNum_t buf)
292 SkyPoint *focus =
map.focus();
293 float radius =
map.projector()->fov();
294 if (radius > 180.0 && SkyMap::Instance()->projector()->
type() != Projector::Stereographic)
297 m_skyMesh->aperture(focus, radius + 1.0, buf);
302 auto trixel = m_skyMesh->index(&obj);
303 auto &lst = m_static_objects[trixel];
304 auto found_iter = std::find(lst.begin(), lst.end(), obj);
310 if (!(found_iter == lst.end()))
312 auto &found = *found_iter;
321 lst.push_back(std::move(copy));
322 auto &inserted = lst.back();
325 auto &object_list = objectLists(inserted.type());
327 object_list.append({ inserted.name(), &inserted });
328 if (inserted.longname() != inserted.name())
329 object_list.append({ inserted.longname(), &inserted });
336 auto objects = m_db_manager.find_objects_by_name(name, 1,
true);
337 if (objects.empty() && !exact)
338 objects = m_db_manager.find_objects_by_name(name);
340 if (objects.size() == 0)
356 for (
auto &dso : m_db_manager.get_objects_in_trixel(it.key()))
364 qCCritical(KSTARS) <<
"Could not load catalog objects in trixel: " << it.key()
368 nullptr,
i18n(
"Could not load catalog objects in trixel: %1", it.key()),
380 m_skyMesh->aperture(p, maxrad, OBJ_NEAREST_BUF);
382 double smallest_r{ 360 };
388 auto trixel = region.
next();
391 auto objects = m_db_manager.get_objects_in_trixel(trixel);
393 found = objects.size() > 0;
395 for (
auto &obj : objects)
399 double r = obj.angularDistanceTo(p).Degrees();
410 nullptr,
i18n(
"Could not load catalog objects in trixel: %1", trixel),
424void CatalogsComponent::tryImportSkyComponents()
427 if (!skycom_db.first)
430 const auto move_skycompdb = [&]()
432 const auto &path = skycom_db.second.databaseName();
433 const auto &new_path =
440 nullptr,
i18n(
"Import custom and internet resolved objects "
441 "from the old DSO database into the new one?"));
450 if (!std::get<0>(success))
452 std::get<1>(success));
454 const auto &add_success =
455 m_db_manager.add_objects(CatalogsDB::user_catalog_id, std::get<2>(success));
457 if (!add_success.first)
463 nullptr,
i18np(
"Successfully added %1 object to the user catalog.",
464 "Successfully added %1 objects to the user catalog.",
465 std::get<2>(success).size()));
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
void JITupdate()
Update the cooridnates and the horizontal coordinates if updateID or updateNumID have changed (global...
SkyObject * objectNearest(SkyPoint *p, double &maxrad) override
Find the SkyObject nearest the given SkyPoint.
SkyObject * findByName(const QString &name, bool exact=true) override
Search the underlying database for an object with the name.
void objectsInArea(QList< SkyObject * > &list, const SkyRegion ®ion) override
Searches the region(s) and appends the SkyObjects found to the list of sky objects.
CatalogsComponent(SkyComposite *parent, const QString &db_filename, bool load_default=false)
Constructs the Catalogscomponent with a parent and a database file under the path db_filename.
CatalogObject & insertStaticObject(const CatalogObject &obj)
Insert an object obj into m_static_objects and return a reference to the newly inserted object.
bool selected() override
Wether to show the DSOs.
void draw(SkyPainter *skyp) override
Draws the objects in the currently visible trixels by dynamically loading them from the database.
Manages the catalog database and provides an interface to provide an interface to query and modify th...
CatalogObjectVector get_objects_in_trixel_null_mag(const int trixel)
CatalogObjectVector get_objects_in_trixel_no_nulls(const int trixel)
Database related error, thrown when database access fails or an action does not succeed.
QColor colorNamed(const QString &name) const
Retrieve a color by name.
KStarsData is the backbone of KStars.
ColorScheme * colorScheme()
MeshIterator is a very lightweight class used to iterate over the result set of an HTMesh intersectio...
Trixel next() const
returns the next trixel
bool hasNext() const
true if there are more trixel to iterate over.
SkyComponent(SkyComposite *parent=nullptr)
Constructor parent pointer to the parent SkyComposite.
SkyComposite is a kind of container class for SkyComponent objects.
This is the canvas on which the sky is painted.
Provides an interface to the Hierarchical Triangular Mesh (HTM) library written by A.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Draws things on the sky, without regard to backend.
virtual bool drawCatalogObject(const CatalogObject &obj)=0
Draw a deep sky object (loaded from the new implementation)
virtual void setBrush(const QBrush &brush)=0
Set the brush of the painter.
virtual void setPen(const QPen &pen)=0
Set the pen of the painter.
The sky coordinates of a point in the sky.
A container to hold cache elements.
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
void detailedError(QWidget *parent, const QString &text, const QString &details, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
VehicleSection::Type type(QStringView coachNumber, QStringView coachClassification)
std::pair< bool, QSqlDatabase > get_skycomp_db()
Get the skycomponent database from the standard path.
std::tuple< bool, QString, CatalogsDB::CatalogObjectVector > get_objects(QSqlDatabase db, const std::list< int > &ids={ 1, 2 })
qint64 currentMSecsSinceEpoch()
bool rename(const QString &newName)
const_iterator constBegin() const const
const_iterator constEnd() const const
void append(QList< T > &&value)
QString arg(Args &&... args) const const
void blockingMap(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)