Merge lp:~stellarium/stellarium/toastImages into lp:stellarium
- toastImages
- Merge into trunk
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 |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
gzotti | Approve | ||
Guillaume Chereau | Pending | ||
Fabien Chéreau | Pending | ||
Review via email: mp+310716@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Alexander Wolf (alexwolf) wrote : | # |
TOAST is "tessellated octahedral adaptive subdivision transform" (details: https:/
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' |
2 | Binary 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' |
4 | Binary 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 "auto zoom out" 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 "auto zoom out" 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' |
1475 | Binary 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' |
1941 | Binary 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' |
2103 | Binary 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 |
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.)