Merge lp:~stellarium/stellarium/toastImages into lp:stellarium

Proposed by Alexander Wolf
Status: Merged
Merged at revision: 8858
Proposed branch: lp:~stellarium/stellarium/toastImages
Merge into: lp:stellarium
Diff against target: 2224 lines (+1671/-115)
32 files modified
data/gui/guiRes.qrc (+2/-0)
src/CMakeLists.txt (+6/-1)
src/core/MultiLevelJsonBase.cpp (+1/-1)
src/core/StelApp.cpp (+6/-1)
src/core/StelLocationMgr.cpp (+1/-1)
src/core/StelSkyLayerMgr.cpp (+1/-0)
src/core/StelSphereGeometry.cpp (+5/-0)
src/core/StelTexture.cpp (+6/-4)
src/core/StelTexture.hpp (+1/-1)
src/core/StelTextureMgr.cpp (+1/-1)
src/core/StelToast.cpp (+235/-0)
src/core/StelToast.hpp (+114/-0)
src/core/StelToastGrid.cpp (+177/-0)
src/core/StelToastGrid.hpp (+90/-0)
src/core/StelUtils.cpp (+17/-0)
src/core/StelUtils.hpp (+3/-0)
src/core/modules/ConstellationMgr.cpp (+1/-1)
src/core/modules/ToastMgr.cpp (+97/-0)
src/core/modules/ToastMgr.hpp (+53/-0)
src/gui/ConfigurationDialog.cpp (+8/-11)
src/gui/ConfigurationDialog.hpp (+0/-2)
src/gui/StelGui.cpp (+31/-0)
src/gui/StelGui.hpp (+9/-0)
src/gui/configurationDialog.ui (+101/-91)
util/DSSToStellarium/UTdssUtils.py (+35/-0)
util/DSSToStellarium/createUpperToastLevels.py (+81/-0)
util/DSSToStellarium/dssUtils.py (+169/-0)
util/DSSToStellarium/generateFullPlate.py (+159/-0)
util/DSSToStellarium/prepareAllPlates.py (+117/-0)
util/DSSToStellarium/readme.txt (+33/-0)
util/toastForShape/main.cpp (+38/-0)
util/toastForShape/toastForShape.pro (+73/-0)
To merge this branch: bzr merge lp:~stellarium/stellarium/toastImages
Reviewer Review Type Date Requested Status
gzotti Approve
Guillaume Chereau Pending
Fabien Chéreau Pending
Review via email: mp+310716@code.launchpad.net
To post a comment you must log in.
Revision history for this message
gzotti (georg-zotti) wrote :

Works like a charm as long as network is good.

Maybe fix following: When disabling network (tset with aircraft mode on notebook), and reenabling, re-establish connection? Not sure what happens currently, network stays disabled. What about short network interruptions - would we have to completely restart Stellarium (and break connection to telescope etc.) to re-enable? It may be acceptable to toggle DSS off/on to reconnect. Maybe give screen notice "DSS: network unavailable" or such?

Things to possibly consider:

Fix TODOs (links) in ToastMgr::init(), and host data at stellarium.org?
Explain what TOAST actually means?
We should be prepared to answer questions about installing data locally (for use at off-line observing sites! Either private PCs or data on an in-house server.) (source, legal state, bandwidth, instructions?)
A chapter in the Guide should explain all this! (Can be added after merge, though.)

review: Needs Fixing
Revision history for this message
Alexander Wolf (alexwolf) wrote :

TOAST is "tessellated octahedral adaptive subdivision transform" (details: https://arxiv.org/pdf/1505.02291.pdf) + see section "2.3.2.8.1 The TOAST Projection" (skyview.gsfc.nasa.gov/current/docs/skyviewinajar.html)

TODOs - I hope Fabien can help with it (I can't add/change DNS names).

Network behaviour: it's more to the StelTexture class behaviour

Revision history for this message
gzotti (georg-zotti) wrote :

Thanks for the paper. This must be referenced in the Guide chapter to be written.

So this network behaviour problem must then become a "wishlist bug" for StelTexture, and should not impede branch merge.

Then it's OK from my side :-)

review: Approve
Revision history for this message
Alexander Wolf (alexwolf) wrote :

Offline mode: full collection of DSS has a size 112GiB and it can be problematic to the usage by many users.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/gui/btToastSurvey-off.png'
2Binary files data/gui/btToastSurvey-off.png 1970-01-01 00:00:00 +0000 and data/gui/btToastSurvey-off.png 2016-11-13 10:24:15 +0000 differ
3=== added file 'data/gui/btToastSurvey-on.png'
4Binary files data/gui/btToastSurvey-on.png 1970-01-01 00:00:00 +0000 and data/gui/btToastSurvey-on.png 2016-11-13 10:24:15 +0000 differ
5=== modified file 'data/gui/guiRes.qrc'
6--- data/gui/guiRes.qrc 2015-12-05 17:34:59 +0000
7+++ data/gui/guiRes.qrc 2016-11-13 10:24:15 +0000
8@@ -88,6 +88,8 @@
9 <file>btConstellationLines-on.png</file>
10 <file>btDSS-off.png</file>
11 <file>btDSS-on.png</file>
12+ <file>btToastSurvey-off.png</file>
13+ <file>btToastSurvey-on.png</file>
14 <file>btEquatorialGrid-off.png</file>
15 <file>btEquatorialGrid-on.png</file>
16 <file>btEquatorialMount-off.png</file>
17
18=== modified file 'src/CMakeLists.txt'
19--- src/CMakeLists.txt 2016-11-05 13:35:49 +0000
20+++ src/CMakeLists.txt 2016-11-13 10:24:15 +0000
21@@ -153,6 +153,10 @@
22 core/TrailGroup.cpp
23 core/RefractionExtinction.hpp
24 core/RefractionExtinction.cpp
25+ core/StelToast.hpp
26+ core/StelToast.cpp
27+ core/StelToastGrid.hpp
28+ core/StelToastGrid.cpp
29 core/StelActionMgr.hpp
30 core/StelActionMgr.cpp
31 core/StelProgressController.hpp
32@@ -249,6 +253,8 @@
33 core/modules/StarMgr.hpp
34 core/modules/StarWrapper.cpp
35 core/modules/StarWrapper.hpp
36+ core/modules/ToastMgr.hpp
37+ core/modules/ToastMgr.cpp
38 core/modules/ZoneArray.cpp
39 core/modules/ZodiacalLight.hpp
40 core/modules/ZodiacalLight.cpp
41@@ -314,7 +320,6 @@
42 SET(stellarium_RES ${CMAKE_SOURCE_DIR}/data/mainRes.qrc)
43 QT5_ADD_RESOURCES(stellarium_RES_CXX ${stellarium_RES})
44
45-
46 #############################################################################################
47 ############################# Standard GUI plugin compilation ###############################
48 #############################################################################################
49
50=== modified file 'src/core/MultiLevelJsonBase.cpp'
51--- src/core/MultiLevelJsonBase.cpp 2014-06-12 15:47:22 +0000
52+++ src/core/MultiLevelJsonBase.cpp 2016-11-13 10:24:15 +0000
53@@ -169,7 +169,7 @@
54 }
55 Q_ASSERT(httpReply==NULL);
56 QNetworkRequest req(qurl);
57- req.setRawHeader("User-Agent", StelUtils::getApplicationName().toLatin1());
58+ req.setRawHeader("User-Agent", StelUtils::getUserAgentString().toLatin1());
59 httpReply = getNetworkAccessManager().get(req);
60 //qDebug() << "Started downloading " << httpReply->request().url().path();
61 Q_ASSERT(httpReply->error()==QNetworkReply::NoError);
62
63=== modified file 'src/core/StelApp.cpp'
64--- src/core/StelApp.cpp 2016-10-23 17:09:45 +0000
65+++ src/core/StelApp.cpp 2016-11-13 10:24:15 +0000
66@@ -37,9 +37,9 @@
67 #include "StelIniParser.hpp"
68 #include "StelProjector.hpp"
69 #include "StelLocationMgr.hpp"
70+#include "ToastMgr.hpp"
71 #include "StelActionMgr.hpp"
72 #include "StelPropertyMgr.hpp"
73-
74 #include "StelProgressController.hpp"
75 #include "StelModuleMgr.hpp"
76 #include "StelLocaleMgr.hpp"
77@@ -457,6 +457,11 @@
78 skyImageMgr->init();
79 getModuleMgr().registerModule(skyImageMgr);
80
81+ // Toast surveys
82+ ToastMgr* toasts = new ToastMgr();
83+ toasts->init();
84+ getModuleMgr().registerModule(toasts);
85+
86 // Init audio manager
87 audioMgr = new StelAudioMgr();
88
89
90=== modified file 'src/core/StelLocationMgr.cpp'
91--- src/core/StelLocationMgr.cpp 2016-10-25 15:39:06 +0000
92+++ src/core/StelLocationMgr.cpp 2016-11-13 10:24:15 +0000
93@@ -356,7 +356,7 @@
94 {
95 QNetworkRequest req( QUrl( QString("http://freegeoip.net/json/") ) );
96 req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
97- req.setRawHeader("User-Agent", StelUtils::getApplicationName().toLatin1());
98+ req.setRawHeader("User-Agent", StelUtils::getUserAgentString().toLatin1());
99 QNetworkReply* networkReply=StelApp::getInstance().getNetworkAccessManager()->get(req);
100 connect(networkReply, SIGNAL(finished()), this, SLOT(changeLocationFromNetworkLookup()));
101 }
102
103=== modified file 'src/core/StelSkyLayerMgr.cpp'
104--- src/core/StelSkyLayerMgr.cpp 2016-06-14 14:56:19 +0000
105+++ src/core/StelSkyLayerMgr.cpp 2016-11-13 10:24:15 +0000
106@@ -69,6 +69,7 @@
107 qWarning() << "ERROR while loading nebula texture set default";
108 else
109 insertSkyImage(path);
110+
111 QSettings* conf = StelApp::getInstance().getSettings();
112 conf->beginGroup("skylayers");
113 foreach (const QString& key, conf->childKeys())
114
115=== modified file 'src/core/StelSphereGeometry.cpp'
116--- src/core/StelSphereGeometry.cpp 2016-07-23 05:23:41 +0000
117+++ src/core/StelSphereGeometry.cpp 2016-11-13 10:24:15 +0000
118@@ -1314,6 +1314,11 @@
119 {
120 return SphericalRegionP(new SphericalPolygon(pathFromQVariantList(l)));
121 }
122+ else if (code=="CONVEX_POLYGON")
123+ {
124+ return SphericalRegionP(new SphericalConvexPolygon(singleContourFromQVariantList(l.at(1).toList())));
125+ }
126+
127 Q_ASSERT(0);
128 return EmptySphericalRegion::staticInstance;
129 }
130
131=== modified file 'src/core/StelTexture.cpp'
132--- src/core/StelTexture.cpp 2016-10-11 14:47:05 +0000
133+++ src/core/StelTexture.cpp 2016-11-13 10:24:15 +0000
134@@ -57,10 +57,12 @@
135 }
136 id = 0;
137 }
138- if (networkReply != NULL)
139+ if (networkReply)
140 {
141 networkReply->abort();
142- networkReply->deleteLater();
143+ //networkReply->deleteLater();
144+ delete networkReply;
145+ networkReply = NULL;
146 }
147 if (loader != NULL) {
148 delete loader;
149@@ -124,9 +126,9 @@
150 QNetworkRequest req = QNetworkRequest(QUrl(fullPath));
151 // Define that preference should be given to cached files (no etag checks)
152 req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
153- req.setRawHeader("User-Agent", StelUtils::getApplicationName().toLatin1());
154+ req.setRawHeader("User-Agent", StelUtils::getUserAgentString().toLatin1());
155 networkReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
156- connect(networkReply, SIGNAL(finished()), this, SLOT(onNetworkReply()));
157+ connect(networkReply, SIGNAL(finished()), this, SLOT(onNetworkReply()));
158 return false;
159 }
160 // The network connection is still running.
161
162=== modified file 'src/core/StelTexture.hpp'
163--- src/core/StelTexture.hpp 2015-02-06 19:40:02 +0000
164+++ src/core/StelTexture.hpp 2016-11-13 10:24:15 +0000
165@@ -147,7 +147,7 @@
166
167
168 //! The URL where to download the file
169- QString fullPath;
170+ QString fullPath;
171
172 //! True when something when wrong in the loading process
173 bool errorOccured;
174
175=== modified file 'src/core/StelTextureMgr.cpp'
176--- src/core/StelTextureMgr.cpp 2015-03-04 18:42:24 +0000
177+++ src/core/StelTextureMgr.cpp 2016-11-13 10:24:15 +0000
178@@ -67,7 +67,7 @@
179
180 StelTextureSP tex = StelTextureSP(new StelTexture());
181 tex->loadParams = params;
182- tex->fullPath = url;
183+ tex->fullPath = url;
184 if (!lazyLoading)
185 {
186 tex->bind();
187
188=== added file 'src/core/StelToast.cpp'
189--- src/core/StelToast.cpp 1970-01-01 00:00:00 +0000
190+++ src/core/StelToast.cpp 2016-11-13 10:24:15 +0000
191@@ -0,0 +1,235 @@
192+/*
193+ * Stellarium
194+ * Copyright (C) 2010 Guillaume Chereau
195+ *
196+ * This program is free software; you can redistribute it and/or
197+ * modify it under the terms of the GNU General Public License
198+ * as published by the Free Software Foundation; either version 2
199+ * of the License, or (at your option) any later version.
200+ *
201+ * This program is distributed in the hope that it will be useful,
202+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
203+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
204+ * GNU General Public License for more details.
205+ *
206+ * You should have received a copy of the GNU General Public License
207+ * along with this program; if not, write to the Free Software
208+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
209+ */
210+
211+#include <QtOpenGL>
212+#include "StelApp.hpp"
213+#include "StelCore.hpp"
214+#include "StelPainter.hpp"
215+#include "StelTexture.hpp"
216+#include "StelTextureMgr.hpp"
217+#include "StelToast.hpp"
218+
219+ToastTile::ToastTile(QObject* parent, int level, int x, int y)
220+ : QObject(parent), level(level), x(x), y(y), empty(false), ready(false), texture(NULL), texFader(NULL)
221+{
222+ Q_ASSERT(level <= getGrid()->getMaxLevel());
223+ const ToastSurvey* survey = getSurvey();
224+ // create the texture
225+ imagePath = survey->getTilePath(level, x, y);
226+
227+ if (level==0)
228+ {
229+ boundingCap.n=Vec3d(1,0,0);
230+ boundingCap.d=-1.;
231+ }
232+ const QVector<Vec3d>& pts = getGrid()->getPolygon(level, x, y);
233+ Vec3d n = pts.at(0);
234+ n+=pts.at(1);
235+ n+=pts.at(2);
236+ n+=pts.at(3);
237+ n.normalize();
238+ boundingCap.n=n;
239+ if (level==1)
240+ boundingCap.d=0;
241+ else
242+ boundingCap.d=qMin(qMin(n*pts.at(0), n*pts.at(1)), qMin(n*pts.at(2), n*pts.at(3)));
243+}
244+
245+const ToastGrid* ToastTile::getGrid() const
246+{
247+ return getSurvey()->getGrid();
248+}
249+
250+
251+const ToastSurvey* ToastTile::getSurvey() const
252+{
253+ // the parent can either be a ToastSurvey either be a ToastTile
254+ ToastSurvey* ret = qobject_cast<ToastSurvey*>(parent());
255+ if (ret)
256+ return ret;
257+ ToastTile* tile = qobject_cast<ToastTile*>(parent());
258+ Q_ASSERT(tile);
259+ return tile->getSurvey();
260+}
261+
262+
263+bool ToastTile::isVisible(const SphericalCap& viewportShape, int maxVisibleLevel) const
264+{
265+ if (empty)
266+ return false;
267+ if (level == 0)
268+ return true;
269+ if (level > maxVisibleLevel)
270+ return false;
271+ return viewportShape.intersects(boundingCap);
272+}
273+
274+bool ToastTile::isCovered(const SphericalCap& viewportShape) const
275+{
276+ // The tile is covered if we have at least one visible child and all the visible children are all ready to be drawn.
277+ int nbVisibleChildren = 0;
278+ foreach (const ToastTile* child, subTiles)
279+ {
280+ if (!viewportShape.intersects(child->boundingCap))
281+ continue;
282+ nbVisibleChildren++;
283+ if (!child->ready || child->texFader->state()==QTimeLine::Running)
284+ return false;
285+ }
286+ return nbVisibleChildren > 0;
287+}
288+
289+
290+void ToastTile::prepareDraw()
291+{
292+ Q_ASSERT(!empty);
293+
294+ if (texture.isNull())
295+ {
296+ //qDebug() << "load texture" << imagePath;
297+ StelTextureMgr& texMgr=StelApp::getInstance().getTextureManager();
298+ texture = texMgr.createTextureThread(imagePath, StelTexture::StelTextureParams(true));
299+ }
300+ if (texture.isNull() || (!texture->isLoading() && !texture->canBind() && !texture->getErrorMessage().isEmpty()))
301+ {
302+ if (!texture.isNull())
303+ qDebug() << "can't get texture" << imagePath << texture->getErrorMessage();
304+ empty = true;
305+ return;
306+ }
307+ if (!texture->canBind())
308+ return;
309+ // Get the opengl arrays
310+ if (vertexArray.empty())
311+ {
312+ int ml = qMin(qMax(3, level+1), getGrid()->getMaxLevel());
313+ vertexArray = getGrid()->getVertexArray(level, x, y, ml);
314+ textureArray = getGrid()->getTextureArray(level, x, y, ml);
315+ indexArray = getGrid()->getTrianglesIndex(level, x, y, ml);
316+ }
317+
318+ if (subTiles.isEmpty() && level < getSurvey()->getMaxLevel())
319+ {
320+ //qDebug() << "Create children";
321+ // Create the children
322+ for (int i = 0; i < 2; ++i)
323+ for (int j = 0; j < 2; ++j)
324+ subTiles.append(new ToastTile(this, level + 1, 2 * this->x + i, 2 * this->y + j));
325+ Q_ASSERT(subTiles.size() == 4);
326+ }
327+ ready = true;
328+}
329+
330+
331+void ToastTile::drawTile(StelPainter* sPainter)
332+{
333+ if (!ready)
334+ prepareDraw();
335+
336+ // Still not ready
337+ if (texture.isNull() || !texture->bind())
338+ return;
339+
340+ if (!texFader)
341+ {
342+ texFader = new QTimeLine(1000, this);
343+ texFader->start();
344+ }
345+
346+ if (texFader->state()==QTimeLine::Running)
347+ {
348+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
349+ glEnable(GL_BLEND);
350+ sPainter->setColor(1,1,1, texFader->currentValue());
351+ }
352+ else
353+ {
354+ glDisable(GL_BLEND);
355+ sPainter->setColor(1, 1, 1, 1);
356+ }
357+
358+ sPainter->enableTexture2d(true);
359+ Q_ASSERT(vertexArray.size() == textureArray.size());
360+
361+ glEnable(GL_CULL_FACE);
362+ // sPainter.drawArrays(GL_TRIANGLES, vertexArray.size(), vertexArray.data(), textureArray.data(), NULL, NULL, indexArray.size(), indexArray.constData());
363+ sPainter->setArrays(vertexArray.constData(), textureArray.constData());
364+ sPainter->drawFromArray(StelPainter::Triangles, indexArray.size(), 0, true, indexArray.constData());
365+ glDisable(GL_CULL_FACE);
366+
367+// SphericalConvexPolygon poly(getGrid()->getPolygon(level, x, y));
368+// sPainter->enableTexture2d(false);
369+// sPainter->drawSphericalRegion(&poly, StelPainter::SphericalPolygonDrawModeBoundary);
370+}
371+
372+
373+void ToastTile::draw(StelPainter* sPainter, const SphericalCap& viewportShape, int maxVisibleLevel)
374+{
375+ if (!isVisible(viewportShape, maxVisibleLevel))
376+ {
377+ // Clean up to save memory.
378+ foreach (ToastTile* child, subTiles)
379+ {
380+ child->deleteLater();
381+ }
382+ subTiles.clear();
383+ ready = false;
384+ return;
385+ }
386+ if (level==maxVisibleLevel || !isCovered(viewportShape))
387+ drawTile(sPainter);
388+
389+ // Draw all the children
390+ foreach (ToastTile* child, subTiles)
391+ {
392+ child->draw(sPainter, viewportShape, maxVisibleLevel);
393+ }
394+}
395+
396+/////// ToastSurvey methods ////////////
397+ToastSurvey::ToastSurvey(const QString& path, int amaxLevel)
398+ : grid(amaxLevel), path(path), maxLevel(amaxLevel)
399+{
400+ rootTile = new ToastTile(this, 0, 0, 0);
401+}
402+
403+
404+QString ToastSurvey::getTilePath(int level, int x, int y) const
405+{
406+ QString ret = path;
407+ ret.replace("{level}", QString::number(level));
408+ ret.replace("{x}", QString::number(x));
409+ ret.replace("{y}", QString::number(y));
410+ return ret;
411+}
412+
413+
414+void ToastSurvey::draw(StelPainter* sPainter)
415+{
416+ // Compute the maximum visible level for the tiles according to the view resolution.
417+ // We know that each tile at level L represents an angle of 360 / 2**L
418+ // The maximum angle we want to see is the size of a tile in pixels time the angle for one visible pixel.
419+ const double anglePerPixel = 1./sPainter->getProjector()->getPixelPerRadAtCenter()*180./M_PI;
420+ const double maxAngle = anglePerPixel * getTilesSize();
421+ int maxVisibleLevel = (int)(log2(360. / maxAngle));
422+
423+ // We also get the viewport shape to discard invisibly tiles.
424+ const SphericalCap& viewportRegion = sPainter->getProjector()->getBoundingCap();
425+ rootTile->draw(sPainter, viewportRegion, maxVisibleLevel);
426+}
427
428=== added file 'src/core/StelToast.hpp'
429--- src/core/StelToast.hpp 1970-01-01 00:00:00 +0000
430+++ src/core/StelToast.hpp 2016-11-13 10:24:15 +0000
431@@ -0,0 +1,114 @@
432+/*
433+ * Stellarium
434+ * Copyright (C) 2010 Guillaume Chereau
435+ *
436+ * This program is free software; you can redistribute it and/or
437+ * modify it under the terms of the GNU General Public License
438+ * as published by the Free Software Foundation; either version 2
439+ * of the License, or (at your option) any later version.
440+ *
441+ * This program is distributed in the hope that it will be useful,
442+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
443+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
444+ * GNU General Public License for more details.
445+ *
446+ * You should have received a copy of the GNU General Public License
447+ * along with this program; if not, write to the Free Software
448+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
449+ */
450+
451+#ifndef _STELTOAST_HPP_
452+#define _STELTOAST_HPP_
453+
454+#include <QObject>
455+#include <QString>
456+#include <QVector>
457+
458+#include "StelSphereGeometry.hpp"
459+#include "StelTexture.hpp"
460+#include "StelTextureTypes.hpp"
461+#include "VecMath.hpp"
462+#include "StelToastGrid.hpp"
463+
464+class StelPainter;
465+class ToastSurvey;
466+
467+//! @class ToastTile
468+//! Represents a tile in a Toast image.
469+//! The tiles are stored in a tree structure, using the QObject
470+//! children/parent relationships.
471+class ToastTile : public QObject
472+{
473+ Q_OBJECT
474+
475+public:
476+ ToastTile(QObject* parent, int level, int x, int y);
477+ void draw(StelPainter* painter, const SphericalCap& viewportShape, int maxVisibleLevel);
478+ bool isTransparent();
479+
480+protected:
481+ void drawTile(StelPainter* painter);
482+ //! Return the survey the tile belongs to.
483+ const ToastSurvey* getSurvey() const;
484+ //! Return the toast grid used by the tile.
485+ const ToastGrid* getGrid() const;
486+ //! Return whether the tile should be drawn
487+ bool isVisible(const SphericalCap& viewportShape, int maxVisibleLevel) const;
488+ //! return whether the tile is covered by its children tiles
489+ //! This is used to avoid drawing tiles that will be covered anyway
490+ bool isCovered(const SphericalCap& viewportShape) const;
491+ void prepareDraw();
492+
493+private:
494+ //! The level of the tile
495+ int level;
496+ // x coordinate of the tile
497+ int x;
498+ // y coordinate of the tile
499+ int y;
500+ //! Path to the tile image
501+ QString imagePath;
502+ // Set to true if the tile has no texture
503+ bool empty;
504+ //! Set to true if the tile is ready to draw
505+ bool ready;
506+ //! The texture associated with the tile
507+ StelTextureSP texture;
508+ //! The bounding cap used to check if the tile is visible
509+ SphericalCap boundingCap;
510+
511+ QList<ToastTile*> subTiles;
512+
513+ // QList<SphericalRegionP> skyConvexPolygons;
514+ //! OpenGl arrays
515+ QVector<Vec3d> vertexArray;
516+ QVector<Vec2f> textureArray;
517+ QVector<unsigned short> indexArray;
518+
519+ // Used for smooth fade in
520+ class QTimeLine* texFader;
521+};
522+
523+
524+//! @class ToastSurvey
525+//! Represents a full Toast survey.
526+class ToastSurvey : public QObject
527+{
528+ Q_OBJECT
529+
530+public:
531+ ToastSurvey(const QString& path, int maxLevel);
532+ QString getTilePath(int level, int x, int y) const;
533+ void draw(StelPainter* sPainter);
534+ const ToastGrid* getGrid() const {return &grid;}
535+ int getMaxLevel() const {return maxLevel;}
536+ int getTilesSize() const {return 256;}
537+
538+private:
539+ ToastGrid grid;
540+ QString path;
541+ ToastTile* rootTile;
542+ int maxLevel;
543+};
544+
545+#endif // _STELTOAST_HPP_
546
547=== added file 'src/core/StelToastGrid.cpp'
548--- src/core/StelToastGrid.cpp 1970-01-01 00:00:00 +0000
549+++ src/core/StelToastGrid.cpp 2016-11-13 10:24:15 +0000
550@@ -0,0 +1,177 @@
551+/*
552+ * Stellarium
553+ * Copyright (C) 2010 Guillaume Chereau
554+ *
555+ * This program is free software; you can redistribute it and/or
556+ * modify it under the terms of the GNU General Public License
557+ * as published by the Free Software Foundation; either version 2
558+ * of the License, or (at your option) any later version.
559+ *
560+ * This program is distributed in the hope that it will be useful,
561+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
562+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
563+ * GNU General Public License for more details.
564+ *
565+ * You should have received a copy of the GNU General Public License
566+ * along with this program; if not, write to the Free Software
567+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
568+ */
569+
570+#include <limits>
571+#include "StelToastGrid.hpp"
572+
573+//! compute the middle of two points on the sphere
574+static inline Vec3d middle(const Vec3d& a, const Vec3d b)
575+{
576+ Vec3d ret = a;
577+ ret += b;
578+ ret.normalize();
579+ return ret;
580+}
581+
582+
583+ToastGrid::ToastGrid(int amaxLevel)
584+ : maxLevel(amaxLevel), size(pow2(amaxLevel) + 1)
585+{
586+ // We assume that initialization of the grid is fast enough to be
587+ // done in the constructor.
588+ init_grid();
589+}
590+
591+
592+void ToastGrid::init_grid()
593+{
594+ // Allocate the grid memory.
595+ grid.resize(size * size);
596+ // Set up the level 0.
597+ at(0, 0, 0) = at(0, 1, 0) = at(0, 1, 1) = at(0, 0, 1) = Vec3d(0, 0, -1);
598+ // And the level 1
599+ // Need mirror
600+ at(1, 1, 1) = Vec3d(0, 0, 1);
601+ at(1, 1, 0) = Vec3d(0, -1, 0);
602+ at(1, 2, 1) = Vec3d(1, 0, 0);
603+ at(1, 1, 2) = Vec3d(0, 1, 0);
604+ at(1, 0, 1) = Vec3d(-1, 0, 0);
605+
606+ // Then we can compute the other levels by recursion
607+ init_grid(1, 0, 0, false);
608+ init_grid(1, 0, 1, true);
609+ init_grid(1, 1, 1, false);
610+ init_grid(1, 1, 0, true);
611+}
612+
613+
614+void ToastGrid::init_grid(int level, int x, int y, bool side)
615+{
616+ Q_ASSERT(level >= 1); // This method won't work for level 0 !
617+ int clevel = level + 1;
618+ int cx = 2*x;
619+ int cy = 2*y;
620+ // first we compute all the mid points
621+ at(clevel, cx, cy+1) = middle(at(level, x, y), at(level, x, y+1));
622+ at(clevel, cx+1, cy+2) = middle(at(level, x, y+1), at(level, x+1, y+1));
623+ at(clevel, cx+2, cy+1) = middle(at(level, x+1, y+1), at(level, x+1, y));
624+ at(clevel, cx+1, cy) = middle(at(level, x+1, y), at(level, x, y));
625+ if (side)
626+ at(clevel, cx+1, cy+1) = middle(at(level, x, y), at(level, x+1, y+1));
627+ else
628+ at(clevel, cx+1, cy+1) = middle(at(level, x, y+1), at(level, x+1, y));
629+ // now we can compute the higher levels
630+ if (clevel < maxLevel)
631+ {
632+ init_grid(clevel, cx, cy, side);
633+ init_grid(clevel, cx+1, cy, side);
634+ init_grid(clevel, cx+1, cy+1, side);
635+ init_grid(clevel, cx, cy+1, side);
636+ }
637+}
638+
639+
640+QVector<Vec3d> ToastGrid::getVertexArray(int level, int x, int y, int resolution) const
641+{
642+ Q_ASSERT(resolution >= level);
643+ Q_ASSERT(resolution <= maxLevel);
644+ // The size of the returned array
645+ int size = pow2(resolution - level) + 1;
646+ QVector<Vec3d> ret;
647+ ret.reserve(size * size);
648+ // Compute the real position in the grid
649+ int scale = pow2(maxLevel - level);
650+ x *= scale;
651+ y *= scale;
652+ // Fill the array
653+ int step = pow2(maxLevel - resolution);
654+ for (int i = 0; i < size; i++)
655+ {
656+ for (int j = 0; j < size; j++)
657+ {
658+ ret.append(at(x + j * step, y + i * step));
659+ }
660+ }
661+ Q_ASSERT(ret.size() == size * size);
662+ return ret;
663+}
664+
665+
666+QVector<Vec2f> ToastGrid::getTextureArray(int level, int x, int y, int resolution) const
667+{
668+ Q_UNUSED(x);
669+ Q_UNUSED(y);
670+ Q_ASSERT(resolution >= level);
671+ Q_ASSERT(resolution <= maxLevel);
672+ // The size of the returned array
673+ int size = pow2(resolution - level) + 1;
674+ QVector<Vec2f> ret;
675+ ret.reserve(size * size);
676+ for (int i = size-1; i >= 0; i--)
677+ {
678+ for (int j = 0; j < size; j++)
679+ {
680+ ret.append(Vec2f(j,i) / (size-1));
681+ }
682+ }
683+ Q_ASSERT(ret.size() == size * size);
684+ return ret;
685+}
686+
687+
688+QVector<unsigned short> ToastGrid::getTrianglesIndex(int level, int x, int y, int resolution) const
689+{
690+ Q_ASSERT(resolution >= level);
691+ Q_ASSERT(resolution <= maxLevel);
692+ int size = pow2(resolution - level) + 1;
693+ int nbTiles = (size - 1) * (size - 1);
694+ // If we are in the top right or the bottom left quadran we invert the diagonal of the triangles.
695+ int middleIndex = pow2(level) / 2;
696+ bool invert = (x >= middleIndex) == (y >= middleIndex);
697+ QVector<unsigned short> ret;
698+ ret.reserve(nbTiles * 6);
699+ for (int i = 0; i < size - 1; ++i)
700+ {
701+ for (int j = 0; j < size - 1; ++j)
702+ {
703+ Q_ASSERT(i * size + j <= std::numeric_limits<short>::max());
704+ unsigned int a = i * size + j;
705+ unsigned int b = (i + 1) * size + j;
706+ unsigned int c = (i + 1) * size + j + 1;
707+ unsigned int d = i * size + j + 1;
708+ if (!invert)
709+ ret << b << c << a << c << d << a;
710+ else
711+ ret << b << d << a << d << b << c;
712+ }
713+ }
714+
715+ Q_ASSERT(ret.size() == nbTiles * 6);
716+ return ret;
717+}
718+
719+
720+QVector<Vec3d> ToastGrid::getPolygon(int level, int x, int y) const
721+{
722+ QVector<Vec3d> array = getVertexArray(level, x, y, level);
723+ QVector<Vec3d> ret;
724+ ret.reserve(4);
725+ ret << array[2] << array[3] << array[1] << array[0];
726+ return ret;
727+}
728
729=== added file 'src/core/StelToastGrid.hpp'
730--- src/core/StelToastGrid.hpp 1970-01-01 00:00:00 +0000
731+++ src/core/StelToastGrid.hpp 2016-11-13 10:24:15 +0000
732@@ -0,0 +1,90 @@
733+/*
734+ * Stellarium
735+ * Copyright (C) 2010 Guillaume Chereau
736+ *
737+ * This program is free software; you can redistribute it and/or
738+ * modify it under the terms of the GNU General Public License
739+ * as published by the Free Software Foundation; either version 2
740+ * of the License, or (at your option) any later version.
741+ *
742+ * This program is distributed in the hope that it will be useful,
743+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
744+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
745+ * GNU General Public License for more details.
746+ *
747+ * You should have received a copy of the GNU General Public License
748+ * along with this program; if not, write to the Free Software
749+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
750+ */
751+
752+#ifndef STELTOASTGRID_HPP
753+#define STELTOASTGRID_HPP
754+
755+#include <QVector>
756+#include "VecMath.hpp"
757+
758+//! Compute 2^x
759+inline int pow2(int x) {return 1 << x;}
760+
761+//! @class ToastGrid
762+//! Convenience class that can be used to compute the toast grid points.
763+//! The ToastGrid class allow to compute the vertex arrays associated
764+//! with Toast tiles. Each method refers to a tile by its level and x
765+//! and y coordinates.
766+class ToastGrid
767+{
768+public:
769+ ToastGrid(int maxLevel);
770+ //! Get the vertice array for a given tile.
771+ //! The position are stored in a grid.
772+ //! @param level the level of the tile.
773+ //! @param x the x coordinate of the tile.
774+ //! @param y the y coordinate of the tile.
775+ //! @param resolution the resolution of the returned array.
776+ QVector<Vec3d> getVertexArray(int level, int x, int y, int resolution) const;
777+ //! Get the texture array for a given tile.
778+ //! The position are stored in a grid
779+ //! @param level the level of the tile.
780+ //! @param x the x coordinate of the tile.
781+ //! @param y the y coordinate of the tile.
782+ //! @param resolution the resolution of the returned array.
783+ QVector<Vec2f> getTextureArray(int level, int x, int y, int resolution) const;
784+ //! Get the index of the vertex from getVertexArray sorted as a list of triangles.
785+ //! @param level the level of the tile.
786+ //! @param x the x coordinate of the tile.
787+ //! @param y the y coordinate of the tile.
788+ //! @param resolution the resolution of the returned array.
789+ QVector<unsigned short> getTrianglesIndex(int level, int x, int y, int resolution) const;
790+ //! Returns the polygon contouring a given tile.
791+ //! @param level the level of the tile.
792+ //! @param x the x coordinate of the tile.
793+ //! @param y the y coordinate of the tile.
794+ QVector<Vec3d> getPolygon(int level, int x, int y) const;
795+ //! Return the max level of this grid.
796+ int getMaxLevel() const {return maxLevel;}
797+
798+private:
799+ //! Get the vector at a given point in the grid
800+ const Vec3d& at(int x, int y) const {return grid[y * size + x];}
801+ //! Get the vector at a given point in the grid
802+ Vec3d& at(int x, int y) {return grid[y * size + x];}
803+ //! Get the vector at a given point in the grid
804+ const Vec3d& at(int level, int x, int y) const
805+ {int scale = pow2(maxLevel - level); return at(scale * x, scale * y);}
806+ //! Get the vector at a given point in the grid
807+ Vec3d& at(int level, int x, int y)
808+ {int scale = pow2(maxLevel - level); return at(scale * x, scale * y);}
809+
810+ //! initialize the grid
811+ void init_grid();
812+ void init_grid(int level, int x, int y, bool side);
813+
814+ //! The max level of the grid
815+ int maxLevel;
816+ //! the size of the grid
817+ int size;
818+ //! The actual grid data
819+ QVector<Vec3d> grid;
820+};
821+
822+#endif // STELTOASTGRID_HPP
823
824=== modified file 'src/core/StelUtils.cpp'
825--- src/core/StelUtils.cpp 2016-10-29 16:37:42 +0000
826+++ src/core/StelUtils.cpp 2016-11-13 10:24:15 +0000
827@@ -56,6 +56,23 @@
828 #endif
829 }
830
831+QString getUserAgentString()
832+{
833+ // Get info about operating system
834+ QString platform = StelUtils::getOperatingSystemInfo();
835+ if (platform.contains("Linux"))
836+ platform = "Linux";
837+ if (platform.contains("FreeBSD"))
838+ platform = "FreeBSD";
839+ if (platform.contains("NetBSD"))
840+ platform = "NetBSD";
841+ if (platform.contains("OpenBSD"))
842+ platform = "OpenBSD";
843+
844+ // Set user agent as "Stellarium/$version$ ($platform$)"
845+ return QString("Stellarium/%1 (%2)").arg(StelUtils::getApplicationVersion()).arg(platform);
846+}
847+
848 QString getOperatingSystemInfo()
849 {
850 QString OS = "Unknown operating system";
851
852=== modified file 'src/core/StelUtils.hpp'
853--- src/core/StelUtils.hpp 2016-10-30 11:04:58 +0000
854+++ src/core/StelUtils.hpp 2016-11-13 10:24:15 +0000
855@@ -49,6 +49,9 @@
856 //! Return the name and the version of operating system, i.e. "Mac OS X 10.7"
857 QString getOperatingSystemInfo();
858
859+ //! Return the user agent name, i.e. "Stellarium/0.15.0 (Linux)"
860+ QString getUserAgentString();
861+
862 //! Convert an angle in hms format to radian.
863 //! @param h hour component
864 //! @param m minute component
865
866=== modified file 'src/core/modules/ConstellationMgr.cpp'
867--- src/core/modules/ConstellationMgr.cpp 2016-09-17 18:27:21 +0000
868+++ src/core/modules/ConstellationMgr.cpp 2016-11-13 10:24:15 +0000
869@@ -134,7 +134,7 @@
870
871 StelObjectMgr *objectManager = GETSTELMODULE(StelObjectMgr);
872 objectManager->registerStelObjectMgr(this);
873- connect(objectManager, SIGNAL(selectedObjectChanged(StelModule::StelModuleSelectAction)),
874+ connect(objectManager, SIGNAL(selectedObjectChanged(StelModule::StelModuleSelectAction)),
875 this, SLOT(selectedObjectChange(StelModule::StelModuleSelectAction)));
876 StelApp *app = &StelApp::getInstance();
877 connect(app, SIGNAL(languageChanged()), this, SLOT(updateI18n()));
878
879=== added file 'src/core/modules/ToastMgr.cpp'
880--- src/core/modules/ToastMgr.cpp 1970-01-01 00:00:00 +0000
881+++ src/core/modules/ToastMgr.cpp 2016-11-13 10:24:15 +0000
882@@ -0,0 +1,97 @@
883+/*
884+ * Stellarium
885+ * Copyright (C) 2006 Fabien Chereau
886+ *
887+ * This program is free software; you can redistribute it and/or
888+ * modify it under the terms of the GNU General Public License
889+ * as published by the Free Software Foundation; either version 2
890+ * of the License, or (at your option) any later version.
891+ *
892+ * This program is distributed in the hope that it will be useful,
893+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
894+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
895+ * GNU General Public License for more details.
896+ *
897+ * You should have received a copy of the GNU General Public License
898+ * along with this program; if not, write to the Free Software
899+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
900+ */
901+
902+#include <QDebug>
903+
904+#include "ToastMgr.hpp"
905+#include "StelToast.hpp"
906+#include "StelFader.hpp"
907+#include "StelPainter.hpp"
908+#include "StelCore.hpp"
909+#include "StelApp.hpp"
910+#include "StelTranslator.hpp"
911+#include "StelModuleMgr.hpp"
912+#include "StelSkyLayerMgr.hpp"
913+
914+#include <QSettings>
915+
916+ToastMgr::ToastMgr()
917+{
918+ setObjectName("ToastMgr");
919+ fader = new LinearFader();
920+}
921+
922+ToastMgr::~ToastMgr()
923+{
924+ if (survey)
925+ {
926+ delete survey;
927+ survey = NULL;
928+ }
929+
930+ delete fader;
931+ fader = NULL;
932+}
933+
934+void ToastMgr::init()
935+{
936+ QSettings* conf = StelApp::getInstance().getSettings();
937+ Q_ASSERT(conf);
938+
939+ // TODO: change settings before release (results->survey; dss.astro.altspu.ru->dss.stellarium.org)
940+ QString toastHost = conf->value("astro/toast_survey_host", "http://dss.astro.altspu.ru").toString();
941+ QString toastDir = conf->value("astro/toast_survey_directory", "results").toString();
942+ int toastLevel = conf->value("astro/toast_survey_levels", 11).toInt();
943+ survey = new ToastSurvey(toastHost+"/" + toastDir + "/{level}/{x}_{y}.jpg", toastLevel);
944+ survey->setParent(this);
945+
946+ // Hide deep-sky survey by default
947+ setFlagSurveyShow(conf->value("astro/flag_toast_survey", false).toBool());
948+
949+ addAction("actionShow_Toast_Survey", N_("Display Options"), N_("Digitized sky survey"), "surveyDisplayed", "Ctrl+Alt+D");
950+}
951+
952+void ToastMgr::draw(StelCore* core)
953+{
954+ if (!getFlagSurveyShow())
955+ return;
956+
957+ StelPainter sPainter(core->getProjection(StelCore::FrameJ2000));
958+ survey->draw(&sPainter);
959+}
960+
961+void ToastMgr::update(double deltaTime)
962+{
963+ fader->update((int)(deltaTime*1000));
964+}
965+
966+void ToastMgr::setFlagSurveyShow(const bool displayed)
967+{
968+ if (*fader != displayed)
969+ {
970+ *fader = displayed;
971+ GETSTELMODULE(StelSkyLayerMgr)->setFlagShow(!displayed);
972+ emit surveyDisplayedChanged(displayed);
973+ }
974+}
975+
976+bool ToastMgr::getFlagSurveyShow() const
977+{
978+ return *fader;
979+}
980
981=== added file 'src/core/modules/ToastMgr.hpp'
982--- src/core/modules/ToastMgr.hpp 1970-01-01 00:00:00 +0000
983+++ src/core/modules/ToastMgr.hpp 2016-11-13 10:24:15 +0000
984@@ -0,0 +1,53 @@
985+/*
986+ * Stellarium
987+ * Copyright (C) 2006 Fabien Chereau
988+ *
989+ * This program is free software; you can redistribute it and/or
990+ * modify it under the terms of the GNU General Public License
991+ * as published by the Free Software Foundation; either version 2
992+ * of the License, or (at your option) any later version.
993+ *
994+ * This program is distributed in the hope that it will be useful,
995+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
996+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
997+ * GNU General Public License for more details.
998+ *
999+ * You should have received a copy of the GNU General Public License
1000+ * along with this program; if not, write to the Free Software
1001+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1002+ */
1003+
1004+#ifndef _TOASTMGR_HPP_
1005+#define _TOASTMGR_HPP_
1006+
1007+#include "StelModule.hpp"
1008+
1009+class ToastMgr : public StelModule
1010+{
1011+ Q_OBJECT
1012+ Q_PROPERTY(bool surveyDisplayed
1013+ READ getFlagSurveyShow
1014+ WRITE setFlagSurveyShow
1015+ NOTIFY surveyDisplayedChanged)
1016+public:
1017+ ToastMgr();
1018+ virtual ~ToastMgr();
1019+ virtual void init();
1020+ virtual void update(double deltaTime);
1021+ virtual void draw(StelCore* core);
1022+ //! Used to determine the order in which the various modules are drawn. MilkyWay=1, we use 7.
1023+ virtual double getCallOrder(StelModuleActionName actionName) const {Q_UNUSED(actionName); return 7.;}
1024+
1025+public slots:
1026+ void setFlagSurveyShow(bool displayed);
1027+ bool getFlagSurveyShow(void) const;
1028+
1029+signals:
1030+ void surveyDisplayedChanged(const bool displayed) const;
1031+
1032+private:
1033+ class ToastSurvey* survey;
1034+ class LinearFader* fader;
1035+};
1036+
1037+#endif // _TOASTMGR_HPP_
1038
1039=== modified file 'src/gui/ConfigurationDialog.cpp'
1040--- src/gui/ConfigurationDialog.cpp 2016-11-04 17:18:42 +0000
1041+++ src/gui/ConfigurationDialog.cpp 2016-11-13 10:24:15 +0000
1042@@ -54,6 +54,7 @@
1043 #include "StelJsonParser.hpp"
1044 #include "StelTranslator.hpp"
1045 #include "EphemWrapper.hpp"
1046+#include "ToastMgr.hpp"
1047
1048 #include <QSettings>
1049 #include <QDebug>
1050@@ -77,15 +78,7 @@
1051 customDeltaTEquationDialog = NULL;
1052 hasDownloadedStarCatalog = false;
1053 isDownloadingStarCatalog = false;
1054- savedProjectionType = StelApp::getInstance().getCore()->getCurrentProjectionType();
1055- // Get info about operating system
1056- QString platform = StelUtils::getOperatingSystemInfo();
1057- if (platform.contains("Linux"))
1058- platform = "Linux";
1059- if (platform.contains("FreeBSD"))
1060- platform = "FreeBSD";
1061- // Set user agent as "Stellarium/$version$ ($platform$)"
1062- userAgent = QString("Stellarium/%1 (%2)").arg(StelUtils::getApplicationVersion()).arg(platform);
1063+ savedProjectionType = StelApp::getInstance().getCore()->getCurrentProjectionType();
1064 }
1065
1066 ConfigurationDialog::~ConfigurationDialog()
1067@@ -298,6 +291,9 @@
1068 ui->showNebulaBgButtonCheckbox->setChecked(gui->getFlagShowNebulaBackgroundButton());
1069 connect(ui->showNebulaBgButtonCheckbox, SIGNAL(toggled(bool)), gui, SLOT(setFlagShowNebulaBackgroundButton(bool)));
1070
1071+ ui->showToastSurveyButtonCheckbox->setChecked(gui->getFlagShowToastSurveyButton());
1072+ connect(ui->showToastSurveyButtonCheckbox, SIGNAL(toggled(bool)), gui, SLOT(setFlagShowToastSurveyButton(bool)));
1073+
1074 ui->showBookmarksButtonCheckBox->setChecked(gui->getFlagShowBookmarksButton());
1075 connect(ui->showBookmarksButtonCheckBox, SIGNAL(toggled(bool)), gui, SLOT(setFlagShowBookmarksButton(bool)));
1076
1077@@ -789,6 +785,7 @@
1078 conf->setValue("gui/auto_hide_horizontal_toolbar", gui->getAutoHideHorizontalButtonBar());
1079 conf->setValue("gui/auto_hide_vertical_toolbar", gui->getAutoHideVerticalButtonBar());
1080 conf->setValue("gui/flag_show_nebulae_background_button", gui->getFlagShowNebulaBackgroundButton());
1081+ conf->setValue("gui/flag_show_toast_survey_button", gui->getFlagShowToastSurveyButton());
1082 conf->setValue("gui/flag_show_decimal_degrees", StelApp::getInstance().getFlagShowDecimalDegrees());
1083 conf->setValue("gui/flag_use_azimuth_from_south", StelApp::getInstance().getFlagSouthAzimuthUsage());
1084 conf->setValue("gui/flag_time_jd", gui->getButtonBar()->getFlagTimeJd());
1085@@ -1176,7 +1173,7 @@
1086 QNetworkRequest req(nextStarCatalogToDownload.value("url").toString());
1087 req.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
1088 req.setAttribute(QNetworkRequest::RedirectionTargetAttribute, false);
1089- req.setRawHeader("User-Agent", userAgent.toLatin1());
1090+ req.setRawHeader("User-Agent", StelUtils::getUserAgentString().toLatin1());
1091 starCatalogDownloadReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
1092 starCatalogDownloadReply->setReadBufferSize(1024*1024*2);
1093 connect(starCatalogDownloadReply, SIGNAL(finished()), this, SLOT(downloadFinished()));
1094@@ -1230,7 +1227,7 @@
1095 QNetworkRequest req(redirect.toUrl());
1096 req.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
1097 req.setAttribute(QNetworkRequest::RedirectionTargetAttribute, false);
1098- req.setRawHeader("User-Agent", userAgent.toLatin1());
1099+ req.setRawHeader("User-Agent", StelUtils::getUserAgentString().toLatin1());
1100 starCatalogDownloadReply = StelApp::getInstance().getNetworkAccessManager()->get(req);
1101 starCatalogDownloadReply->setReadBufferSize(1024*1024*2);
1102 connect(starCatalogDownloadReply, SIGNAL(readyRead()), this, SLOT(newStarCatalogData()));
1103
1104=== modified file 'src/gui/ConfigurationDialog.hpp'
1105--- src/gui/ConfigurationDialog.hpp 2016-10-29 11:47:49 +0000
1106+++ src/gui/ConfigurationDialog.hpp 2016-11-13 10:24:15 +0000
1107@@ -72,8 +72,6 @@
1108 QFile* currentDownloadFile;
1109 class StelProgressController* progressBar;
1110
1111- QString userAgent;
1112-
1113 private slots:
1114 void setNoSelectedInfo();
1115 void setAllSelectedInfo();
1116
1117=== modified file 'src/gui/StelGui.cpp'
1118--- src/gui/StelGui.cpp 2016-10-29 12:45:33 +0000
1119+++ src/gui/StelGui.cpp 2016-11-13 10:24:15 +0000
1120@@ -42,6 +42,7 @@
1121 #include "StelObjectType.hpp"
1122 #include "StelObject.hpp"
1123 #include "SolarSystem.hpp"
1124+#include "ToastMgr.hpp"
1125 #include "StelSkyLayerMgr.hpp"
1126 #include "StelStyle.hpp"
1127 #include "StelSkyDrawer.hpp"
1128@@ -102,6 +103,8 @@
1129 , flipHoriz(NULL)
1130 , flagShowNebulaBackgroundButton(false)
1131 , btShowNebulaeBackground(NULL)
1132+ , flagShowToastSurveyButton(false)
1133+ , btShowToastSurvey(NULL)
1134 , flagShowBookmarksButton(false)
1135 , btShowBookmarks(NULL)
1136 , initDone(false)
1137@@ -382,6 +385,7 @@
1138 // add the flip buttons if requested in the config
1139 setFlagShowFlipButtons(conf->value("gui/flag_show_flip_buttons", false).toBool());
1140 setFlagShowNebulaBackgroundButton(conf->value("gui/flag_show_nebulae_background_button", false).toBool());
1141+ setFlagShowToastSurveyButton(conf->value("gui/flag_show_toast_survey_button", false).toBool());
1142 setFlagShowBookmarksButton(conf->value("gui/flag_show_bookmarks_button", false).toBool());
1143
1144 ///////////////////////////////////////////////////////////////////////
1145@@ -537,6 +541,10 @@
1146 if (getAction("actionShow_DSS")->isChecked() != flag)
1147 getAction("actionShow_DSS")->setChecked(flag);
1148
1149+ flag = GETSTELMODULE(ToastMgr)->getFlagSurveyShow();
1150+ if (getAction("actionShow_Toast_Survey")->isChecked() != flag)
1151+ getAction("actionShow_Toast_Survey")->setChecked(flag);
1152+
1153 flag = StelApp::getInstance().getVisionModeNight();
1154 if (getAction("actionShow_Night_Mode")->isChecked() != flag)
1155 getAction("actionShow_Night_Mode")->setChecked(flag);
1156@@ -712,6 +720,24 @@
1157 }
1158 }
1159
1160+// Define whether the button toggling TOAST survey images should be visible
1161+void StelGui::setFlagShowToastSurveyButton(bool b)
1162+{
1163+ if (b==true) {
1164+ if (btShowToastSurvey==NULL) {
1165+ // Create the nebulae background button
1166+ QPixmap pxmapGlow32x32(":/graphicGui/glow32x32.png");
1167+ QPixmap pxmapOn(":/graphicGui/btToastSurvey-on.png");
1168+ QPixmap pxmapOff(":/graphicGui/btToastSurvey-off.png");
1169+ btShowToastSurvey = new StelButton(NULL, pxmapOn, pxmapOff, pxmapGlow32x32, "actionShow_Toast_Survey");
1170+ }
1171+ getButtonBar()->addButton(btShowToastSurvey, "040-nebulaeGroup");
1172+ } else {
1173+ getButtonBar()->hideButton("actionShow_Toast_Survey");
1174+ }
1175+ flagShowToastSurveyButton = b;
1176+}
1177+
1178 void StelGui::setFlagShowDecimalDegrees(bool b)
1179 {
1180 StelApp::getInstance().setFlagShowDecimalDegrees(b);
1181@@ -809,6 +835,11 @@
1182 return flagShowNebulaBackgroundButton;
1183 }
1184
1185+bool StelGui::getFlagShowToastSurveyButton() const
1186+{
1187+ return flagShowToastSurveyButton;
1188+}
1189+
1190 bool StelGui::getFlagShowBookmarksButton() const
1191 {
1192 return flagShowBookmarksButton;
1193
1194=== modified file 'src/gui/StelGui.hpp'
1195--- src/gui/StelGui.hpp 2016-08-24 13:32:23 +0000
1196+++ src/gui/StelGui.hpp 2016-11-13 10:24:15 +0000
1197@@ -92,6 +92,9 @@
1198 //! Get whether the button toggling nebulae background is visible
1199 bool getFlagShowNebulaBackgroundButton() const;
1200
1201+ //! Get whether the button toggling TOAST survey is visible
1202+ bool getFlagShowToastSurveyButton() const;
1203+
1204 //! Get whether the button toggling bookmarks is visible
1205 bool getFlagShowBookmarksButton() const;
1206
1207@@ -123,6 +126,9 @@
1208 //! Define whether the button toggling nebulae background should be visible
1209 void setFlagShowNebulaBackgroundButton(bool b);
1210
1211+ //! Define whether the button toggling TOAST survey should be visible
1212+ void setFlagShowToastSurveyButton(bool b);
1213+
1214 //! Define whether the button toggling bookmarks should be visible
1215 void setFlagShowBookmarksButton(bool b);
1216
1217@@ -212,6 +218,9 @@
1218 bool flagShowNebulaBackgroundButton;
1219 StelButton* btShowNebulaeBackground;
1220
1221+ bool flagShowToastSurveyButton;
1222+ StelButton* btShowToastSurvey;
1223+
1224 bool flagShowBookmarksButton;
1225 StelButton* btShowBookmarks;
1226
1227
1228=== modified file 'src/gui/configurationDialog.ui'
1229--- src/gui/configurationDialog.ui 2016-11-05 18:23:26 +0000
1230+++ src/gui/configurationDialog.ui 2016-11-13 10:24:15 +0000
1231@@ -7,7 +7,7 @@
1232 <x>0</x>
1233 <y>0</y>
1234 <width>512</width>
1235- <height>563</height>
1236+ <height>579</height>
1237 </rect>
1238 </property>
1239 <layout class="QVBoxLayout">
1240@@ -1291,7 +1291,70 @@
1241 <property name="bottomMargin">
1242 <number>0</number>
1243 </property>
1244- <item row="3" column="0">
1245+ <item row="8" column="0" colspan="2">
1246+ <widget class="QCheckBox" name="autoZoomResetsDirectionCheckbox">
1247+ <property name="toolTip">
1248+ <string>When enabled, the &quot;auto zoom out&quot; key will also set the initial viewing direction</string>
1249+ </property>
1250+ <property name="text">
1251+ <string>Auto zoom out returns to initial direction of view</string>
1252+ </property>
1253+ </widget>
1254+ </item>
1255+ <item row="0" column="1">
1256+ <widget class="QCheckBox" name="diskViewportCheckbox">
1257+ <property name="toolTip">
1258+ <string>Mask out everything outside a central circle in the main view</string>
1259+ </property>
1260+ <property name="text">
1261+ <string>Disc viewport</string>
1262+ </property>
1263+ </widget>
1264+ </item>
1265+ <item row="1" column="1">
1266+ <widget class="QCheckBox" name="gravityLabelCheckbox">
1267+ <property name="toolTip">
1268+ <string>Align labels with the horizon</string>
1269+ </property>
1270+ <property name="text">
1271+ <string>Gravity labels</string>
1272+ </property>
1273+ </widget>
1274+ </item>
1275+ <item row="4" column="1">
1276+ <widget class="QCheckBox" name="decimalDegreeCheckBox">
1277+ <property name="toolTip">
1278+ <string>Use decimal degrees for coordinates</string>
1279+ </property>
1280+ <property name="text">
1281+ <string>Use decimal degrees</string>
1282+ </property>
1283+ </widget>
1284+ </item>
1285+ <item row="0" column="0">
1286+ <widget class="QCheckBox" name="sphericMirrorCheckbox">
1287+ <property name="toolTip">
1288+ <string>Spheric mirror distortion is used when projecting Stellarium onto a spheric mirror for low-cost planetarium systems.</string>
1289+ </property>
1290+ <property name="text">
1291+ <string>Spheric mirror distortion</string>
1292+ </property>
1293+ <property name="checkable">
1294+ <bool>true</bool>
1295+ </property>
1296+ </widget>
1297+ </item>
1298+ <item row="5" column="1">
1299+ <widget class="QCheckBox" name="topocentricCheckBox">
1300+ <property name="toolTip">
1301+ <string>Activate to view as seen from surface of the planet (recommended). If switched off, display planetocentric view.</string>
1302+ </property>
1303+ <property name="text">
1304+ <string>Topocentric coordinates</string>
1305+ </property>
1306+ </widget>
1307+ </item>
1308+ <item row="4" column="0">
1309 <widget class="QCheckBox" name="autoEnableAtmosphereCheckBox">
1310 <property name="toolTip">
1311 <string>Auto-enabling of the atmosphere for bodies with atmosphere in location window</string>
1312@@ -1301,6 +1364,29 @@
1313 </property>
1314 </widget>
1315 </item>
1316+ <item row="2" column="1">
1317+ <widget class="QCheckBox" name="showFlipButtonsCheckbox">
1318+ <property name="toolTip">
1319+ <string>Toggle vertical and horizontal image flip buttons.</string>
1320+ </property>
1321+ <property name="text">
1322+ <string>Show flip buttons</string>
1323+ </property>
1324+ </widget>
1325+ </item>
1326+ <item row="1" column="0">
1327+ <widget class="QCheckBox" name="selectSingleConstellationButton">
1328+ <property name="toolTip">
1329+ <string>Hide other constellations when you click one</string>
1330+ </property>
1331+ <property name="statusTip">
1332+ <string>Hide other constellations when you click one</string>
1333+ </property>
1334+ <property name="text">
1335+ <string>Select single constellation</string>
1336+ </property>
1337+ </widget>
1338+ </item>
1339 <item row="2" column="0">
1340 <widget class="QCheckBox" name="showNebulaBgButtonCheckbox">
1341 <property name="toolTip">
1342@@ -1311,7 +1397,7 @@
1343 </property>
1344 </widget>
1345 </item>
1346- <item row="4" column="0">
1347+ <item row="5" column="0">
1348 <widget class="QCheckBox" name="nutationCheckBox">
1349 <property name="toolTip">
1350 <string>Nutation is a small wobble of Earth's axis, amounting to a few arcseconds.</string>
1351@@ -1321,7 +1407,7 @@
1352 </property>
1353 </widget>
1354 </item>
1355- <item row="5" column="0">
1356+ <item row="6" column="0">
1357 <widget class="QCheckBox" name="azimuthFromSouthcheckBox">
1358 <property name="toolTip">
1359 <string>Activate this option to calculate azimuth from south towards west.</string>
1360@@ -1332,72 +1418,16 @@
1361 </widget>
1362 </item>
1363 <item row="3" column="1">
1364- <widget class="QCheckBox" name="decimalDegreeCheckBox">
1365- <property name="toolTip">
1366- <string>Use decimal degrees for coordinates</string>
1367- </property>
1368- <property name="text">
1369- <string>Use decimal degrees</string>
1370- </property>
1371- </widget>
1372- </item>
1373- <item row="4" column="1">
1374- <widget class="QCheckBox" name="topocentricCheckBox">
1375- <property name="toolTip">
1376- <string>Activate to view as seen from surface of the planet (recommended). If switched off, display planetocentric view.</string>
1377- </property>
1378- <property name="text">
1379- <string>Topocentric coordinates</string>
1380- </property>
1381- </widget>
1382- </item>
1383- <item row="2" column="1">
1384- <widget class="QCheckBox" name="showFlipButtonsCheckbox">
1385- <property name="toolTip">
1386- <string>Toggle vertical and horizontal image flip buttons.</string>
1387- </property>
1388- <property name="text">
1389- <string>Show flip buttons</string>
1390- </property>
1391- </widget>
1392- </item>
1393- <item row="1" column="1">
1394- <widget class="QCheckBox" name="gravityLabelCheckbox">
1395- <property name="toolTip">
1396- <string>Align labels with the horizon</string>
1397- </property>
1398- <property name="text">
1399- <string>Gravity labels</string>
1400- </property>
1401- </widget>
1402- </item>
1403- <item row="1" column="0">
1404- <widget class="QCheckBox" name="selectSingleConstellationButton">
1405- <property name="toolTip">
1406- <string>Hide other constellations when you click one</string>
1407- </property>
1408- <property name="statusTip">
1409- <string>Hide other constellations when you click one</string>
1410- </property>
1411- <property name="text">
1412- <string>Select single constellation</string>
1413- </property>
1414- </widget>
1415- </item>
1416- <item row="0" column="0">
1417- <widget class="QCheckBox" name="sphericMirrorCheckbox">
1418- <property name="toolTip">
1419- <string>Spheric mirror distortion is used when projecting Stellarium onto a spheric mirror for low-cost planetarium systems.</string>
1420- </property>
1421- <property name="text">
1422- <string>Spheric mirror distortion</string>
1423- </property>
1424- <property name="checkable">
1425- <bool>true</bool>
1426- </property>
1427- </widget>
1428- </item>
1429- <item row="5" column="1">
1430+ <widget class="QCheckBox" name="showToastSurveyButtonCheckbox">
1431+ <property name="toolTip">
1432+ <string>Toggle display Digitized Sky Survey.</string>
1433+ </property>
1434+ <property name="text">
1435+ <string>Show DSS button</string>
1436+ </property>
1437+ </widget>
1438+ </item>
1439+ <item row="6" column="1">
1440 <widget class="QCheckBox" name="autoChangeLandscapesCheckBox">
1441 <property name="toolTip">
1442 <string>Automatic change of landscape when planet is changed</string>
1443@@ -1407,27 +1437,7 @@
1444 </property>
1445 </widget>
1446 </item>
1447- <item row="0" column="1">
1448- <widget class="QCheckBox" name="diskViewportCheckbox">
1449- <property name="toolTip">
1450- <string>Mask out everything outside a central circle in the main view</string>
1451- </property>
1452- <property name="text">
1453- <string>Disc viewport</string>
1454- </property>
1455- </widget>
1456- </item>
1457- <item row="7" column="0" colspan="2">
1458- <widget class="QCheckBox" name="autoZoomResetsDirectionCheckbox">
1459- <property name="toolTip">
1460- <string>When enabled, the &quot;auto zoom out&quot; key will also set the initial viewing direction</string>
1461- </property>
1462- <property name="text">
1463- <string>Auto zoom out returns to initial direction of view</string>
1464- </property>
1465- </widget>
1466- </item>
1467- <item row="6" column="0">
1468+ <item row="3" column="0">
1469 <widget class="QCheckBox" name="showBookmarksButtonCheckBox">
1470 <property name="text">
1471 <string>Show bookmarks button</string>
1472
1473=== added directory 'util/DSSToStellarium'
1474=== added file 'util/DSSToStellarium/DejaVuSans.ttf'
1475Binary files util/DSSToStellarium/DejaVuSans.ttf 1970-01-01 00:00:00 +0000 and util/DSSToStellarium/DejaVuSans.ttf 2016-11-13 10:24:15 +0000 differ
1476=== added file 'util/DSSToStellarium/UTdssUtils.py'
1477--- util/DSSToStellarium/UTdssUtils.py 1970-01-01 00:00:00 +0000
1478+++ util/DSSToStellarium/UTdssUtils.py 2016-11-13 10:24:15 +0000
1479@@ -0,0 +1,35 @@
1480+#!/usr/bin/python
1481+
1482+# This file is part of Stellarium. Stellarium is free software: you can
1483+# redistribute it and/or modify it under the terms of the GNU General Public
1484+# License as published by the Free Software Foundation, version 2.
1485+#
1486+# This program is distributed in the hope that it will be useful, but WITHOUT
1487+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1488+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1489+# details.
1490+#
1491+# You should have received a copy of the GNU General Public License along with
1492+# this program; if not, write to the Free Software Foundation, Inc., 51
1493+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1494+#
1495+# Copyright Fabien Chereau <fabien.chereau@gmail.com>
1496+
1497+import dssUtils
1498+import unittest
1499+
1500+class TestDssUtils(unittest.TestCase):
1501+
1502+ def setUp(self):
1503+ pass
1504+
1505+ def test_pointProjection(self):
1506+ wcs = dssUtils.DssWcs("S032")
1507+ pixPos = [500, 1253]
1508+ raDecPos = wcs.pixelToRaDec(pixPos)
1509+ self.assertAlmostEqual(pixPos[0], wcs.raDecToPixel(raDecPos)[0])
1510+ self.assertAlmostEqual(pixPos[1], wcs.raDecToPixel(raDecPos)[1])
1511+
1512+if __name__ == '__main__':
1513+ unittest.main()
1514+
1515
1516=== added file 'util/DSSToStellarium/createUpperToastLevels.py'
1517--- util/DSSToStellarium/createUpperToastLevels.py 1970-01-01 00:00:00 +0000
1518+++ util/DSSToStellarium/createUpperToastLevels.py 2016-11-13 10:24:15 +0000
1519@@ -0,0 +1,81 @@
1520+#!/usr/bin/python
1521+
1522+# This file is part of Stellarium. Stellarium is free software: you can
1523+# redistribute it and/or modify it under the terms of the GNU General Public
1524+# License as published by the Free Software Foundation, version 2.
1525+#
1526+# This program is distributed in the hope that it will be useful, but WITHOUT
1527+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1528+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1529+# details.
1530+#
1531+# You should have received a copy of the GNU General Public License along with
1532+# this program; if not, write to the Free Software Foundation, Inc., 51
1533+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1534+#
1535+# Copyright Fabien Chereau <fabien.chereau@gmail.com>
1536+
1537+import Image
1538+import os
1539+from subprocess import Popen, PIPE, STDOUT
1540+
1541+outDirectory = 'results'
1542+level=11
1543+imSize = 256
1544+
1545+print "Generate upper levels tile in " + outDirectory
1546+
1547+if not os.path.exists(outDirectory):
1548+ print "Output directory %s doesn't exist. It should be there and contain tiles for level %d" % (outDirectory, level)
1549+ exit(-1)
1550+
1551+level=level-1
1552+while level>=0:
1553+ print "Start level %s" % level
1554+ os.system("mkdir %s/%d" % (outDirectory, level))
1555+ allTiles = []
1556+ for filename in os.listdir("%s/%d" % (outDirectory, level+1)):
1557+ basename, extension = filename.split('.')
1558+ if basename.endswith("partial"):
1559+ tmp, partial = basename.split('-')
1560+ if not os.path.exists("%s/%d/%s" % (outDirectory, level+1, tmp+'.'+extension)):
1561+ cmd = "mv %s/%d/%s %s/%d/%s" % (outDirectory, level+1, filename, outDirectory, level+1, tmp+'.'+extension)
1562+ os.system(cmd)
1563+ basename = tmp
1564+ xystr = basename.split('_')
1565+ allTiles.append((int(xystr[0]), int(xystr[1])))
1566+
1567+ toGenerate = {}
1568+ for tile in allTiles:
1569+ key = (tile[0]/2, tile[1]/2)
1570+ if key not in toGenerate:
1571+ toGenerate[key]=[]
1572+ toGenerate[key].append(tile)
1573+
1574+ i = 0
1575+ for (x, y) in toGenerate:
1576+ i = i+1
1577+ if i % 1000 == 0:
1578+ print "%d/%d" % (i,len(toGenerate))
1579+ resImg=Image.new("RGB", (imSize, imSize))
1580+ tile = toGenerate[(x, y)]
1581+ if (x*2, y*2) in tile:
1582+ im = Image.open("%s/%d/%d_%d.jpg" % (outDirectory, level+1, x*2, y*2)).resize((imSize/2, imSize/2), Image.NEAREST)
1583+ resImg.paste(im, (0, 0))
1584+ if (x*2+1, y*2) in tile:
1585+ im = Image.open("%s/%d/%d_%d.jpg" % (outDirectory, level+1, x*2+1, y*2)).resize((imSize/2, imSize/2), Image.NEAREST)
1586+ resImg.paste(im, (imSize/2, 0))
1587+ if (x*2, y*2+1) in tile:
1588+ im = Image.open("%s/%d/%d_%d.jpg" % (outDirectory, level+1, x*2, y*2+1)).resize((imSize/2, imSize/2), Image.NEAREST)
1589+ resImg.paste(im, (0, imSize/2))
1590+ if ((x*2+1, y*2+1)) in tile:
1591+ im = Image.open("%s/%d/%d_%d.jpg" % (outDirectory, level+1, x*2+1, y*2+1)).resize((imSize/2, imSize/2), Image.NEAREST)
1592+ resImg.paste(im, (imSize/2, imSize/2))
1593+ resImg.save("%s/%d/%d_%d.jpg" % (outDirectory, level, x, y), quality=90)
1594+
1595+ level=level-1
1596+
1597+
1598+
1599+
1600+
1601
1602=== added file 'util/DSSToStellarium/dssUtils.py'
1603--- util/DSSToStellarium/dssUtils.py 1970-01-01 00:00:00 +0000
1604+++ util/DSSToStellarium/dssUtils.py 2016-11-13 10:24:15 +0000
1605@@ -0,0 +1,169 @@
1606+#!/usr/bin/python
1607+
1608+# This file is part of Stellarium. Stellarium is free software: you can
1609+# redistribute it and/or modify it under the terms of the GNU General Public
1610+# License as published by the Free Software Foundation, version 2.
1611+#
1612+# This program is distributed in the hope that it will be useful, but WITHOUT
1613+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1614+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1615+# details.
1616+#
1617+# You should have received a copy of the GNU General Public License along with
1618+# this program; if not, write to the Free Software Foundation, Inc., 51
1619+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1620+#
1621+# Copyright Fabien Chereau <fabien.chereau@gmail.com>
1622+
1623+
1624+import Image, ImageFilter, ImageStat, ImageChops
1625+import os
1626+import json
1627+import sys
1628+from astropy import wcs
1629+from astropy.io import fits
1630+import numpy
1631+import scipy.interpolate
1632+
1633+def getAllPlatesNames():
1634+ """Return the list of all DSS plates names"""
1635+ ret = []
1636+ for i in range(1, 895):
1637+ ret.append("S%03d" % i)
1638+ for i in range(2, 899):
1639+ ret.append("N%03d" % i)
1640+ return ret
1641+
1642+def getTestingPlatesNames():
1643+ """Return a list of some testing DSS plates names"""
1644+ ret = []
1645+ for i in range(100, 305):
1646+ ret.append("N%03d" % i)
1647+ return ret
1648+
1649+def getTestingPlatesNamesLMC():
1650+ """Return a list of some testing DSS plates names covering the Large Magellanic Cloud (one of the worst case)"""
1651+ return ["S086", "S085", "S057", "S056", "S033", "S032", "S055", "S054"]
1652+
1653+def getValidRegionForPlate(plateName):
1654+ """Return the polygon defining the valid pixels inside the full resolution plate image"""
1655+ if plateName[0]=='N':
1656+ return [[0,0], [17232, 0], [17232, 1200], [19200, 1200], [19200, 19200], [0, 19200]]
1657+ else:
1658+ assert plateName[0]=='S'
1659+ return [[480,0], [17232, 0], [17232, 17232], [0, 17232], [0, 624], [480, 624]]
1660+
1661+def enhancePlate(plateName, plate, referenceImage):
1662+ """Return a transformed version of the plate so that it matches the referenceImage
1663+ This is Fabien's version. It just attempts to scale brightness based on the average
1664+ brightness on a 8x8 map"""
1665+
1666+ print "Enhance darker part of the image"
1667+ plate = plate.point(lambda t : 2.*t-256.*(t/256.)**1.8)
1668+
1669+ """
1670+ plate.save("tmp/%s-full.jpg" % plateName, 'JPEG', quality=80)
1671+ referenceImage.save("tmp/%s-reference.jpg" % plateName, 'JPEG', quality=95)
1672+ return plate
1673+
1674+ print "Enhance plate"
1675+ plateMap = plate.resize((8,8) , Image.ANTIALIAS)
1676+ plateMap.save("tmp/%s-full.jpg" % plateName, 'JPEG', quality=95)
1677+
1678+ referenceImageMap = referenceImage.resize((8,8) , Image.ANTIALIAS)
1679+ referenceImageMap.save("tmp/%s-reference.jpg" % plateName, 'JPEG', quality=95)
1680+
1681+ diffMap = plateMap-referenceImageMap
1682+
1683+ step=8./plate.size[0]
1684+
1685+ platePix = plate.load()
1686+ for i in range(plate.size[0]):
1687+ for j in range(plate.size[1]):
1688+ platePix[i, j] = platePix[i, j]+i*step
1689+
1690+ print "Done enhancing plate"
1691+ """
1692+ return plate
1693+
1694+def enhancePlate2(plateName, plate, referenceImage):
1695+ """Return a transformed version of the plate so that it matches the referenceImage"""
1696+ #print "Enhance darker part of the image"
1697+ plate = plate.point(lambda t : 2.*t-256.*(t/256.)**1.8)
1698+
1699+ enhanceScaling = 32
1700+
1701+ print "Enhance plate"
1702+ plate = plate.resize((256,256) , Image.BICUBIC)
1703+ plate.save("tmp/%s-full.jpg" % plateName, 'JPEG', quality=95)
1704+ #referenceImage = referenceImage.resize(plate.size, Image.BILINEAR)
1705+ referenceImage.save("tmp/%s-reference.jpg" % plateName, 'JPEG', quality=95)
1706+
1707+ plate = None
1708+ #referenceImage = None
1709+
1710+ #os.system("python src/main.py --hi_res tmp/%s-full.jpg --lo_res tmp/%s-reference.jpg --output tmp/%s-enhanced.jpg" % (plateName, plateName, plateName) )
1711+ referenceImage.save("tmp/%s-enhanced.jpg" % plateName, 'JPEG', quality=95)
1712+
1713+ plate = Image.open("tmp/%s-enhanced.jpg" % plateName)
1714+ plate = plate.resize((plate.size[0]*enhanceScaling, plate.size[0]*enhanceScaling) , Image.BILINEAR)
1715+ print "Done enhancing plate"
1716+
1717+ return plate
1718+
1719+class DssWcs:
1720+ """A pixel to sky conversion class. It wraps a WCS object read from the FITS header"""
1721+ def __init__(self, plateName):
1722+ # Load the FITS hdulist using astropy.io.fits
1723+ assert os.path.exists("preparedPlates/")
1724+ hdulist = fits.open("preparedPlates/%s/%s_00_00_x64-FITS-header.hhh" % (plateName, plateName))
1725+ self.w = wcs.WCS(hdulist[0].header)
1726+
1727+ try:
1728+ f = open("preparedPlates/%s/%s.offsets" % (plateName, plateName), 'r')
1729+ except IOError:
1730+ self.gridPixelPos = None
1731+ self.gridOffset = None
1732+ self.inverseGridPixelPos = None
1733+ else:
1734+ offsets = json.loads(f.read())
1735+ f.close()
1736+
1737+ self.gridPixelPos = []
1738+ self.gridOffset = []
1739+ self.inverseGridPixelPos = []
1740+ for el in offsets:
1741+ self.gridPixelPos.append(el['pixelPos'])
1742+ self.gridOffset.append(el['offset'])
1743+ self.inverseGridPixelPos.append([el['pixelPos'][0]+el['offset'][0], el['pixelPos'][1]+el['offset'][1]])
1744+ self.gridPixelPos = numpy.array(self.gridPixelPos)
1745+ self.gridOffset = numpy.array(self.gridOffset)
1746+ self.inverseGridPixelPos = numpy.array(self.inverseGridPixelPos)
1747+
1748+ def pixelToRaDec(self, pixelPos):
1749+ """Return the RA DEC pair for a given pixel position (even if outside the plate)
1750+ the passed wcs must be the one laying in the preparedPlates directory"""
1751+ arr = [pixelPos[0], pixelPos[1]]
1752+ if self.inverseGridPixelPos!=None:
1753+ nearestOffset = scipy.interpolate.griddata(self.inverseGridPixelPos, self.gridOffset, [arr], method='nearest')
1754+ arr = [arr[0]-nearestOffset[0][0], arr[1]-nearestOffset[0][1]]
1755+
1756+ arr = [arr[0]/64.+1.5, arr[1]/64.+1.5]
1757+ arr = numpy.array([arr], numpy.float_)
1758+ ret = self.w.wcs_pix2world(arr, 1)
1759+ return [ret[0][0], ret[0][1]]
1760+
1761+ def raDecToPixel(self, raDecPos):
1762+ """Return the pixel pos for a given RA DEC sky position (even if outside the plate)
1763+ the passed wcs must be the one laying in the preparedPlates directory"""
1764+ arr = numpy.array([[raDecPos[0], raDecPos[1]]], numpy.float_)
1765+ ret = self.w.wcs_world2pix(arr, 1)
1766+ ret = [(ret[0][0]-1.5)*64., (ret[0][1]-1.5)*64.]
1767+
1768+ # Add offset to compensate for linear WCS model errors
1769+ if self.gridOffset!=None:
1770+ nearestOffset = scipy.interpolate.griddata(self.gridPixelPos, self.gridOffset, [ret], method='nearest')
1771+ ret = [ret[0]+nearestOffset[0][0], ret[1]+nearestOffset[0][1]]
1772+
1773+ return ret
1774+
1775
1776=== added file 'util/DSSToStellarium/generateFullPlate.py'
1777--- util/DSSToStellarium/generateFullPlate.py 1970-01-01 00:00:00 +0000
1778+++ util/DSSToStellarium/generateFullPlate.py 2016-11-13 10:24:15 +0000
1779@@ -0,0 +1,159 @@
1780+#!/usr/bin/python
1781+
1782+# This file is part of Stellarium. Stellarium is free software: you can
1783+# redistribute it and/or modify it under the terms of the GNU General Public
1784+# License as published by the Free Software Foundation, version 2.
1785+#
1786+# This program is distributed in the hope that it will be useful, but WITHOUT
1787+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1788+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1789+# details.
1790+#
1791+# You should have received a copy of the GNU General Public License along with
1792+# this program; if not, write to the Free Software Foundation, Inc., 51
1793+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1794+#
1795+# Copyright Fabien Chereau <fabien.chereau@gmail.com>
1796+
1797+
1798+# -----------------------------------------------------------
1799+# Generate the survey, i.e.
1800+# Cut and re-project toast tiles from color DSS plates
1801+# -----------------------------------------------------------
1802+# python generateFullPlate.py
1803+#
1804+# input : the "preparedPlates" directory created in step 1 must be present
1805+# output: a "results" directory containing the survey ready for display in Stellarium
1806+
1807+
1808+import Image, ImageFilter, ImageStat, ImageChops, ImageOps, ImageDraw, ImageFont
1809+import os
1810+import json
1811+from subprocess import Popen, PIPE, STDOUT
1812+import sys
1813+import dssUtils
1814+
1815+# Test code where I tried to use a low res image from Axel mellinger as reference
1816+# for color harmonization (the image we use for the milky way in Stellarium)
1817+# It's not working well yet, so let commented for now
1818+#mellingerImage = Image.open("mellinger_rgb_rect-curved.jpg")
1819+#mellingerImagePix = mellingerImage.load()
1820+
1821+def generatePlate(plateName, maxLevel):
1822+ if not os.path.exists("results"):
1823+ os.system("mkdir results")
1824+ if not os.path.exists("results/%d" % maxLevel):
1825+ os.system("mkdir results/%d" % maxLevel)
1826+ if not os.path.exists("tmp"):
1827+ os.system("mkdir tmp")
1828+
1829+ print "-------- " + plateName + " --------"
1830+ if os.path.exists("results/%s.stamp" % (plateName)):
1831+ print "Plate %s already processed" % (plateName)
1832+ return
1833+
1834+ assert os.path.exists("preparedPlates")
1835+ assert os.path.exists("preparedPlates/%s/%s.jpg" % (plateName, plateName))
1836+
1837+ print "Get list of TOAST tiles intersecting the plate"
1838+
1839+ wcs = dssUtils.DssWcs(plateName)
1840+
1841+ # And make sure to get rid of the plate edges in the corner..
1842+ #points = dssUtils.getValidRegionForPlate(plateName)
1843+ points = [[0,0], [19200, 0], [19200, 19200], [0, 19200]]
1844+ plateCornersRaDec = [wcs.pixelToRaDec(p) for p in points]
1845+ cmd = './toastForShape %d "' % (maxLevel) + json.dumps(plateCornersRaDec).replace('"', '\\"') + '"'
1846+ print cmd
1847+ p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True)
1848+ jsonTriangles = p.stdout.read()
1849+ triangles = json.loads(jsonTriangles)
1850+
1851+ print "Convert the pixel position of the toast tiles into the existing DSS image"
1852+ allTrianglesRadecPos = []
1853+ for tri in triangles:
1854+ allTrianglesRadecPos.extend(tri['tile'][1:])
1855+ allTrianglesPixelPos = [wcs.raDecToPixel(p) for p in allTrianglesRadecPos]
1856+
1857+ # Put all contained triangles (to be cut) in the tiles dict
1858+ tiles = {}
1859+ i=0
1860+ for tri in triangles:
1861+ tile = allTrianglesPixelPos[i*4:i*4+4]
1862+ t = {'XY': [tri['i'], tri['j']], 'tile': tile}
1863+ tiles[json.dumps(t['XY'])]=t
1864+ i=i+1
1865+
1866+ tiles = tiles.values()
1867+
1868+ print "Cut and save the toast tiles (%d tiles at level %s)." % (len(tiles), maxLevel)
1869+
1870+ # Create the sub directories
1871+
1872+ os.system("mkdir tmp/%s" % plateName)
1873+ os.system("mkdir tmp/%s/%d" % (plateName, maxLevel))
1874+
1875+
1876+ print "load full plate image"
1877+ resImg = Image.open("preparedPlates/%s/%s.jpg" % (plateName, plateName))
1878+ #draw = ImageDraw.Draw(resImg)
1879+ #font = ImageFont.truetype("DejaVuSans.ttf", 600)
1880+ #draw.text([9500, 9500], plateName, font=font, fill=(255,255,0))
1881+
1882+ resImg = ImageOps.flip(resImg)
1883+
1884+ def raDecToMellinger(raDec):
1885+ return [(-raDec[0]/360.+0.5)*mellingerImage.size[0], (-raDec[1]/180.+0.5)*mellingerImage.size[1]]
1886+
1887+ # Generate a low res reference image from Mellinger data
1888+ delta = 19200./256.
1889+ referenceImage = Image.new("RGB", (256, 256))
1890+ #pix = referenceImage.load()
1891+ #for i in range(256):
1892+ # for j in range(256):
1893+ # raDec = wcs.pixelToRaDec((i*delta+delta/2, j*delta+delta/2))
1894+ # if raDec[0]>180:
1895+ # raDec[0]=raDec[0]-360
1896+ # mellingerPos = raDecToMellinger(raDec)
1897+ # pix[i, j] = mellingerImagePix[mellingerPos[0], mellingerPos[1]]
1898+
1899+ # Enhance plate
1900+ resImg = dssUtils.enhancePlate(plateName, resImg, referenceImage)
1901+
1902+ def isPartial(imageW, imageH, region):
1903+ for i in range(len(region)/2):
1904+ p = [region[i*2], region[i*2+1]]
1905+ if p[0]<0 or p[0]>imageW or p[1]<0 or p[1]>imageH:
1906+ return True
1907+ return False
1908+
1909+ print "Cut tiles"
1910+ for tile in tiles:
1911+ tt = []
1912+ partial = False
1913+ for p in tile['tile']:
1914+ x=p[0]
1915+ y=p[1]
1916+ tt.append(x)
1917+ tt.append(y)
1918+ tt = tt[6:]+tt[0:6]
1919+
1920+ partial = isPartial(resImg.size[0], resImg.size[1], tt)
1921+ im = resImg.transform((256,256), Image.QUAD, tuple(tt), Image.BILINEAR)
1922+
1923+ xy = tile['XY']
1924+ im.save("tmp/%s/%d/%d_%d%s.jpg" % (plateName, maxLevel, xy[0], xy[1], "-partial" if partial else ""), quality=95)
1925+
1926+ print "package and store results"
1927+ os.system("mv tmp/%s/%d/* results/%d/" % (plateName, maxLevel, maxLevel))
1928+ os.system("rm -rf tmp/%s" % plateName)
1929+ os.system("touch results/%s.stamp" % plateName)
1930+
1931+
1932+if __name__ == '__main__':
1933+ maxLevel = 11
1934+
1935+ for plate in dssUtils.getAllPlatesNames():
1936+ generatePlate(plate, maxLevel)
1937+
1938+ os.system("python createUpperToastLevels.py")
1939
1940=== added file 'util/DSSToStellarium/mellinger_rgb_rect-curved.jpg'
1941Binary files util/DSSToStellarium/mellinger_rgb_rect-curved.jpg 1970-01-01 00:00:00 +0000 and util/DSSToStellarium/mellinger_rgb_rect-curved.jpg 2016-11-13 10:24:15 +0000 differ
1942=== added file 'util/DSSToStellarium/prepareAllPlates.py'
1943--- util/DSSToStellarium/prepareAllPlates.py 1970-01-01 00:00:00 +0000
1944+++ util/DSSToStellarium/prepareAllPlates.py 2016-11-13 10:24:15 +0000
1945@@ -0,0 +1,117 @@
1946+#!/usr/bin/python
1947+
1948+# This file is part of Stellarium. Stellarium is free software: you can
1949+# redistribute it and/or modify it under the terms of the GNU General Public
1950+# License as published by the Free Software Foundation, version 2.
1951+#
1952+# This program is distributed in the hope that it will be useful, but WITHOUT
1953+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1954+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1955+# details.
1956+#
1957+# You should have received a copy of the GNU General Public License along with
1958+# this program; if not, write to the Free Software Foundation, Inc., 51
1959+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1960+#
1961+# Copyright Fabien Chereau <fabien.chereau@gmail.com>
1962+
1963+import Image, ImageFilter, ImageStat, ImageChops
1964+import os
1965+from astLib import astWCS
1966+import json
1967+from subprocess import Popen, PIPE, STDOUT
1968+import sys
1969+from multiprocessing import Pool
1970+import dssUtils
1971+from astropy import wcs
1972+from astropy.io import fits
1973+import numpy
1974+
1975+# -----------------------------------------------------------
1976+# Pre-process zipped plates to extract only necessary data
1977+# This has to be run once if you don't already have the
1978+# preprocessed plates
1979+# -----------------------------------------------------------
1980+# python prepareAllPlates.py
1981+#
1982+# input : a directory with all original plates .tgz files (change in code)
1983+# output: a directory "preparedPlates" containing for each plate a single full resolution jpg image + a FITS headers necessary for sky-to-pixel projection
1984+# usage : you must change the location of your input DSS plates path directly in the script
1985+
1986+# The directory containing the plates .tgz files
1987+originalPlatesDirectory = "/media/fabien/data/DSS-orig"
1988+
1989+# Pre-compute meta-infos about the plate as well as a re-combination of all tile into one large image
1990+def preparePlate(plateName):
1991+ if not os.path.exists("preparedPlates"):
1992+ os.system("mkdir preparedPlates")
1993+
1994+ if os.path.exists("preparedPlates/%s-x64-FITS-header.hhh" % plateName):
1995+ print "%s already processed, skip." % plateName
1996+ return
1997+
1998+ print "-------- " + plateName + " --------"
1999+ if os.path.exists("preparedPlates/%s" % (plateName)):
2000+ print "Plate %s already pre-processed" % (plateName)
2001+ return
2002+ print "Copy and prepare plate data"
2003+ os.system("cp %s/%s.tgz ." % (originalPlatesDirectory, plateName))
2004+ os.system("tar -xzf %s.tgz" % plateName)
2005+ os.system("chmod -R a+w %s" % plateName)
2006+ assert os.path.exists("%s" % plateName)
2007+
2008+ print "create full plate image"
2009+ resImg=Image.new("RGB", (64*300, 64*300))
2010+ for j in range(0, 64):
2011+ for i in range(0,64):
2012+ if os.path.exists("%s/x1/%s_%.2d_%.2d_x1.jpg" % (plateName, plateName, i, j)):
2013+ im = Image.open("%s/x1/%s_%.2d_%.2d_x1.jpg" % (plateName, plateName, i, j))
2014+ resImg.paste(im, (i*300, 64*300-j*300-300))
2015+ else:
2016+ print "Missing jpeg tile: %s/x1/%s_%.2d_%.2d_x1.jpg" % (plateName, plateName, i, j)
2017+
2018+ print "package and store results"
2019+ os.system("mkdir preparedPlates/%s" % plateName)
2020+ resImg.save("preparedPlates/%s/%s.jpg" % (plateName, plateName))
2021+ os.system("cp %s/x64/%s_00_00_x64.hhh preparedPlates/%s/%s_00_00_x64-FITS-header.hhh" % (plateName, plateName, plateName, plateName))
2022+
2023+ wcsWithoutCorrection = dssUtils.DssWcs(plateName)
2024+
2025+ print "Compute the array of pixel offsets needed to adjust WCS conversions."
2026+ # Load the x1 FITS headers to get the corrective offset term
2027+ allOffsets = []
2028+
2029+ for i in range(0,64, 4):
2030+ for j in range(0, 64, 4):
2031+ if not os.path.exists("%s/x1/%s_%.2d_%.2d_x1.hhh" % (plateName, plateName, i, j)):
2032+ print "Missing .hhh file"
2033+ continue
2034+ hdulist = fits.open("%s/x1/%s_%.2d_%.2d_x1.hhh" % (plateName, plateName, i, j))
2035+ w = wcs.WCS(hdulist[0].header)
2036+ arr = numpy.array([[0., 0.]], numpy.float_) # Bottom left corner
2037+ radecCorner = w.wcs_pix2world(arr, 1)
2038+ realPixelPos = [i*300, j*300]
2039+ currPixelPos = wcsWithoutCorrection.raDecToPixel([radecCorner[0][0], radecCorner[0][1]])
2040+ assert currPixelPos!=None
2041+ allOffsets.append({'pixelPos': currPixelPos, 'offset': [realPixelPos[0]-currPixelPos[0], realPixelPos[1]-currPixelPos[1]]})
2042+
2043+ f = open("preparedPlates/%s/%s.offsets" % (plateName, plateName), 'w')
2044+ f.write(json.dumps(allOffsets))
2045+ f.close()
2046+
2047+ print "clean up"
2048+ os.system("rm %s.tgz" % plateName)
2049+ os.system("rm -rf %s" % plateName)
2050+
2051+jobsArgs = dssUtils.getAllPlatesNames()()
2052+
2053+pool = Pool(2)
2054+try:
2055+ pool.map_async(preparePlate, jobsArgs).get(9999999)
2056+except KeyboardInterrupt:
2057+ print "Caught KeyboardInterrupt, terminating workers"
2058+ pool.terminate()
2059+ pool.join()
2060+
2061+
2062+
2063
2064=== added file 'util/DSSToStellarium/readme.txt'
2065--- util/DSSToStellarium/readme.txt 1970-01-01 00:00:00 +0000
2066+++ util/DSSToStellarium/readme.txt 2016-11-13 10:24:15 +0000
2067@@ -0,0 +1,33 @@
2068+A set of pyton scripts used to process DSS plates for Stellarium
2069+
2070+Dependencies:
2071+ - astropy: (sudo pip install astropy)
2072+ - PIL (sudo apt-get install python-imaging)
2073+ - numpy
2074+
2075+-----------------------------------------------------------
2076+1- Pre-process zipped plates to extract only necessary data
2077+-----------------------------------------------------------
2078+python prepareAllPlates.py
2079+
2080+input: a directory with all original plates .tgz files (change in code)
2081+output: a directory "preparedPlates" containing for each plate a single full resolution jpg image + a FITS headers necessary for sky-to-pixel projection
2082+usage: you must change the location of your input DSS plates path directly in the script
2083+
2084+
2085+-----------------------------------------------------------
2086+2- Generate the survey
2087+-----------------------------------------------------------
2088+python generateFullPlate.py
2089+
2090+input: the "preparedPlates" directory created in step 1 must be present
2091+output: a "results" directory containing the survey ready for display in Stellarium
2092+
2093+
2094+-----------------------------------------------------------
2095+3- Display the survey
2096+-----------------------------------------------------------
2097+Get the Stellarium branch bzr+ssh://bazaar.launchpad.net/~stellarium/stellarium/toastImages
2098+Change the base location of the survey to match the path where the results/ directory is stored. This can be done in ToastMgr.cpp line 29
2099+Compile and run the soft. Remove ground and atmosphere (press G and A), the survey should be visible in the south hemisphere.
2100+
2101
2102=== added file 'util/DSSToStellarium/toastForShape'
2103Binary files util/DSSToStellarium/toastForShape 1970-01-01 00:00:00 +0000 and util/DSSToStellarium/toastForShape 2016-11-13 10:24:15 +0000 differ
2104=== added directory 'util/toastForShape'
2105=== added file 'util/toastForShape/main.cpp'
2106--- util/toastForShape/main.cpp 1970-01-01 00:00:00 +0000
2107+++ util/toastForShape/main.cpp 2016-11-13 10:24:15 +0000
2108@@ -0,0 +1,38 @@
2109+#include <QtCore/QCoreApplication>
2110+#include "StelToast.hpp"
2111+#include "StelJsonParser.hpp"
2112+
2113+int main(int argc, char *argv[])
2114+{
2115+ Q_ASSERT(argc==3);
2116+ QByteArray ar = argv[1];
2117+ bool ok;
2118+ int level = ar.toInt(&ok);
2119+ if (!ok)
2120+ {
2121+ qFatal("Argument 1 must be a valid level number");
2122+ }
2123+ int length = sqrt(pow(4, level));
2124+ SphericalRegionP reg = SphericalRegionP::loadFromQVariant(StelJsonParser::parse(argv[2]).toList());
2125+ //SphericalRegionP reg = SphericalRegionP::loadFromQVariant(StelJsonParser::parse("[[21.286982057125858, 82.117482778097937], [341.20801035028205, 82.141350178494122], [308.54824444399429, 86.661406614892087], [54.398199236987082, 86.613098160666411]]").toList());
2126+ ToastGrid grid(level);
2127+ QVariantList l;
2128+ for (int i=0;i<length;++i)
2129+ {
2130+ for (int j=0;j<length;++j)
2131+ {
2132+ SphericalConvexPolygon poly(grid.getPolygon(level,i,j));
2133+ if (reg->intersects(poly))
2134+ {
2135+ QVariantMap m;
2136+ m["i"]=i;
2137+ m["j"]=j;
2138+ m["tile"]= poly.toQVariant();
2139+ l << m;
2140+ }
2141+ }
2142+ }
2143+ printf("%s", StelJsonParser::write(l).constData());
2144+
2145+ return 0;
2146+}
2147
2148=== added file 'util/toastForShape/toastForShape.pro'
2149--- util/toastForShape/toastForShape.pro 1970-01-01 00:00:00 +0000
2150+++ util/toastForShape/toastForShape.pro 2016-11-13 10:24:15 +0000
2151@@ -0,0 +1,73 @@
2152+#-------------------------------------------------
2153+#
2154+# Project created by QtCreator 2010-11-28T20:43:35
2155+#
2156+#-------------------------------------------------
2157+
2158+QT += core gui opengl network
2159+
2160+DEFINES += PACKAGE_VERSION=\\\"0.10.6\\\"
2161+DEFINES += DEFAULT_GRAPHICS_SYSTEM=\\\"raster\\\"
2162+DEFINES += INSTALL_DATADIR=\\\"/usr/share/stellarium\\\"
2163+DEFINES += INSTALL_LOCALEDIR=\\\"/usr/share/locale\\\"
2164+DEFINES += NDEBUG=1
2165+
2166+TARGET = toastForShape
2167+CONFIG += console
2168+CONFIG -= app_bundle
2169+
2170+TEMPLATE = app
2171+
2172+INCLUDEPATH += ../../src/core/ ../../src/core/external/glues_stel/source ../../src/core/external
2173+
2174+SOURCES += main.cpp \
2175+ ../../src/core/StelSphereGeometry.cpp \
2176+ ../../src/core/StelToastGrid.cpp \
2177+ ../../src/core/StelJsonParser.cpp \
2178+ ../../src/core/OctahedronPolygon.cpp \
2179+ ../../src/core/StelUtils.cpp \
2180+ ../../src/core/StelProjector.cpp \
2181+ ../../src/core/external/glues_stel/source/glues_error.c \
2182+ ../../src/core/external/glues_stel/source/libtess/tessmono.c \
2183+ ../../src/core/external/glues_stel/source/libtess/tess.c \
2184+ ../../src/core/external/glues_stel/source/libtess/sweep.c \
2185+ ../../src/core/external/glues_stel/source/libtess/render.c \
2186+ ../../src/core/external/glues_stel/source/libtess/priorityq.c \
2187+ ../../src/core/external/glues_stel/source/libtess/normal.c \
2188+ ../../src/core/external/glues_stel/source/libtess/mesh.c \
2189+ ../../src/core/external/glues_stel/source/libtess/memalloc.c \
2190+ ../../src/core/external/glues_stel/source/libtess/geom.c \
2191+ ../../src/core/external/glues_stel/source/libtess/dict.c \
2192+ ../../src/core/StelVertexArray.cpp \
2193+ ../../src/core/StelTranslator.cpp \
2194+ ../../src/core/StelFileMgr.cpp
2195+
2196+HEADERS += \
2197+ ../../src/core/VecMath.hpp \
2198+ ../../src/core/StelSphereGeometry.hpp \
2199+ ../../src/core/StelToastGrid.hpp \
2200+ ../../src/core/StelJsonParser.hpp \
2201+ ../../src/core/OctahedronPolygon.hpp \
2202+ ../../src/core/StelUtils.hpp \
2203+ ../../src/core/external/glues_stel/source/glues.h \
2204+ ../../src/core/external/glues_stel/source/glues_error.h \
2205+ ../../src/core/external/glues_stel/source/libtess/tessmono.h \
2206+ ../../src/core/external/glues_stel/source/libtess/tess.h \
2207+ ../../src/core/external/glues_stel/source/libtess/sweep.h \
2208+ ../../src/core/external/glues_stel/source/libtess/render.h \
2209+ ../../src/core/external/glues_stel/source/libtess/priorityq.h \
2210+ ../../src/core/external/glues_stel/source/libtess/priorityq-sort.h \
2211+ ../../src/core/external/glues_stel/source/libtess/priorityq-heap.h \
2212+ ../../src/core/external/glues_stel/source/libtess/normal.h \
2213+ ../../src/core/external/glues_stel/source/libtess/mesh.h \
2214+ ../../src/core/external/glues_stel/source/libtess/memalloc.h \
2215+ ../../src/core/external/glues_stel/source/libtess/geom.h \
2216+ ../../src/core/external/glues_stel/source/libtess/dict.h \
2217+ ../../src/core/external/glues_stel/source/libtess/dict-list.h \
2218+ ../../src/core/StelVertexArray.hpp \
2219+ ../../src/core/StelTranslator.hpp
2220+
2221+OTHER_FILES += \
2222+ ../../src/core/external/glues_stel/source/libtess/README \
2223+ ../../src/core/external/glues_stel/source/libtess/priorityq-heap.i \
2224+ ../../src/core/external/glues_stel/source/libtess/alg-outline