Kstars

starcomponent.cpp
1 /*
2  SPDX-FileCopyrightText: 2005 Thomas Kabelmann <[email protected]>
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 
46 StarComponent *StarComponent::pinstance = nullptr;
47 
48 StarComponent::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 
80 StarComponent::~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 
104 bool 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 
114 int 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.
134 {
135 }
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 
140 bool 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 
161 void 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 
206 float 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 
218 float 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
354  Q_UNUSED(skyp)
355 #endif
356 }
357 
358 void 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 
394 bool 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.
398  FILE *dataFile, *nameFile;
399  bool swapBytes = false, named = false, gnamed = false;
400  BinFileHelper dataReader, nameReader;
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 
585 SkyObject *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;
614  BinFileHelper hdidxReader;
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;
699  SkyObject *oTry;
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 
717 void 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 
753 void 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 /*
765 void 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 
810 bool 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 */
void setKSNumbers(KSNumbers *num)
sets the time for indexing StarObjects and CLines.
Definition: skymesh.h:145
void append(const T &value)
const T value(const Key &key) const const
Represents the stars on the sky map. For optimization reasons the stars are not separate objects and ...
Definition: starcomponent.h:47
SkyObject * objectNearest(SkyPoint *p, double &maxrad) override
Find the SkyObject nearest the given SkyPoint.
static bool testFileExists(const QString &fileName)
Checks if a file exists.
A 32-byte Structure that holds star data.
Definition: stardata.h:17
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
static void initStarImages()
Recalculates the star pixmaps.
bool readHeader()
Read the header and index table from the file and fill up the QVector s with the entries.
void append(const T &value)
bool getByteSwap() const
Should we do byte swapping?
CachingDms * lst()
Definition: kstarsdata.h:224
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
virtual QString name(void) const
Definition: skyobject.h:145
void setNames(const QString &name, const QString &name2)
Sets the name, genetive name, and long name.
Definition: starobject.cpp:231
float mag() const
Definition: skyobject.h:206
void push_back(const T &value)
void setPen(const QPen &pen)
sets the pen used for drawing labels on the sky.
Definition: skylabeler.cpp:197
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
void objectsInArea(QList< SkyObject * > &list, const SkyRegion &region) override
Searches the region(s) and appends the SkyObjects found to the list of sky objects.
static StarComponent * Create(SkyComposite *)
Create an instance of StarComponent.
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
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
qint32 RA
Raw signed 32-bit RA value.
Definition: stardata.h:19
QHash::iterator insert(const Key &key, const T &value)
SkyComposite * parent()
Definition: skycomponent.h:137
double pmMagnitude() const
returns the magnitude of the proper motion correction in milliarcsec/year
Definition: starobject.h:193
void closeFile()
Close the binary data file.
int size() const const
QString gname(bool useGreekChars=true) const
Returns the genetive name of the star.
Definition: starobject.cpp:559
void clear()
unsigned int getRecordCount(int id) const
Returns the number of records under the given index ID.
QString i18n(const char *text, const TYPE &arg...)
Store several time-dependent astronomical quantities.
Definition: ksnumbers.h:42
const CachingDms * lat() const
Definition: geolocation.h:70
QHash::const_iterator constBegin() const const
QHash::const_iterator constEnd() const const
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
the KStars Splash Screen.
Definition: kstarssplash.h:20
DrawID drawID() const
Definition: skymesh.h:264
subclass of SkyObject specialized for stars.
Definition: starobject.h:32
SkipEmptyParts
QString getError()
Get error string.
bool isEmpty() const const
GeoLocation * geo()
Definition: kstarsdata.h:230
virtual bool drawPointSource(const SkyPoint *loc, float mag, char sp='A')=0
Draw a point source (e.g., a star).
const T & at(int i) const const
Implements an interface to handle binary data files used by KStars.
Definition: binfilehelper.h:38
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 init(const StarData *stardata)
Initializes a StarObject to given data.
Definition: starobject.cpp:133
Draws things on the sky, without regard to backend.
Definition: skypainter.h:39
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
Definition: skypoint.cpp:899
bool hasNext() const
true if there are more trixel to iterate over.
Definition: MeshIterator.h:27
void show()
static SkyMesh * Instance()
returns the default instance of SkyMesh or null if it has not yet been created.
Definition: skymesh.cpp:39
QString toLower() const const
char spchar() const
Returns just the first character of the spectral type string.
Definition: starobject.cpp:554
bool selected() override
qint32 HD
unsigned 32-bit Henry Draper Index.
Definition: stardata.h:24
void update(KSNumbers *num) override
Update the sky positions of this component.
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void raise()
StarObject * clone() const override
Create copy of object.
Definition: starobject.cpp:126
bool drawNameLabel(SkyObject *obj, const QPointF &_p, const qreal padding_factor=1)
Tries to draw a label for an object.
Definition: skylabeler.cpp:161
const double & Degrees() const
Definition: dms.h:141
qint16 mag
signed 16-bit raw magnitude.
Definition: stardata.h:25
Canvas widget for displaying the sky bitmap; also handles user interaction events.
Definition: skymap.h:53
QPointF toScreen(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
This is exactly the same as toScreenVec but it returns a QPointF.
Definition: projector.cpp:93
const char * name(StandardAction id)
void clear()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void JITupdate()
added for JIT updates from both StarComponent and ConstellationLines
Definition: starobject.cpp:526
qint32 Dec
Raw signed 32-bit DE value.
Definition: stardata.h:20
virtual QString longname(void) const
Definition: skyobject.h:164
void drawLabels()
draw all the labels in the prioritized LabelLists and then clear the LabelLists.
double julianCenturies() const
Definition: ksnumbers.h:88
QString name2(void) const
Definition: skyobject.h:156
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.
Information about an object in the sky.
Definition: skyobject.h:41
void draw(SkyPainter *skyp) override
Draw the object on the SkyMap skyp a pointer to the SkyPainter to use.
static double reindexInterval(double pm)
returns the reindex interval (in centuries!) for the given magnitude of proper motion (in milliarcsec...
Definition: starobject.cpp:46
FILE * openFile(const QString &fileName)
WARNING: This function may not be compatible in other locales, because it calls QString::toAscii.
Trixel next() const
returns the next trixel
Definition: MeshIterator.h:31
long getDataOffset() const
Returns the offset at which the data begins.
int getErrorNumber()
Get error number.
void appendListObject(SkyObject *object)
Append a star to the Object List.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Sun Oct 1 2023 04:02:44 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.