Kstars

starcomponent.cpp
1/*
2 SPDX-FileCopyrightText: 2005 Thomas Kabelmann <thomas.kabelmann@gmx.de>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "starcomponent.h"
8
9#include "binfilehelper.h"
10#include "deepstarcomponent.h"
11#include "highpmstarlist.h"
12#ifndef KSTARS_LITE
13#include "kstars.h"
14#endif
15#include "kstarsdata.h"
16#include "kstarssplash.h"
17#include "Options.h"
18#include "skylabeler.h"
19#include "skymap.h"
20#include "skymesh.h"
21#ifndef KSTARS_LITE
22#include "skyqpainter.h"
23#endif
24#include "htmesh/MeshIterator.h"
25#include "projections/projector.h"
26
27#include "kstars_debug.h"
28
29#include <qplatformdefs.h>
30
31#ifdef _WIN32
32#include <windows.h>
33#endif
34
35#if defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD)
36#include <sys/endian.h>
37#define bswap_16(x) bswap16(x)
38#define bswap_32(x) bswap32(x)
39#else
40#include "byteorder.h"
41#endif
42
43// Qt version calming
44#include <qtskipemptyparts.h>
45
46StarComponent *StarComponent::pinstance = nullptr;
47
48StarComponent::StarComponent(SkyComposite *parent)
49 : ListComponent(parent), m_reindexNum(J2000)
50{
51 m_skyMesh = SkyMesh::Instance();
52 m_StarBlockFactory = StarBlockFactory::Instance();
53
54 m_starIndex.reset(new StarIndex());
55 for (int i = 0; i < m_skyMesh->size(); i++)
56 m_starIndex->append(new StarList());
57 m_highPMStars.append(new HighPMStarList(840.0));
58 m_highPMStars.append(new HighPMStarList(304.0));
59 m_reindexInterval = StarObject::reindexInterval(304.0);
60
61 for (int i = 0; i <= MAX_LINENUMBER_MAG; i++)
62 m_labelList[i] = new LabelList;
63
64 // Actually load data
65 emitProgressText(i18n("Loading stars"));
66
67 loadStaticData();
68 // Load any deep star catalogs that are available
69 loadDeepStarCatalogs();
70
71 // The following works but can cause crashes sometimes
72 //QtConcurrent::run(this, &StarComponent::loadDeepStarCatalogs);
73
74 //In KStars Lite star images are initialized in SkyMapLite
75#ifndef KSTARS_LITE
77#endif
78}
79
80StarComponent::~StarComponent()
81{
82 qDeleteAll(*m_starIndex);
83 m_starIndex->clear();
84 qDeleteAll(m_DeepStarComponents);
85 m_DeepStarComponents.clear();
86 qDeleteAll(m_highPMStars);
87 m_highPMStars.clear();
88 for (int i = 0; i <= MAX_LINENUMBER_MAG; i++)
89 delete m_labelList[i];
90}
91
93{
94 delete pinstance;
95 pinstance = new StarComponent(parent);
96 return pinstance;
97}
98
100{
101 return Options::showStars();
102}
103
104bool StarComponent::addDeepStarCatalogIfExists(const QString &fileName, float trigMag, bool staticstars)
105{
106 if (BinFileHelper::testFileExists(fileName))
107 {
108 m_DeepStarComponents.append(new DeepStarComponent(parent(), fileName, trigMag, staticstars));
109 return true;
110 }
111 return false;
112}
113
114int StarComponent::loadDeepStarCatalogs()
115{
116 // Look for the basic unnamed star catalog to mag 8.0
117 if (!addDeepStarCatalogIfExists("unnamedstars.dat", -5.0, true))
118 return 0;
119
120 // Look for the Tycho-2 add-on with 2.5 million stars to mag 12.5
121 if (!addDeepStarCatalogIfExists("tycho2.dat", 8.0) && !addDeepStarCatalogIfExists("deepstars.dat", 8.0))
122 return 1;
123
124 // Look for the USNO NOMAD 1e8 star catalog add-on with stars to mag 16
125 if (!addDeepStarCatalogIfExists("USNO-NOMAD-1e8.dat", 11.0))
126 return 2;
127
128 return 3;
129}
130
131//This function is empty for a reason; we override the normal
132//update function in favor of JiT updates for stars.
136
137// We use the update hook to re-index all the stars when the date has changed by
138// more than 150 years.
139
140bool StarComponent::reindex(KSNumbers *num)
141{
142 if (!num)
143 return false;
144
145 // for large time steps we re-index all points
146 if (fabs(num->julianCenturies() - m_reindexNum.julianCenturies()) > m_reindexInterval)
147 {
148 reindexAll(num);
149 return true;
150 }
151
152 bool highPM = true;
153
154 // otherwise we just re-index fast movers as needed
155 for (auto &star : m_highPMStars)
156 highPM &= !(star->reindex(num, m_starIndex.get()));
157
158 return !(highPM);
159}
160
161void StarComponent::reindexAll(KSNumbers *num)
162{
163#if 0
164 if (0 && !m_reindexSplash)
165 {
166 m_reindexSplash = new KStarsSplash(i18n("Please wait while re-indexing stars..."));
167 QObject::connect(KStarsData::Instance(), SIGNAL(progressText(QString)), m_reindexSplash,
168 SLOT(setMessage(QString)));
169
170 m_reindexSplash->show();
171 m_reindexSplash->raise();
172 return;
173 }
174#endif
175
176 qCInfo(KSTARS) << "Re-indexing Stars to year" << 2000.0 + num->julianCenturies() * 100.0;
177
178 m_reindexNum = KSNumbers(*num);
179 m_skyMesh->setKSNumbers(num);
180
181 // clear out the old index
182 for (auto &item : *m_starIndex)
183 {
184 item->clear();
185 }
186
187 // re-populate it from the objectList
188 for (auto &object : m_ObjectList)
189 {
190 StarObject *star = dynamic_cast<StarObject *>(object);
191 Trixel trixel = m_skyMesh->indexStar(star);
192
193 m_starIndex->at(trixel)->append(star);
194 }
195
196 // Let everyone else know we have re-indexed to num
197 for (auto &star : m_highPMStars)
198 {
199 star->setIndexTime(num);
200 }
201
202 //delete m_reindexSplash;
203 //m_reindexSplash = 0;
204}
205
206float StarComponent::faintMagnitude() const
207{
208 float faintmag = m_FaintMagnitude;
209
210 for (auto &component : m_DeepStarComponents)
211 {
212 if (faintmag < component->faintMagnitude())
213 faintmag = component->faintMagnitude();
214 }
215 return faintmag;
216}
217
218float StarComponent::zoomMagnitudeLimit()
219{
220 //adjust maglimit for ZoomLevel
221 double lgmin = log10(MINZOOM);
222 double lgz = log10(Options::zoomFactor());
223
224 // Old formula:
225 // float maglim = ( 2.000 + 2.444 * Options::memUsage() / 10.0 ) * ( lgz - lgmin ) + Options::magLimitDrawStarZoomOut();
226
227 /*
228 Explanation for the following formula:
229 --------------------------------------
230 Estimates from a sample of 125000 stars shows that, magnitude
231 limit vs. number of stars follows the formula:
232 nStars = 10^(.45 * maglim + .95)
233 (A better formula is available here: https://www.aa.quae.nl/en/antwoorden/magnituden.html
234 which we do not implement for simplicity)
235 We want to keep the star density on screen a constant. This is directly proportional to the number of stars
236 and directly proportional to the area on screen. The area is in turn inversely proportional to the square
237 of the zoom factor ( zoomFactor / MINZOOM ). This means that (taking logarithms):
238 0.45 * maglim + 0.95 - 2 * log( ZoomFactor ) - log( Star Density ) - log( Some proportionality constant )
239 hence the formula. We've gathered together all the constants and set it to 3.5, so as to set the minimum
240 possible value of maglim to 3.5
241 */
242
243 // float maglim = 4.444 * ( lgz - lgmin ) + 2.222 * log10( Options::starDensity() ) + 3.5;
244
245 // Reducing the slope w.r.t zoom factor to avoid the extremely fast increase in star density with zoom
246 // that 4.444 gives us (although that is what the derivation gives us)
247
248 return 3.5 + 3.7 * (lgz - lgmin) + 2.222 * log10(static_cast<float>(Options::starDensity()));
249}
250
252{
253#ifndef KSTARS_LITE
254 if (!selected())
255 return;
256
257 SkyMap *map = SkyMap::Instance();
258 const Projector *proj = map->projector();
259 KStarsData *data = KStarsData::Instance();
260 UpdateID updateID = data->updateID();
261
262 bool checkSlewing = (map->isSlewing() && Options::hideOnSlew());
263 m_hideLabels = checkSlewing || !(Options::showStarMagnitudes() || Options::showStarNames());
264
265 //shortcuts to inform whether to draw different objects
266 bool hideFaintStars = checkSlewing && Options::hideStars();
267 double hideStarsMag = Options::magLimitHideStar();
268 reindex(data->updateNum());
269
270 double lgmin = log10(MINZOOM);
271 double lgmax = log10(MAXZOOM);
272 double lgz = log10(Options::zoomFactor());
273
274 double maglim;
275 m_zoomMagLimit = maglim = zoomMagnitudeLimit();
276
277 double labelMagLim = Options::starLabelDensity() / 5.0;
278 labelMagLim += (12.0 - labelMagLim) * (lgz - lgmin) / (lgmax - lgmin);
279 if (labelMagLim > 8.0)
280 labelMagLim = 8.0;
281
282 //Calculate sizeMagLim
283 // Old formula:
284 // float sizeMagLim = ( 2.000 + 2.444 * Options::memUsage() / 10.0 ) * ( lgz - lgmin ) + 5.8;
285
286 // Using the maglim to compute the sizes of stars reduces
287 // discernability between brighter and fainter stars at high zoom
288 // levels. To fix that, we use an "arbitrary" constant in place of
289 // the variable star density.
290 // Not using this formula now.
291 // float sizeMagLim = 4.444 * ( lgz - lgmin ) + 5.0;
292
293 float sizeMagLim = zoomMagnitudeLimit();
294 if (sizeMagLim > faintMagnitude() * (1 - 1.5 / 16))
295 sizeMagLim = faintMagnitude() * (1 - 1.5 / 16);
296 skyp->setSizeMagLimit(sizeMagLim);
297
298 //Loop for drawing star images
299
300 MeshIterator region(m_skyMesh, DRAW_BUF);
301 magLim = maglim;
302
303 // If we are hiding faint stars, then maglim is really the brighter of hideStarsMag and maglim
304 if (hideFaintStars && maglim > hideStarsMag)
305 maglim = hideStarsMag;
306
307 m_StarBlockFactory->drawID = m_skyMesh->drawID();
308
309 int nTrixels = 0;
310
311 while (region.hasNext())
312 {
313 ++nTrixels;
314 Trixel currentRegion = region.next();
315 StarList *starList = m_starIndex->at(currentRegion);
316
317 for (auto &star : *starList)
318 {
319 if (!star)
320 continue;
321
322 float mag = star->mag();
323
324 // break loop if maglim is reached
325 if (mag > maglim)
326 break;
327
328 if (star->updateID != updateID)
329 star->JITupdate();
330
331 bool drawn = skyp->drawPointSource(star, mag, star->spchar());
332
333 //FIXME_SKYPAINTER: find a better way to do this.
334 if (drawn && !(m_hideLabels || mag > labelMagLim))
335 addLabel(proj->toScreen(star), star);
336 }
337 }
338
339 // Draw focusStar if not null
340 if (focusStar)
341 {
342 if (focusStar->updateID != updateID)
343 focusStar->JITupdate();
344 float mag = focusStar->mag();
345 skyp->drawPointSource(focusStar, mag, focusStar->spchar());
346 }
347
348 // Now draw each of our DeepStarComponents
349 for (auto &component : m_DeepStarComponents)
350 {
351 component->draw(skyp);
352 }
353#else
355#endif
356}
357
358void StarComponent::addLabel(const QPointF &p, StarObject *star)
359{
360 int idx = int(star->mag() * 10.0);
361 if (idx < 0)
362 idx = 0;
363 if (idx > MAX_LINENUMBER_MAG)
364 idx = MAX_LINENUMBER_MAG;
365 m_labelList[idx]->append(SkyLabel(p, star));
366}
367
369{
370 if (m_hideLabels)
371 return;
372
373 SkyLabeler *labeler = SkyLabeler::Instance();
374 labeler->setPen(QColor(KStarsData::Instance()->colorScheme()->colorNamed("SNameColor")));
375
376 int max = int(m_zoomMagLimit * 10.0);
377 if (max < 0)
378 max = 0;
379 if (max > MAX_LINENUMBER_MAG)
380 max = MAX_LINENUMBER_MAG;
381
382 for (int i = 0; i <= max; i++)
383 {
384 LabelList *list = m_labelList[i];
385
386 for (const auto &item : *list)
387 {
388 labeler->drawNameLabel(item.obj, item.o);
389 }
390 list->clear();
391 }
392}
393
394bool StarComponent::loadStaticData()
395{
396 // We break from Qt / KDE API and use traditional file handling here, to obtain speed.
397 // We also avoid C++ constructors for the same reason.
399 bool swapBytes = false, named = false, gnamed = false;
401 QString name, gname, visibleName;
402 StarObject *star;
403
404 if (starsLoaded)
405 return true;
406
407 // prepare to index stars to this date
408 m_skyMesh->setKSNumbers(&m_reindexNum);
409
410 /* Open the data files */
411 // TODO: Maybe we don't want to hardcode the filename?
412 if ((dataFile = dataReader.openFile("namedstars.dat")) == nullptr)
413 {
414 qCWarning(KSTARS) << "Could not open data file namedstars.dat";
415 return false;
416 }
417
418 if (!(nameFile = nameReader.openFile("starnames.dat")))
419 {
420 qCWarning(KSTARS) << "Could not open data file starnames.dat";
421 return false;
422 }
423
424 if (!dataReader.readHeader())
425 {
426 qCWarning(KSTARS) << "Error reading namedstars.dat header : " << dataReader.getErrorNumber() << " : "
427 << dataReader.getError();
428 return false;
429 }
430
431 if (!nameReader.readHeader())
432 {
433 qCWarning(KSTARS) << "Error reading starnames.dat header : " << nameReader.getErrorNumber() << " : "
434 << nameReader.getError();
435 return false;
436 }
437 //KDE_fseek(nameFile, nameReader.getDataOffset(), SEEK_SET);
438 QT_FSEEK(nameFile, nameReader.getDataOffset(), SEEK_SET);
439 swapBytes = dataReader.getByteSwap();
440
441 long int nstars = 0;
442
443 //KDE_fseek(dataFile, dataReader.getDataOffset(), SEEK_SET);
444 QT_FSEEK(dataFile, dataReader.getDataOffset(), SEEK_SET);
445
446 qint16 faintmag;
447 quint8 htm_level;
448 quint16 t_MSpT;
449 int ret = 0;
450
451 // Faint Magnitude
452 ret = fread(&faintmag, 2, 1, dataFile);
453 if (swapBytes)
454 faintmag = bswap_16(faintmag);
455
456 // HTM Level
457 ret = fread(&htm_level, 1, 1, dataFile);
458
459 // Unused
460 {
461 int rc = fread(&t_MSpT, 2, 1, dataFile);
462 Q_UNUSED(rc)
463 }
464
465 if (faintmag / 100.0 > m_FaintMagnitude)
466 m_FaintMagnitude = faintmag / 100.0;
467
468 if (htm_level != m_skyMesh->level())
469 qCWarning(KSTARS)
470 << "HTM Level in shallow star data file and HTM Level in m_skyMesh do not match. EXPECT TROUBLE"
471 ;
472 for (int i = 0; i < m_skyMesh->size(); ++i)
473 {
474 Trixel trixel = i; // = ( ( i >= 256 ) ? ( i - 256 ) : ( i + 256 ) );
475 for (unsigned long j = 0; j < static_cast<unsigned long>(dataReader.getRecordCount(i)); ++j)
476 {
477 if (1 != fread(&stardata, sizeof(StarData), 1, dataFile))
478 {
479 qCCritical(KSTARS) << "FILE FORMAT ERROR: Could not read StarData structure for star #" << j << " under trixel #"
480 << trixel;
481 continue;
482 }
483
484 /* Swap Bytes when required */
485 if (swapBytes)
486 byteSwap(&stardata);
487
488 named = false;
489 gnamed = false;
490
491 /* Named Star - Read the nameFile */
492 if (stardata.flags & 0x01)
493 {
494 visibleName = "";
495 if (1 != fread(&starname, sizeof(starName), 1, nameFile))
496 qCCritical(KSTARS) << "ERROR: fread() call on nameFile failed in trixel " << trixel << " star " << j;
497
498 name = QByteArray(starname.longName, 32);
499 named = !name.isEmpty();
500
501 gname = QByteArray(starname.bayerName, 8);
502 gnamed = !gname.isEmpty();
503
504 if (gnamed && starname.bayerName[0] != '.')
505 visibleName = gname;
506
507 if (named)
508 {
509 // HEV: look up star name in internationalization filesource
510 name = i18nc("star name", name.toLocal8Bit().data());
511 }
512 else
513 {
514 name = i18n("star");
515 }
516 }
517 else
518 qCCritical(KSTARS) << "ERROR: Named star file contains unnamed stars! Expect trouble.";
519
520 /* Create the new StarObject */
521 star = new StarObject;
522 star->init(&stardata);
523 //if( star->getHDIndex() != 0 && name == i18n("star"))
524 if (stardata.HD)
525 {
526 m_HDHash.insert(stardata.HD, star);
527 if (named == false)
528 {
529 name = QString("HD %1").arg(stardata.HD);
530 named = true;
531 }
532 }
533
534 star->setNames(name, visibleName);
535 //star->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
536 ++nstars;
537
538 if (gnamed)
539 m_genName.insert(gname, star);
540
541 //if ( ! name.isEmpty() && name != i18n("star"))
542 if (named)
543 {
544 objectNames(SkyObject::STAR).append(name);
545 objectLists(SkyObject::STAR).append(QPair<QString, const SkyObject *>(name, star));
546 }
547
548 if (!visibleName.isEmpty() && gname != name)
549 {
550 QString gName = star->gname(false);
551 objectNames(SkyObject::STAR).append(gName);
552 objectLists(SkyObject::STAR).append(QPair<QString, const SkyObject *>(gName, star));
553 }
554
555 appendListObject(star);
556
557 m_starIndex->at(trixel)->append(star);
558 double pm = star->pmMagnitude();
559
560 for (auto &list : m_highPMStars)
561 {
562 if (list->append(trixel, star, pm))
563 break;
564 }
565 }
566 }
567
568 dataReader.closeFile();
569 nameReader.closeFile();
570
571 starsLoaded = true;
572 return true;
573}
574
576{
577 m_ObjectList.append(object);
578 m_ObjectHash.insert(object->name().toLower(), object);
579 m_ObjectHash.insert(object->longname().toLower(), object);
580 m_ObjectHash.insert(object->name2().toLower(), object);
581 m_ObjectHash.insert(object->name2().toLower(), object);
582 m_ObjectHash.insert((dynamic_cast<StarObject *>(object))->gname(false).toLower(), object);
583}
584
585SkyObject *StarComponent::findStarByGenetiveName(const QString name)
586{
587 if (name.startsWith(QLatin1String("HD")))
588 {
589 QStringList fields = name.split(' ', Qt::SkipEmptyParts);
590 bool Ok = false;
591 unsigned int HDNum = fields[1].toInt(&Ok);
592 if (Ok)
593 return findByHDIndex(HDNum);
594 }
595 return m_genName.value(name);
596}
597
599{
600 for (SkyRegion::const_iterator it = region.constBegin(); it != region.constEnd(); ++it)
601 {
602 Trixel trixel = it.key();
603 StarList *starlist = m_starIndex->at(trixel);
604 for (int i = 0; starlist && i < starlist->size(); i++)
605 if (starlist->at(i) && starlist->at(i)->name() != QString("star"))
606 list.push_back(starlist->at(i));
607 }
608}
609
611{
612 KStarsData *data = KStarsData::Instance();
613 StarObject *o = nullptr;
615
616 // First check the hash to see if we have a corresponding StarObject already
617 if ((o = m_HDHash.value(HDnum, nullptr)))
618 return o;
619 // If we don't have the StarObject here, try it in the DeepStarComponents' hashes
620 if (m_DeepStarComponents.size() >= 1)
621 if ((o = m_DeepStarComponents.at(0)->findByHDIndex(HDnum)))
622 return o;
623 if (m_DeepStarComponents.size() >= 2)
624 {
625 qint32 offset = 0;
626 int ret = 0;
627 FILE *hdidxFile = hdidxReader.openFile("Henry-Draper.idx");
628 FILE *dataFile = nullptr;
629
630 if (!hdidxFile)
631 return nullptr;
632 //KDE_fseek( hdidxFile, (HDnum - 1) * 4, SEEK_SET );
633 QT_FSEEK(hdidxFile, (HDnum - 1) * 4, SEEK_SET);
634 // TODO: Offsets need to be byteswapped if this is a big endian machine.
635 // This means that the Henry Draper Index needs a endianness indicator.
636 ret = fread(&offset, 4, 1, hdidxFile);
637 if (offset <= 0)
638 return nullptr;
639 dataFile = m_DeepStarComponents.at(1)->getStarReader()->getFileHandle();
640 //KDE_fseek( dataFile, offset, SEEK_SET );
641 QT_FSEEK(dataFile, offset, SEEK_SET);
642 {
643 int rc = fread(&stardata, sizeof(StarData), 1, dataFile);
644 Q_UNUSED(rc)
645 }
646 if (m_DeepStarComponents.at(1)->getStarReader()->getByteSwap())
647 {
648 byteSwap(&stardata);
649 }
650 m_starObject.init(&stardata);
651 m_starObject.EquatorialToHorizontal(data->lst(), data->geo()->lat());
652 m_starObject.JITupdate();
653 focusStar = m_starObject.clone();
654 m_HDHash.insert(HDnum, focusStar);
655 hdidxReader.closeFile();
656 return focusStar;
657 }
658
659 return nullptr;
660}
661
662// This uses the main star index for looking up nearby stars but then
663// filters out objects with the generic name "star". We could easily
664// build an index for just the named stars which would make this go
665// much faster still. -jbb
666//
668{
669 m_zoomMagLimit = zoomMagnitudeLimit();
670
671 SkyObject *oBest = nullptr;
672
673 MeshIterator region(m_skyMesh, OBJ_NEAREST_BUF);
674
675 while (region.hasNext())
676 {
677 Trixel currentRegion = region.next();
678 StarList *starList = m_starIndex->at(currentRegion);
679
680 for (auto &star : *starList)
681 {
682 if (!star)
683 continue;
684 if (star->mag() > m_zoomMagLimit)
685 continue;
686
687 double r = star->angularDistanceTo(p).Degrees();
688
689 if (r < maxrad)
690 {
691 oBest = star;
692 maxrad = r;
693 }
694 }
695 }
696
697 // Check up with our Deep Star Components too!
698 double rTry, rBest;
700 // JM 2016-03-30: Multiply rBest by a factor of 0.5 so that named stars are preferred to unnamed stars searched below
701 rBest = maxrad * 0.5;
702 rTry = maxrad;
703 for (auto &component : m_DeepStarComponents)
704 {
705 oTry = component->objectNearest(p, rTry);
706 if (rTry < rBest)
707 {
708 rBest = rTry;
709 oBest = oTry;
710 }
711 }
712 maxrad = rBest;
713
714 return oBest;
715}
716
717void StarComponent::starsInAperture(QList<StarObject *> &list, const SkyPoint &center, float radius, float maglim)
718{
719 // Ensure that we have deprecessed the (RA, Dec) to (RA0, Dec0)
720 Q_ASSERT(center.ra0().Degrees() >= 0.0);
721 Q_ASSERT(center.dec0().Degrees() <= 90.0);
722
723 m_skyMesh->intersect(center.ra0().Degrees(), center.dec0().Degrees(), radius, static_cast<BufNum>(OBJ_NEAREST_BUF));
724
725 MeshIterator region(m_skyMesh, OBJ_NEAREST_BUF);
726
727 if (maglim < -28)
728 maglim = m_FaintMagnitude;
729
730 while (region.hasNext())
731 {
732 Trixel currentRegion = region.next();
733 StarList *starList = m_starIndex->at(currentRegion);
734
735 for (auto &star : *starList)
736 {
737 if (!star)
738 continue;
739 if (star->mag() > m_FaintMagnitude)
740 continue;
741 if (star->angularDistanceTo(&center).Degrees() <= radius)
742 list.append(star);
743 }
744 }
745
746 // Add stars from the DeepStarComponents as well
747 for (auto &component : m_DeepStarComponents)
748 {
749 component->starsInAperture(list, center, radius, maglim);
750 }
751}
752
753void StarComponent::byteSwap(StarData *stardata)
754{
755 stardata->RA = bswap_32(stardata->RA);
756 stardata->Dec = bswap_32(stardata->Dec);
757 stardata->dRA = bswap_32(stardata->dRA);
758 stardata->dDec = bswap_32(stardata->dDec);
759 stardata->parallax = bswap_32(stardata->parallax);
760 stardata->HD = bswap_32(stardata->HD);
761 stardata->mag = bswap_16(stardata->mag);
762 stardata->bv_index = bswap_16(stardata->bv_index);
763}
764/*
765void StarComponent::printDebugInfo() {
766
767 int nTrixels = 0;
768 int nBlocks = 0;
769 long int nStars = 0;
770 float faintMag = -5.0;
771
772 MeshIterator trixels( m_skyMesh, DRAW_BUF );
773 Trixel trixel;
774
775 while( trixels.hasNext() ) {
776 trixel = trixels.next();
777 nTrixels++;
778 for(int i = 0; i < m_starBlockList[ trixel ]->getBlockCount(); ++i) {
779 nBlocks++;
780 StarBlock *block = m_starBlockList[ trixel ]->block( i );
781 for(int j = 0; j < block->getStarCount(); ++j) {
782 nStars++;
783 }
784 if( block->getFaintMag() > faintMag ) {
785 faintMag = block->getFaintMag();
786 }
787 }
788 }
789
790 printf( "========== UNNAMED STAR MEMORY ALLOCATION INFORMATION ==========\n" );
791 printf( "Number of visible trixels = %8d\n", nTrixels );
792 printf( "Number of visible StarBlocks = %8d\n", nBlocks );
793 printf( "Number of StarBlocks allocated via SBF = %8d\n", m_StarBlockFactory.getBlockCount() );
794 printf( "Number of unnamed stars in memory = %8ld\n", nStars );
795 printf( "Magnitude of the faintest star in memory = %8.2f\n", faintMag );
796 printf( "Target magnitude limit = %8.2f\n", magLim );
797 printf( "Size of each StarBlock = %8d bytes\n", sizeof( StarBlock ) );
798 printf( "Size of each StarObject = %8d bytes\n", sizeof( StarObject ) );
799 printf( "Memory use due to visible unnamed stars = %8.2f MB\n", ( sizeof( StarObject ) * nStars / 1048576.0 ) );
800 printf( "Memory use due to visible StarBlocks = %8d bytes\n", sizeof( StarBlock ) * nBlocks );
801 printf( "Memory use due to StarBlocks in SBF = %8d bytes\n", sizeof( StarBlock ) * m_StarBlockFactory.getBlockCount() );
802 printf( "=============== STAR DRAW LOOP TIMING INFORMATION ==============\n" );
803 printf( "Time taken for drawing named stars = %8ld ms\n", t_drawNamed );
804 printf( "Time taken for dynamic load of data = %8ld ms\n", t_dynamicLoad );
805 printf( "Time taken for updating LRU cache = %8ld ms\n", t_updateCache );
806 printf( "Time taken for drawing unnamed stars = %8ld ms\n", t_drawUnnamed );
807 printf( "================================================================\n" );
808}
809
810bool StarComponent::verifySBLIntegrity() {
811
812 float faintMag = -5.0;
813 bool integrity = true;
814 for(Trixel trixel = 0; trixel < m_skyMesh->size(); ++trixel) {
815 for(int i = 0; i < m_starBlockList[ trixel ]->getBlockCount(); ++i) {
816 StarBlock *block = m_starBlockList[ trixel ]->block( i );
817 if( i == 0 )
818 faintMag = block->getBrightMag();
819 // NOTE: Assumes 2 decimal places in magnitude field. TODO: Change if it ever does change
820 if( block->getBrightMag() != faintMag && ( block->getBrightMag() - faintMag ) > 0.016) {
821 qDebug() << Q_FUNC_INFO << "Trixel " << trixel << ": ERROR: faintMag of prev block = " << faintMag
822 << ", brightMag of block #" << i << " = " << block->getBrightMag();
823 integrity = false;
824 }
825 if( i > 1 && ( !block->prev ) )
826 qDebug() << Q_FUNC_INFO << "Trixel " << trixel << ": ERROR: Block" << i << "is unlinked in LRU Cache";
827 if( block->prev && block->prev->parent == m_starBlockList[ trixel ]
828 && block->prev != m_starBlockList[ trixel ]->block( i - 1 ) ) {
829 qDebug() << Q_FUNC_INFO << "Trixel " << trixel << ": ERROR: SBF LRU Cache linked list seems to be broken at before block " << i;
830 integrity = false;
831 }
832 faintMag = block->getFaintMag();
833 }
834 }
835 return integrity;
836}
837*/
This class provides utility functions to handle binary data files in the format prescribed by KStars.
static bool testFileExists(const QString &fileName)
Checks if a file exists.
Stores and manages unnamed stars, most of which are dynamically loaded into memory.
const CachingDms * lat() const
Definition geolocation.h:70
int size() const
returns the total number of trixels in the HTM.
Definition HTMesh.h:118
int level() const
returns the mesh level.
Definition HTMesh.h:122
void intersect(double ra, double dec, double radius, BufNum bufNum=0)
NOTE: The intersect() routines below are all used to find the trixels needed to cover a geometric obj...
Definition HTMesh.cpp:104
Holds a list of stars with high proper motion along with the trixel each star is currently located in...
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
double julianCenturies() const
Definition ksnumbers.h:88
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
CachingDms * lst()
Definition kstarsdata.h:224
GeoLocation * geo()
Definition kstarsdata.h:230
The KStars Splash Screen.
An abstract parent class, to be inherited by SkyComponents that store a QList of SkyObjects.
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.
The Projector class is the primary class that serves as an interface to handle projections.
Definition projector.h:58
SkyComposite * parent()
SkyComposite is a kind of container class for SkyComponent objects.
The purpose of this class is to prevent labels from overlapping.
Definition skylabeler.h:99
This is the canvas on which the sky is painted.
Definition skymap.h:54
static SkyMesh * Instance()
returns the default instance of SkyMesh or null if it has not yet been created.
Definition skymesh.cpp:39
DrawID drawID() const
Definition skymesh.h:264
void setKSNumbers(KSNumbers *num)
sets the time for indexing StarObjects and CLines.
Definition skymesh.h:145
Trixel indexStar(StarObject *star)
returns the trixel that contains the star at the set time with proper motion taken into account but n...
Definition skymesh.cpp:79
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
virtual QString name(void) const
Definition skyobject.h:145
virtual QString longname(void) const
Definition skyobject.h:164
QString name2(void) const
Definition skyobject.h:156
float mag() const
Definition skyobject.h:206
Draws things on the sky, without regard to backend.
Definition skypainter.h:40
The sky coordinates of a point in the sky.
Definition skypoint.h:45
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
Definition skypoint.cpp:899
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
static void initStarImages()
Recalculates the star pixmaps.
Represents the stars on the sky map.
void update(KSNumbers *num) override
Update the sky positions of this component.
bool selected() override
void draw(SkyPainter *skyp) override
Draw the object on the SkyMap skyp a pointer to the SkyPainter to use.
void starsInAperture(QList< StarObject * > &list, const SkyPoint &center, float radius, float maglim=-29)
Add to the given list, the stars from this component, that lie within the specified circular aperture...
StarObject * findByHDIndex(int HDnum)
Find stars by HD catalog index.
SkyObject * objectNearest(SkyPoint *p, double &maxrad) override
Find the SkyObject nearest the given SkyPoint.
void appendListObject(SkyObject *object)
Append a star to the Object List.
static StarComponent * Create(SkyComposite *)
Create an instance of StarComponent.
void drawLabels()
draw all the labels in the prioritized LabelLists and then clear the LabelLists.
void objectsInArea(QList< SkyObject * > &list, const SkyRegion &region) override
Searches the region(s) and appends the SkyObjects found to the list of sky objects.
This is a subclass of SkyObject.
Definition starobject.h:33
static double reindexInterval(double pm)
returns the reindex interval (in centuries!) for the given magnitude of proper motion (in milliarcsec...
StarObject * clone() const override
Create copy of object.
void JITupdate()
added for JIT updates from both StarComponent and ConstellationLines
void setNames(const QString &name, const QString &name2)
Sets the name, genetive name, and long name.
char spchar() const
Returns just the first character of the spectral type string.
double pmMagnitude() const
returns the magnitude of the proper motion correction in milliarcsec/year
Definition starobject.h:193
void init(const StarData *stardata)
Initializes a StarObject to given data.
QString gname(bool useGreekChars=true) const
Returns the genetive name of the star.
const double & Degrees() const
Definition dms.h:141
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)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QString name(StandardShortcut id)
char * data()
Int toInt() const const
const_iterator constBegin() const const
const_iterator constEnd() const const
iterator insert(const Key &key, const T &value)
T value(const Key &key) const const
void append(QList< T > &&value)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString arg(Args &&... args) const const
bool isEmpty() const const
QStringList split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QByteArray toLocal8Bit() const const
QString toLower() const const
SkipEmptyParts
void raise()
void show()
A 32-byte Structure that holds star data.
Definition stardata.h:18
qint16 mag
signed 16-bit raw magnitude.
Definition stardata.h:25
qint32 RA
Raw signed 32-bit RA value.
Definition stardata.h:19
qint32 HD
unsigned 32-bit Henry Draper Index.
Definition stardata.h:24
qint32 Dec
Raw signed 32-bit DE value.
Definition stardata.h:20
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:04 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.