• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Stellarium / stellarium / 15670918640

16 Jun 2025 02:08AM UTC coverage: 11.775% (-0.2%) from 11.931%
15670918640

push

github

alex-w
Updated data

14700 of 124846 relevant lines covered (11.77%)

18324.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/core/StelSkyImageTile.cpp
1
/*
2
 * Copyright (C) 2008 Fabien Chereau
3
 *
4
 * This program is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU General Public License
6
 * as published by the Free Software Foundation; either version 2
7
 * of the License, or (at your option) any later version.
8
 *
9
 * This program is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU General Public License
15
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA  02110-1335, USA.
17
 */
18

19
#include "StelSkyImageTile.hpp"
20
#include "StelTextureMgr.hpp"
21
#include "StelApp.hpp"
22
#include "StelFileMgr.hpp"
23
#include "StelUtils.hpp"
24
#include "StelTexture.hpp"
25
#include "StelProjector.hpp"
26
#include "StelToneReproducer.hpp"
27
#include "StelCore.hpp"
28
#include "StelSkyDrawer.hpp"
29
#include "StelPainter.hpp"
30
#include "StelModuleMgr.hpp"
31
#include "SolarSystem.hpp"
32
#include <QDebug>
33

34
#include <cstdio>
35

36
StelSkyImageTile::StelSkyImageTile()
×
37
{
38
        initCtor();
×
39
}
×
40

41
void StelSkyImageTile::initCtor()
×
42
{
43
        minResolution = -1;
×
44
        luminance = -1;
×
45
        alphaBlend = false;
×
46
        noTexture = false;
×
47
        texFader = Q_NULLPTR;
×
48
        birthJD = -1e10;
×
49
        withAberration = true;
×
50
        decimation = 1;
×
51
        flagVisible = true;
×
52
}
×
53

54
// Constructor
55
StelSkyImageTile::StelSkyImageTile(const QString& url, StelSkyImageTile* parent, int decimateBy) : MultiLevelJsonBase(parent)
×
56
{
57
        initCtor();
×
58
        decimation=decimateBy;
×
59
        if (parent)
×
60
        {
61
                luminance = parent->luminance;
×
62
                alphaBlend = parent->alphaBlend;
×
63
        }
64
        initFromUrl(url);
×
65
}
×
66

67
// Constructor from a map used for JSON files with more than 1 level
68
StelSkyImageTile::StelSkyImageTile(const QVariantMap& map, StelSkyImageTile* parent, int decimateBy) : MultiLevelJsonBase(parent)
×
69
{
70
        initCtor();
×
71
        decimation=decimateBy;
×
72
        if (parent)
×
73
        {
74
                luminance = parent->luminance;
×
75
                alphaBlend = parent->alphaBlend;
×
76
        }
77
        initFromQVariantMap(map);
×
78
}
×
79

80
// Destructor
81
StelSkyImageTile::~StelSkyImageTile()
×
82
{
83
}
×
84

85
void StelSkyImageTile::draw(StelCore* core, StelPainter& sPainter, float opacity)
×
86
{
87
        Q_UNUSED(opacity)
88
        const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
×
89

90
        // compute aberration correction vector
91
        Vec3d vel(0.0);
×
92
        if ((core) && (core->getUseAberration()) && (core->getCurrentPlanet()) && (withAberration))
×
93
        {
94
                vel = core->getAberrationVec(core->getJDE());
×
95
        }
96

97
        const float limitLuminance = core->getSkyDrawer()->getLimitLuminance();
×
98
        QMultiMap<double, StelSkyImageTile*> result;
×
99
        // TODO: adjust that viewportconvexpolygon by aberration to select the right tiles.
100
        // I thought the viewportpolygon needs to be enlarged just a bit. (I use 20 arcseconds here as estimate of max. aberration from earth.)
101
        //getTilesToDraw(result, core, prj->getViewportConvexPolygon(0,0)->getEnlarged(20./3600.*M_PI_180 *core->getAberrationFactor()), limitLuminance, true);
102
        // But it seems not even the AllSky region prevents clipping, so it must be caused somewhere else.
103
//        const SphericalCap& hp = prj->getBoundingCap();
104
//        getTilesToDraw(result, core, SphericalRegionP(new SphericalCap(hp)), limitLuminance, true);
105
        getTilesToDraw(result, core, SphericalRegionP(new AllSkySphericalRegion()), limitLuminance, true);
×
106

107
        int numToBeLoaded=0;
×
108
        for (auto* t : std::as_const(result))
×
109
                if (t->isReadyToDisplay()==false)
×
110
                        ++numToBeLoaded;
×
111
        updatePercent(result.size(), numToBeLoaded);
×
112

113
        // Draw in the good order
114
        sPainter.setBlending(true, GL_ONE, GL_ONE);
×
115
        auto i = result.end();
×
116
        while (i!=result.begin())
×
117
        {
118
                --i;
×
119
                i.value()->drawTile(core, sPainter, vel);
×
120
        }
121

122
        deleteUnusedSubTiles();
×
123
}
×
124

125
// Return the list of tiles which should be drawn.
126
void StelSkyImageTile::getTilesToDraw(QMultiMap<double, StelSkyImageTile*>& result, StelCore* core, const SphericalRegionP& viewPortPoly, float limitLuminance, bool recheckIntersect)
×
127
{
128
#ifndef NDEBUG
129
        // When this method is called, we can assume that:
130
        // - the parent tile min resolution was reached
131
        // - the parent tile is intersecting FOV
132
        // - the parent tile is not scheduled for deletion
133
        const StelSkyImageTile* parent = qobject_cast<StelSkyImageTile*>(QObject::parent());
×
134
        if (parent!=Q_NULLPTR)
×
135
        {
136
                Q_ASSERT(isDeletionScheduled()==false);
×
137
                const double degPerPixel = 1./core->getProjection(StelCore::FrameJ2000)->getPixelPerRadAtCenter()*M_180_PI;
×
138
                Q_ASSERT(degPerPixel<parent->minResolution);
×
139

140
                Q_ASSERT(parent->isDeletionScheduled()==false);
×
141
        }
142
#endif
143

144
        // An error occurred during loading
145
        if (errorOccured)
×
146
                return;
×
147

148
        // The JSON file is currently being downloaded
149
        if (downloading)
×
150
        {
151
                //qDebug() << "Downloading " << contructorUrl;
152
                return;
×
153
        }
154

155
        if (luminance>0 && luminance<limitLuminance)
×
156
        {
157
                // Schedule a deletion
158
                scheduleChildsDeletion();
×
159
                return;
×
160
        }
161

162
        if (birthJD>-1e10 && birthJD>core->getJD())
×
163
        {
164
                // Schedule a deletion
165
                scheduleChildsDeletion();
×
166
                return;
×
167
        }
168

169
        if (flagVisible == false)
×
170
        {
171
                // Schedule a deletion
172
                scheduleChildsDeletion();
×
173
                return;
×
174
        }
175

176
        // Check that we are in the screen
177
        bool fullInScreen = true;
×
178
        bool intersectScreen = false;
×
179
        if (recheckIntersect)
×
180
        {
181
                if (skyConvexPolygons.isEmpty())
×
182
                {
183
                        // If no polygon is defined, we assume that the tile covers the whole sky
184
                        fullInScreen=false;
×
185
                        intersectScreen=true;
×
186
                }
187
                else
188
                {
189
                        for (const auto& poly : std::as_const(skyConvexPolygons))
×
190
                        {
191
                                if (viewPortPoly->contains(poly))
×
192
                                {
193
                                        intersectScreen = true;
×
194
                                }
195
                                else
196
                                {
197
                                        fullInScreen = false;
×
198
                                        if (viewPortPoly->intersects(poly))
×
199
                                                intersectScreen = true;
×
200
                                }
201
                        }
202
                }
203
        }
204
        // The tile is outside screen
205
        if (fullInScreen==false && intersectScreen==false)
×
206
        {
207
                // Schedule a deletion
208
                scheduleChildsDeletion();
×
209
                return;
×
210
        }
211

212
        // The tile is in screen, and it is a precondition that its resolution is higher than the limit
213
        // make sure that it's not going to be deleted
214
        cancelDeletion();
×
215

216
        if (noTexture==false)
×
217
        {
218
                if (!tex)
×
219
                {
220
                        // The tile has an associated texture, but it is not yet loaded: load it now
221
                        StelTextureMgr& texMgr=StelApp::getInstance().getTextureManager();
×
222
                        tex = texMgr.createTextureThread(absoluteImageURI, StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE, false, decimation));
×
223
                        if (!tex)
×
224
                        {
225
                                qWarning() << "Can't create tile: " << absoluteImageURI;
×
226
                                errorOccured = true;
×
227
                                return;
×
228
                        }
229
                }
230

231
                // The tile is in screen and has a texture: every test passed :) The tile will be displayed
232
                result.insert(minResolution, this);
×
233
        }
234

235
        // Check if we reach the resolution limit
236
        const float degPerPixel = 1.f/core->getProjection(StelCore::FrameJ2000)->getPixelPerRadAtCenter()*M_180_PIf;
×
237
        if (degPerPixel < minResolution)
×
238
        {
239
                if (subTiles.isEmpty() && !subTilesUrls.isEmpty())
×
240
                {
241
                        // Load the sub tiles because we reached the maximum resolution and they are not yet loaded
242
                        for (const auto& s : std::as_const(subTilesUrls))
×
243
                        {
244
                                StelSkyImageTile* nt;
245
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
246
                                if (s.metaType()==QMetaType(QMetaType::QVariantMap))
×
247
#else
248
                                if (s.type()==QVariant::Map)
249
#endif
250
                                        nt = new StelSkyImageTile(s.toMap(), this, decimation);
×
251
                                else
252
                                {
253
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
254
                                        Q_ASSERT(s.metaType()==QMetaType(QMetaType::QString));
×
255
#else
256
                                        Q_ASSERT(s.type()==QVariant::String);
257
#endif
258
                                        nt = new StelSkyImageTile(s.toString(), this, decimation);
×
259
                                }
260
                                subTiles.append(nt);
×
261
                        }
262
                }
263
                // Try to add the subtiles
264
                for (auto* tile : std::as_const(subTiles))
×
265
                {
266
                        qobject_cast<StelSkyImageTile*>(tile)->getTilesToDraw(result, core, viewPortPoly, limitLuminance, !fullInScreen);
×
267
                }
268
        }
269
        else
270
        {
271
                // The subtiles should not be displayed because their resolution is too high
272
                scheduleChildsDeletion();
×
273
        }
274
}
275

276
// Draw the image on the screen.
277
// Assume GL_TEXTURE_2D is enabled
278
bool StelSkyImageTile::drawTile(StelCore* core, StelPainter& sPainter, const Vec3d &vel)
×
279
{
280
        if (!tex->bind())
×
281
                return false;
×
282

283
        if (!texFader)
×
284
        {
285
                texFader = new QTimeLine(1000, this);
×
286
                texFader->start();
×
287
        }
288

289
        // Draw the real texture for this image
290
        float ad_lum = (luminance>0) ? qMin(1.0f, core->getToneReproducer()->adaptLuminanceScaled(luminance)) : 1.f;
×
291
        Vec4f color;
×
292
        if (alphaBlend || texFader->state()==QTimeLine::Running)
×
293
        {
294
                if (!alphaBlend)
×
295
                        sPainter.setBlending(true); // Normal transparency mode
×
296
                else
297
                        sPainter.setBlending(true, GL_ONE, GL_ONE); // additive blending
×
298
                color.set(ad_lum,ad_lum,ad_lum, static_cast<float>(texFader->currentValue()));
×
299
        }
300
        else
301
        {
302
                sPainter.setBlending(false);
×
303
                color.set(ad_lum,ad_lum,ad_lum, 1.f);
×
304
        }
305

306
        const bool withExtinction=(getFrameType()!=StelCore::FrameAltAz && core->getSkyDrawer()->getFlagHasAtmosphere() && core->getSkyDrawer()->getExtinction().getExtinctionCoefficient()>=0.01f);
×
307

308
        for (const auto& poly : std::as_const(skyConvexPolygons))
×
309
        {
310
                // Not sure: Are all skyConvexPolygons in J2000 frame? This would also simplify code below...
311
                // No, by scripting we can have other frames!
312
                //Q_ASSERT(getFrameType() == StelCore::FrameJ2000);
313

314
                Vec4f extinctedColor = color;
×
315
                if (withExtinction)
×
316
                {
317
                        Vec3d bary= poly->getPointInside(); // This is a "frame" vector that points "somewhere" in the first triangle.
×
318

319
                        // 2017-03: we need a definite J2000 vector:
320
                        Vec3d baryJ2000;
×
321
                        double lng, lat, ra, dec; // aux. values for coordinate transformations
322
                        double eclJ2000, eclJDE;
323
                        //qDebug() << "Frame: " << getFrameType();
324
                        switch (getFrameType()) // all possible but AzAlt!
×
325
                        {
326
                                case StelCore::FrameJ2000:
×
327
                                        baryJ2000=bary;
×
328
                                        break;
×
329
                                case        StelCore::FrameEquinoxEqu:
×
330
                                        baryJ2000=core->equinoxEquToJ2000(bary, StelCore::RefractionOff);
×
331
                                        break;
×
332
                                case        StelCore::FrameObservercentricEclipticJ2000:
×
333
                                        // For the ecliptic cases, apply clumsy trafos from StelUtil!
334
                                        eclJ2000=GETSTELMODULE(SolarSystem)->getEarth()->getRotObliquity(2451545.0);
×
335
                                        StelUtils::rectToSphe(&lng, &lat, bary);
×
336
                                        StelUtils::eclToEqu(lng, lat, eclJ2000, &ra, &dec);
×
337
                                        StelUtils::spheToRect(ra, dec, baryJ2000);
×
338
                                        break;
×
339
                                case        StelCore::FrameObservercentricEclipticOfDate:
×
340
                                        // Trafo to eqDate, then as above.
341
                                        eclJDE = GETSTELMODULE(SolarSystem)->getEarth()->getRotObliquity(core->getJDE());
×
342
                                        StelUtils::rectToSphe(&lng, &lat, bary);
×
343
                                        StelUtils::eclToEqu(lng, lat, eclJDE, &ra, &dec); // convert to Equatorial/equinox of date
×
344
                                        StelUtils::spheToRect(ra, dec, bary);
×
345
                                        baryJ2000=core->equinoxEquToJ2000(bary, StelCore::RefractionOff);
×
346
                                        break;
×
347
                                case        StelCore::FrameGalactic:
×
348
                                        baryJ2000=core->galacticToJ2000(bary);
×
349
                                        break;
×
350
                                case        StelCore::FrameSupergalactic:
×
351
                                        baryJ2000=core->supergalacticToJ2000(bary);
×
352
                                        break;
×
353
                                default:
×
354
                                        Q_ASSERT(0);
×
355
                                        qDebug() << "StelSkyImageTile: unknown FrameType. Assume J2000.";
356
                                        baryJ2000=bary;
357
                        }
358
                        Vec3d altAz = core->j2000ToAltAz(baryJ2000, StelCore::RefractionOff);
×
359
                        float extinctionMagnitude=0.0f;
×
360
                        altAz.normalize();
×
361
                        core->getSkyDrawer()->getExtinction().forward(altAz, &extinctionMagnitude);
×
362
                        // compute a simple factor from magnitude loss.
363
                        float extinctionFactor=std::pow(0.4f , extinctionMagnitude); // drop of one magnitude: factor 2.5 or 40%
×
364
                        extinctedColor[0]*=fabs(extinctionFactor);
×
365
                        extinctedColor[1]*=fabs(extinctionFactor);
×
366
                        extinctedColor[2]*=fabs(extinctionFactor);
×
367
                }
368
                sPainter.setColor(extinctedColor);
×
369
                sPainter.drawSphericalRegion(poly.data(), StelPainter::SphericalPolygonDrawModeTextureFill, Q_NULLPTR, true, 5., vel);
×
370
        }
371

372
#ifdef DEBUG_STELSKYIMAGE_TILE
373
        if (debugFont==Q_NULLPTR)
374
        {
375
                debugFont = &StelApp::getInstance().getFontManager().getStandardFont(StelApp::getInstance().getLocaleMgr().getSkyLanguage(), 12);
376
        }
377
        color.set(1.0,0.5,0.5,1.0);
378
        for (const auto& poly : skyConvexPolygons)
379
        {
380
                Vec3d win;
381
                Vec3d bary = poly->getPointInside();
382
                sPainter.getProjector()->project(bary,win);
383
                sPainter.drawText(debugFont, win[0], win[1], getAbsoluteImageURI());
384
                sPainter.enableTexture2d(false);
385
                sPainter.drawSphericalRegion(poly.get(), StelPainter::SphericalPolygonDrawModeBoundary, &color);
386
                sPainter.enableTexture2d(true);
387
        }
388
#endif
389

390
        return true;
×
391
}
392

393
// Return true if the tile is fully loaded and can be displayed
394
bool StelSkyImageTile::isReadyToDisplay() const
×
395
{
396
        return tex && tex->canBind();
×
397
}
398

399
// Load the tile from a valid QVariantMap
400
void StelSkyImageTile::loadFromQVariantMap(const QVariantMap& map)
×
401
{
402
        if (map.contains("imageCredits"))
×
403
        {
404
                QVariantMap dsCredits = map.value("imageCredits").toMap();
×
405
                dataSetCredits.shortCredits = dsCredits.value("short").toString();
×
406
                dataSetCredits.fullCredits = dsCredits.value("full").toString();
×
407
                dataSetCredits.infoURL = dsCredits.value("infoUrl").toString();
×
408
        }
×
409
        if (map.contains("serverCredits"))
×
410
        {
411
                QVariantMap sCredits = map.value("serverCredits").toMap();
×
412
                serverCredits.shortCredits = sCredits.value("short").toString();
×
413
                serverCredits.fullCredits = sCredits.value("full").toString();
×
414
                serverCredits.infoURL = sCredits.value("infoUrl").toString();
×
415
        }
×
416
        if (map.contains("description"))
×
417
        {
418
                htmlDescription = map.value("description").toString();
×
419
                if (parent()==Q_NULLPTR)
×
420
                {
421
                        htmlDescription+= "<h3>URL: "+constructorUrl+"</h3>";
×
422
                }
423
        }
424
        else
425
        {
426
                if (parent()==Q_NULLPTR)
×
427
                {
428
                        htmlDescription= "<h3>URL: "+constructorUrl+"</h3>";
×
429
                }
430
        }
431

432
        shortName = map.value("shortName").toString();
×
433
        if (shortName.isEmpty())
×
434
                shortName = "no name";
×
435
        bool ok=false;
×
436
        if (!map.contains("minResolution"))
×
437
                throw std::runtime_error(qPrintable(QString("minResolution is mandatory")));
×
438
        minResolution = map.value("minResolution").toFloat(&ok);
×
439
        if (!ok)
×
440
        {
441
                throw std::runtime_error(qPrintable(QString("minResolution expects a double value, found: \"%1\"").arg(map.value("minResolution").toString())));
×
442
        }
443

444
        if (map.contains("luminance"))
×
445
        {
446
                luminance = map.value("luminance").toFloat(&ok);
×
447
                if (!ok)
×
448
                        throw std::runtime_error("luminance expects a float value");
×
449
                qWarning() << "luminance in preview JSON files is deprecated. Replace with maxBrightness.";
×
450
        }
451

452
        if (map.contains("maxBrightness"))
×
453
        {
454
                // maxBrightness is the maximum nebula brightness in Vmag/arcmin^2
455
                luminance = map.value("maxBrightness").toFloat(&ok);
×
456
                if (!ok)
×
457
                        throw std::runtime_error("maxBrightness expects a float value");
×
458
                luminance = StelApp::getInstance().getCore()->getSkyDrawer()->surfaceBrightnessToLuminance(luminance);
×
459
        }
460

461
        if (map.contains("alphaBlend"))
×
462
        {
463
                alphaBlend = map.value("alphaBlend").toBool();
×
464
        }
465

466
        // Load the convex polygons (if any)
467
        QVariantList polyList = map.value("skyConvexPolygons").toList();
×
468
        if (polyList.empty())
×
469
                polyList = map.value("worldCoords").toList();
×
470
        else
471
                qWarning() << "skyConvexPolygons in preview JSON files is deprecated. Replace with worldCoords.";
×
472

473
        // Load the matching textures positions (if any)
474
        QVariantList texCoordList = map.value("textureCoords").toList();
×
475
        if (!texCoordList.isEmpty() && polyList.size()!=texCoordList.size())
×
476
                        throw std::runtime_error("the number of convex polygons does not match the number of texture space polygon");
×
477

478
        for (int i=0;i<polyList.size();++i)
×
479
        {
480
                const QVariant& polyRaDec = polyList.at(i);
×
481
                QVector<Vec3d> vertices;
×
482
                const QList<QVariant> polyRaDecList=polyRaDec.toList();
×
483
                for (const auto& vRaDec : polyRaDecList)
×
484
                {
485
                        const QVariantList vl = vRaDec.toList();
×
486
                        Vec3d v;
×
487
                        StelUtils::spheToRect(vl.at(0).toFloat(&ok)*M_PI_180f, vl.at(1).toFloat(&ok)*M_PI_180f, v);
×
488
                        if (!ok)
×
489
                                throw std::runtime_error("wrong Ra and Dec, expect a double value");
×
490
                        vertices.append(v);
×
491
                }
×
492
                Q_ASSERT(vertices.size()==4);
×
493

494
                if (!texCoordList.isEmpty())
×
495
                {
496
                        const QVariant& polyXY = texCoordList.at(i);
×
497
                        QVector<Vec2f> texCoords;
×
498
                        const QList<QVariant> polyXYlist=polyXY.toList();
×
499
                        for (const auto& vXY : polyXYlist)
×
500
                        {
501
                                const QVariantList vl = vXY.toList();
×
502
                                texCoords.append(Vec2f(vl.at(0).toFloat(&ok), vl.at(1).toFloat(&ok)));
×
503
                                if (!ok)
×
504
                                        throw std::runtime_error("wrong X and Y, expect a double value");
×
505
                        }
×
506
                        Q_ASSERT(texCoords.size()==4);
×
507

508
                        SphericalTexturedConvexPolygon* pol = new SphericalTexturedConvexPolygon(vertices, texCoords);
×
509
                        Q_ASSERT(pol->checkValid());
×
510
                        skyConvexPolygons.append(SphericalRegionP(pol));
×
511
                }
×
512
                else
513
                {
514
                        SphericalConvexPolygon* pol = new SphericalConvexPolygon(vertices);
×
515
                        Q_ASSERT(pol->checkValid());
×
516
                        skyConvexPolygons.append(SphericalRegionP(pol));
×
517
                }
518
        }
×
519

520
        if (map.contains("imageUrl"))
×
521
        {
522
                QString imageUrl = map.value("imageUrl").toString();
×
523
                if (baseUrl.startsWith("http", Qt::CaseInsensitive))
×
524
                {
525
                        absoluteImageURI = baseUrl+imageUrl;
×
526
                }
527
                else
528
                {
529
                        absoluteImageURI = StelFileMgr::findFile(baseUrl+imageUrl);
×
530
                        if (absoluteImageURI.isEmpty())
×
531
                        {
532
                                // Maybe the user meant a file in stellarium local files
533
                                absoluteImageURI = imageUrl;
×
534
                        }
535
                }
536
        }
×
537
        else
538
                noTexture = true;
×
539

540
        birthJD = map.value("birthJD", -1e10).toDouble();
×
541

542
        // This is a list of URLs to the child tiles or a list of already loaded map containing child information
543
        // (in this later case, the StelSkyImageTile objects will be created later)
544
        subTilesUrls = map.value("subTiles").toList();
×
545
        for (auto& variant : subTilesUrls)
×
546
        {
547
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
548
                if (variant.metaType() == QMetaType(QMetaType::QVariantMap))
×
549
#else
550
                if (variant.type() == QVariant::Map)
551
#endif
552
                {
553
                        // Check if the JSON object is a reference, i.e. if it contains a $ref key
554
                        QVariantMap m = variant.toMap();
×
555
                        if (m.size()==1 && m.contains("$ref"))
×
556
                        {
557
                                variant = QString(m["$ref"].toString());
×
558
                        }
559
                }
×
560
        }
561
//         if (subTilesUrls.size()>10)
562
//         {
563
//                 qWarning() << "Large tiles number for " << shortName << ": " << subTilesUrls.size();
564
//         }
565

566
        withAberration = map.value("withAberration", true).toBool();
×
567
}
×
568

569
// Convert the image information to a map following the JSON structure.
570
QVariantMap StelSkyImageTile::toQVariantMap() const
×
571
{
572
        QVariantMap res;
×
573

574
        // Image credits
575
        QVariantMap imCredits;
×
576
        if (!dataSetCredits.shortCredits.isEmpty())
×
577
                imCredits["short"]=dataSetCredits.shortCredits;
×
578
        if (!dataSetCredits.fullCredits.isEmpty())
×
579
                imCredits["full"]=dataSetCredits.fullCredits;
×
580
        if (!dataSetCredits.infoURL.isEmpty())
×
581
                imCredits["infoUrl"]=dataSetCredits.infoURL;
×
582
        if (!imCredits.empty())
×
583
                res["imageCredits"]=imCredits;
×
584

585
        // Server credits
586
        QVariantMap serCredits;
×
587
        if (!serverCredits.shortCredits.isEmpty())
×
588
                imCredits["short"]=serverCredits.shortCredits;
×
589
        if (!serverCredits.fullCredits.isEmpty())
×
590
                imCredits["full"]=serverCredits.fullCredits;
×
591
        if (!serverCredits.infoURL.isEmpty())
×
592
                imCredits["infoUrl"]=serverCredits.infoURL;
×
593
        if (!serCredits.empty())
×
594
                res["serverCredits"]=serCredits;
×
595

596
        // Misc
597
        if (!shortName.isEmpty())
×
598
                res["shortName"] = shortName;
×
599
        if (minResolution>0)
×
600
                res["minResolution"]=minResolution;
×
601
        if (luminance>0)
×
602
                res["maxBrightness"]=StelApp::getInstance().getCore()->getSkyDrawer()->luminanceToSurfacebrightness(luminance);
×
603
        if (alphaBlend)
×
604
                res["alphaBlend"]=true;
×
605
        if (noTexture==false)
×
606
                res["imageUrl"]=absoluteImageURI;
×
607
        if (birthJD>-1e10)
×
608
                res["birthJD"]=birthJD;
×
609
        res["withAberration"] = withAberration;
×
610

611
        // Polygons
612
        // TODO
613

614
        // textures positions
615
        // TODO
616

617
        if (!subTilesUrls.empty())
×
618
        {
619
                res["subTiles"] = subTilesUrls;
×
620
        }
621

622
        return res;
×
623
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc