Merge lp:~i-martividal/stellarium/Observability into lp:stellarium

Proposed by Ivan Marti-Vidal
Status: Merged
Merged at revision: 5524
Proposed branch: lp:~i-martividal/stellarium/Observability
Merge into: lp:stellarium
Diff against target: 2579 lines (+2483/-0)
12 files modified
CMakeLists.txt (+1/-0)
plugins/CMakeLists.txt (+3/-0)
plugins/Observability/CMakeLists.txt (+11/-0)
plugins/Observability/Observability.qrc (+6/-0)
plugins/Observability/src/CMakeLists.txt (+62/-0)
plugins/Observability/src/Observability.cpp (+1433/-0)
plugins/Observability/src/Observability.hpp (+255/-0)
plugins/Observability/src/gui/ObservabilityDialog.cpp (+229/-0)
plugins/Observability/src/gui/ObservabilityDialog.hpp (+69/-0)
plugins/Observability/src/gui/ObservabilityDialog.ui (+405/-0)
src/CMakeLists.txt (+5/-0)
src/StelMainGraphicsView.cpp (+4/-0)
To merge this branch: bzr merge lp:~i-martividal/stellarium/Observability
Reviewer Review Type Date Requested Status
gzotti Approve
Alexander Wolf Approve
Review via email: mp+118902@code.launchpad.net

Description of the change

Dear all,

I'm happy and proud to tell that Observability is finally a mature code. The GUI for configuration is finished and there are some minor bugs corrected, as well as a new feature implemented (now it also gives the local times for "today's ephemeris"). I checked the code at North and South hemispheres, different years, and extreme latitudes and it seems to work well (which doesn't mean you may still find errors if you do a deep bug hunting).

I'd therefore kindly ask for the merging of the code into the main trunk, if there are no further problems! :D

This plugin gives the user a lot of information on the ephemeris of the selected object (or the screen center if nothing is selected): Rise time, set time, transit time (all these also for the Sun and Moon!), and additional info for the year ephemeris: Date of Sun opposition, Heliacal Rise/Set dates (maybe useful for Arhaeoastronomy?), and ranges when the source is best observable (i.e., above the horizon during the astronomical night).

If you need more details, please don't hesitate to ask!

    Best wishes,

         Ivan

To post a comment you must log in.
Revision history for this message
Alexander Wolf (alexwolf) wrote :

Please fix conflicts (you can merge code from trunk for it)

review: Needs Fixing
Revision history for this message
gzotti (georg-zotti) wrote :
Download full text (5.1 KiB)

Dear Ivan,

very interesting work indeed, I know a few people in my astronomy club who
are craving for such a functionality!

However, I have a few points of concern before this should go into regular
distribution:

Your "heliacal" dates are dates when the object rises/sets opposite the
sun. This is actually called "acronychal" rise/set and has nothing to do
with Heliacals. Heliacal rising for stars is always in the morning, some
time before sunrise, heliacal setting is in the evening, shortly after
sunset, during twilight and (at least for planets where it matters most
for historical issues) inside the twilight dome. BTW, there is another
sophistry: simultaneous rising/setting with the sun. This is called
"cosmical", may also be sometimes confused with Heliacal events, but is
also typically not observable.

The visibility period for an object is from Heliacal rising to Heliacal
setting, obviously.

Think of Venus, it is easily visible in bright twilight, so the current
criterion is a first proxy, but should be improved. Writing "Mercury:
Observable in many dates of the year" is no real help. Maybe just give
dates for the current/next period?

Computing Heliacal events is a bit more difficult and must at least
involve object magnitudes and hopefully also atmospheric extinction. The
classical approach used e.g. by researchers dealing with Mesopotamian
cuneiform records is described in works by Schoch (1927). Look for "arcus
visionis" or "arc of vision" in the literature. Also Bradley Schaefer
wrote articles in Sky&Telescope (including some code) and other journals
in the later 1990s (sorry, must look up the issue...). Computing Heliacal
times for objects far from the ecliptic is AFAIK still not completely
solved! Whatever model you use, you should name it.

A problem is that your acronychal events are typically not observable.
Please rename this current functionality to "acronychal rise" etc. for now
to avoid confusion, and consider "real" Heliacal events for a next
version.

Inner planets (Mercury, Venus) have no opposition date. Usually you will
find max elongation or max difference in ecliptical longitude, not max
difference in RA. Of course, they have a visibility period in their
eastern elongation also starting in the evening, which will end with its
"regular" Heliacal setting. Their morning apparition starts with a
"regularly computed" Heliacal rising and ends when the Heliacal criterion
again fails, i.e. the arc between sun and planet gets too short. Also
opposition for the outer planets is defined as opposition in ecliptical
longitude, not RA. (Will be close, but can be different!)

Twilight times are usually defined as "civil" (geometrical solar centre
above -6°), "nautical" (above -12°) and astronomical (above -18°). Under
dark-site conditions, solar altitudes above -18° are indeed noticeable by
at least some light on the horizon above the sun. Maybe add a
slider/combobox for user-selectable twilight altitudes (e.g. -6..-19)
[Some Muslim communities define dark night even with -19]? Speaking of
Muslims, first evening visibility of the Lunar crescent would be of
importance for them. Papers on the topic can be found online.

Can you ...

Read more...

5333. By Ivan Marti-Vidal
5334. By Ivan Marti-Vidal

Added day of Full-Moon and corrected the bad Heliacal nomenclature. Added user-defined Sun elevation at twilight, and corrected opposition (now by maximizing angular separation to the Sun). Observable epochs for Mercury are now also shown.

5335. By Ivan Marti-Vidal

Improved speed and accuracy of Full-Moon algorithm. Added additional info for the users.

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

Ivan, it's good changes, thanks, but you need fix text conflict in CMakeLists.txt and in src/StelMainGraphicsView.cpp files

review: Needs Fixing
5336. By Ivan Marti-Vidal

Added a copy of the trunk version of StelMainGraphicsView.cpp

5337. By Ivan Marti-Vidal

Modified CMakeLists

5338. By Ivan Marti-Vidal

Conflicts with current trunk are resolved

5339. By Ivan Marti-Vidal

Conflicts with current trunk are resolved

5340. By Ivan Marti-Vidal

Conflicts with current trunk are resolved

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

GUI for Observability plugin don't support changes of languages:

Object::connect: No such slot ObservabilityDialog::languageChanged() in /home/aw/devel/stellarium/Observability/plugins/Observability/src/gui/ObservabilityDialog.cpp:60
Object::connect: (sender name: 'StelApp')

Please fix it.

review: Needs Fixing
5341. By Ivan Marti-Vidal

languageChanged() fixed

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

For that plugin need a few small improvements but in general his can be merged to trunk.

review: Approve
5342. By Ivan Marti-Vidal

Sun opposition is now largest Sun separation (that separation is also shown now)

5343. By Ivan Marti-Vidal

Sun opposition is now largest Sun separation (that separation is also shown now)

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

Small edits in the About text:

1) consideres -> considers
2) Full moon: 1 minute *accuracy*, not precision.

Maybe the wording should still be improved: not "Observable epoch" but "above horizon at nights from..to..." or "Best observed from ... to ...".

For the inner planets: "Largest separation from the sun" -> "Greatest elongation". Maybe you can also add (later?) whether Mercury/Venus have morning or evening apparition?

Else it seems to work at its current level. Hopefully you can implement "real" Heliacal visibilities later!

Thanks,
Georg

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

OK. I'm merge plugin into trunk and add some small fixes.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2012-08-07 14:49:23 +0000
3+++ CMakeLists.txt 2012-08-12 12:25:22 +0000
4@@ -207,6 +207,7 @@
5 SET(USE_PLUGIN_QUASARS 1 CACHE BOOL "Define whether the Quasars plugin should be created.")
6 SET(USE_PLUGIN_PULSARS 1 CACHE BOOL "Define whether the Pulsars plugin should be created.")
7 SET(USE_PLUGIN_EXOPLANETS 1 CACHE BOOL "Define whether the Exoplanets plugin should be created.")
8+SET(USE_PLUGIN_OBSERVABILITY 1 CACHE BOOL "Define whether the Observability plugin should be created.")
9
10 ########## Static plugins need to define includes and libraries
11 ########## for the compilation of Stellarium itself
12
13=== modified file 'plugins/CMakeLists.txt'
14--- plugins/CMakeLists.txt 2012-02-22 09:11:14 +0000
15+++ plugins/CMakeLists.txt 2012-08-12 12:25:22 +0000
16@@ -6,6 +6,9 @@
17 ADD_DEFINITIONS(-DQT_DLL)
18 ADD_DEFINITIONS(-D_REENTRANT)
19
20+IF (USE_PLUGIN_OBSERVABILITY)
21+ ADD_SUBDIRECTORY( Observability )
22+ENDIF()
23 IF (USE_PLUGIN_ANGLEMEASURE)
24 ADD_SUBDIRECTORY( AngleMeasure )
25 ENDIF()
26
27=== added directory 'plugins/Observability'
28=== added file 'plugins/Observability/CMakeLists.txt'
29--- plugins/Observability/CMakeLists.txt 1970-01-01 00:00:00 +0000
30+++ plugins/Observability/CMakeLists.txt 2012-08-12 12:25:22 +0000
31@@ -0,0 +1,11 @@
32+SET(OBSERVABILITY_VERSION "0.1.0")
33+
34+ADD_SUBDIRECTORY( src )
35+
36+IF(APPLE)
37+ SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/Library/Application\ Support/Stellarium)
38+ELSE(APPLE)
39+ SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/.stellarium)
40+ENDIF(APPLE)
41+
42+INSTALL(FILES DESTINATION "modules/Observability")
43
44=== added file 'plugins/Observability/Observability.qrc'
45--- plugins/Observability/Observability.qrc 1970-01-01 00:00:00 +0000
46+++ plugins/Observability/Observability.qrc 2012-08-12 12:25:22 +0000
47@@ -0,0 +1,6 @@
48+<RCC>
49+ <qresource prefix="observability" >
50+ <file>bt_observab_on.png</file>
51+ <file>bt_observab_off.png</file>
52+ </qresource>
53+</RCC>
54
55=== added directory 'plugins/Observability/bckp'
56=== added file 'plugins/Observability/bckp/bt_observab_off.png'
57Binary files plugins/Observability/bckp/bt_observab_off.png 1970-01-01 00:00:00 +0000 and plugins/Observability/bckp/bt_observab_off.png 2012-08-12 12:25:22 +0000 differ
58=== added file 'plugins/Observability/bckp/bt_observab_on.png'
59Binary files plugins/Observability/bckp/bt_observab_on.png 1970-01-01 00:00:00 +0000 and plugins/Observability/bckp/bt_observab_on.png 2012-08-12 12:25:22 +0000 differ
60=== added file 'plugins/Observability/bt_observab_off.png'
61Binary files plugins/Observability/bt_observab_off.png 1970-01-01 00:00:00 +0000 and plugins/Observability/bt_observab_off.png 2012-08-12 12:25:22 +0000 differ
62=== added file 'plugins/Observability/bt_observab_on.png'
63Binary files plugins/Observability/bt_observab_on.png 1970-01-01 00:00:00 +0000 and plugins/Observability/bt_observab_on.png 2012-08-12 12:25:22 +0000 differ
64=== added directory 'plugins/Observability/src'
65=== added file 'plugins/Observability/src/CMakeLists.txt'
66--- plugins/Observability/src/CMakeLists.txt 1970-01-01 00:00:00 +0000
67+++ plugins/Observability/src/CMakeLists.txt 2012-08-12 12:25:22 +0000
68@@ -0,0 +1,62 @@
69+INCLUDE_DIRECTORIES(
70+ .
71+ gui
72+ ${CMAKE_BINARY_DIR}/plugins/Observability/src
73+ ${CMAKE_BINARY_DIR}/plugins/Observability/src/gui
74+)
75+
76+LINK_DIRECTORIES(${BUILD_DIR}/src)
77+
78+SET(Observability_SRCS
79+ Observability.hpp
80+ Observability.cpp
81+ gui/ObservabilityDialog.hpp
82+ gui/ObservabilityDialog.cpp
83+)
84+
85+################# compiles resources files ############
86+
87+SET(ObservabilityDialog_UIS
88+ gui/ObservabilityDialog.ui
89+)
90+QT4_WRAP_UI(ObservabilityDialog_UIS_H ${ObservabilityDialog_UIS})
91+
92+
93+SET(Observability_RES ../Observability.qrc)
94+QT4_ADD_RESOURCES(Observability_RES_CXX ${Observability_RES})
95+
96+
97+SET(Observability_MOC_HDRS
98+ Observability.hpp
99+ gui/ObservabilityDialog.hpp
100+)
101+
102+QT4_WRAP_CPP(Observability_MOC_SRCS ${Observability_MOC_HDRS})
103+
104+SET(extLinkerOption ${QT_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${OPENGL_LIBRARIES} ${ICONV_LIBRARIES} ${INTL_LIBRARIES})
105+
106+IF(BUILD_DYNAMIC_PLUGINS)
107+ ADD_LIBRARY(Observability MODULE ${Observability_SRCS} ${Observability_MOC_SRCS} ${Observability_RES_CXX} ${ObservabilityDialog_UIS_H})
108+ IF(APPLE)
109+ FIND_LIBRARY(OPENGL_LIBRARY OpenGL)
110+ MARK_AS_ADVANCED(OPENGL_LIBRARY)
111+ SET_TARGET_PROPERTIES(Observability PROPERTIES LINK_FLAGS "-undefined dynamic_lookup" SUFFIX ".dylib")
112+ ENDIF()
113+ IF(WIN32)
114+ SET_TARGET_PROPERTIES(Observability PROPERTIES LINK_FLAGS "-enable-runtime-pseudo-reloc -Wl,--allow-multiple-definition" )
115+ SET(StelMain stelMain)
116+ ELSE(WIN32)
117+ SET(StelMain )
118+ ENDIF(WIN32)
119+
120+ TARGET_LINK_LIBRARIES(Observability ${StelMain} ${extLinkerOption})
121+ INSTALL(TARGETS Observability DESTINATION "modules/Observability")
122+ENDIF()
123+
124+IF(BUILD_STATIC_PLUGINS)
125+ ADD_LIBRARY(Observability-static STATIC ${Observability_SRCS} ${Observability_MOC_SRCS} ${Observability_RES_CXX} ${ObservabilityDialog_UIS_H})
126+ SET_TARGET_PROPERTIES(Observability-static PROPERTIES OUTPUT_NAME "Observability")
127+ TARGET_LINK_LIBRARIES(Observability-static ${extLinkerOption})
128+ SET_TARGET_PROPERTIES(Observability-static PROPERTIES COMPILE_FLAGS "-DQT_STATICPLUGIN")
129+ ADD_DEPENDENCIES(AllStaticPlugins Observability-static)
130+ENDIF()
131
132=== added file 'plugins/Observability/src/Observability.cpp'
133--- plugins/Observability/src/Observability.cpp 1970-01-01 00:00:00 +0000
134+++ plugins/Observability/src/Observability.cpp 2012-08-12 12:25:22 +0000
135@@ -0,0 +1,1433 @@
136+/*
137+ * Copyright (C) 2012 Ivan Marti-Vidal
138+ *
139+ * This program is free software; you can redistribute it and/or
140+ * modify it under the terms of the GNU General Public License
141+ * as published by the Free Software Foundation; either version 2
142+ * of the License, or (at your option) any later version.
143+ *
144+ * This program is distributed in the hope that it will be useful,
145+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
146+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
147+ * GNU General Public License for more details.
148+ *
149+ * You should have received a copy of the GNU General Public License
150+ * along with this program; if not, write to the Free Software
151+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
152+ */
153+
154+#include <QSettings>
155+#include <QPixmap>
156+#include <QTimer>
157+#include <QtOpenGL>
158+#include <QString>
159+#include <QDebug>
160+#include <QAction>
161+#include <QKeyEvent>
162+#include <QtNetwork>
163+#include <QKeyEvent>
164+#include <QMouseEvent>
165+
166+#include "StelIniParser.hpp"
167+#include "StelProjector.hpp"
168+#include "StarMgr.hpp"
169+#include "StelObject.hpp"
170+#include "StelObserver.hpp"
171+#include "StelUtils.hpp"
172+#include "StelApp.hpp"
173+#include "StelObjectMgr.hpp"
174+#include "StelLocaleMgr.hpp"
175+#include "StelModuleMgr.hpp"
176+#include "StelGui.hpp"
177+#include "StelGuiItems.hpp"
178+#include "StelMovementMgr.hpp"
179+#include "StelFileMgr.hpp"
180+#include "StelVertexArray.hpp"
181+#include "StelCore.hpp"
182+#include "StelPainter.hpp"
183+#include "ZoneArray.hpp"
184+#include "StelSkyDrawer.hpp"
185+#include "Observability.hpp"
186+#include "ObservabilityDialog.hpp"
187+
188+#include "SolarSystem.hpp"
189+#include "Planet.hpp"
190+#include "StelFader.hpp"
191+
192+StelModule* ObservabilityStelPluginInterface::getStelModule() const
193+{
194+ return new Observability();
195+}
196+
197+StelPluginInfo ObservabilityStelPluginInterface::getPluginInfo() const
198+{
199+ Q_INIT_RESOURCE(Observability);
200+
201+ StelPluginInfo info;
202+ info.id = N_("Observability");
203+ info.displayedName = N_("Observability analysis");
204+ info.authors = N_("Ivan Marti-Vidal (Onsala Space Observatory)");
205+ info.contact = N_("i.martividal@gmail.com");
206+ info.description = N_("Reports an analysis of source observability (rise, set, and transit times), as well as the epochs of year when the source is best observed. It assumes that a source is observable if it is above the horizon during a fraction of the night. The plugin also gives the day for largest separation from the Sun and the days of Acronychal and Cosmical rise/set.<br><br> An explanation of the quantities shown by this script is given in the 'About' tab of the configuration window");
207+ return info;
208+}
209+
210+Q_EXPORT_PLUGIN2(Observability, ObservabilityStelPluginInterface)
211+
212+Observability::Observability()
213+ : flagShowObservability(false), OnIcon(NULL), OffIcon(NULL), GlowIcon(NULL),toolbarButton(NULL)
214+{
215+ setObjectName("Observability");
216+ configDialog = new ObservabilityDialog();
217+
218+
219+ // Some useful constants:
220+ Rad2Deg = 180./3.1415927; // Convert degrees into radians
221+ Rad2Hr = 12./3.1415927; // Convert hours into radians
222+ UA = 1.4958e+8; // Astronomical Unit in Km.
223+ TFrac = 0.9972677595628414; // Convert sidereal time into Solar time
224+ JDsec = 1./86400.; // A second in days.
225+ halfpi = 1.57079632675; // pi/2
226+ MoonT = 29.530588; // Moon synodic period (used as first estimate of Full Moon).
227+ RefFullMoon = 2451564.696; // Reference Julian date of a Full Moon.
228+ nextFullMoon = 0.0;
229+ prevFullMoon = 0.0;
230+ selName = "";
231+
232+
233+
234+////////////////////////////
235+// Read configuration:
236+
237+ QSettings* conf = StelApp::getInstance().getSettings();
238+ // Setup defaults if not present
239+ if (!conf->contains("Observability/font_size"))
240+ conf->setValue("Observability/font_size", 15);
241+
242+ if (!conf->contains("Observability/font_color"))
243+ conf->setValue("Observability/font_color", "0,0.5,1");
244+
245+ if (!conf->contains("Observability/show_AcroCos"))
246+ conf->setValue("Observability/show_AcroCos", true);
247+
248+ if (!conf->contains("Observability/show_Good_Nights"))
249+ conf->setValue("Observability/show_Good_Nights", true);
250+
251+ if (!conf->contains("Observability/show_Best_Night"))
252+ conf->setValue("Observability/show_Best_Night", true);
253+
254+ if (!conf->contains("Observability/show_Today"))
255+ conf->setValue("Observability/show_Today", true);
256+
257+ if (!conf->contains("Observability/Sun_Altitude"))
258+ conf->setValue("Observability/Sun_Altitude", 12);
259+
260+ if (!conf->contains("Observability/show_FullMoon"))
261+ conf->setValue("Observability/show_FullMoon", true);
262+
263+// if (!conf->contains("Observability/show_Crescent"))
264+// conf->setValue("Observability/show_Crescent", true);
265+
266+// if (!conf->contains("Observability/show_SuperMoon"))
267+// conf->setValue("Observability/show_SuperMoon", true);
268+
269+
270+ // Load settings from main config file
271+ fontSize = conf->value("Observability/font_size",15).toInt();
272+ iAltitude = conf->value("Observability/Sun_Altitude",12).toInt();
273+ AstroTwiAlti = -((double) iAltitude)/Rad2Deg ;
274+ font.setPixelSize(fontSize);
275+ QString fontColorStr = conf->value("Observability/font_color", "0,0.5,1").toString();
276+ fontColor = StelUtils::strToVec3f(fontColorStr);
277+ show_AcroCos = conf->value("Observability/show_AcroCos", true).toBool();
278+ show_Good_Nights = conf->value("Observability/show_Good_Nights", true).toBool();
279+ show_Best_Night = conf->value("Observability/show_Best_Night", true).toBool();
280+ show_Today = conf->value("Observability/show_Today", true).toBool();
281+ show_FullMoon = conf->value("Observability/show_FullMoon", true).toBool();
282+// show_Crescent = conf->value("Observability/show_Crescent", true).toBool();
283+// show_SuperMoon = conf->value("Observability/show_SuperMoon", true).toBool();
284+
285+/////////////////////////////////
286+
287+
288+
289+ // Dummy initial values for parameters and data vectors:
290+ mylat = 1000.; mylon = 1000.;
291+ myJD = 0.0;
292+ currYear = 0;
293+ isStar = true;
294+ isMoon = false;
295+ isSun = false;
296+ isScreen = true;
297+ raised=false;
298+
299+ ObserverLoc[0]=0.0;ObserverLoc[1]=0.0;ObserverLoc[2]=0.0;
300+
301+//Get pointer to the Earth:
302+ PlanetP Earth = GETSTELMODULE(SolarSystem)->getEarth();
303+ myEarth = Earth.data();
304+
305+// Get pointer to the Moon/Sun:
306+ PlanetP Moon = GETSTELMODULE(SolarSystem)->getMoon();
307+ myMoon = Moon.data();
308+
309+
310+ for (int i=0;i<366;i++) {
311+ SunRA[i] = 0.0; SunDec[i] = 0.0;
312+ ObjectRA[i] = 0.0; ObjectDec[i]=0.0;
313+ SunSidT[0][i]=0.0; SunSidT[1][i]=0.0;
314+ ObjectSidT[0][i]=0.0; ObjectSidT[1][i]=0.0;
315+ ObjectH0[i] = 0.0;
316+ yearJD[i] = 0.0;
317+ };
318+
319+
320+ // Set names of the months:
321+ QString mons[12]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
322+ for (int i=0;i<12;i++) {
323+ months[i]=mons[i];
324+ };
325+
326+}
327+
328+Observability::~Observability()
329+{
330+ if (GlowIcon!=NULL)
331+ delete GlowIcon;
332+ if (OnIcon!=NULL)
333+ delete OnIcon;
334+ if (OffIcon!=NULL)
335+ delete OffIcon;
336+ delete configDialog;
337+}
338+
339+double Observability::getCallOrder(StelModuleActionName actionName) const
340+{
341+ if (actionName==StelModule::ActionDraw)
342+ return StelApp::getInstance().getModuleMgr().getModule("LandscapeMgr")->getCallOrder(actionName)+10.;
343+ return 0;
344+}
345+
346+void Observability::init()
347+{
348+ qDebug() << "init called for Observability";
349+
350+ try
351+ {
352+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
353+ GlowIcon = new QPixmap(":/graphicGui/glow32x32.png");
354+ OnIcon = new QPixmap(":/observability/bt_observab_on.png");
355+ OffIcon = new QPixmap(":/observability/bt_observab_off.png");
356+
357+ gui->addGuiActions("actionShow_Observability",N_("Observability"),"",N_("Plugin Key Bindings"),true, false);
358+ gui->getGuiActions("actionShow_Observability")->setChecked(flagShowObservability);
359+ toolbarButton = new StelButton(NULL, *OnIcon, *OffIcon, *GlowIcon, gui->getGuiActions("actionShow_Observability"));
360+ gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
361+ connect(gui->getGuiActions("actionShow_Observability"), SIGNAL(toggled(bool)), this, SLOT(enableObservability(bool)));
362+
363+ gui->addGuiActions("actionShow_Observability_ConfigDialog", N_("Observability configuration window"), "",N_("Plugin Key Bindings"), true);
364+ connect(gui->getGuiActions("actionShow_Observability_ConfigDialog"), SIGNAL(toggled(bool)), configDialog, SLOT(setVisible(bool)));
365+ connect(configDialog, SIGNAL(visibleChanged(bool)), gui->getGuiActions("actionShow_Observability_ConfigDialog"), SLOT(setChecked(bool)));
366+ }
367+ catch (std::exception &e)
368+ {
369+ qWarning() << "WARNING: unable create toolbar button for Observability plugin (or load gonfig GUI). " << e.what();
370+ };
371+}
372+
373+/////////////////////////////////////////////
374+// MAIN CODE:
375+void Observability::draw(StelCore* core)
376+{
377+
378+ if (!flagShowObservability) return; // Button is off.
379+
380+/////////////////////////////////////////////////////////////////
381+// PRELIMINARS:
382+ bool souChanged, locChanged, yearChanged;
383+ QString objnam;
384+ StelObjectP selectedObject;
385+ Planet* currPlanet;
386+
387+
388+// Only execute plugin if we are on Earth.
389+ if (core->getCurrentLocation().planetName != "Earth") {return;};
390+
391+// Set the painter:
392+ StelPainter paintresult(core->getProjection2d());
393+ paintresult.setColor(fontColor[0],fontColor[1],fontColor[2],1);
394+ font.setPixelSize(fontSize);
395+ paintresult.setFont(font);
396+
397+
398+// Get current date, location, and check if there is something selected.
399+ double currlat = (core->getCurrentLocation().latitude)/Rad2Deg;
400+ double currlon = (core->getCurrentLocation().longitude)/Rad2Deg;
401+ double currheight = (6371.+(core->getCurrentLocation().altitude)/1000.)/UA;
402+ double currJD = core->getJDay();
403+ double currJDint;
404+ double currLocalT = 24.*modf(currJD + StelApp::getInstance().getLocaleMgr().getGMTShift(currJD)/24.0,&currJDint);
405+
406+ int auxm, auxd, auxy;
407+ StelUtils::getDateFromJulianDay(currJD,&auxy,&auxm,&auxd);
408+ bool isSource = StelApp::getInstance().getStelObjectMgr().getWasSelected();
409+ bool isSat = false;
410+ bool show_Year = show_Best_Night || show_Good_Nights || show_AcroCos; // || show_FullMoon;
411+
412+//////////////////////////////////////////////////////////////////
413+
414+
415+//////////////////////////////////////////////////////////////////
416+// NOW WE CHECK THE CHANGED PARAMETERS W.R.T. THE PREVIOUS FRAME:
417+
418+// Update JD.
419+ myJD = currJD;
420+
421+// If we have changed the year, we must recompute the Sun's position for each new day:
422+ if (auxy != currYear) {
423+ yearChanged = true;
424+ currYear = auxy;
425+ SunRADec(core);}
426+ else {
427+ yearChanged = false;
428+ };
429+
430+// Have we changed the latitude or longitude?
431+ if (currlat == mylat && currlon == mylon) {
432+ locChanged = false;}
433+ else {
434+ locChanged = true;
435+ mylat = currlat; mylon = currlon;
436+ double temp1 = currheight*std::cos(currlat);
437+ ObserverLoc[0] = temp1*std::cos(currlon);
438+ ObserverLoc[1] = temp1*std::sin(currlon);
439+ ObserverLoc[2] = currheight*std::sin(currlat);
440+ };
441+
442+// If we have changed latitude (or year), we update the vector of Sun's hour
443+// angles at twilight, and re-compute Sun/Moon ephemeris (if selected):
444+ if (locChanged || yearChanged || configChanged)
445+ {
446+ SunHTwi();
447+ lastJDMoon = 0.0;
448+ };
449+
450+//////////////////////////////////////////////////////////////////
451+
452+
453+//////////////////////////////////////////////////////////////////
454+// NOW WE DEAL WITH THE SOURCE (OR SCREEN-CENTER) POSITION:
455+
456+ if (isScreen) souChanged=true; // Always re-compute everything for the screen center.
457+
458+ if (isSource) { // There is something selected!
459+
460+// Get the selected source and its name:
461+ selectedObject = StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0];
462+
463+// Don't do anything for satellites:
464+ if(selectedObject->getType()== "Satellite") return;
465+
466+ QString tempName = selectedObject->getEnglishName();
467+
468+// Check if the source is Sun or Moon (i.e., it changes quite a bit during one day):
469+ isMoon = ("Moon" == tempName)?true:false;
470+ isSun = ("Sun" == tempName)?true:false;
471+
472+//Update position:
473+ EquPos = selectedObject->getEquinoxEquatorialPos(core);
474+ EquPos.normalize();
475+ LocPos = core->equinoxEquToAltAz(EquPos);
476+
477+// Check if the user has changed the source (or if the source is Sun/Moon).
478+ if (tempName == selName && isMoon==false && isSun == false) {
479+ souChanged = false;} // Don't retouch anything regarding RA/Dec (to save a bit of resources).
480+ else { // Check also if the (new) source belongs to the Solar System:
481+ currPlanet = dynamic_cast<Planet*>(selectedObject.data());
482+ isStar = (currPlanet)?false:true;
483+ souChanged = true;
484+ selName = tempName;
485+ };
486+ }
487+ else { // There is no source selected!
488+
489+// If no source is selected, get the position vector of the screen center:
490+ selName = ""; isStar=true; isMoon = false; isSun = false; isScreen=true;
491+ Vec3d currentPos = GETSTELMODULE(StelMovementMgr)->getViewDirectionJ2000();
492+ currentPos.normalize();
493+ EquPos = core->j2000ToEquinoxEqu(currentPos);
494+ LocPos = core->j2000ToAltAz(currentPos);
495+ }
496+
497+
498+// Convert EquPos to RA/Dec:
499+ toRADec(EquPos,selRA,selDec);
500+
501+// Compute source's altitude (in radians):
502+ alti = std::asin(LocPos[2]);
503+
504+// Force re-computation of ephemeris if the location changes or the user changes the configuration:
505+ if (locChanged || configChanged)
506+ {
507+ souChanged=true;
508+ configChanged=false;
509+ };
510+
511+/////////////////////////////////////////////////////////////////
512+
513+
514+/////////////////////////////////////////////////////////////////
515+// NOW WE COMPUTE RISE/SET/TRANSIT TIMES FOR THE CURRENT DAY:
516+ double currH = HourAngle(mylat,alti,selDec);
517+ horizH = HourAngle(mylat,0.0,selDec);
518+ QString RS1, RS2, RS, Cul; // strings with Rise/Set/Culmination times
519+ double Rise, Set; // Actual Rise/Set times (in GMT).
520+ int d1,m1,s1,d2,m2,s2,dc,mc,sc; // Integers for the time spans in hh:mm:ss.
521+ bool solvedMoon = false;
522+ bool transit; // Is the source above the horizon? Did it culminate?
523+
524+ int ephHour, ephMinute, ephSecond; // Local time for selected ephemeris
525+
526+ if (show_Today) { // We show ephemeris for today (i.e., rise, set, and transit times).
527+
528+ if (isMoon || isSun) {
529+ solvedMoon = MoonSunSolve(core); // False if fails; True otherwise.
530+ currH = std::abs(24.*(MoonCulm-myJD)/TFrac);
531+ transit = MoonCulm-myJD<0.0;
532+ if (solvedMoon) { // If failed, Set and Rise will be dummy.
533+ Set = std::abs(24.*(MoonSet-myJD)/TFrac);
534+ Rise = std::abs(24.*(MoonRise-myJD)/TFrac);
535+ };
536+ }
537+ else if (horizH>0.0) { // The source is not circumpolar and can be seen from this latitude.
538+
539+ if ( LocPos[1]>0.0 ) { // The source is at the eastern side...
540+ if ( currH>horizH ) { // ... and below the horizon.
541+ Set = 24.-currH-horizH;
542+ Rise = currH-horizH;
543+ raised = false;}
544+ else { // ... and above the horizon.
545+ Rise = horizH-currH;
546+ Set = 2.*horizH-Rise;
547+ raised = true;};
548+ }
549+ else { // The source is at the western side...
550+ if ( currH>horizH ) { // ... and below the horizon.
551+ Set = currH-horizH;
552+ Rise = 24.-currH-horizH;
553+ raised = false;}
554+ else { // ... and above the horizon.
555+ Rise = horizH+currH;
556+ Set = horizH-currH;
557+ raised = true;};
558+ };
559+
560+ };
561+
562+ if ((solvedMoon && MoonRise>0.0) || (isMoon==false && isSun==false && horizH>0.0))
563+ {
564+ double2hms(TFrac*Set,d1,m1,s1);
565+ double2hms(TFrac*Rise,d2,m2,s2);
566+
567+// Strings with time spans for rise/set/transit:
568+ RS1 = (d1==0)?"":q_("%1h ").arg(d1); RS1 += (m1==0)?"":q_("%1m ").arg(m1); RS1 += q_("%1s ").arg(s1);
569+ RS2 = (d2==0)?"":q_("%1h ").arg(d2); RS2 += (m2==0)?"":q_("%1m ").arg(m2); RS2 += q_("%1s").arg(s2);
570+ if (raised)
571+ {
572+ double2hms(toUnsignedRA(currLocalT+TFrac*Set+12.),ephHour,ephMinute,ephSecond);
573+ SetTime = q_("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0')); // Local time for set.
574+
575+ double2hms(toUnsignedRA(currLocalT-TFrac*Rise+12.),ephHour,ephMinute,ephSecond); // Local time for rise.
576+ RiseTime = q_("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0'));
577+
578+ RS1 = q_("Sets at ")+ SetTime + q_(" (in ")+RS1 + q_(")");
579+ RS2 = q_("Raised at ") + RiseTime + q_(" (")+ RS2 + q_(" ago)"); }
580+ else
581+ {
582+ double2hms(toUnsignedRA(currLocalT-TFrac*Set+12.),ephHour,ephMinute,ephSecond);
583+ SetTime = q_("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0'));
584+
585+ double2hms(toUnsignedRA(currLocalT+TFrac*Rise+12.),ephHour,ephMinute,ephSecond);
586+ RiseTime = q_("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0'));
587+
588+ RS1 = q_("Has set at ")+ SetTime + q_(" (")+RS1+q_(" ago)");
589+ RS2 = q_("Raises at ") + RiseTime + q_(" (in ")+RS2 + q_(")");
590+ };
591+ }
592+ else { // The source is either circumpolar or never rises:
593+ (alti>0.0)? RS1 = q_("Circumpolar."): RS1 = q_("No rise.");
594+ RS2 = "";
595+ };
596+
597+// Culmination:
598+
599+ if (isSun==false && isMoon == false)
600+ {
601+ culmAlt = std::abs(mylat-selDec); // 90.-altitude at transit.
602+ transit = LocPos[1]<0.0;
603+ };
604+
605+ if (culmAlt<halfpi) { // Source can be observed.
606+ double altiAtCulmi = Rad2Deg*(halfpi-culmAlt);
607+ double2hms(TFrac*currH,dc,mc,sc);
608+
609+// String with the time span for culmination:
610+ Cul = (dc==0)?"":q_("%1h ").arg(dc); Cul += (mc==0)?"":q_("%1m ").arg(mc); Cul += q_("%1s").arg(sc);
611+ if (transit==false) {
612+
613+ double2hms(toUnsignedRA(currLocalT+TFrac*currH+12.),ephHour,ephMinute,ephSecond); // Local time at transit.
614+ CulmTime = q_("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0'));
615+ Cul = q_("Culminates at ") + CulmTime + q_(" (in ")+Cul+q_(") at %1 deg.").arg(altiAtCulmi,0,'f',1);}
616+ else {
617+ double2hms(toUnsignedRA(currLocalT-TFrac*currH+12.),ephHour,ephMinute,ephSecond);
618+ CulmTime = q_("%1:%2").arg(ephHour).arg(ephMinute,2,10,QLatin1Char('0'));
619+ Cul = q_("Culminated at ") + CulmTime + q_(" (")+ Cul + q_(" ago) at %1 deg.").arg(altiAtCulmi,0,'f',1);
620+ };
621+ };
622+
623+ }; // This comes from show_Today==True
624+////////////////////////////////////////////////////////////
625+
626+
627+////////////////////////////////////////////////////////////
628+// NOW WE ANALYZE THE SOURCE OBSERVABILITY FOR THE WHOLE YEAR:
629+
630+// Compute yearly ephemeris (only if necessary, and not for Sun nor Moon):
631+
632+// if (isMoon && (show_FullMoon || show_Crescent || show_SuperMoon))
633+// {
634+// computeMoonEphemeris();
635+// };
636+
637+ if (isSun)
638+ {
639+ bestNight=""; ObsRange = "";
640+ }
641+ else if (!isMoon && show_Year) {
642+
643+ if (isStar==false && (souChanged || yearChanged)) { // Object moves.
644+ PlanetRADec(core,selName);} // Re-compute ephemeris.
645+
646+ else { // Object is fixed on the sky.
647+ double auxH = HourAngle(mylat,0.0,selDec);
648+ double auxSidT1 = toUnsignedRA(selRA - auxH);
649+ double auxSidT2 = toUnsignedRA(selRA + auxH);
650+ for (int i=0;i<nDays;i++) {
651+ ObjectH0[i] = auxH;
652+ ObjectRA[i] = selRA;
653+ ObjectDec[i] = selDec;
654+ ObjectSidT[0][i] = auxSidT1;
655+ ObjectSidT[1][i] = auxSidT2;
656+ };
657+ };
658+
659+// Determine source observability (only if something changed):
660+ if ((souChanged || locChanged || yearChanged)) {
661+ bestNight=""; ObsRange = "";
662+
663+ if (culmAlt>=halfpi) { // Source cannot be seen.
664+ ObsRange = "Source is not observable.";
665+ AcroCos = "No Acronychal nor Cosmical rise/set.";
666+ }
667+ else { // Source can be seen.
668+
669+///////////////////////////
670+// - Part 1. Determine the best observing night (i.e., opposition to the Sun):
671+ if (show_Best_Night) {
672+ int selday = 0;
673+ double deltaPhs = -1.0; // Initial dummy value
674+ double tempPhs; //, tempSep;
675+
676+ for (int i=0;i<nDays;i++) { // Maximize the Sun-object separation.
677+ tempPhs = Lambda(ObjectRA[i],ObjectDec[i],SunRA[i],SunDec[i]);
678+ if (tempPhs>deltaPhs) {selday=i;deltaPhs=tempPhs;};
679+ };
680+ bestNight = q_("Largest Sun separation: ");
681+ bestNight = bestNight + CalenDate(selday) + q_(" (at %1 deg.)").arg(deltaPhs*Rad2Deg,0,'f',1);
682+ };
683+
684+///////////////////////////////
685+// - Part 2. Determine Acronychal and Cosmical rise and set:
686+
687+ if (show_AcroCos) {
688+ int selRise, selSet, selRise2, selSet2; // days of year for Acronical and Cosmical rise/set.
689+ int Acro = CheckAcro(selRise,selSet,selRise2,selSet2);
690+ QString AcroRiseStr, AcroSetStr;
691+ QString CosmRiseStr, CosmSetStr;
692+
693+ AcroRiseStr = (selRise>0)?CalenDate(selRise):"N/A";
694+ AcroSetStr = (selSet>0)?CalenDate(selSet):"N/A";
695+
696+ CosmRiseStr = (selRise2>0)?CalenDate(selRise2):"N/A";
697+ CosmSetStr = (selSet2>0)?CalenDate(selSet2):"N/A";
698+
699+ AcroCos = (Acro==3 || Acro==1)?q_("Acronychal rise/set: ")+AcroRiseStr+q_(" / ")+AcroSetStr:q_("No Acronychal rise/set");
700+ AcroCos += (Acro==3 || Acro==2)?q_(". Cosmical rise/set: ")+CosmRiseStr+q_(" / ")+CosmSetStr:q_(". No Cosmical rise/set.");
701+
702+ };
703+
704+
705+////////////////////////////
706+// - Part 3. Determine range of good nights
707+// (i.e., above horizon before/after twilight):
708+
709+ if (show_Good_Nights) {
710+ int selday = 0;
711+ int selday2 = 0;
712+ bool bestBegun = false; // Are we inside a good time range?
713+ bool atLeastOne = false;
714+ QString dateRange = "";
715+ bool PoleNight, twiGood;
716+
717+ for (int i=0;i<nDays;i++) {
718+
719+ PoleNight = SunSidT[0][i]<0.0 && std::abs(SunDec[i]-mylat)>=halfpi; // Is it night during 24h?
720+ twiGood = (PoleNight && std::abs(ObjectDec[i]-mylat)<halfpi)?true:CheckRise(i);
721+ if (twiGood && bestBegun == false) {
722+ selday = i;
723+ bestBegun = true;
724+ atLeastOne = true;
725+ };
726+
727+ if (!twiGood && bestBegun == true) {
728+ selday2 = i;
729+ bestBegun = false;
730+ if (selday2 > selday) {
731+ if (dateRange!="") { dateRange += ", ";};
732+ dateRange += CalenDate(selday)+" to "+CalenDate(selday2);
733+ };
734+ };
735+ };
736+
737+ if (bestBegun) { // There were good dates till the end of the year.
738+ if (dateRange!="") { dateRange += ", ";};
739+ dateRange += CalenDate(selday)+" to 31 Dec";
740+ };
741+
742+ if (dateRange == "")
743+ {
744+ if (atLeastOne)
745+ { // The whole year is good.
746+ ObsRange = "Observable during the whole year.";}
747+ else
748+ {
749+ ObsRange = "Not observable at dark night.";};
750+ }
751+ else {
752+ ObsRange = "Observable epochs: "+dateRange;
753+ };
754+
755+// if (selName == "Mercury") {ObsRange = "Observable in many dates of the year";}; // Special case of Mercury.
756+
757+ }; // Comes from show_Good_Nights==True"
758+ }; // Comes from the "else" of "culmAlt>=..."
759+ };// Comes from "souChanged || ..."
760+ }; // Comes from the "else" with "!isMoon"
761+
762+// Print all results:
763+
764+ int yLine = 7*fontSize+80;
765+ int xLine = 50;
766+
767+ if (show_Today)
768+ {
769+ paintresult.drawText(xLine, yLine,q_(" TODAY:"));
770+ paintresult.drawText(xLine+fontSize, yLine-fontSize, RS2);
771+ paintresult.drawText(xLine+fontSize, yLine-fontSize*2, RS1);
772+ paintresult.drawText(xLine+fontSize, yLine-fontSize*3, Cul);
773+ yLine -= fontSize*5;
774+ };
775+
776+ if ((isMoon && show_FullMoon) || (isSun == false && isMoon == false && show_Year))
777+ {
778+ paintresult.drawText(xLine,yLine," THIS YEAR:");
779+ if (show_Best_Night || show_FullMoon)
780+ {
781+ yLine -= fontSize;
782+ paintresult.drawText(xLine+fontSize, yLine, bestNight);
783+ };
784+ if (show_Good_Nights)
785+ {
786+ yLine -= fontSize;
787+ paintresult.drawText(xLine+fontSize, yLine, ObsRange);
788+ };
789+ if (show_AcroCos)
790+ {
791+ yLine -= fontSize;
792+ paintresult.drawText(xLine+fontSize, yLine, AcroCos);
793+ };
794+
795+ };
796+
797+}
798+
799+// END OF MAIN CODE
800+///////////////////////////////////////////////////////
801+
802+
803+//////////////////////////////
804+// AUXILIARY FUNCTIONS
805+
806+////////////////////////////////////
807+// Returns the hour angle for a given altitude:
808+double Observability::HourAngle(double lat, double h, double Dec)
809+{
810+ double Denom = std::cos(lat)*std::cos(Dec);
811+ double Numer = (std::sin(h)-std::sin(lat)*std::sin(Dec));
812+
813+ if ( std::abs(Numer)>std::abs(Denom) )
814+ {return -0.5/86400.;} // Source doesn't reach that altitude.
815+ else
816+ {return Rad2Hr*std::acos(Numer/Denom);}
817+
818+}
819+////////////////////////////////////
820+
821+
822+////////////////////////////////////
823+// Returns the angular separation between two points on the Sky:
824+// RA is given in hours and Dec in radians.
825+double Observability::Lambda(double RA1, double Dec1, double RA2, double Dec2)
826+{
827+ return std::acos(std::sin(Dec1)*std::sin(Dec2)+std::cos(Dec1)*std::cos(Dec2)*std::cos((RA1-RA2)/Rad2Hr));
828+}
829+////////////////////////////////////
830+
831+
832+////////////////////////////////////
833+// Returns the hour angle for a given a Sid. Time:
834+double Observability::HourAngle2(double RA, double ST)
835+{
836+ double Htemp = toUnsignedRA(RA-ST/15.);
837+ Htemp -= (Htemp>12.)?24.0:0.0;
838+ return Htemp;
839+
840+}
841+////////////////////////////////////
842+
843+
844+////////////////////////////////////
845+// Converts a float time/angle span (in hours/degrees) in the (integer) format hh/dd,mm,ss:
846+void Observability::double2hms(double hfloat, int &h1, int &h2, int &h3)
847+{
848+ double f1,f2,f3;
849+ hfloat = std::abs(hfloat);
850+ double ffrac = std::modf(hfloat,&f1);
851+ double ffrac2 = std::modf(60.*ffrac,&f2);
852+ ffrac2 = std::modf(3600.*(ffrac-f2/60.),&f3);
853+ h1 = (int)f1 ; h2 = (int)std::abs(f2) ; h3 = (int)std::abs(f3);
854+}
855+////////////////////////////////////
856+
857+
858+////////////////////////////////////
859+// Adds/subtracts 24hr to ensure a RA between 0 and 24hr:
860+double Observability::toUnsignedRA(double RA)
861+{
862+ double tempRA,tempmod;
863+ if (RA<0.0) {tempmod = std::modf(-RA/24.,&tempRA); RA += 24.*(tempRA+1.0);};
864+ double auxRA = 24.*std::modf(RA/24.,&tempRA);
865+ auxRA += (auxRA<0.0)?24.0:((auxRA>24.0)?-24.0:0.0);
866+ return auxRA;
867+}
868+////////////////////////////////////
869+
870+
871+///////////////////////////////////////////////
872+// Returns the day and month of year (to put it in format '25 Apr')
873+QString Observability::CalenDate(int selday)
874+{
875+ int day,month,year;
876+ StelUtils::getDateFromJulianDay(yearJD[selday],&year,&month,&day);
877+ return q_("%1 "+months[month-1]).arg(day);
878+}
879+//////////////////////////////////////////////
880+
881+
882+//////////////////////////////////////////////////
883+// Returns the RA and Dec of the selected planet
884+//for each day of the current year:
885+void Observability::PlanetRADec(StelCore *core, QString Name)
886+{
887+ int gene = -1;
888+ double TempH;
889+ Vec3d TP, TP2;
890+ Mat4d LocTrans;
891+
892+// If object is a Moon, we select its parent planet:
893+ PlanetP Object = GETSTELMODULE(SolarSystem)->searchByEnglishName(Name);
894+ PlanetP parent = Object->getParent();
895+
896+ if (parent) {
897+ while (parent) {
898+ gene += 1;
899+ parent = parent->getParent();}
900+ };
901+ for (int g=0; g<gene;g++) {
902+ Object = Object->getParent();
903+ };
904+
905+// Get a pointer to the planet's instance:
906+ Planet* myPlanet = Object.data();
907+
908+// Compute planet's position for each day of the current year:
909+
910+ for (int i=0;i<nDays;i++) {
911+ myPlanet->computePosition(yearJD[i]);
912+ myPlanet->computeTransMatrix(yearJD[i]);
913+ TP = myPlanet->getHeliocentricEclipticPos();
914+ LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(EarthPos[i]));
915+ TP2 = core->j2000ToEquinoxEqu(LocTrans*TP);
916+ toRADec(TP2,ObjectRA[i],ObjectDec[i]);
917+ TempH = HourAngle(mylat,0.0,ObjectDec[i]);
918+ ObjectH0[i] = TempH;
919+ ObjectSidT[0][i] = toUnsignedRA(ObjectRA[i]-TempH);
920+ ObjectSidT[1][i] = toUnsignedRA(ObjectRA[i]+TempH);
921+ }
922+
923+// Return the planet to its current time:
924+ myPlanet->computePosition(myJD);
925+ myPlanet->computeTransMatrix(myJD);
926+
927+
928+}
929+
930+/////////////////////////////////////////////////
931+// Computes the Sun's RA and Dec (and the JD) for
932+// each day of the current year.
933+void Observability::SunRADec(StelCore* core)
934+{
935+ int day,month,year,year2;
936+ Vec3d TP, TP2;
937+
938+// Get current date:
939+ StelUtils::getDateFromJulianDay(myJD,&year,&month,&day);
940+
941+// Get JD for the Jan 1 of current year:
942+ StelUtils::getJDFromDate(&Jan1stJD,year,1,1,0,0,0);
943+
944+// Check if we are on a leap year:
945+ StelUtils::getDateFromJulianDay(Jan1stJD+365.,&year2,&month,&day);
946+ nDays = (year==year2)?366:365;
947+
948+// Compute Earth's position throughout the year:
949+ for (int i=0;i<nDays;i++) {
950+ yearJD[i] = Jan1stJD+(double)i;
951+ myEarth->computePosition(yearJD[i]);
952+ myEarth->computeTransMatrix(yearJD[i]);
953+ TP = myEarth->getHeliocentricEclipticPos();
954+ TP[0] = -TP[0]; TP[1] = -TP[1]; TP[2] = -TP[2];
955+ TP2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*TP);
956+ EarthPos[i] = TP;
957+ toRADec(TP2,SunRA[i],SunDec[i]);
958+ };
959+
960+//Return the Earth to its current time:
961+ myEarth->computePosition(myJD);
962+ myEarth->computeTransMatrix(myJD);
963+}
964+///////////////////////////////////////////////////
965+
966+
967+////////////////////////////////////////////
968+// Computes Sun's Sidereal Times at twilight and culmination:
969+void Observability::SunHTwi()
970+{
971+ double TempH, TempH00;
972+
973+ for (int i=0; i<nDays; i++) {
974+ TempH = HourAngle(mylat,AstroTwiAlti,SunDec[i]);
975+ TempH00 = HourAngle(mylat,0.0,SunDec[i]);
976+ if (TempH>0.0) {
977+ SunSidT[0][i] = toUnsignedRA(SunRA[i]-TempH*(1.00278));
978+ SunSidT[1][i] = toUnsignedRA(SunRA[i]+TempH*(1.00278));}
979+ else {
980+ SunSidT[0][i] = -1000.0;
981+ SunSidT[1][i] = -1000.0;};
982+ if (TempH00>0.0) {
983+ SunSidT[2][i] = toUnsignedRA(SunRA[i]+TempH00);
984+ SunSidT[3][i] = toUnsignedRA(SunRA[i]-TempH00);}
985+ else {
986+ SunSidT[2][i] = -1000.0;
987+ SunSidT[3][i] = -1000.0;};
988+
989+
990+ };
991+}
992+////////////////////////////////////////////
993+
994+
995+///////////////////////////////////////////
996+// Checks if a source can be observed with the Sun below the twilight altitude.
997+bool Observability::CheckRise(int i)
998+{
999+
1000+ // If Sun can't reach twilight elevation, return false:
1001+ if (SunSidT[0][i]<0.0 || SunSidT[1][i]<0.0) { return false;};
1002+
1003+ // Iterate over the whole year:
1004+ int nBin = 1000;
1005+ double auxSid1 = SunSidT[0][i];
1006+ auxSid1 += (SunSidT[0][i] < SunSidT[1][i])?24.0:0.0;
1007+ double deltaT = (auxSid1-SunSidT[1][i])/((double)nBin);
1008+
1009+ double Hour;
1010+ for (int j=0;j<nBin;j++) {
1011+ Hour = toUnsignedRA(SunSidT[1][i]+deltaT*(double)j - ObjectRA[i]);
1012+ Hour -= (Hour>12.)?24.0:0.0;
1013+ if (std::abs(Hour)<ObjectH0[i] || (ObjectH0[i] < 0.0 && alti>0.0)) {return true;};
1014+ };
1015+
1016+
1017+ return false;
1018+}
1019+///////////////////////////////////////////
1020+
1021+
1022+///////////////////////////////////////////
1023+// Finds the dates of Acronichal (Rise, Set) and Cosmical (Rise2, Set2) dates.
1024+// Returns 0 if no dates found, 1 if Acro exists, 2 if Cosm exists, and 3 if both are found.
1025+int Observability::CheckAcro(int &Rise, int &Set, int &Rise2, int &Set2)
1026+{
1027+
1028+ Rise = -1;
1029+ Set = -1;
1030+ Rise2 = -1;
1031+ Set2 = -1;
1032+
1033+ double BestDiffRise = 12.0;
1034+ double BestDiffSet = 12.0;
1035+ double BestDiffRise2 = 12.0;
1036+ double BestDiffSet2 = 12.0;
1037+
1038+ double HourDiffRise, HourDiffSet, HourDiffRise2, HourDiffSet2;
1039+ bool success = false;
1040+
1041+ for (int i=0;i<366;i++)
1042+ {
1043+ if (ObjectH0[i]>0.0 && SunSidT[2][i]>0.0 && SunSidT[3][i]>0.0) {
1044+ success = true;
1045+ HourDiffRise = toUnsignedRA(ObjectRA[i] - ObjectH0[i]);
1046+ HourDiffRise2 = HourDiffRise-SunSidT[3][i];
1047+ HourDiffRise -= SunSidT[2][i];
1048+
1049+ HourDiffSet = toUnsignedRA(ObjectRA[i] + ObjectH0[i]);
1050+ HourDiffSet2 = HourDiffSet - SunSidT[2][i];
1051+ HourDiffSet -= SunSidT[3][i];
1052+
1053+ // Acronychal Rise/Set:
1054+ if (std::abs(HourDiffRise)<BestDiffRise)
1055+ {
1056+ BestDiffRise = std::abs(HourDiffRise);
1057+ Rise = i;
1058+ };
1059+ if (std::abs(HourDiffSet)<BestDiffSet)
1060+ {
1061+ BestDiffSet = std::abs(HourDiffSet);
1062+ Set = i;
1063+ };
1064+
1065+ // Cosmical Rise/Set:
1066+ if (std::abs(HourDiffRise2)<BestDiffRise2)
1067+ {
1068+ BestDiffRise2 = std::abs(HourDiffRise2);
1069+ Rise2 = i;
1070+ };
1071+ if (std::abs(HourDiffSet2)<BestDiffSet2)
1072+ {
1073+ BestDiffSet2 = std::abs(HourDiffSet2);
1074+ Set2 = i;
1075+ };
1076+
1077+
1078+ };
1079+ };
1080+
1081+ Rise *= (BestDiffRise > 0.083)?-1:1; // Check that difference is lower than 5 minutes.
1082+ Set *= (BestDiffSet > 0.083)?-1:1; // Check that difference is lower than 5 minutes.
1083+ Rise2 *= (BestDiffRise2 > 0.083)?-1:1; // Check that difference is lower than 5 minutes.
1084+ Set2 *= (BestDiffSet2 > 0.083)?-1:1; // Check that difference is lower than 5 minutes.
1085+// qDebug() << q_("%1 %2").arg(Rise).arg(Rise2);
1086+ int Result = (Rise>0 || Set>0)?1:0;
1087+ Result += (Rise2>0 || Set2>0)?2:0;
1088+ return (success)?Result:0;
1089+}
1090+///////////////////////////////////////////
1091+
1092+
1093+////////////////////////////////////////////
1094+// Convert an Equatorial Vec3d into RA and Dec:
1095+void Observability::toRADec(Vec3d TempLoc, double &RA, double &Dec)
1096+{
1097+ TempLoc.normalize();
1098+ Dec = std::asin(TempLoc[2]); // in radians
1099+ RA = toUnsignedRA(std::atan2(TempLoc[1],TempLoc[0])*Rad2Hr); // in hours.
1100+}
1101+////////////////////////////////////////////
1102+
1103+
1104+
1105+///////////////////////////
1106+// Just return the sign of a double
1107+double Observability::sign(double d)
1108+{
1109+ return (d<0.0)?-1.0:1.0;
1110+}
1111+//////////////////////////
1112+
1113+
1114+
1115+//////////////////////////
1116+// Get the coordinates of Sun or Moon for a given JD:
1117+// getBack controls whether Earth and Moon must be returned to their original positions after computation.
1118+void Observability::getSunMoonCoords(StelCore *core, double JD, double &RASun, double &DecSun, double &RAMoon, double &DecMoon, bool getBack) //, Vec3d &AltAzVector)
1119+{
1120+
1121+ if (getBack) // Return the Moon and Earth to their current position:
1122+ {
1123+ myEarth->computePosition(myJD);
1124+ myEarth->computeTransMatrix(myJD);
1125+ myMoon->computePosition(myJD);
1126+ myMoon->computeTransMatrix(myJD);
1127+ }
1128+ else
1129+ { // Compute coordinates:
1130+ myEarth->computePosition(JD);
1131+ myEarth->computeTransMatrix(JD);
1132+ Pos0 = myEarth->getHeliocentricEclipticPos();
1133+ double currSidT;
1134+
1135+// Sun coordinates:
1136+ Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Pos0));
1137+ toRADec(Pos2,RASun,DecSun);
1138+
1139+// Moon coordinates:
1140+ currSidT = myEarth->getSiderealTime(JD)/Rad2Deg;
1141+ RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc;
1142+ LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos0));
1143+ myMoon->computePosition(JD);
1144+ myMoon->computeTransMatrix(JD);
1145+ Pos1 = myMoon->getHeliocentricEclipticPos();
1146+ Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotObserver;
1147+
1148+ toRADec(Pos2,RAMoon,DecMoon);
1149+ };
1150+}
1151+//////////////////////////////////////////////
1152+
1153+
1154+
1155+//////////////////////////////////////////////
1156+// Solves Moon's or Sun's ephemeris by bissection. Returns JD:
1157+bool Observability::MoonSunSolve(StelCore* core)
1158+{
1159+
1160+ int Niter = 100;
1161+ int i;
1162+ double Hhoriz, RA, Dec, RAS, DecS, TempH, jd1, tempEphH, currSidT;
1163+ Vec3d Observer;
1164+
1165+ Hhoriz = HourAngle(mylat,0.0,selDec);
1166+ bool raises = Hhoriz > 0.0;
1167+
1168+
1169+// Only recompute ephemeris from second to second (at least)
1170+// or if the source has changed (i.e., Sun <-> Moon). This saves resources:
1171+ if (std::abs(myJD-lastJDMoon)<JDsec && LastSun==isSun) return raises;
1172+
1173+ LastSun = isSun;
1174+ myEarth->computePosition(myJD);
1175+ myEarth->computeTransMatrix(myJD);
1176+ Pos0 = myEarth->getHeliocentricEclipticPos();
1177+
1178+ if (isSun)
1179+ {
1180+ Pos2 = core->j2000ToEquinoxEqu((core->matVsop87ToJ2000)*(-Pos0));}
1181+ else
1182+ {
1183+ currSidT = myEarth->getSiderealTime(myJD)/Rad2Deg;
1184+ RotObserver = (Mat4d::zrotation(currSidT))*ObserverLoc;
1185+ LocTrans = (core->matVsop87ToJ2000)*(Mat4d::translation(-Pos0));
1186+ myMoon->computePosition(myJD);
1187+ myMoon->computeTransMatrix(myJD);
1188+ Pos1 = myMoon->getHeliocentricEclipticPos();
1189+ Pos2 = (core->j2000ToEquinoxEqu(LocTrans*Pos1))-RotObserver;
1190+ };
1191+
1192+ toRADec(Pos2,RA,Dec);
1193+ Vec3d MoonAltAz = core->equinoxEquToAltAz(Pos2);
1194+ raised = MoonAltAz[2] > 0.0;
1195+
1196+// Initial guesses of rise/set/transit times.
1197+// They are called 'Moon', but are also used for the Sun:
1198+
1199+ double Hcurr = -HourAngle(mylat,alti,selDec)*sign(LocPos[1]);
1200+ double SidT = toUnsignedRA(selRA + Hcurr);
1201+
1202+ MoonCulm = -Hcurr;
1203+ MoonRise = (-Hhoriz-Hcurr);
1204+ MoonSet = (Hhoriz-Hcurr);
1205+
1206+ if (raises) {
1207+ if (raised==false) {
1208+ MoonRise += (MoonRise<0.0)?24.0:0.0;
1209+ MoonSet -= (MoonSet>0.0)?24.0:0.0;
1210+ };
1211+
1212+// Rise time:
1213+ tempEphH = MoonRise*TFrac;
1214+ MoonRise = myJD + (MoonRise/24.);
1215+ for (i=0; i<Niter; i++)
1216+ {
1217+ // Get modified coordinates:
1218+ jd1 = MoonRise;
1219+ getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false);
1220+ if (isSun) {RA = RAS; Dec = DecS;};
1221+
1222+ // Current hour angle at mod. coordinates:
1223+ Hcurr = toUnsignedRA(SidT-RA);
1224+ Hcurr -= (raised)?0.0:24.;
1225+ Hcurr -= (Hcurr>12.)?24.0:0.0;
1226+
1227+ // H at horizon for mod. coordinates:
1228+ Hhoriz = HourAngle(mylat,0.0,Dec);
1229+ // Compute eph. times for mod. coordinates:
1230+ TempH = (-Hhoriz-Hcurr)*TFrac;
1231+ if (raised==false) TempH += (TempH<0.0)?24.0:0.0;
1232+ // Check convergence:
1233+ if (std::abs(TempH-tempEphH)<JDsec) break;
1234+ // Update rise-time estimate:
1235+ tempEphH = TempH;
1236+ MoonRise = myJD + (tempEphH/24.);
1237+ };
1238+
1239+// Set time:
1240+ tempEphH = MoonSet;
1241+ MoonSet = myJD + (MoonSet/24.);
1242+ for (i=0; i<Niter; i++)
1243+ {
1244+ // Get modified coordinates:
1245+ jd1 = MoonSet;
1246+ getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false);
1247+ if (isSun) {RA = RAS; Dec = DecS;};
1248+
1249+ // Current hour angle at mod. coordinates:
1250+ Hcurr = toUnsignedRA(SidT-RA);
1251+ Hcurr -= (raised)?24.:0.;
1252+ Hcurr += (Hcurr<-12.)?24.0:0.0;
1253+ // H at horizon for mod. coordinates:
1254+ Hhoriz = HourAngle(mylat,0.0,Dec);
1255+ // Compute eph. times for mod. coordinates:
1256+ TempH = (Hhoriz-Hcurr)*TFrac;
1257+ if (raised==false) TempH -= (TempH>0.0)?24.0:0.0;
1258+ // Check convergence:
1259+ if (std::abs(TempH-tempEphH)<JDsec) break;
1260+ // Update set-time estimate:
1261+ tempEphH = TempH;
1262+ MoonSet = myJD + (tempEphH/24.);
1263+ };
1264+ }
1265+ else // Comes from if(raises)
1266+ {
1267+ MoonSet = -1.0; MoonRise = -1.0;
1268+ };
1269+
1270+// Culmination time:
1271+ tempEphH = MoonCulm;
1272+ MoonCulm = myJD + (MoonCulm/24.);
1273+
1274+ for (i=0; i<Niter; i++)
1275+ {
1276+ // Get modified coordinates:
1277+ jd1 = MoonCulm;
1278+ getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false);
1279+ if (isSun) {RA = RAS; Dec = DecS;};
1280+
1281+
1282+ // Current hour angle at mod. coordinates:
1283+ Hcurr = toUnsignedRA(SidT-RA);
1284+ Hcurr += (LocPos[1]<0.0)?24.0:-24.0;
1285+ Hcurr -= (Hcurr>12.)?24.0:0.0;
1286+
1287+ // Compute eph. times for mod. coordinates:
1288+ TempH = -Hcurr*TFrac;
1289+ // Check convergence:
1290+ if (std::abs(TempH-tempEphH)<JDsec) break;
1291+ tempEphH = TempH;
1292+ MoonCulm = myJD + (tempEphH/24.);
1293+ culmAlt = std::abs(mylat-Dec); // 90 - altitude at transit.
1294+ };
1295+
1296+
1297+// Find out the days of Full Moon and Crescent at Sunset:
1298+ if (isMoon && show_FullMoon) // || show_SuperMoon))
1299+ {
1300+
1301+ // Only extimate date of Full Moon if we have changed Lunar month:
1302+ if (myJD > nextFullMoon || myJD < prevFullMoon)
1303+ {
1304+
1305+
1306+ // Estimate the closest Full Moon:
1307+ double nT;
1308+ double dT = std::modf((myJD-RefFullMoon)/MoonT,&nT);
1309+ if (dT>0.5) {nT += 1.0;};
1310+ double TempFullMoon = RefFullMoon + nT*MoonT;
1311+
1312+ // Improve the estimate iteratively (Secant method over Lunar-phase vs. time):
1313+
1314+ dT = 1./1440.; // Our time span for the finite-difference derivative estimate.
1315+ double Phase1, Phase2; // Variables for temporal use.
1316+ double Deriv1, Deriv2; // Variables for temporal use.
1317+ double Sec1, Sec2, Temp1, Temp2; // Variables for temporal use.
1318+
1319+ for (int j=0; j<2; j++)
1320+ { // Two steps: one for the previos Full Moon and the other for the next one.
1321+
1322+ Sec1 = TempFullMoon - 0.01*MoonT;
1323+ Sec2 = TempFullMoon + 0.01*MoonT;
1324+
1325+ for (int i=0; i<100; i++) // A limit of 100 iterations.
1326+ {
1327+ getSunMoonCoords(core,Sec1+dT/2.,RAS,DecS,RA,Dec,false);
1328+ Temp1 = Lambda(RA,Dec,RAS,DecS);
1329+ getSunMoonCoords(core,Sec1-dT/2.,RAS,DecS,RA,Dec,false);
1330+ Temp2 = Lambda(RA,Dec,RAS,DecS);
1331+
1332+ Deriv1 = (Temp1-Temp2)/dT;
1333+ Phase1 = (Temp1+Temp2)/2.;
1334+
1335+ getSunMoonCoords(core,Sec2+dT/2.,RAS,DecS,RA,Dec,false);
1336+ Temp1 = Lambda(RA,Dec,RAS,DecS);
1337+ getSunMoonCoords(core,Sec2-dT/2.,RAS,DecS,RA,Dec,false);
1338+ Temp2 = Lambda(RA,Dec,RAS,DecS);
1339+
1340+ Deriv2 = (Temp1-Temp2)/dT;
1341+ Phase2 = (Temp1+Temp2)/2.;
1342+
1343+ Temp1 = Sec2 - Deriv2*(Sec2-Sec1)/(Deriv2-Deriv1);
1344+ Sec1 = Sec2; Sec2 = Temp1;
1345+
1346+ if (std::abs(Sec2-Sec1) < dT) {break;} // Convergence.
1347+
1348+ };
1349+
1350+ if (TempFullMoon > myJD)
1351+ {
1352+ nextFullMoon = TempFullMoon;
1353+ TempFullMoon -= MoonT;
1354+ } else
1355+ {
1356+ prevFullMoon = TempFullMoon;
1357+ TempFullMoon += MoonT;
1358+ };
1359+
1360+ };
1361+
1362+ };
1363+
1364+ // Update the string shown in the screen:
1365+ int fullDay, fullMonth,fullYear, fullHour, fullMinute, fullSecond;
1366+ StelUtils::getDateFromJulianDay(prevFullMoon,&fullYear,&fullMonth,&fullDay);
1367+ double dT;
1368+ double nT = 24.*(std::modf(prevFullMoon,&dT));
1369+ double2hms(nT,fullHour,fullMinute,fullSecond);
1370+ bestNight = q_("Previous Full Moon: %1 "+months[fullMonth-1]+" at %2:%3. ").arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0'));
1371+ StelUtils::getDateFromJulianDay(nextFullMoon,&fullYear,&fullMonth,&fullDay);
1372+ nT = 24.*(std::modf(nextFullMoon,&dT));
1373+ double2hms(nT,fullHour,fullMinute,fullSecond);
1374+ bestNight += q_(" Next Full Moon: %1 "+months[fullMonth-1]+" at %2:%3. ").arg(fullDay).arg(fullHour).arg(fullMinute,2,10,QLatin1Char('0'));
1375+
1376+
1377+ // Now, compute the days of all the Full Moons of the current year, and get the Earth/Moon distance:
1378+// double monthFrac;
1379+// int PrevMonths = (int) std::modf((nextFullMoon-Jan1stJD)/MoonT,&monthFrac);
1380+// double BestDistance = 1.0; // initial dummy value for Sun-Moon distance;
1381+
1382+// for (int i=-PrevMonths; i<13 ; i++)
1383+// {
1384+// jd1 = nextFullMoon + MoonT*((double) i);
1385+// getSunMoonCoords(core,jd1,RAS,DecS,RA,Dec,false);
1386+// COMPUTE THE DISTANCE VECTOR!
1387+// if (Dist < BestDistance)
1388+// {
1389+// BestDistance = Dist;
1390+// nextSuperMoon = jd1;
1391+// };
1392+// };
1393+ }
1394+ else
1395+ {
1396+ bestNight = "";
1397+ };
1398+
1399+ ObsRange = "";
1400+ AcroCos = "";
1401+
1402+
1403+// Return the Moon and Earth to its current position:
1404+ getSunMoonCoords(core,myJD,RAS,DecS,RA,Dec,true);
1405+ lastJDMoon = myJD;
1406+
1407+ return raises;
1408+}
1409+
1410+
1411+
1412+
1413+//////////////////////////////////
1414+/// STUFF FOR THE GUI CONFIG
1415+
1416+bool Observability::configureGui(bool show)
1417+{
1418+ if (show)
1419+ {
1420+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
1421+ gui->getGuiActions("actionShow_Observability_ConfigDialog")->setChecked(true);
1422+ }
1423+
1424+ return true;
1425+}
1426+
1427+void Observability::restoreDefaults(void)
1428+{
1429+ restoreDefaultConfigIni();
1430+ readSettingsFromConfig();
1431+}
1432+
1433+void Observability::restoreDefaultConfigIni(void)
1434+{
1435+ QSettings* conf = StelApp::getInstance().getSettings();
1436+
1437+ // delete all existing settings...
1438+ conf->remove("");
1439+
1440+ // Set defaults
1441+ conf->setValue("Observability/font_size", 15);
1442+ conf->setValue("Observability/Sun_Altitude", 12);
1443+ conf->setValue("Observability/font_color", "0,0.5,1");
1444+ conf->setValue("Observability/show_AcroCos", true);
1445+ conf->setValue("Observability/show_Good_Nights", true);
1446+ conf->setValue("Observability/show_Best_Night", true);
1447+ conf->setValue("Observability/show_Today", true);
1448+ conf->setValue("Observability/show_FullMoon", true);
1449+// conf->setValue("Observability/show_Crescent", true);
1450+// conf->setValue("Observability/show_SuperMoon", true);
1451+}
1452+
1453+void Observability::readSettingsFromConfig(void)
1454+{
1455+ QSettings* conf = StelApp::getInstance().getSettings();
1456+
1457+ // Load settings from main config file
1458+ fontSize = conf->value("Observability/font_size",15).toInt();
1459+ font.setPixelSize(fontSize);
1460+ fontColor = StelUtils::strToVec3f(conf->value("Observability/font_color", "0,0.5,1").toString());
1461+ show_AcroCos = conf->value("Observability/show_AcroCos", true).toBool();
1462+ show_Good_Nights = conf->value("Observability/show_Good_Nights", true).toBool();
1463+ show_Best_Night = conf->value("Observability/show_Best_Night", true).toBool();
1464+ show_Today = conf->value("Observability/show_Today", true).toBool();
1465+ show_FullMoon = conf->value("Observability/show_FullMoon", true).toBool();
1466+// show_Crescent = conf->value("Observability/show_Crescent", true).toBool();
1467+// show_SuperMoon = conf->value("Observability/show_SuperMoon", true).toBool();
1468+
1469+ iAltitude = conf->value("Observability/Sun_Altitude", 12).toInt();
1470+ AstroTwiAlti = -((double)iAltitude)/Rad2Deg ;
1471+
1472+
1473+}
1474+
1475+void Observability::saveSettingsToConfig(void)
1476+{
1477+ QSettings* conf = StelApp::getInstance().getSettings();
1478+ QString fontColorStr = q_("%1,%2,%3").arg(fontColor[0],0,'f',2).arg(fontColor[1],0,'f',2).arg(fontColor[2],0,'f',2);
1479+ // Set updated values
1480+ conf->setValue("Observability/font_size", fontSize);
1481+ conf->setValue("Observability/Sun_Altitude", iAltitude);
1482+ conf->setValue("Observability/font_color", fontColorStr);
1483+ conf->setValue("Observability/show_AcroCos", show_AcroCos);
1484+ conf->setValue("Observability/show_Good_Nights", show_Good_Nights);
1485+ conf->setValue("Observability/show_Best_Night", show_Best_Night);
1486+ conf->setValue("Observability/show_Today", show_Today);
1487+ conf->setValue("Observability/show_FullMoon", show_FullMoon);
1488+// conf->setValue("Observability/show_Crescent", show_Crescent);
1489+// conf->setValue("Observability/show_SuperMoon", show_SuperMoon);
1490+}
1491+
1492+
1493+
1494+void Observability::setShow(int output, bool setVal)
1495+{
1496+ switch(output)
1497+ {
1498+ case 1: {show_Today = setVal; break;}
1499+ case 2: {show_AcroCos = setVal; break;}
1500+ case 3: {show_Good_Nights = setVal; break;}
1501+ case 4: {show_Best_Night = setVal; break;}
1502+ case 5: {show_FullMoon = setVal; nextFullMoon=0.0; prevFullMoon=0.0; break;}
1503+// case 6: {show_Crescent = setVal; break;}
1504+// case 7: {show_SuperMoon = setVal; break;}
1505+ };
1506+ configChanged = true;
1507+}
1508+
1509+bool Observability::getShowFlags(int iFlag)
1510+{
1511+ switch (iFlag)
1512+ {
1513+ case 1: return show_Today;
1514+ case 2: return show_AcroCos;
1515+ case 3: return show_Good_Nights;
1516+ case 4: return show_Best_Night;
1517+ case 5: return show_FullMoon;
1518+// case 6: return show_Crescent;
1519+// case 7: return show_SuperMoon;
1520+ };
1521+}
1522+
1523+Vec3f Observability::getFontColor(void)
1524+{
1525+ return fontColor;
1526+}
1527+
1528+int Observability::getFontSize(void)
1529+{
1530+ return fontSize;
1531+}
1532+
1533+int Observability::getSunAltitude(void)
1534+{
1535+ return iAltitude;
1536+}
1537+
1538+void Observability::setFontColor(int color, int value)
1539+{
1540+ float fValue = (float)(value) / 100.;
1541+ fontColor[color] = fValue;
1542+}
1543+
1544+void Observability::setFontSize(int value)
1545+{
1546+ fontSize = value;
1547+}
1548+
1549+void Observability::setSunAltitude(int value)
1550+{
1551+ AstroTwiAlti = -((double) value)/Rad2Deg ;
1552+ iAltitude = value;
1553+ configChanged = true;
1554+}
1555+
1556+
1557+/// END OF STUFF FOR THE GUI CONFIG.
1558+///////////////////////////////
1559+
1560+
1561+
1562+
1563+// Enable the Observability:
1564+void Observability::enableObservability(bool b)
1565+{
1566+ flagShowObservability = b;
1567+}
1568+
1569
1570=== added file 'plugins/Observability/src/Observability.hpp'
1571--- plugins/Observability/src/Observability.hpp 1970-01-01 00:00:00 +0000
1572+++ plugins/Observability/src/Observability.hpp 2012-08-12 12:25:22 +0000
1573@@ -0,0 +1,255 @@
1574+/*
1575+ * Copyright (C) 2012 Ivan Marti-Vidal
1576+ *
1577+ * This program is free software; you can redistribute it and/or
1578+ * modify it under the terms of the GNU General Public License
1579+ * as published by the Free Software Foundation; either version 2
1580+ * of the License, or (at your option) any later version.
1581+ *
1582+ * This program is distributed in the hope that it will be useful,
1583+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1584+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1585+ * GNU General Public License for more details.
1586+ *
1587+ * You should have received a copy of the GNU General Public License
1588+ * along with this program; if not, write to the Free Software
1589+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1590+ */
1591+#ifndef OBSERVABILITY_HPP_
1592+#define OBSERVABILITY_HPP_
1593+
1594+#include "StelModule.hpp"
1595+#include <QFont>
1596+#include <QString>
1597+#include "VecMath.hpp"
1598+#include "SolarSystem.hpp"
1599+#include "Planet.hpp"
1600+#include "StelFader.hpp"
1601+
1602+class QPixmap;
1603+class StelButton;
1604+class ObservabilityDialog;
1605+
1606+class Observability : public StelModule
1607+{
1608+ Q_OBJECT
1609+public:
1610+ Observability();
1611+ virtual ~Observability();
1612+ virtual void init();
1613+ virtual void update(double) {;}
1614+ virtual void draw(StelCore* core);
1615+ virtual double getCallOrder(StelModuleActionName actionName) const;
1616+
1617+
1618+ //! Implement this to tell the main Stellarium GUI that there is a GUI element to configure this plugin.
1619+ virtual bool configureGui(bool show=true);
1620+
1621+
1622+ //! Set up the plugin with default values.
1623+ void restoreDefaults(void);
1624+ void restoreDefaultConfigIni(void);
1625+
1626+ //! Read (or re-read) settings from the main config file. This will be called from init and also
1627+ //! when restoring defaults (i.e. from the configuration dialog / restore defaults button).
1628+ void readSettingsFromConfig(void);
1629+
1630+ //! Save the settings to the main configuration file.
1631+ void saveSettingsToConfig(void);
1632+
1633+ //! Set which output is shown.
1634+ //! @param output is the index of the output (e.g., 1 for today's ephemeris, 5 for Full Moon).
1635+ //! @param show is a boolean (true to show the output; false to hide it).
1636+ void setShow(int output, bool show);
1637+
1638+ //! Set the font colors. Color is (0,1,2) for (R,G,B):
1639+ void setFontColor(int Color, int Value);
1640+
1641+ //! Set the font size:
1642+ void setFontSize(int);
1643+
1644+ //! Set the Sun altitude at twilight:
1645+ void setSunAltitude(int);
1646+
1647+
1648+ //! get Show Flags from current configuration:
1649+ bool getShowFlags(int);
1650+
1651+ //! get the current font color:
1652+ Vec3f getFontColor(void);
1653+
1654+ //! get current font size:
1655+ int getFontSize(void);
1656+
1657+ //! get current Sun altitude at twilight:
1658+ int getSunAltitude(void);
1659+
1660+public slots:
1661+//! Set whether observability will execute or not:
1662+ void enableObservability(bool b);
1663+
1664+private:
1665+
1666+
1667+//! Stuff for the configuration GUI:
1668+ ObservabilityDialog* configDialog;
1669+ QByteArray normalStyleSheet;
1670+ QByteArray nightStyleSheet;
1671+
1672+
1673+//! Computes the Hour Angle (culmination=0h) in absolute value (from 0h to 12h).
1674+//! @param latitude latitude of the observer (in radians).
1675+//! @param elevation elevation angle of the object (horizon=0) in radians.
1676+//! @param declination declination of the object in radians.
1677+ virtual double HourAngle(double latitude,double elevation,double declination);
1678+
1679+//! Computes the Hour Angle for a given Right Ascension and Sidereal Time.
1680+//! @param RA right ascension (hours).
1681+//! @param ST sidereal time (degrees).
1682+ virtual double HourAngle2(double RA, double ST);
1683+
1684+//! Solves Moon/Sun Rise/Set/Transit times for the current Julian day. This function updates the variables MoonRise, MoonSet, MoonCulm. Returns success status.
1685+ virtual bool MoonSunSolve(StelCore* core);
1686+
1687+//! Finds the heliacal rise/set dates of the year for the currently-selected object.
1688+//! @param Rise day of year of the Acronycal rise.
1689+//! @param Set day of year of the Acronycal set.
1690+//! @param Rise2 day of year of the Cosmical rise.
1691+//! @param Set2 day of year of the Cosmical set.
1692+ virtual int CheckAcro(int &Rise, int &Set, int &Rise2, int &Set2);
1693+
1694+
1695+//! computes the Sun or Moon coordinates at a given Julian date.
1696+//! @param core the stellarium core.
1697+//! @param JD double for the Julian date.
1698+//! @param RASun right ascension of the Sun (in hours).
1699+//! @param DecSun declination of the Sun (in radians).
1700+//! @param RAMoon idem for the Moon.
1701+//! @param DecMoon idem for the Moon.
1702+//! @param getBack controls whether Earth and Moon must be returned to their original positions after computation.
1703+ virtual void getSunMoonCoords(StelCore* core, double JD, double &RASun, double &DecSun, double &RAMoon, double &DecMoon, bool getBack);
1704+
1705+
1706+//! Returns the angular separation (in radians) between two points.
1707+//! @param RA1 right ascension of point 1 (in hours)
1708+//! @param Dec1 declination of point 1 (in radians)
1709+//! @param RA2 idem for point 2
1710+//! @param Dec2 idem for point 2
1711+ virtual double Lambda(double RA1, double Dec1, double RA2, double Dec2);
1712+
1713+//! Converts a time span in hours (given as double) in hh:mm:ss (integers).
1714+//! @param t time span (double, in hours).
1715+//! @param h hour (integer).
1716+//! @param m minute (integer).
1717+//! @param s second (integer).
1718+ virtual void double2hms(double t, int &h,int &m,int &s);
1719+
1720+//! Just returns the sign of a double;
1721+ virtual double sign(double d);
1722+
1723+//! Returns a string of date (e.g. "25 Apr") from a Day of Year (integer).
1724+//! @param DoY Day of the year.
1725+ virtual QString CalenDate(int DoY);
1726+
1727+//! Just subtracts/adds 24h to a RA (or HA), to make it fall within 0-24h.
1728+//! @param RA right ascension (in hours).
1729+ virtual double toUnsignedRA(double RA);
1730+
1731+//! Computes the RA, Dec and Rise/Set Sid. times of the selected planet for each day of the current year.
1732+//! @param core the current Stellarium core.
1733+//! @param Name name of the currently selected planet.
1734+ virtual void PlanetRADec(StelCore *core, QString Name);
1735+
1736+//! Computes the Sun's RA and Dec for each day of a given year.
1737+//! @param core current Stellarium core.
1738+ virtual void SunRADec(StelCore* core);
1739+
1740+//! Computes the Sun's Sid. Times at astronomical twilight (for each year's day)
1741+ virtual void SunHTwi();
1742+
1743+//! Just convert the Vec3d named TempLoc into RA/Dec:
1744+ virtual void toRADec(Vec3d TempLoc, double &RA, double &Dec);
1745+
1746+//! Vector to store the Julian Dates for the current year:
1747+ double yearJD[366];
1748+
1749+//! Check if a source is observable during a given date:
1750+//! @aparm i the day of the year.
1751+ virtual bool CheckRise(int i);
1752+
1753+//! Some useful constants and variables(almost self-explanatory).
1754+ double Rad2Deg, Rad2Hr, AstroTwiAlti, UA, TFrac, JDsec, Jan1stJD, halfpi, MoonT, nextFullMoon, prevFullMoon, RefFullMoon;
1755+
1756+//! RA, Dec, observer latitude, object's elevation, and Hour Angle at horizon.
1757+ double selRA, selDec, mylat, mylon, alti, horizH, culmAlt, myJD;
1758+
1759+//! Vectors to store Sun's RA, Dec, and Sid. Time at twilight and rise/set.
1760+ double SunRA[366], SunDec[366], SunSidT[4][366];
1761+
1762+//! Vectors to store planet's RA, Dec, and Sid. Time at rise/set.
1763+ double ObjectRA[366], ObjectDec[366], ObjectH0[366], ObjectSidT[2][366];
1764+
1765+//! Rise/Set/Transit times for the Moon at current day:
1766+ double MoonRise, MoonSet, MoonCulm, lastJDMoon;
1767+
1768+//! Vector of Earth position through the year.
1769+ Vec3d EarthPos[366];
1770+
1771+//! Position of the observer relative to the Earth Center or other coordinates:
1772+ Vec3d ObserverLoc, Pos0, Pos1, Pos2, RotObserver; //, Pos3;
1773+
1774+//! Matrix to transform coordinates for Sun/Moon ephemeris:
1775+ Mat4d LocTrans;
1776+
1777+//! Pointer to the Earth:
1778+ Planet* myEarth;
1779+ Planet* myMoon;
1780+
1781+//! Current simulation year and number of days in the year.;
1782+ int currYear, nDays, iAltitude;
1783+
1784+//! Useful auxiliary strings, to help checking changes in source/observer. Also to store results that must survive between iterations.
1785+ QString selName, bestNight, ObsRange, objname, AcroCos;
1786+
1787+//! Strings to save ephemeris Times:
1788+ QString RiseTime, SetTime, CulmTime;
1789+
1790+//! Just the names of the months.
1791+ QString months[12];
1792+
1793+//! Equatorial and local coordinates of currently-selected source.
1794+ Vec3d EquPos, LocPos;
1795+
1796+//! Some booleans to check the kind of source selected and the kind of output to produce.
1797+ bool isStar,isMoon,isSun,isScreen, LastSun, raised, configChanged;
1798+
1799+//! Some booleans to select the kind of output.
1800+ bool show_AcroCos, show_Good_Nights, show_Best_Night, show_Today, show_FullMoon; //, show_Crescent, show_SuperMoon;
1801+
1802+//! Parameters for the graphics (i.e., font, icons, etc.):
1803+ QFont font;
1804+ Vec3f fontColor;
1805+ bool flagShowObservability;
1806+ int fontSize;
1807+ QPixmap* OnIcon;
1808+ QPixmap* OffIcon;
1809+ QPixmap* GlowIcon;
1810+ StelButton* toolbarButton;
1811+
1812+
1813+};
1814+
1815+#include "fixx11h.h"
1816+#include <QObject>
1817+#include "StelPluginInterface.hpp"
1818+
1819+class ObservabilityStelPluginInterface : public QObject, public StelPluginInterface
1820+{
1821+ Q_OBJECT
1822+ Q_INTERFACES(StelPluginInterface)
1823+public:
1824+ virtual StelModule* getStelModule() const;
1825+ virtual StelPluginInfo getPluginInfo() const;
1826+};
1827+
1828+#endif /*OBSERVABILITY_HPP_*/
1829
1830=== added directory 'plugins/Observability/src/gui'
1831=== added file 'plugins/Observability/src/gui/ObservabilityDialog.cpp'
1832--- plugins/Observability/src/gui/ObservabilityDialog.cpp 1970-01-01 00:00:00 +0000
1833+++ plugins/Observability/src/gui/ObservabilityDialog.cpp 2012-08-12 12:25:22 +0000
1834@@ -0,0 +1,229 @@
1835+/*
1836+ * Stellarium Observability Plug-in GUI
1837+ *
1838+ * Copyright (C) 2012 Ivan Marti-Vidal (based on code by Alexander Wolf)
1839+ *
1840+ * This program is free software; you can redistribute it and/or
1841+ * modify it under the terms of the GNU General Public License
1842+ * as published by the Free Software Foundation; either version 2
1843+ * of the License, or (at your option) any later version.
1844+ *
1845+ * This program is distributed in the hope that it will be useful,
1846+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1847+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1848+ * GNU General Public License for more details.
1849+ *
1850+ * You should have received a copy of the GNU General Public License
1851+ * along with this program; if not, write to the Free Software
1852+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
1853+*/
1854+
1855+#include <QDebug>
1856+#include <QFileDialog>
1857+
1858+#include "StelApp.hpp"
1859+#include "ui_ObservabilityDialog.h"
1860+#include "ObservabilityDialog.hpp"
1861+#include "Observability.hpp"
1862+#include "StelModuleMgr.hpp"
1863+#include "StelObjectMgr.hpp"
1864+#include "StelMovementMgr.hpp"
1865+#include "StelStyle.hpp"
1866+#include "StelGui.hpp"
1867+#include "StelMainGraphicsView.hpp"
1868+#include "StelFileMgr.hpp"
1869+#include "StelTranslator.hpp"
1870+
1871+ObservabilityDialog::ObservabilityDialog()
1872+{
1873+ ui = new Ui_ObservabilityDialog;
1874+}
1875+
1876+ObservabilityDialog::~ObservabilityDialog()
1877+{
1878+ delete ui;
1879+}
1880+
1881+void ObservabilityDialog::retranslate()
1882+{
1883+ if (dialog)
1884+ ui->retranslateUi(dialog);
1885+ setAboutHtml();
1886+}
1887+
1888+// Initialize the dialog widgets and connect the signals/slots
1889+void ObservabilityDialog::createDialogContent()
1890+{
1891+ ui->setupUi(dialog);
1892+ ui->tabs->setCurrentIndex(0);
1893+ connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
1894+
1895+ // Settings:
1896+ connect(ui->Today, SIGNAL(stateChanged(int)), this, SLOT(setTodayFlag(int)));
1897+ connect(ui->AcroCos, SIGNAL(stateChanged(int)), this, SLOT(setAcroCosFlag(int)));
1898+ connect(ui->Opposition, SIGNAL(stateChanged(int)), this, SLOT(setOppositionFlag(int)));
1899+ connect(ui->Goods, SIGNAL(stateChanged(int)), this, SLOT(setGoodDatesFlag(int)));
1900+ connect(ui->FullMoon, SIGNAL(stateChanged(int)), this, SLOT(setFullMoonFlag(int)));
1901+// connect(ui->Crescent, SIGNAL(stateChanged(int)), this, SLOT(setCrescentMoonFlag(int)));
1902+// connect(ui->SuperMoon, SIGNAL(stateChanged(int)), this, SLOT(setSuperMoonFlag(int)));
1903+
1904+ connect(ui->Red, SIGNAL(sliderMoved(int)), this, SLOT(setRed(int)));
1905+ connect(ui->Green, SIGNAL(sliderMoved(int)), this, SLOT(setGreen(int)));
1906+ connect(ui->Blue, SIGNAL(sliderMoved(int)), this, SLOT(setBlue(int)));
1907+ connect(ui->fontSize, SIGNAL(sliderMoved(int)), this, SLOT(setSize(int)));
1908+ connect(ui->SunAltitude, SIGNAL(sliderMoved(int)), this, SLOT(setAltitude(int)));
1909+
1910+ connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
1911+ connect(ui->restoreDefaultsButton, SIGNAL(clicked()), this, SLOT(restoreDefaults()));
1912+ connect(ui->saveSettingsButton, SIGNAL(clicked()), this, SLOT(saveSettings()));
1913+
1914+ // About tab
1915+ setAboutHtml();
1916+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
1917+ Q_ASSERT(gui);
1918+ ui->aboutTextBrowser->document()->setDefaultStyleSheet(QString(gui->getStelStyle().htmlStyleSheet));
1919+
1920+ updateGuiFromSettings();
1921+
1922+}
1923+
1924+void ObservabilityDialog::setAboutHtml(void)
1925+{
1926+ QString html = "<html><head></head><body>";
1927+ html += "<h2>" + q_("Observability Plug-in") + "</h2><table width=\"90%\">";
1928+ html += "<tr width=\"30%\"><td>" + q_("Version:") + "</td><td> 1.0.1 </td></tr>";
1929+ html += "<tr><td>" + q_("Author:") + "</td><td>Ivan Marti-Vidal &lt;i.martividal@gmail.com&gt;</td></tr></table>";
1930+
1931+ html += "<p>" + q_("Plugin that analyzes the observability of the selected source (or the screen center, if no source is selected). The plugin can show rise, transit, and set times, as well as the best epoch of the year (i.e., largest angular separation from the Sun), the date range when the source is above the horizon at dark night, and the dates of Acronychal and Cosmical rise/set.<br>Ephemeris of the Solar-System objects and parallax effects are taken into account.<br><br> The author thanks Alexander Wolf and Georg Zotti for their advice.<br><br>Ivan Marti-Vidal (Onsala Space Observatory)") + "</p>";
1932+
1933+ html += "<br><h2>" + q_("Explanation of some parameters<br>") + "</h2><table width=\"90%\">";
1934+
1935+ html += "<tr><td>" + q_("Sun altitude at twilight:") + "</td><td>Any celestial object will be considered visible when the Sun is below this altitude. The altitude at astronomical twilight ranges usually between -12 and -18 degrees. This parameter is only used for the estimate of the range of observable epochs (see below).<br></td></tr>";
1936+
1937+ html += "<tr><td>" + q_("Today ephemeris:") + "</td><td>Self-explanatory. The program will show the rise, set, and culmination (transit) times. The exact times for these ephemeris are given in two ways: as time spans (referred to the current time) and as clock hours (in local time).<br></td></tr>";
1938+
1939+
1940+ html += "<tr><td>" + q_("Acronychal/Cosmical rise/set:") + "</td><td>The Acronychal rise (or set) of an object happens when the object rises (or sets) just when the Sun sets (or rises), respectively. The exact dates of these ephemeris depend on the Observer's location. The dates between the Acronychal set and rise are those when the altitude of the celestial object uses to be high when the Sun is well below the horizon (hence the object can be well observed). On the contrary, the Cosmical rise (or set) happens when both, the object and the Sun, rise (or set) simultaneously. It is obvious that the source is hardly observable (or not observable at all) in the dates between Cosmical set and rise.<br></td></tr>";
1941+
1942+ html += "<tr><td>" + q_("Largest Sun separation:") + "</td><td>Happens when the angular separation between the Sun and the celestial object are maximum. In most cases, this is equivalent to say that the Equatorial longitudes of the Sun and the object differ by 180 degrees, so the Sun is in opposition to the object. When an object is at its maximum possible angular separation from the Sun (no matter if it is a planet or a star), it culminates roughly at midnight, and on the darkest possible area of the Sky at that declination. Hence, that is the 'best' night to observe a particular object.<br></td></tr>";
1943+
1944+ html += "<tr><td>" + q_("Observable epochs:") + "</td><td><br>The program computes the range of dates when the celestial object is above the horizon at least during one moment of the night. By 'night', the program consideres the time span when the Sun altitude is below that of the twilight (which can be set by the user; see above). When the objects are fixed on the sky (or are exterior planets), the range of observable epochs for the current year can have two possible forms: either a range from one date to another (e.g., 20 Jan to 15 Sep) or in two steps (from 1 Jan to a given date and from another date to 31 Dec). In the first case, the first date (20 Jan in our example) shall be close to the so-called 'Heliacal rise of a star' and the second date (15 Sep in our example) shall be close to the 'Heliacal set'. In the second case (e.g., a range in the form 1 Jan to 20 May and 21 Sep to 31 Dec), the first date (20 May in our example) would be close to the Heliacal set and the second one (21 Sep in our example) to the Heliacal rise. More exact equations to estimate the Heliacal rise/set of stars and planets (which will not depend on the mere input of a twilight Sun elevation by the user) will be implemented in future versions of this plugin.</td></tr>";
1945+
1946+ html += "<tr><td>" + q_("Full Moon:") + "</td><td><br>When the Moon is selected, the program can compute the exact closest dates (up to 1 minute precision) of the Moon's opposition to the Sun.</td></tr>";
1947+
1948+
1949+ html += "</table>";
1950+
1951+
1952+ html += "</body></html>";
1953+
1954+ ui->aboutTextBrowser->setHtml(html);
1955+}
1956+
1957+
1958+void ObservabilityDialog::restoreDefaults(void)
1959+{
1960+ qDebug() << "Observability::restoreDefaults";
1961+ GETSTELMODULE(Observability)->restoreDefaults();
1962+ GETSTELMODULE(Observability)->readSettingsFromConfig();
1963+ updateGuiFromSettings();
1964+}
1965+
1966+void ObservabilityDialog::updateGuiFromSettings(void)
1967+{
1968+ ui->Today->setChecked(GETSTELMODULE(Observability)->getShowFlags(1));
1969+ ui->AcroCos->setChecked(GETSTELMODULE(Observability)->getShowFlags(2));
1970+ ui->Goods->setChecked(GETSTELMODULE(Observability)->getShowFlags(3));
1971+ ui->Opposition->setChecked(GETSTELMODULE(Observability)->getShowFlags(4));
1972+ ui->FullMoon->setChecked(GETSTELMODULE(Observability)->getShowFlags(5));
1973+// ui->Crescent->setChecked(GETSTELMODULE(Observability)->getShowFlags(6));
1974+// ui->SuperMoon->setChecked(GETSTELMODULE(Observability)->getShowFlags(7));
1975+
1976+ Vec3f currFont = GETSTELMODULE(Observability)->getFontColor();
1977+ int Rv = (int)(100.*currFont[0]);
1978+ int Gv = (int)(100.*currFont[1]);
1979+ int Bv = (int)(100.*currFont[2]);
1980+ ui->Red->setValue(Rv);
1981+ ui->Green->setValue(Gv);
1982+ ui->Blue->setValue(Bv);
1983+ ui->fontSize->setValue(GETSTELMODULE(Observability)->getFontSize());
1984+ int SAlti = GETSTELMODULE(Observability)->getSunAltitude();
1985+ ui->SunAltitude->setValue(SAlti);
1986+ ui->AltiText->setText(q_("-%1 deg.").arg(SAlti));
1987+}
1988+
1989+void ObservabilityDialog::saveSettings(void)
1990+{
1991+ GETSTELMODULE(Observability)->saveSettingsToConfig();
1992+}
1993+
1994+void ObservabilityDialog::setTodayFlag(int checkState)
1995+{
1996+ bool b = checkState != Qt::Unchecked;
1997+ GETSTELMODULE(Observability)->setShow(1,b);
1998+}
1999+
2000+void ObservabilityDialog::setAcroCosFlag(int checkState)
2001+{
2002+ bool b = checkState != Qt::Unchecked;
2003+ GETSTELMODULE(Observability)->setShow(2,b);
2004+}
2005+
2006+void ObservabilityDialog::setGoodDatesFlag(int checkState)
2007+{
2008+ bool b = checkState != Qt::Unchecked;
2009+ GETSTELMODULE(Observability)->setShow(3,b);
2010+}
2011+
2012+void ObservabilityDialog::setOppositionFlag(int checkState)
2013+{
2014+ bool b = checkState != Qt::Unchecked;
2015+ GETSTELMODULE(Observability)->setShow(4,b);
2016+}
2017+
2018+void ObservabilityDialog::setFullMoonFlag(int checkState)
2019+{
2020+ bool b = checkState != Qt::Unchecked;
2021+ GETSTELMODULE(Observability)->setShow(5,b);
2022+}
2023+
2024+//void ObservabilityDialog::setCrescentMoonFlag(int checkState)
2025+//{
2026+// bool b = checkState != Qt::Unchecked;
2027+// GETSTELMODULE(Observability)->setShow(6,b);
2028+//}
2029+
2030+//void ObservabilityDialog::setSuperMoonFlag(int checkState)
2031+//{
2032+// bool b = checkState != Qt::Unchecked;
2033+// GETSTELMODULE(Observability)->setShow(7,b);
2034+//}
2035+
2036+void ObservabilityDialog::setRed(int Value)
2037+{
2038+ GETSTELMODULE(Observability)->setFontColor(0,Value);
2039+}
2040+
2041+void ObservabilityDialog::setGreen(int Value)
2042+{
2043+ GETSTELMODULE(Observability)->setFontColor(1,Value);
2044+}
2045+
2046+void ObservabilityDialog::setBlue(int Value)
2047+{
2048+ GETSTELMODULE(Observability)->setFontColor(2,Value);
2049+}
2050+
2051+void ObservabilityDialog::setSize(int Value)
2052+{
2053+ GETSTELMODULE(Observability)->setFontSize(Value);
2054+}
2055+
2056+void ObservabilityDialog::setAltitude(int Value)
2057+{
2058+ ui->AltiText->setText(q_("-%1 deg.").arg(Value));
2059+ GETSTELMODULE(Observability)->setSunAltitude(Value);
2060+}
2061+
2062+
2063+
2064
2065=== added file 'plugins/Observability/src/gui/ObservabilityDialog.hpp'
2066--- plugins/Observability/src/gui/ObservabilityDialog.hpp 1970-01-01 00:00:00 +0000
2067+++ plugins/Observability/src/gui/ObservabilityDialog.hpp 2012-08-12 12:25:22 +0000
2068@@ -0,0 +1,69 @@
2069+/*
2070+ * Stellarium Observability Plug-in GUI
2071+ *
2072+ * Copyright (C) 2012 Ivan Marti-Vidal
2073+ *
2074+ * This program is free software; you can redistribute it and/or
2075+ * modify it under the terms of the GNU General Public License
2076+ * as published by the Free Software Foundation; either version 2
2077+ * of the License, or (at your option) any later version.
2078+ *
2079+ * This program is distributed in the hope that it will be useful,
2080+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2081+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2082+ * GNU General Public License for more details.
2083+ *
2084+ * You should have received a copy of the GNU General Public License
2085+ * along with this program; if not, write to the Free Software
2086+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
2087+*/
2088+
2089+#ifndef _OBSERVABILITYDIALOG_HPP_
2090+#define _OBSERVABILITYDIALOG_HPP_
2091+
2092+#include <QObject>
2093+#include "StelDialog.hpp"
2094+#include "Observability.hpp"
2095+
2096+class Ui_ObservabilityDialog;
2097+
2098+class ObservabilityDialog : public StelDialog
2099+{
2100+ Q_OBJECT
2101+
2102+public:
2103+ ObservabilityDialog();
2104+ ~ObservabilityDialog();
2105+
2106+protected:
2107+ //! Initialize the dialog widgets and connect the signals/slots
2108+ void createDialogContent();
2109+
2110+public slots:
2111+ void retranslate();
2112+
2113+private slots:
2114+ void setTodayFlag(int);
2115+ void setAcroCosFlag(int);
2116+ void setOppositionFlag(int);
2117+ void setGoodDatesFlag(int);
2118+ void setFullMoonFlag(int);
2119+// void setCrescentMoonFlag(int);
2120+// void setSuperMoonFlag(int);
2121+
2122+ void restoreDefaults(void);
2123+ void saveSettings(void);
2124+ void setRed(int);
2125+ void setGreen(int);
2126+ void setBlue(int);
2127+ void setSize(int);
2128+ void setAltitude(int);
2129+
2130+private:
2131+ Ui_ObservabilityDialog* ui;
2132+ void setAboutHtml(void);
2133+ void updateGuiFromSettings(void);
2134+
2135+};
2136+
2137+#endif // _OBSERVABILITYDIALOG_HPP_
2138
2139=== added file 'plugins/Observability/src/gui/ObservabilityDialog.ui'
2140--- plugins/Observability/src/gui/ObservabilityDialog.ui 1970-01-01 00:00:00 +0000
2141+++ plugins/Observability/src/gui/ObservabilityDialog.ui 2012-08-12 12:25:22 +0000
2142@@ -0,0 +1,405 @@
2143+<?xml version="1.0" encoding="UTF-8"?>
2144+<ui version="4.0">
2145+ <class>ObservabilityDialog</class>
2146+ <widget class="QWidget" name="ObservabilityDialog">
2147+ <property name="geometry">
2148+ <rect>
2149+ <x>0</x>
2150+ <y>0</y>
2151+ <width>530</width>
2152+ <height>560</height>
2153+ </rect>
2154+ </property>
2155+ <property name="windowTitle">
2156+ <string>Observability Configuration</string>
2157+ </property>
2158+ <layout class="QVBoxLayout" name="verticalLayout_2">
2159+ <property name="spacing">
2160+ <number>0</number>
2161+ </property>
2162+ <property name="margin">
2163+ <number>0</number>
2164+ </property>
2165+ <item>
2166+ <widget class="BarFrame" name="TitleBar">
2167+ <property name="sizePolicy">
2168+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
2169+ <horstretch>0</horstretch>
2170+ <verstretch>0</verstretch>
2171+ </sizepolicy>
2172+ </property>
2173+ <property name="minimumSize">
2174+ <size>
2175+ <width>530</width>
2176+ <height>25</height>
2177+ </size>
2178+ </property>
2179+ <property name="maximumSize">
2180+ <size>
2181+ <width>530</width>
2182+ <height>25</height>
2183+ </size>
2184+ </property>
2185+ <property name="focusPolicy">
2186+ <enum>Qt::NoFocus</enum>
2187+ </property>
2188+ <property name="autoFillBackground">
2189+ <bool>false</bool>
2190+ </property>
2191+ <property name="frameShape">
2192+ <enum>QFrame::StyledPanel</enum>
2193+ </property>
2194+ <layout class="QHBoxLayout">
2195+ <property name="spacing">
2196+ <number>0</number>
2197+ </property>
2198+ <property name="leftMargin">
2199+ <number>0</number>
2200+ </property>
2201+ <property name="topMargin">
2202+ <number>0</number>
2203+ </property>
2204+ <property name="rightMargin">
2205+ <number>4</number>
2206+ </property>
2207+ <property name="bottomMargin">
2208+ <number>0</number>
2209+ </property>
2210+ <item>
2211+ <spacer>
2212+ <property name="orientation">
2213+ <enum>Qt::Horizontal</enum>
2214+ </property>
2215+ <property name="sizeHint" stdset="0">
2216+ <size>
2217+ <width>40</width>
2218+ <height>20</height>
2219+ </size>
2220+ </property>
2221+ </spacer>
2222+ </item>
2223+ <item>
2224+ <widget class="QLabel" name="stelWindowTitle">
2225+ <property name="text">
2226+ <string>Observability Plug-in Configuration</string>
2227+ </property>
2228+ </widget>
2229+ </item>
2230+ <item>
2231+ <spacer>
2232+ <property name="orientation">
2233+ <enum>Qt::Horizontal</enum>
2234+ </property>
2235+ <property name="sizeHint" stdset="0">
2236+ <size>
2237+ <width>40</width>
2238+ <height>20</height>
2239+ </size>
2240+ </property>
2241+ </spacer>
2242+ </item>
2243+ <item>
2244+ <widget class="QPushButton" name="closeStelWindow">
2245+ <property name="minimumSize">
2246+ <size>
2247+ <width>16</width>
2248+ <height>16</height>
2249+ </size>
2250+ </property>
2251+ <property name="maximumSize">
2252+ <size>
2253+ <width>16</width>
2254+ <height>16</height>
2255+ </size>
2256+ </property>
2257+ <property name="focusPolicy">
2258+ <enum>Qt::NoFocus</enum>
2259+ </property>
2260+ <property name="text">
2261+ <string/>
2262+ </property>
2263+ </widget>
2264+ </item>
2265+ </layout>
2266+ </widget>
2267+ </item>
2268+ <item>
2269+ <widget class="QTabWidget" name="tabs">
2270+ <property name="currentIndex">
2271+ <number>0</number>
2272+ </property>
2273+ <property name="documentMode">
2274+ <bool>false</bool>
2275+ </property>
2276+ <widget class="QWidget" name="settingsTab">
2277+ <attribute name="title">
2278+ <string>Settings</string>
2279+ </attribute>
2280+ <layout class="QGridLayout" name="gridLayout">
2281+ <item row="9" column="0">
2282+ <layout class="QVBoxLayout" name="verticalLayout_4">
2283+ <item>
2284+ <widget class="QLabel" name="label_7">
2285+ <property name="font">
2286+ <font>
2287+ <family>Arial</family>
2288+ <pointsize>14</pointsize>
2289+ <weight>75</weight>
2290+ <bold>true</bold>
2291+ </font>
2292+ </property>
2293+ <property name="text">
2294+ <string>Showing Options</string>
2295+ </property>
2296+ </widget>
2297+ </item>
2298+ <item>
2299+ <widget class="QCheckBox" name="Today">
2300+ <property name="text">
2301+ <string>Today's ephemeris (rise, set, and transit times)</string>
2302+ </property>
2303+ </widget>
2304+ </item>
2305+ <item>
2306+ <widget class="QCheckBox" name="AcroCos">
2307+ <property name="text">
2308+ <string>Dates of Acronychal and Cosmical rise/set</string>
2309+ </property>
2310+ </widget>
2311+ </item>
2312+ <item>
2313+ <widget class="QCheckBox" name="Opposition">
2314+ <property name="text">
2315+ <string>Date of largest separation to the Sun</string>
2316+ </property>
2317+ </widget>
2318+ </item>
2319+ <item>
2320+ <widget class="QCheckBox" name="Goods">
2321+ <property name="text">
2322+ <string>Range of observable epochs</string>
2323+ </property>
2324+ </widget>
2325+ </item>
2326+ <item>
2327+ <widget class="QCheckBox" name="FullMoon">
2328+ <property name="text">
2329+ <string>Dates of previous and next Full Moon</string>
2330+ </property>
2331+ </widget>
2332+ </item>
2333+ </layout>
2334+ </item>
2335+ <item row="10" column="0">
2336+ <layout class="QHBoxLayout" name="horizontalLayout_7">
2337+ <item>
2338+ <widget class="QPushButton" name="restoreDefaultsButton">
2339+ <property name="sizePolicy">
2340+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
2341+ <horstretch>0</horstretch>
2342+ <verstretch>0</verstretch>
2343+ </sizepolicy>
2344+ </property>
2345+ <property name="text">
2346+ <string>Restore default settings</string>
2347+ </property>
2348+ </widget>
2349+ </item>
2350+ <item>
2351+ <widget class="QPushButton" name="saveSettingsButton">
2352+ <property name="sizePolicy">
2353+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
2354+ <horstretch>0</horstretch>
2355+ <verstretch>0</verstretch>
2356+ </sizepolicy>
2357+ </property>
2358+ <property name="text">
2359+ <string>Save settings as default</string>
2360+ </property>
2361+ </widget>
2362+ </item>
2363+ </layout>
2364+ </item>
2365+ <item row="0" column="0">
2366+ <layout class="QVBoxLayout" name="verticalLayout_3">
2367+ <item>
2368+ <widget class="QLabel" name="label_5">
2369+ <property name="font">
2370+ <font>
2371+ <family>Arial</family>
2372+ <pointsize>14</pointsize>
2373+ <weight>75</weight>
2374+ <bold>true</bold>
2375+ </font>
2376+ </property>
2377+ <property name="text">
2378+ <string>Font color and size</string>
2379+ </property>
2380+ </widget>
2381+ </item>
2382+ <item>
2383+ <layout class="QHBoxLayout" name="horizontalLayout">
2384+ <item alignment="Qt::AlignRight">
2385+ <widget class="QLabel" name="label">
2386+ <property name="text">
2387+ <string>Red</string>
2388+ </property>
2389+ </widget>
2390+ </item>
2391+ <item alignment="Qt::AlignLeft">
2392+ <widget class="QSlider" name="Red">
2393+ <property name="maximumSize">
2394+ <size>
2395+ <width>508</width>
2396+ <height>19</height>
2397+ </size>
2398+ </property>
2399+ <property name="orientation">
2400+ <enum>Qt::Horizontal</enum>
2401+ </property>
2402+ </widget>
2403+ </item>
2404+ </layout>
2405+ </item>
2406+ <item>
2407+ <layout class="QHBoxLayout" name="horizontalLayout_2">
2408+ <item alignment="Qt::AlignRight">
2409+ <widget class="QLabel" name="label_2">
2410+ <property name="text">
2411+ <string>Green</string>
2412+ </property>
2413+ </widget>
2414+ </item>
2415+ <item alignment="Qt::AlignLeft">
2416+ <widget class="QSlider" name="Green">
2417+ <property name="orientation">
2418+ <enum>Qt::Horizontal</enum>
2419+ </property>
2420+ </widget>
2421+ </item>
2422+ </layout>
2423+ </item>
2424+ <item>
2425+ <layout class="QHBoxLayout" name="horizontalLayout_3">
2426+ <item alignment="Qt::AlignRight">
2427+ <widget class="QLabel" name="label_3">
2428+ <property name="text">
2429+ <string>Blue</string>
2430+ </property>
2431+ </widget>
2432+ </item>
2433+ <item alignment="Qt::AlignLeft">
2434+ <widget class="QSlider" name="Blue">
2435+ <property name="maximum">
2436+ <number>99</number>
2437+ </property>
2438+ <property name="orientation">
2439+ <enum>Qt::Horizontal</enum>
2440+ </property>
2441+ </widget>
2442+ </item>
2443+ </layout>
2444+ </item>
2445+ <item>
2446+ <layout class="QHBoxLayout" name="horizontalLayout_4">
2447+ <item alignment="Qt::AlignRight">
2448+ <widget class="QLabel" name="label_4">
2449+ <property name="text">
2450+ <string>Font Size</string>
2451+ </property>
2452+ </widget>
2453+ </item>
2454+ <item alignment="Qt::AlignLeft">
2455+ <widget class="QSlider" name="fontSize">
2456+ <property name="minimum">
2457+ <number>5</number>
2458+ </property>
2459+ <property name="maximum">
2460+ <number>30</number>
2461+ </property>
2462+ <property name="orientation">
2463+ <enum>Qt::Horizontal</enum>
2464+ </property>
2465+ </widget>
2466+ </item>
2467+ </layout>
2468+ </item>
2469+ </layout>
2470+ </item>
2471+ <item row="6" column="0">
2472+ <layout class="QVBoxLayout" name="verticalLayout_5">
2473+ <item>
2474+ <widget class="QLabel" name="label_6">
2475+ <property name="font">
2476+ <font>
2477+ <family>Arial</family>
2478+ <pointsize>14</pointsize>
2479+ <weight>75</weight>
2480+ <bold>true</bold>
2481+ </font>
2482+ </property>
2483+ <property name="text">
2484+ <string>Sun altitude at twilight</string>
2485+ </property>
2486+ </widget>
2487+ </item>
2488+ <item>
2489+ <layout class="QHBoxLayout" name="horizontalLayout_5">
2490+ <item alignment="Qt::AlignRight">
2491+ <widget class="QLabel" name="AltiText">
2492+ <property name="text">
2493+ <string>0 deg.</string>
2494+ </property>
2495+ </widget>
2496+ </item>
2497+ <item alignment="Qt::AlignLeft">
2498+ <widget class="QSlider" name="SunAltitude">
2499+ <property name="maximum">
2500+ <number>20</number>
2501+ </property>
2502+ <property name="orientation">
2503+ <enum>Qt::Horizontal</enum>
2504+ </property>
2505+ </widget>
2506+ </item>
2507+ </layout>
2508+ </item>
2509+ </layout>
2510+ </item>
2511+ </layout>
2512+ </widget>
2513+ <widget class="QWidget" name="aboutTab">
2514+ <attribute name="title">
2515+ <string>About</string>
2516+ </attribute>
2517+ <layout class="QVBoxLayout" name="verticalLayout_11">
2518+ <property name="spacing">
2519+ <number>9</number>
2520+ </property>
2521+ <item>
2522+ <widget class="QTextBrowser" name="aboutTextBrowser">
2523+ <property name="openExternalLinks">
2524+ <bool>true</bool>
2525+ </property>
2526+ <property name="openLinks">
2527+ <bool>true</bool>
2528+ </property>
2529+ </widget>
2530+ </item>
2531+ </layout>
2532+ </widget>
2533+ </widget>
2534+ </item>
2535+ </layout>
2536+ </widget>
2537+ <customwidgets>
2538+ <customwidget>
2539+ <class>BarFrame</class>
2540+ <extends>QFrame</extends>
2541+ <header>Dialog.hpp</header>
2542+ <container>1</container>
2543+ </customwidget>
2544+ </customwidgets>
2545+ <resources/>
2546+ <connections/>
2547+</ui>
2548
2549=== added file 'plugins/exts2.tar.gz'
2550Binary files plugins/exts2.tar.gz 1970-01-01 00:00:00 +0000 and plugins/exts2.tar.gz 2012-08-12 12:25:22 +0000 differ
2551=== modified file 'src/CMakeLists.txt'
2552--- src/CMakeLists.txt 2012-07-22 14:35:41 +0000
2553+++ src/CMakeLists.txt 2012-08-12 12:25:22 +0000
2554@@ -519,6 +519,11 @@
2555 ADD_DEFINITIONS(-DUSE_STATIC_PLUGIN_HELLOSTELMODULE)
2556 ENDIF()
2557
2558+IF (USE_PLUGIN_OBSERVABILITY)
2559+ SET(STELLARIUM_STATIC_PLUGINS_LIBRARIES ${STELLARIUM_STATIC_PLUGINS_LIBRARIES} "${CMAKE_BINARY_DIR}/plugins/Observability/src/${CMAKE_CFG_INTDIR}/libObservability.a")
2560+ ADD_DEFINITIONS(-DUSE_STATIC_PLUGIN_OBSERVABILITY)
2561+ENDIF()
2562+
2563 IF (USE_PLUGIN_ANGLEMEASURE)
2564 SET(STELLARIUM_STATIC_PLUGINS_LIBRARIES ${STELLARIUM_STATIC_PLUGINS_LIBRARIES} "${CMAKE_BINARY_DIR}/plugins/AngleMeasure/src/${CMAKE_CFG_INTDIR}/libAngleMeasure.a")
2565 ADD_DEFINITIONS(-DUSE_STATIC_PLUGIN_ANGLEMEASURE)
2566
2567=== modified file 'src/StelMainGraphicsView.cpp'
2568--- src/StelMainGraphicsView.cpp 2012-07-01 16:42:36 +0000
2569+++ src/StelMainGraphicsView.cpp 2012-08-12 12:25:22 +0000
2570@@ -117,6 +117,10 @@
2571 Q_IMPORT_PLUGIN(Exoplanets)
2572 #endif
2573
2574+#ifdef USE_STATIC_PLUGIN_OBSERVABILITY
2575+Q_IMPORT_PLUGIN(Observability)
2576+#endif
2577+
2578 // Initialize static variables
2579 StelMainGraphicsView* StelMainGraphicsView::singleton = NULL;
2580