11#include "kstars_debug.h"
14#include "projections/projector.h"
15#include "projections/lambertprojector.h"
20HIPSFinder * HIPSFinder::m_Instance =
nullptr;
25HIPSFinder *HIPSFinder::Instance()
27 if (m_Instance ==
nullptr)
29 m_Instance =
new HIPSFinder();
38HIPSFinder::HIPSFinder()
40 m_ScanRender.reset(
new ScanRender());
41 m_HEALpix.reset(
new HEALPix());
47bool HIPSFinder::render(
SkyPoint *center, uint8_t level,
double zoom,
QImage *destinationImage,
double &fov_w,
50 double ra =
center->ra0().radians();
51 double de =
center->dec0().radians();
55 if (std::isnan(ra) || std::isnan(de))
57 qCWarning(KSTARS) <<
"NAN Center, HiPS rendering failed.";
61 m_RenderedMap.clear();
64 ViewParams viewParams;
65 viewParams.width = destinationImage->
width();
66 viewParams.height = destinationImage->
height();
68 viewParams.useAltAz =
false;
69 viewParams.zoomFactor =
zoom;
72 m_Projector.
reset(
new LambertProjector(viewParams));
75 int centerPix = m_HEALpix->getPix(level, ra, de);
77 SkyPoint cornerSkyCoords[4];
81 m_HEALpix->getCornerPoints(level, centerPix, cornerSkyCoords);
87 for (
int i = 0; i < 2; i++)
88 tileLine[i] = m_Projector->toScreen(&cornerSkyCoords[i]);
90 int size = std::sqrt(std::pow(tileLine[0].x() - tileLine[1].x(), 2) + std::pow(tileLine[0].y() - tileLine[1].y(), 2));
92 size = HIPSManager::Instance()->getCurrentTileWidth();
94 m_ScanRender->setBilinearInterpolationEnabled(size >= HIPSManager::Instance()->getCurrentTileWidth());
96 renderRec(level, centerPix, destinationImage);
98 return !m_RenderedMap.isEmpty();
104bool HIPSFinder::renderFOV(
SkyPoint *center,
double fov_radius,
double rotation,
QImage *destinationImage)
106 double ra =
center->ra0().radians();
107 double de =
center->dec0().radians();
111 if (std::isnan(ra) || std::isnan(de))
113 qCWarning(KSTARS) <<
"NAN Center, HiPS rendering failed.";
117 m_RenderedMap.clear();
119 auto width = destinationImage->
width();
120 auto height = destinationImage->
height();
121 auto zoom = sqrt(width * width + height * height) / (fov_radius * 2 * M_PI / 180.0);
124 ViewParams viewParams;
125 viewParams.width = width;
126 viewParams.height = height;
128 viewParams.useAltAz =
false;
129 viewParams.zoomFactor =
zoom;
130 viewParams.rotationAngle = dms(rotation);
131 viewParams.focus =
center;
133 m_Projector.
reset(
new LambertProjector(viewParams));
138 double minfov = 58.5;
139 double fov = m_Projector->fov() * width / height;
149 level = HIPSManager::Instance()->getUsableOfflineLevel(level);
152 int centerPix = m_HEALpix->getPix(level, ra, de);
154 m_ScanRender->setBilinearInterpolationEnabled(Options::hIPSBiLinearInterpolation());
156 renderRec(level, centerPix, destinationImage);
158 return !m_RenderedMap.isEmpty();
165void HIPSFinder::renderRec(uint8_t level,
int pix,
QImage *destinationImage)
167 if (m_RenderedMap.contains(pix))
170 if (renderPix(level, pix, destinationImage))
172 m_RenderedMap.insert(pix);
174 int nside = 1 <<
level;
176 m_HEALpix->neighbours(nside, pix, dirs);
178 renderRec(level, dirs[0], destinationImage);
179 renderRec(level, dirs[2], destinationImage);
180 renderRec(level, dirs[4], destinationImage);
181 renderRec(level, dirs[6], destinationImage);
188bool HIPSFinder::renderPix(
int level,
int pix,
QImage *destinationImage)
190 SkyPoint cornerSkyCoords[4];
191 QPointF cornerScreenCoords[4];
192 bool isVisible =
false;
194 m_HEALpix->getCornerPoints(level, pix, cornerSkyCoords);
196 for (
int i = 0; i < 4; i++)
198 cornerScreenCoords[i] = m_Projector->toScreen(&cornerSkyCoords[i]);
199 isVisible |= m_Projector->checkVisibility(&cornerSkyCoords[i]);
204 int dir = (pix / 10000) * 10000;
206 QString(
"/HIPS/Norder%1/Dir%2/Npix%3.jpg").arg(level).arg(dir).arg(pix));
207 QImage sourceImage(path);
209 if (!sourceImage.isNull())
211 QPointF uv[16][4] = {{QPointF(.25, .25), QPointF(0.25, 0), QPointF(0, .0), QPointF(0, .25)},
212 {QPointF(.25, .5), QPointF(0.25, 0.25), QPointF(0, .25), QPointF(0, .5)},
213 {QPointF(.5, .25), QPointF(0.5, 0), QPointF(.25, .0), QPointF(.25, .25)},
214 {QPointF(.5, .5), QPointF(0.5, 0.25), QPointF(.25, .25), QPointF(.25, .5)},
216 {QPointF(.25, .75), QPointF(0.25, 0.5), QPointF(0, 0.5), QPointF(0, .75)},
217 {QPointF(.25, 1), QPointF(0.25, 0.75), QPointF(0, .75), QPointF(0, 1)},
218 {QPointF(.5, .75), QPointF(0.5, 0.5), QPointF(.25, .5), QPointF(.25, .75)},
219 {QPointF(.5, 1), QPointF(0.5, 0.75), QPointF(.25, .75), QPointF(.25, 1)},
221 {QPointF(.75, .25), QPointF(0.75, 0), QPointF(0.5, .0), QPointF(0.5, .25)},
222 {QPointF(.75, .5), QPointF(0.75, 0.25), QPointF(0.5, .25), QPointF(0.5, .5)},
223 {QPointF(1, .25), QPointF(1, 0), QPointF(.75, .0), QPointF(.75, .25)},
224 {QPointF(1, .5), QPointF(1, 0.25), QPointF(.75, .25), QPointF(.75, .5)},
226 {QPointF(.75, .75), QPointF(0.75, 0.5), QPointF(0.5, .5), QPointF(0.5, .75)},
227 {QPointF(.75, 1), QPointF(0.75, 0.75), QPointF(0.5, .75), QPointF(0.5, 1)},
228 {QPointF(1, .75), QPointF(1, 0.5), QPointF(.75, .5), QPointF(.75, .75)},
229 {QPointF(1, 1), QPointF(1, 0.75), QPointF(.75, .75), QPointF(.75, 1)},
235 m_HEALpix->getPixChilds(pix, childPixelID);
238 for (
int id : childPixelID)
240 int grandChildPixelID[4];
246 m_HEALpix->getPixChilds(
id, grandChildPixelID);
248 QPointF fineScreenCoords[4];
250 for (
int id2 : grandChildPixelID)
252 SkyPoint fineSkyPoints[4];
253 m_HEALpix->getCornerPoints(level + 2, id2, fineSkyPoints);
255 for (
int i = 0; i < 4; i++)
256 fineScreenCoords[i] = m_Projector->toScreen(&fineSkyPoints[i]);
258 m_ScanRender->renderPolygon(3, fineScreenCoords, destinationImage, &sourceImage, uv[j]);
The sky coordinates of a point in the sky.
dms angularDistanceTo(const SkyPoint *sp, double *const positionAngle=nullptr) const
Computes the angular distance between two SkyObjects.
bool fillGround
If the ground is filled, then points below horizon are invisible.
const double & Degrees() const
QString path(const QString &relativePath)
QStringView level(QStringView ifopt)
KIOCORE_EXPORT QString dir(const QString &fileClass)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
QTextStream & center(QTextStream &stream)