9#include "hipsmanager.h"
11#include "auxiliary/kspaths.h"
12#include "auxiliary/ksuserdb.h"
14#include "kstarsdata.h"
15#include "kstars_debug.h"
19#include <KConfigDialog>
23#include <QNetworkDiskCache>
27static UrlFileDownload *g_download =
nullptr;
29static int qHash(
const pixCacheKey_t &key, uint seed)
35inline bool operator==(
const pixCacheKey_t &k1,
const pixCacheKey_t &k2)
37 return (k1.uid == k2.uid) && (k1.level == k2.level) && (k1.pix == k2.pix);
40HIPSManager * HIPSManager::_HIPSManager =
nullptr;
42HIPSManager *HIPSManager::Instance()
44 if (_HIPSManager ==
nullptr)
46 _HIPSManager =
new HIPSManager();
49 QDir hipsDirectory(Options::hIPSOfflinePath());
51 HIPSManager::Instance()->setOfflineLevels(orders);
53 if (Options::hIPSUseOfflineSource())
54 _HIPSManager->setCurrentSource(Options::hIPSSource());
62 if (g_discCache ==
nullptr)
67 if (g_download ==
nullptr)
69 g_download =
new UrlFileDownload(
this, g_discCache);
76 qint64 net = Options::hIPSNetCache();
77 qint64 value = net * 1024 * 1024;
79 value = Options::hIPSMemoryCache() * 1024 * 1024;
80 m_cache.setMaxCost(Options::hIPSMemoryCache() * 1024 * 1024);
86void HIPSManager::showSettings()
89 if (dialog ==
nullptr)
95 displaySettings.reset(
new OpsHIPSDisplay());
99 cacheSettings.reset(
new OpsHIPSCache());
100 page = dialog->
addPage(cacheSettings.get(),
i18n(
"Cache"));
103 sourceSettings.reset(
new OpsHIPS());
104 page = dialog->
addPage(sourceSettings.get(),
i18n(
"Sources"));
113void HIPSManager::slotApply()
115 if (Options::hIPSUseOfflineSource())
117 QDir hipsDirectory(Options::hIPSOfflinePath());
119 HIPSManager::Instance()->setOfflineLevels(orders);
120 _HIPSManager->setCurrentSource(Options::hIPSSource());
128qint64 HIPSManager::getDiscCacheSize()
const
133void HIPSManager::readSources()
135 KStarsData::Instance()->
userdb()->GetAllHIPSSources(m_hipsSources);
137 QString currentSourceTitle = Options::hIPSSource();
139 setCurrentSource(currentSourceTitle);
148QImage *HIPSManager::getPix(
bool allsky,
int level,
int pix,
bool &freeImage)
150 if (Options::hIPSUseOfflineSource() ==
false && m_currentSource.
isEmpty())
152 qCWarning(KSTARS) <<
"HIPS source not available!";
171 pixCacheItem_t *item = getCacheItem(key);
178 key.level =
level - 1;
180 pixCacheItem_t *item = getCacheItem(key);
184 QImage *cacheImage = item->image;
185 int size = m_currentTileWidth >> 1;
186 int offset = cacheImage->
width() / size;
187 QImage *image = cacheImage;
189 int index[4] = {0, 2, 1, 3};
191 int ox = index[pix % 4] % offset;
192 int oy = index[pix % 4] / offset;
194 QImage *newImage =
new QImage(image->
copy(ox * size, oy * size, size, size));
203 QImage *cacheImage = item->image;
205 Q_ASSERT(!item->image->
isNull());
207 if (allsky && cacheImage !=
nullptr)
211 int offset = cacheImage->
width() / size;
212 QImage *image = cacheImage;
214 int ox = origPix % offset;
215 int oy = origPix / offset;
217 QImage *newImage =
new QImage(image->
copy(ox * size, oy * size, size, size));
229 int dir = (pix / 10000) * 10000;
232 '.' + m_currentFormat;
236 path =
"/Norder3/Allsky." + m_currentFormat;
239 QUrl downloadURL(m_currentURL);
240 downloadURL.setPath(downloadURL.path() + path);
241 g_download->begin(downloadURL, key);
242 m_downloadMap.
insert(key);
249bool HIPSManager::parseProperties(hipsParams_t *param,
const QString &filename,
const QString &url)
255 qDebug() << Q_FUNC_INFO <<
"nf" << f.fileName();
259 QMap <QString, QString>
map;
273 qDebug() << Q_FUNC_INFO << url;
278 if (
map.contains(
"obs_collection"))
280 param->name =
map[
"obs_collection"];
284 if (
map.contains(
"hips_tile_width"))
286 param->tileWidth =
map[
"hips_tile_width"].toInt();
290 if (
map.contains(
"hips_order"))
292 param->max_level =
map[
"hips_order"].toInt();
296 if (
map.contains(
"hips_tile_format"))
298 tmp =
map[
"hips_tile_format"];
304 param->imageExtension =
"jpg";
309 param->imageExtension =
"png";
314 if (
map.contains(
"hips_frame") ||
map.contains(
"ohips_frame"))
316 if (
map.contains(
"hips_frame"))
317 tmp =
map[
"hips_frame"];
319 tmp =
map[
"ohips_frame"];
321 if (tmp ==
"equatorial")
323 param->frame = HIPS_FRAME_EQT;
326 else if (tmp ==
"galactic")
328 param->frame = HIPS_FRAME_GAL;
337void HIPSManager::cancelAll()
339 g_download->abortAll();
342void HIPSManager::clearDiscCache()
344 g_discCache->
clear();
351 m_downloadMap.
remove(key);
353 auto *item =
new pixCacheItem_t;
355 item->image =
new QImage();
358 addToMemoryCache(key, item);
365 qCWarning(KSTARS) <<
"no image. Data size: " << data.
length();
372 m_downloadMap.
remove(key);
376 auto *timer =
new RemoveTimer();
378 connect(timer, SIGNAL(
remove(pixCacheKey_t &)),
this, SLOT(removeTimer(pixCacheKey_t &)));
383void HIPSManager::removeTimer(pixCacheKey_t &key)
385 m_downloadMap.
remove(key);
390PixCache *HIPSManager::getCache()
395void HIPSManager::addToMemoryCache(pixCacheKey_t &key, pixCacheItem_t *item)
398 Q_ASSERT(item->image);
402 m_cache.add(key, item, cost);
405pixCacheItem_t *HIPSManager::getCacheItem(pixCacheKey_t &key)
407 return m_cache.get(key);
410bool HIPSManager::setCurrentSource(
const QString &title)
414 Options::setShowHIPS(
false);
415 Options::setHIPSSource(title);
416 m_currentSource.
clear();
417 m_currentFormat.
clear();
418 m_currentFrame = HIPS_OTHER_FRAME;
419 m_currentURL.
clear();
421 m_currentTileWidth = 0;
426 else if (Options::hIPSUseOfflineSource())
428 m_currentFormat =
"jpg";
429 m_currentTileWidth = 512;
430 m_currentFrame = HIPS_EQUATORIAL_FRAME;
431 m_currentURL =
QUrl(Options::hIPSOfflinePath());
433 m_currentOrder = m_OfflineLevelsMap.
lastKey();
434 m_uid =
qHash(m_currentURL);
435 Options::setShowHIPS(
true);
437 Options::setHIPSSource(
"DSS Colored");
443 if (source.value(
"obs_title") == title)
445 m_currentSource = source;
446 m_currentFormat = source.value(
"hips_tile_format");
447 if (m_currentFormat.
contains(
"jpeg"))
448 m_currentFormat =
"jpg";
449 else if (m_currentFormat.
contains(
"png"))
450 m_currentFormat =
"png";
453 qCWarning(KSTARS) <<
"FITS HIPS images are not currently supported.";
457 m_currentOrder = source.value(
"hips_order").toInt();
458 m_currentTileWidth = source.value(
"hips_tile_width").toInt();
460 if (source.value(
"hips_frame") ==
"equatorial")
461 m_currentFrame = HIPS_EQUATORIAL_FRAME;
462 else if (source.value(
"hips_frame") ==
"galactic")
463 m_currentFrame = HIPS_GALACTIC_FRAME;
465 m_currentFrame = HIPS_OTHER_FRAME;
467 m_currentURL =
QUrl(source.value(
"hips_service_url"));
468 m_uid =
qHash(m_currentURL);
470 Options::setHIPSSource(title);
471 Options::setShowHIPS(
true);
481void HIPSManager::setOfflineLevels(
const QStringList &value)
483 for (
auto oneLevel : value)
485 if (oneLevel.startsWith(
"Norder"))
487 oneLevel.remove(
"Norder");
494 if (m_OfflineLevelsMap.
isEmpty())
496 for (
int i = 0; i <= 20; i++)
497 m_OfflineLevelsMap[i] = 1;
502 for (
int i = 0; i <= 20; i++)
505 if (m_OfflineLevelsMap.
contains(i) ==
false)
507 const auto keys = m_OfflineLevelsMap.
keys();
508 const auto values = m_OfflineLevelsMap.
values();
509 auto it = std::upper_bound(keys.constBegin(), keys.constEnd(), i);
510 if (it != keys.end())
511 m_OfflineLevelsMap[i] = *it;
513 m_OfflineLevelsMap[i] = values.
last();
519int HIPSManager::getUsableLevel(
int level)
const
521 return Options::hIPSUseOfflineSource() ? m_OfflineLevelsMap[
level] :
level;
524int HIPSManager::getUsableOfflineLevel(
int level)
const
526 return m_OfflineLevelsMap[
level];
529void RemoveTimer::setKey(
const pixCacheKey_t &key)
KPageWidgetItem * addPage(QWidget *page, const QString &itemName, const QString &pixmapName=QString(), const QString &header=QString(), bool manage=true)
static KConfigDialog * exists(const QString &name)
QPushButton * button(QDialogButtonBox::StandardButton which) const
void setIcon(const QIcon &icon)
This is the main window for KStars.
static KStars * Instance()
void repopulateHIPS()
Load HIPS information and repopulate menu.
HIPS Settings including download of external sources and enabling/disabling them accordingly.
void forceUpdate(bool now=false)
Recalculates the positions of objects in the sky, and then repaints the sky map.
QString i18n(const char *text, const TYPE &arg...)
KCALENDARCORE_EXPORT size_t qHash(const KCalendarCore::Period &key, size_t seed=0)
KIOCORE_EXPORT bool operator==(const UDSEntry &entry, const UDSEntry &other)
QString path(const QString &relativePath)
QStringView level(QStringView ifopt)
KIOCORE_EXPORT QString dir(const QString &fileClass)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
qsizetype length() const const
QIcon fromTheme(const QString &name)
QImage copy(const QRect &rectangle) const const
bool isNull() const const
bool loadFromData(QByteArrayView data, const char *format)
qsizetype sizeInBytes() const const
bool contains(const Key &key) const const
bool isEmpty() const const
QList< Key > keys() const const
const Key & lastKey() const const
QList< T > values() const const
virtual qint64 cacheSize() const const override
virtual void clear() override
void setCacheDirectory(const QString &cacheDir)
void setMaximumCacheSize(qint64 size)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QObject * sender() const const
bool contains(const QSet< T > &other) const const
iterator insert(const T &value)
bool remove(const T &value)
QString arg(Args &&... args) const const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
qsizetype indexOf(QChar ch, qsizetype from, Qt::CaseSensitivity cs) const const
QString left(qsizetype n) const const
QString mid(qsizetype position, qsizetype n) const const
QString number(double n, char format, int precision)
QString simplified() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
uint toUInt(bool *ok, int base) const const
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void setScheme(const QString &scheme)