Kstars

hipsfinder.cpp
1 /*
2  SPDX-FileCopyrightText: 2021 Jasem Mutlaq
3 
4  Static version of the HIPS Renderer for a single point in the sky.
5 
6  SPDX-License-Identifier: GPL-2.0-or-later
7 */
8 
9 #include "hipsfinder.h"
10 
11 #include "kstars_debug.h"
12 #include "Options.h"
13 #include "skymap.h"
14 #include "kstars.h"
15 #include "skyqpainter.h"
16 #include "kspaths.h"
17 #include "projections/projector.h"
18 #include "projections/lambertprojector.h"
19 
20 ///////////////////////////////////////////////////////////////////////////////////////////
21 ///
22 ///////////////////////////////////////////////////////////////////////////////////////////
23 HIPSFinder * HIPSFinder::m_Instance = nullptr;
24 
25 ///////////////////////////////////////////////////////////////////////////////////////////
26 ///
27 ///////////////////////////////////////////////////////////////////////////////////////////
28 HIPSFinder *HIPSFinder::Instance()
29 {
30  if (m_Instance == nullptr)
31  {
32  m_Instance = new HIPSFinder();
33  }
34 
35  return m_Instance;
36 }
37 
38 ///////////////////////////////////////////////////////////////////////////////////////////
39 ///
40 ///////////////////////////////////////////////////////////////////////////////////////////
41 HIPSFinder::HIPSFinder()
42 {
43  m_ScanRender.reset(new ScanRender());
44  m_HEALpix.reset(new HEALPix());
45 }
46 
47 ///////////////////////////////////////////////////////////////////////////////////////////
48 /// Static
49 ///////////////////////////////////////////////////////////////////////////////////////////
50 bool HIPSFinder::render(SkyPoint *center, uint8_t level, double zoom, QImage *destinationImage, double &fov_w, double &fov_h)
51 {
52  double ra = center->ra0().radians();
53  double de = center->dec0().radians();
54  // do we need this? or updateCoords?
55  //center.catalogueCoord(KStarsData::Instance()->updateNum()->julianDay());
56 
57  if (std::isnan(ra) || std::isnan(de))
58  {
59  qCWarning(KSTARS) << "NAN Center, HiPS rendering failed.";
60  return false;
61  }
62 
63  m_RenderedMap.clear();
64 
65  //const Projector *m = KStars::Instance()->map()->projector();
66 
67  // Setup sample projector
68  ViewParams viewParams;
69  viewParams.width = destinationImage->width();
70  viewParams.height = destinationImage->height();
71  viewParams.fillGround = false;
72  viewParams.useAltAz = false;
73  viewParams.zoomFactor = zoom;
74  viewParams.focus = center;
75 
76  m_Projector.reset(new LambertProjector(viewParams));
77 
78  // Get the ID of the face at this level containing the coordinates.
79  int centerPix = m_HEALpix->getPix(level, ra, de);
80 
81  SkyPoint cornerSkyCoords[4];
82  QPointF tileLine[2];
83 
84  // Get corners for this face
85  m_HEALpix->getCornerPoints(level, centerPix, cornerSkyCoords);
86 
87  fov_w = cornerSkyCoords[0].angularDistanceTo(&cornerSkyCoords[1]).Degrees();
88  fov_h = cornerSkyCoords[1].angularDistanceTo(&cornerSkyCoords[2]).Degrees();
89 
90  // Map the tile lines to the corners
91  for (int i = 0; i < 2; i++)
92  tileLine[i] = m_Projector->toScreen(&cornerSkyCoords[i]);
93 
94  int size = std::sqrt(std::pow(tileLine[0].x() - tileLine[1].x(), 2) + std::pow(tileLine[0].y() - tileLine[1].y(), 2));
95  if (size < 0)
96  size = HIPSManager::Instance()->getCurrentTileWidth();
97 
98  m_ScanRender->setBilinearInterpolationEnabled(size >= HIPSManager::Instance()->getCurrentTileWidth());
99 
100  renderRec(level, centerPix, destinationImage);
101 
102  return !m_RenderedMap.isEmpty();
103 }
104 
105 ///////////////////////////////////////////////////////////////////////////////////////////
106 /// Static
107 ///////////////////////////////////////////////////////////////////////////////////////////
108 void HIPSFinder::renderRec(uint8_t level, int pix, QImage *destinationImage)
109 {
110  if (m_RenderedMap.contains(pix))
111  return;
112 
113  if (renderPix(level, pix, destinationImage))
114  {
115  m_RenderedMap.insert(pix);
116  int dirs[8];
117  int nside = 1 << level;
118 
119  m_HEALpix->neighbours(nside, pix, dirs);
120 
121  renderRec(level, dirs[0], destinationImage);
122  renderRec(level, dirs[2], destinationImage);
123  renderRec(level, dirs[4], destinationImage);
124  renderRec(level, dirs[6], destinationImage);
125  }
126 }
127 
128 ///////////////////////////////////////////////////////////////////////////////////////////
129 ///
130 ///////////////////////////////////////////////////////////////////////////////////////////
131 bool HIPSFinder::renderPix(int level, int pix, QImage *destinationImage)
132 {
133  SkyPoint cornerSkyCoords[4];
134  QPointF cornerScreenCoords[4];
135  bool isVisible = false;
136 
137  m_HEALpix->getCornerPoints(level, pix, cornerSkyCoords);
138 
139  for (int i = 0; i < 4; i++)
140  {
141  cornerScreenCoords[i] = m_Projector->toScreen(&cornerSkyCoords[i]);
142  isVisible |= m_Projector->checkVisibility(&cornerSkyCoords[i]);
143  }
144 
145  if (isVisible)
146  {
147  int dir = (pix / 10000) * 10000;
148  QString path = KSPaths::locate(QStandardPaths::AppLocalDataLocation,
149  QString("/HIPS/Norder%1/Dir%2/Npix%3.jpg").arg(level).arg(dir).arg(pix));
150  QImage sourceImage(path);
151 
152  if (!sourceImage.isNull())
153  {
154  QPointF uv[16][4] = {{QPointF(.25, .25), QPointF(0.25, 0), QPointF(0, .0), QPointF(0, .25)},
155  {QPointF(.25, .5), QPointF(0.25, 0.25), QPointF(0, .25), QPointF(0, .5)},
156  {QPointF(.5, .25), QPointF(0.5, 0), QPointF(.25, .0), QPointF(.25, .25)},
157  {QPointF(.5, .5), QPointF(0.5, 0.25), QPointF(.25, .25), QPointF(.25, .5)},
158 
159  {QPointF(.25, .75), QPointF(0.25, 0.5), QPointF(0, 0.5), QPointF(0, .75)},
160  {QPointF(.25, 1), QPointF(0.25, 0.75), QPointF(0, .75), QPointF(0, 1)},
161  {QPointF(.5, .75), QPointF(0.5, 0.5), QPointF(.25, .5), QPointF(.25, .75)},
162  {QPointF(.5, 1), QPointF(0.5, 0.75), QPointF(.25, .75), QPointF(.25, 1)},
163 
164  {QPointF(.75, .25), QPointF(0.75, 0), QPointF(0.5, .0), QPointF(0.5, .25)},
165  {QPointF(.75, .5), QPointF(0.75, 0.25), QPointF(0.5, .25), QPointF(0.5, .5)},
166  {QPointF(1, .25), QPointF(1, 0), QPointF(.75, .0), QPointF(.75, .25)},
167  {QPointF(1, .5), QPointF(1, 0.25), QPointF(.75, .25), QPointF(.75, .5)},
168 
169  {QPointF(.75, .75), QPointF(0.75, 0.5), QPointF(0.5, .5), QPointF(0.5, .75)},
170  {QPointF(.75, 1), QPointF(0.75, 0.75), QPointF(0.5, .75), QPointF(0.5, 1)},
171  {QPointF(1, .75), QPointF(1, 0.5), QPointF(.75, .5), QPointF(.75, .75)},
172  {QPointF(1, 1), QPointF(1, 0.75), QPointF(.75, .75), QPointF(.75, 1)},
173  };
174 
175  int childPixelID[4];
176 
177  // Find all the 4 children of the current pixel
178  m_HEALpix->getPixChilds(pix, childPixelID);
179 
180  int j = 0;
181  for (int id : childPixelID)
182  {
183  int grandChildPixelID[4];
184  // Find the children of this child (i.e. grand child)
185  // Then we have 4x4 pixels under the primary pixel
186  // The image is interpolated and rendered over these pixels
187  // coordinate to minimize any distortions due to the projection
188  // system.
189  m_HEALpix->getPixChilds(id, grandChildPixelID);
190 
191  QPointF fineScreenCoords[4];
192 
193  for (int id2 : grandChildPixelID)
194  {
195  SkyPoint fineSkyPoints[4];
196  m_HEALpix->getCornerPoints(level + 2, id2, fineSkyPoints);
197 
198  for (int i = 0; i < 4; i++)
199  fineScreenCoords[i] = m_Projector->toScreen(&fineSkyPoints[i]);
200 
201  m_ScanRender->renderPolygon(3, fineScreenCoords, destinationImage, &sourceImage, uv[j]);
202  j++;
203  }
204  }
205 
206  return true;
207  }
208  }
209 
210  return false;
211 }
int height() const const
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
QStringView level(QStringView ifopt)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
void reset()
This is just a container that holds information needed to do projections.
Definition: projector.h:36
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
Definition: skypoint.cpp:899
bool fillGround
If the ground is filled, then points below horizon are invisible.
Definition: projector.h:43
KIOFILEWIDGETS_EXPORT QString dir(const QString &fileClass)
const double & Degrees() const
Definition: dms.h:141
KStandardDirs * dirs()
QTextStream & center(QTextStream &stream)
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Aug 11 2022 03:59:59 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.