Kstars

deepstarcomponent.cpp
1/*
2 SPDX-FileCopyrightText: 2008 Akarsh Simha Thomas Kabelmann <akarshsimha@gmail.com, thomas.kabelmann@gmx.de>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "deepstarcomponent.h"
8
9#include "byteorder.h"
10#include "kstarsdata.h"
11#include "Options.h"
12#ifndef KSTARS_LITE
13#include "skymap.h"
14#endif
15#include "skymesh.h"
16#include "skypainter.h"
17#include "starblock.h"
18#include "starcomponent.h"
19#include "htmesh/MeshIterator.h"
20#include "projections/projector.h"
21
22#include <qplatformdefs.h>
23#include <QtConcurrent>
24#include <QElapsedTimer>
25
26#include <kstars_debug.h>
27
28#ifdef _WIN32
29#include <windows.h>
30#endif
31
32DeepStarComponent::DeepStarComponent(SkyComposite *parent, QString fileName, float trigMag, bool staticstars)
33 : ListComponent(parent), m_reindexNum(J2000), triggerMag(trigMag), m_FaintMagnitude(-5.0), staticStars(staticstars),
34 dataFileName(fileName)
35{
36 fileOpened = false;
37 openDataFile();
38 if (staticStars)
39 loadStaticStars();
40 qCInfo(KSTARS) << "Loaded DSO catalog file: " << dataFileName;
41}
42
43DeepStarComponent::~DeepStarComponent()
44{
45 if (fileOpened)
46 starReader.closeFile();
47 fileOpened = false;
48}
49
50bool DeepStarComponent::loadStaticStars()
51{
53
54 if (!staticStars)
55 return true;
56 if (!fileOpened)
57 return false;
58
59 dataFile = starReader.getFileHandle();
60 rewind(dataFile);
61
62 if (!starReader.readHeader())
63 {
64 qCCritical(KSTARS) << "Error reading header of catalog file " << dataFileName << ": " << starReader.getErrorNumber()
65 << ": " << starReader.getError();
66 return false;
67 }
68
69 quint8 recordSize = starReader.guessRecordSize();
70
71 if (recordSize != 16 && recordSize != 32)
72 {
73 qCCritical(KSTARS) << "Cannot understand catalog file " << dataFileName;
74 return false;
75 }
76
77 //KDE_fseek(dataFile, starReader.getDataOffset(), SEEK_SET);
79
80 qint16 faintmag;
81 quint8 htm_level;
82 quint16 t_MSpT;
83 int ret = 0;
84
85 ret = fread(&faintmag, 2, 1, dataFile);
86 if (starReader.getByteSwap())
87 faintmag = bswap_16(faintmag);
88 ret = fread(&htm_level, 1, 1, dataFile);
89 ret = fread(&t_MSpT, 2, 1, dataFile); // Unused
90 if (starReader.getByteSwap())
91 faintmag = bswap_16(faintmag);
92
93 // TODO: Read the multiplying factor from the dataFile
94 m_FaintMagnitude = faintmag / 100.0;
95
96 if (htm_level != m_skyMesh->level())
97 qCWarning(KSTARS) << "HTM Level in shallow star data file and HTM Level in m_skyMesh do not match. EXPECT TROUBLE!";
98
99 // JM 2012-12-05: Breaking into 2 loops instead of one previously with multiple IF checks for recordSize
100 // While the CPU branch prediction might not suffer any penalties since the branch prediction after a few times
101 // should always gets it right. It's better to do it this way to avoid any chances since the compiler might not optimize it.
102 if (recordSize == 32)
103 {
104 for (Trixel i = 0; i < m_skyMesh->size(); ++i)
105 {
106 Trixel trixel = i;
107 quint64 records = starReader.getRecordCount(i);
108 std::shared_ptr<StarBlock> SB(new StarBlock(records));
109
110 if (!SB.get())
111 qCCritical(KSTARS) << "ERROR: Could not allocate new StarBlock to hold shallow unnamed stars for trixel "
112 << trixel;
113
114 m_starBlockList.at(trixel)->setStaticBlock(SB);
115
116 for (quint64 j = 0; j < records; ++j)
117 {
118 bool fread_success = fread(&stardata, sizeof(StarData), 1, dataFile);
119
120 if (!fread_success)
121 {
122 qCCritical(KSTARS) << "ERROR: Could not read StarData structure for star #" << j << " under trixel #"
123 << trixel;
124 }
125
126 /* Swap Bytes when required */
127 if (starReader.getByteSwap())
128 byteSwap(&stardata);
129
130 /* Initialize star with data just read. */
131 StarObject *star;
132#ifdef KSTARS_LITE
133 star = &(SB->addStar(stardata)->star);
134#else
135 star = SB->addStar(stardata);
136#endif
137 if (star)
138 {
139 //KStarsData* data = KStarsData::Instance();
140 //star->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
141 //if( star->getHDIndex() != 0 )
142 if (stardata.HD)
143 m_CatalogNumber.insert(stardata.HD, star);
144 }
145 else
146 {
147 qCCritical(KSTARS) << "CODE ERROR: More unnamed static stars in trixel " << trixel
148 << " than we allocated space for!";
149 }
150 }
151 }
152 }
153 else
154 {
155 for (Trixel i = 0; i < m_skyMesh->size(); ++i)
156 {
157 Trixel trixel = i;
158 quint64 records = starReader.getRecordCount(i);
159 std::shared_ptr<StarBlock> SB(new StarBlock(records));
160
161 if (!SB.get())
162 qCCritical(KSTARS) << "Could not allocate new StarBlock to hold shallow unnamed stars for trixel "
163 << trixel;
164
165 m_starBlockList.at(trixel)->setStaticBlock(SB);
166
167 for (quint64 j = 0; j < records; ++j)
168 {
169 bool fread_success = false;
170 fread_success = fread(&deepstardata, sizeof(DeepStarData), 1, dataFile);
171
172 if (!fread_success)
173 {
174 qCCritical(KSTARS) << "Could not read StarData structure for star #" << j << " under trixel #"
175 << trixel;
176 }
177
178 /* Swap Bytes when required */
179 if (starReader.getByteSwap())
180 byteSwap(&deepstardata);
181
182 /* Initialize star with data just read. */
183 StarObject *star;
184#ifdef KSTARS_LITE
185 star = &(SB->addStar(stardata)->star);
186#else
187 star = SB->addStar(deepstardata);
188#endif
189 if (star)
190 {
191 //KStarsData* data = KStarsData::Instance();
192 //star->EquatorialToHorizontal( data->lst(), data->geo()->lat() );
193 //if( star->getHDIndex() != 0 )
194 if (stardata.HD)
195 m_CatalogNumber.insert(stardata.HD, star);
196 }
197 else
198 {
199 qCCritical(KSTARS) << "CODE ERROR: More unnamed static stars in trixel " << trixel
200 << " than we allocated space for!";
201 }
202 }
203 }
204 }
205
206 return true;
207}
208
210{
211 return Options::showStars() && fileOpened;
212}
213
214bool openIndexFile()
215{
216 // TODO: Work out the details
217 /*
218 if( hdidxReader.openFile( "Henry-Draper.idx" ) )
219 qDebug() << Q_FUNC_INFO << "Could not open HD Index file. Search by HD numbers for deep stars will not work.";
220 */
221 return 0;
222}
223
224//This function is empty for a reason; we override the normal
225//update function in favor of JiT updates for stars.
229
230// TODO: Optimize draw, if it is worth it.
232{
233#ifndef KSTARS_LITE
234 if (!fileOpened)
235 return;
236
237#ifdef PROFILE_SINCOS
238 long trig_calls_here = -dms::trig_function_calls;
239 long trig_redundancy_here = -dms::redundant_trig_function_calls;
240 long cachingdms_bad_uses = -CachingDms::cachingdms_bad_uses;
241 dms::seconds_in_trig = 0.;
242#endif
243
244#ifdef PROFILE_UPDATECOORDS
245 StarObject::updateCoordsCpuTime = 0.;
246 StarObject::starsUpdated = 0;
247#endif
248 SkyMap *map = SkyMap::Instance();
249 KStarsData *data = KStarsData::Instance();
250 UpdateID updateID = data->updateID();
251
252 //FIXME_FOV -- maybe not clamp like that...
253 float radius = map->projector()->fov();
254 if (radius > 90.0 && SkyMap::Instance()->projector()->type() != Projector::Stereographic)
255 radius = 90.0;
256
257 if (m_skyMesh != SkyMesh::Instance() && m_skyMesh->inDraw())
258 {
259 printf("Warning: aborting concurrent DeepStarComponent::draw()");
260 }
261 bool checkSlewing = (map->isSlewing() && Options::hideOnSlew());
262
263 //shortcuts to inform whether to draw different objects
264 bool hideFaintStars(checkSlewing && Options::hideStars());
265 double hideStarsMag = Options::magLimitHideStar();
266
267 //adjust maglimit for ZoomLevel
268 // double lgmin = log10(MINZOOM);
269 // double lgmax = log10(MAXZOOM);
270 // double lgz = log10(Options::zoomFactor());
271 // TODO: Enable hiding of faint stars
272
273 float maglim = StarComponent::zoomMagnitudeLimit();
274
275 if (maglim < triggerMag)
276 return;
277
278 m_zoomMagLimit = maglim;
279
280 m_skyMesh->inDraw(true);
281
282 SkyPoint *focus = map->focus();
283 m_skyMesh->aperture(focus, radius + 1.0, DRAW_BUF); // divide by 2 for testing
284
285 MeshIterator region(m_skyMesh, DRAW_BUF);
286
287 // If we are to hide the fainter stars (eg: while slewing), we set the magnitude limit to hideStarsMag.
288 if (hideFaintStars && maglim > hideStarsMag)
289 maglim = hideStarsMag;
290
291 StarBlockFactory *m_StarBlockFactory = StarBlockFactory::Instance();
292 // m_StarBlockFactory->drawID = m_skyMesh->drawID();
293 // qDebug() << Q_FUNC_INFO << "Mesh size = " << m_skyMesh->size() << "; drawID = " << m_skyMesh->drawID();
295 int nTrixels = 0;
296
297 t_dynamicLoad = 0;
298 t_updateCache = 0;
299 t_drawUnnamed = 0;
300
301 visibleStarCount = 0;
302
303 t.start();
304
305 // Mark used blocks in the LRU Cache. Not required for static stars
306 if (!staticStars)
307 {
308 while (region.hasNext())
309 {
310 Trixel currentRegion = region.next();
311 for (int i = 0; i < m_starBlockList.at(currentRegion)->getBlockCount(); ++i)
312 {
313 std::shared_ptr<StarBlock> prevBlock = ((i >= 1) ? m_starBlockList.at(currentRegion)->block(
314 i - 1) : std::shared_ptr<StarBlock>());
315 std::shared_ptr<StarBlock> block = m_starBlockList.at(currentRegion)->block(i);
316
317 if (i == 0 && !m_StarBlockFactory->markFirst(block))
318 qCWarning(KSTARS) << "markFirst failed in trixel" << currentRegion;
319 if (i > 0 && !m_StarBlockFactory->markNext(prevBlock, block))
320 qCWarning(KSTARS) << "markNext failed in trixel" << currentRegion << "while marking block" << i;
321 if (i < m_starBlockList.at(currentRegion)->getBlockCount() &&
322 m_starBlockList.at(currentRegion)->block(i)->getFaintMag() < maglim)
323 break;
324 }
325 }
326 t_updateCache = t.elapsed();
327 region.reset();
328 }
329
330 while (region.hasNext())
331 {
332 ++nTrixels;
333 Trixel currentRegion = region.next();
334
335 // NOTE: We are guessing that the last 1.5/16 magnitudes in the catalog are just additions and the star catalog
336 // is actually supposed to reach out continuously enough only to mag m_FaintMagnitude * ( 1 - 1.5/16 )
337 // TODO: Is there a better way? We may have to change the magnitude tolerance if the catalog changes
338 // Static stars need not execute fillToMag
339
340 // Safety check if the current region is in star block list
341 if (currentRegion >= m_starBlockList.size())
342 continue;
343
344 if (!staticStars)
345 {
346 m_starBlockList.at(currentRegion)->fillToMag(maglim);
347 }
348
349 // if (!staticStars && !m_starBlockList.at(currentRegion)->fillToMag(maglim) &&
350 // maglim <= m_FaintMagnitude * (1 - 1.5 / 16))
351 // {
352 // qCWarning(KSTARS) << "SBL::fillToMag( " << maglim << " ) failed for trixel " << currentRegion;
353 // }
354
355 t_dynamicLoad += t.restart();
356
357 // qDebug() << Q_FUNC_INFO << "Drawing SBL for trixel " << currentRegion << ", SBL has "
358 // << m_starBlockList[ currentRegion ]->getBlockCount() << " blocks";
359
360 // REMARK: The following should never carry state, except for const parameters like updateID and maglim
361 std::function<void(std::shared_ptr<StarBlock>)> mapFunction = [&updateID, &maglim](std::shared_ptr<StarBlock> myBlock)
362 {
363 for (StarObject &star : myBlock->contents())
364 {
365 if (star.updateID != updateID)
366 star.JITupdate();
367 if (star.mag() > maglim)
368 break;
369 }
370 };
371
372 QtConcurrent::blockingMap(m_starBlockList.at(currentRegion)->contents(), mapFunction);
373
374 for (int i = 0; i < m_starBlockList.at(currentRegion)->getBlockCount(); ++i)
375 {
376 std::shared_ptr<StarBlock> block = m_starBlockList.at(currentRegion)->block(i);
377 // qDebug() << Q_FUNC_INFO << "---> Drawing stars from block " << i << " of trixel " <<
378 // currentRegion << ". SB has " << block->getStarCount() << " stars";
379 for (int j = 0; j < block->getStarCount(); j++)
380 {
381 StarObject *curStar = block->star(j);
382
383 // qDebug() << Q_FUNC_INFO << "We claim that he's from trixel " << currentRegion
384 //<< ", and indexStar says he's from " << m_skyMesh->indexStar( curStar );
385
386 float mag = curStar->mag();
387
388 if (mag > maglim)
389 break;
390
391 if (skyp->drawPointSource(curStar, mag, curStar->spchar()))
392 visibleStarCount++;
393 }
394 }
395
396 // DEBUG: Uncomment to identify problems with Star Block Factory / preservation of Magnitude Order in the LRU Cache
397 // verifySBLIntegrity();
398 t_drawUnnamed += t.restart();
399 }
400 m_skyMesh->inDraw(false);
401#ifdef PROFILE_SINCOS
402 trig_calls_here += dms::trig_function_calls;
403 trig_redundancy_here += dms::redundant_trig_function_calls;
404 cachingdms_bad_uses += CachingDms::cachingdms_bad_uses;
405 qDebug() << Q_FUNC_INFO << "Spent " << dms::seconds_in_trig << " seconds doing " << trig_calls_here
406 << " trigonometric function calls amounting to an average of "
407 << 1000.0 * dms::seconds_in_trig / double(trig_calls_here) << " ms per call";
408 qDebug() << Q_FUNC_INFO << "Redundancy of trig calls in this draw: "
409 << double(trig_redundancy_here) / double(trig_calls_here) * 100. << "%";
410 qDebug() << Q_FUNC_INFO << "CachedDms constructor calls so far: " << CachingDms::cachingdms_constructor_calls;
411 qDebug() << Q_FUNC_INFO << "Caching has prevented " << CachingDms::cachingdms_delta << " redundant trig function calls";
412 qDebug() << Q_FUNC_INFO << "Bad cache uses in this draw: " << cachingdms_bad_uses;
413#endif
414#ifdef PROFILE_UPDATECOORDS
415 qDebug() << Q_FUNC_INFO << "Spent " << StarObject::updateCoordsCpuTime << " seconds updating " << StarObject::starsUpdated
416 << " stars' coordinates (StarObject::updateCoords) for an average of "
417 << double(StarObject::updateCoordsCpuTime) / double(StarObject::starsUpdated) * 1.e6 << " us per star.";
418#endif
419
420#else
422#endif
423}
424
425bool DeepStarComponent::openDataFile()
426{
427 if (starReader.getFileHandle())
428 return true;
429
430 starReader.openFile(dataFileName);
431 fileOpened = false;
432 if (!starReader.getFileHandle())
433 qCWarning(KSTARS) << "Failed to open deep star catalog " << dataFileName << ". Disabling it.";
434 else if (!starReader.readHeader())
435 qCWarning(KSTARS) << "Header read error for deep star catalog " << dataFileName << "!! Disabling it!";
436 else
437 {
438 qint16 faintmag;
439 quint8 htm_level;
440 int ret = 0;
441
442 ret = fread(&faintmag, 2, 1, starReader.getFileHandle());
443 if (starReader.getByteSwap())
444 faintmag = bswap_16(faintmag);
445 if (starReader.guessRecordSize() == 16)
446 m_FaintMagnitude = faintmag / 1000.0;
447 else
448 m_FaintMagnitude = faintmag / 100.0;
449 ret = fread(&htm_level, 1, 1, starReader.getFileHandle());
450 qCInfo(KSTARS) << "Processing " << dataFileName << ", HTMesh Level" << htm_level;
451 m_skyMesh = SkyMesh::Instance(htm_level);
452 if (!m_skyMesh)
453 {
454 if (!(m_skyMesh = SkyMesh::Create(htm_level)))
455 {
456 qCWarning(KSTARS) << "Could not create HTMesh of level " << htm_level << " for catalog " << dataFileName
457 << ". Skipping it.";
458 return false;
459 }
460 }
461 ret = fread(&MSpT, 2, 1, starReader.getFileHandle());
462 if (starReader.getByteSwap())
463 MSpT = bswap_16(MSpT);
464 fileOpened = true;
465 qCInfo(KSTARS) << " Sky Mesh Size: " << m_skyMesh->size();
466 for (long int i = 0; i < m_skyMesh->size(); i++)
467 {
468 std::shared_ptr<StarBlockList> sbl(new StarBlockList(i, this));
469
470 if (!sbl.get())
471 {
472 qCWarning(KSTARS) << "nullptr starBlockList. Expect trouble!";
473 }
474 m_starBlockList.append(sbl);
475 }
476 m_zoomMagLimit = 0.06;
477 }
478
479 return fileOpened;
480}
481
483{
484 // Currently, we only handle HD catalog indexes
485 return m_CatalogNumber.value(HDnum, nullptr); // TODO: Maybe, make this more general.
486}
487
488// This uses the main star index for looking up nearby stars but then
489// filters out objects with the generic name "star". We could easily
490// build an index for just the named stars which would make this go
491// much faster still. -jbb
492//
493
495{
496 StarObject *oBest = nullptr;
497
498#ifdef KSTARS_LITE
499 m_zoomMagLimit = StarComponent::zoomMagnitudeLimit();
500#endif
501 if (!fileOpened)
502 return nullptr;
503
504 m_skyMesh->index(p, maxrad + 1.0, OBJ_NEAREST_BUF);
505
506 MeshIterator region(m_skyMesh, OBJ_NEAREST_BUF);
507
508 while (region.hasNext())
509 {
510 Trixel currentRegion = region.next();
511
512 // Safety check if the current region is in star block list
513 if ((int)currentRegion >= m_starBlockList.size())
514 continue;
515
516 for (int i = 0; i < m_starBlockList.at(currentRegion)->getBlockCount(); ++i)
517 {
518 std::shared_ptr<StarBlock> block = m_starBlockList.at(currentRegion)->block(i);
519 for (int j = 0; j < block->getStarCount(); ++j)
520 {
521#ifdef KSTARS_LITE
522 StarObject *star = &(block->star(j)->star);
523#else
524 StarObject *star = block->star(j);
525#endif
526 if (!star)
527 continue;
528 if (star->mag() > m_zoomMagLimit)
529 continue;
530
531 double r = star->angularDistanceTo(p).Degrees();
532 if (r < maxrad)
533 {
534 oBest = star;
535 maxrad = r;
536 }
537 }
538 }
539 }
540
541 // TODO: What if we are looking around a point that's not on
542 // screen? objectNearest() will need to keep on filling up all
543 // trixels around the SkyPoint to find the best match in case it
544 // has not been found. Ideally, this should be implemented in a
545 // different method and should be called after all other
546 // candidates (eg: DeepSkyObject::objectNearest()) have been
547 // called.
548
549 return oBest;
550}
551
552bool DeepStarComponent::starsInAperture(QList<StarObject *> &list, const SkyPoint &center, float radius, float maglim)
553{
554 if (maglim < triggerMag)
555 return false;
556
557 // For DeepStarComponents, whether we use ra0() and dec0(), or
558 // ra() and dec(), should not matter, because the stars are
559 // repeated in all trixels that they will pass through, although
560 // the factuality of this statement needs to be verified
561
562 // Ensure that we have deprecessed the (RA, Dec) to (RA0, Dec0)
563 Q_ASSERT(center.ra0().Degrees() >= 0.0);
564 Q_ASSERT(center.dec0().Degrees() <= 90.0);
565
566 m_skyMesh->intersect(center.ra0().Degrees(), center.dec0().Degrees(), radius, (BufNum)OBJ_NEAREST_BUF);
567
568 MeshIterator region(m_skyMesh, OBJ_NEAREST_BUF);
569
570 if (maglim < -28)
571 maglim = m_FaintMagnitude;
572
573 while (region.hasNext())
574 {
575 Trixel currentRegion = region.next();
576 // FIXME: Build a better way to iterate over all stars.
577 // Ideally, StarBlockList should have such a facility.
578 std::shared_ptr<StarBlockList> sbl = m_starBlockList[currentRegion];
579 sbl->fillToMag(maglim);
580 for (int i = 0; i < sbl->getBlockCount(); ++i)
581 {
582 std::shared_ptr<StarBlock> block = sbl->block(i);
583 for (int j = 0; j < block->getStarCount(); ++j)
584 {
585#ifdef KSTARS_LITE
586 StarObject *star = &(block->star(j)->star);
587#else
588 StarObject *star = block->star(j);
589#endif
590 if (star->mag() > maglim)
591 break; // Stars are organized by magnitude, so this should work
592 if (star->angularDistanceTo(&center).Degrees() <= radius)
593 list.append(star);
594 }
595 }
596 }
597
598 return true;
599}
600
601void DeepStarComponent::byteSwap(DeepStarData *stardata)
602{
603 stardata->RA = bswap_32(stardata->RA);
604 stardata->Dec = bswap_32(stardata->Dec);
605 stardata->dRA = bswap_16(stardata->dRA);
606 stardata->dDec = bswap_16(stardata->dDec);
607 stardata->B = bswap_16(stardata->B);
608 stardata->V = bswap_16(stardata->V);
609}
610
611void DeepStarComponent::byteSwap(StarData *stardata)
612{
613 stardata->RA = bswap_32(stardata->RA);
614 stardata->Dec = bswap_32(stardata->Dec);
615 stardata->dRA = bswap_32(stardata->dRA);
616 stardata->dDec = bswap_32(stardata->dDec);
617 stardata->parallax = bswap_32(stardata->parallax);
618 stardata->HD = bswap_32(stardata->HD);
619 stardata->mag = bswap_16(stardata->mag);
620 stardata->bv_index = bswap_16(stardata->bv_index);
621}
622
623bool DeepStarComponent::verifySBLIntegrity()
624{
625 float faintMag = -5.0;
626 bool integrity = true;
627
628 for (Trixel trixel = 0; trixel < m_skyMesh->size(); ++trixel)
629 {
630 for (int i = 0; i < m_starBlockList[trixel]->getBlockCount(); ++i)
631 {
632 std::shared_ptr<StarBlock> block = m_starBlockList[trixel]->block(i);
633
634 if (i == 0)
635 faintMag = block->getBrightMag();
636 // NOTE: Assumes 2 decimal places in magnitude field. TODO: Change if it ever does change
637 if (block->getBrightMag() != faintMag && (block->getBrightMag() - faintMag) > 0.5)
638 {
639 qCWarning(KSTARS) << "Trixel " << trixel << ": ERROR: faintMag of prev block = " << faintMag
640 << ", brightMag of block #" << i << " = " << block->getBrightMag();
641 integrity = false;
642 }
643 if (i > 1 && (!block->prev))
644 qCWarning(KSTARS) << "Trixel " << trixel << ": ERROR: Block" << i << "is unlinked in LRU Cache";
645 if (block->prev && block->prev->parent == m_starBlockList[trixel].get() &&
646 block->prev != m_starBlockList[trixel]->block(i - 1))
647 {
648 qCWarning(KSTARS) << "Trixel " << trixel
649 << ": ERROR: SBF LRU Cache linked list seems to be broken at before block " << i;
650 integrity = false;
651 }
652 faintMag = block->getFaintMag();
653 }
654 }
655 return integrity;
656}
FILE * getFileHandle() const
Get the file handle corresponding to the currently open file.
long getDataOffset() const
Returns the offset at which the data begins.
void closeFile()
Close the binary data file.
bool readHeader()
Read the header and index table from the file and fill up the QVector s with the entries.
int getErrorNumber()
Get error number.
bool getByteSwap() const
Should we do byte swapping?
unsigned int getRecordCount(int id) const
Returns the number of records under the given index ID.
FILE * openFile(const QString &fileName)
WARNING: This function may not be compatible in other locales, because it calls QString::toAscii.
QString getError()
Get error string.
int guessRecordSize() const
Return a guessed record size.
bool 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...
void draw(SkyPainter *skyp) override
Draw the object on the SkyMap skyp a pointer to the SkyPainter to use.
void update(KSNumbers *num) override
Update the sky position(s) of this component.
StarObject * findByHDIndex(int HDnum)
SkyObject * objectNearest(SkyPoint *p, double &maxrad) override
bool selected() override
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
There are several time-dependent values used in position calculations, that are not specific to an ob...
Definition ksnumbers.h:43
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
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...
void reset() const
sets the count back to zero so you can use this iterator to iterate again over the same result set.
Trixel next() const
returns the next trixel
bool hasNext() const
true if there are more trixel to iterate over.
SkyComposite is a kind of container class for SkyComponent objects.
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
static SkyMesh * Create(int level)
creates the single instance of SkyMesh.
Definition skymesh.cpp:25
void aperture(SkyPoint *center, double radius, MeshBufNum_t bufNum=DRAW_BUF)
finds the set of trixels that cover the circular aperture specified after first performing a reverse ...
Definition skymesh.cpp:56
Trixel index(const SkyPoint *p)
returns the index of the trixel containing p.
Definition skymesh.cpp:74
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
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
A factory that creates StarBlocks and recycles them in an LRU Cache.
bool markNext(std::shared_ptr< StarBlock > &after, std::shared_ptr< StarBlock > &block)
Rank a given StarBlock after another given StarBlock in the LRU list and sync its drawID with the cur...
bool markFirst(std::shared_ptr< StarBlock > &block)
Mark a StarBlock as most recently used and sync its drawID with the current drawID.
Maintains a list of StarBlocks that contain the stars lying in a single trixel.
Holds a block of stars and various peripheral variables to mark its place in data structures.
Definition starblock.h:43
This is a subclass of SkyObject.
Definition starobject.h:33
void JITupdate()
added for JIT updates from both StarComponent and ConstellationLines
const double & Degrees() const
Definition dms.h:141
qint64 elapsed() const const
qint64 restart()
iterator insert(const Key &key, const T &value)
T value(const Key &key) const const
void blockingMap(Iterator begin, Iterator end, MapFunctor &&function)
A 16-byte structure that holds star data for really faint stars.
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 Fri May 17 2024 11:48:27 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.