diff --git a/guide/app_config_ini.tex b/guide/app_config_ini.tex index 5665b1761e1ce..60c3c5c18617f 100644 --- a/guide/app_config_ini.tex +++ b/guide/app_config_ini.tex @@ -629,7 +629,7 @@ \subsection{\big[navigation\big]} or \emph{Preset} (start at time defined by preset\_sky\_time)\\%\midrule flag\_enable\_zoom\_keys & bool & Set to \emph{false} if you want to disable the zoom\\%\midrule flag\_manual\_zoom & bool & Set to \emph{false} for normal zoom behaviour as described in this guide. - When set to true, the auto zoom feature only moves in a small amount and must be pressed many times\\%\midrule + When set to \emph{true}, the auto zoom feature only moves in a small amount and must be pressed many times\\%\midrule flag\_enable\_move\_keys & bool & Set to \emph{false} if you want to disable the arrow keys\\%\midrule flag\_enable\_mouse\_navigation & bool & Set to \emph{false} if you want to disable the mouse pan (drag).\\%\midrule flag\_enable\_mouse\_zooming & bool & Set to \emph{false} if you want to disable the mouse zooming (mousewheel).\\%\midrule @@ -646,7 +646,6 @@ \subsection{\big[navigation\big]} zoom\_speed & float & Sets the zoom speed\\%\midrule viewing\_mode & string & If set to \emph{horizon}, the viewing mode simulate an alt/azi mount, if set to \emph{equator}, the viewing mode simulates an equatorial mount\\%\midrule -flag\_manual\_zoom & bool & Set to \emph{true} if you want to auto-zoom in incrementally.\\%\midrule auto\_zoom\_out\_resets\_direction & bool & Set to \emph{true} if you want to auto-zoom restoring direction.\\%\midrule time\_correction\_algorithm & string & Algorithm of DeltaT correction.\\\bottomrule %% TODO: list values! And write ref. chapter! \end{longtable} @@ -952,7 +951,9 @@ \subsection{\big[viewing\big]} flag\_night & bool & Enable night mode (red-only mode) on startup\\\midrule light\_pollution\_luminance & float & Sets the level of the light pollution simulation\\\midrule %% TODO: WHAT IS THIS? use\_luminance\_adaptation & bool & Enable dynamic eye adaptation\\\midrule %% TODO: DESCRIBE! -sky\_brightness\_label\_threshold & float & Sky brightness [$cd/m^2$] to show infotext in black \\ %% +sky\_brightness\_label\_threshold & float & Sky brightness [$cd/m^2$] to show infotext in black \\\midrule %% +flag\_landscape\_autoselection & bool & load fitting landscape after changing planet (use \emph{zero} landscape when no fitting found).\\ +flag\_environment\_auto\_enable & bool & Enable/disable atmosphere, fog and cardinals for observer location when switching planet.\\ \bottomrule \end{longtable} diff --git a/guide/ch_interface.tex b/guide/ch_interface.tex index 14536672bb5a6..bf715450b8888 100644 --- a/guide/ch_interface.tex +++ b/guide/ch_interface.tex @@ -61,7 +61,7 @@ \section{Setting Your Location} \label{sec:gui:location} \begin{figure}[htbp] -\centering\includegraphics[width=0.75\textwidth]{location_dialog.png} +\centering\includegraphics[width=0.85\textwidth]{location_dialog.png} \caption{Location window} \label{fig:gui:location} \end{figure} @@ -113,6 +113,16 @@ \section{Setting Your Location} ``use as default'' checkbox, disable ``Get location from Network'', and close the location window. +Two settings may influence the Landscape when changing locations: +\begin{description} +\item[Auto select landscapes] When changing the planet, +a fitting landscape panorama will be shown when available. +Also, \newFeature{23.2} when clicking on the earth map, +a zero-altitude landscape is displayed in the approximate color of that location (taken from the map). +\item[Auto-enable atmosphere] When changing planet during + location change, the atmosphere will be switched as required. +\end{description} + \subsection{Time Zones} \label{sec:gui:location:timezones} Locations in Stellarium's location database include their respective @@ -337,8 +347,6 @@ \subsection{The Tools Tab} \item[Select single constellation] When active, clicking on a star that is member in the constellation lines will make the constellation stand out. See section~\ref{sec:starlore:singleConstellations} for details. -\item[Auto-enabling for the environment] When changing planet during - location change, atmosphere will be switched as required. \item[Dithering] options to allow select better simulation of sky on different hardware. \item[Auto zoom out returns to initial direction of view] When enabled, this option changes the behavior of the zoom out key @@ -363,8 +371,6 @@ \subsection{The Tools Tab} Usually it should be enabled. (See~\ref{sec:Concepts:Parallax:Topocentric}) \item[Include nutation] Compute the slight wobble of earth's axis. This feature is active only about 500 years around J2000.0. -\item[Auto select landscapes] When changing the planet in the location - panel, a fitting landscape panorama will be shown when available. \item[Indication for mount mode] You can activate the short display of a message when switching type of used mount. \item[Edit keyboard shortcuts\ldots] See section~\ref{sec:gui:help:hotkeys}. \item[Mouse cursor timeout] You can decide whether, and when, the diff --git a/guide/pictures/config_dialog_extras_tab.png b/guide/pictures/config_dialog_extras_tab.png index 9bbfa3239b7b7..943536d33c6da 100644 Binary files a/guide/pictures/config_dialog_extras_tab.png and b/guide/pictures/config_dialog_extras_tab.png differ diff --git a/guide/pictures/config_dialog_info_tab.png b/guide/pictures/config_dialog_info_tab.png index d2650117c9bbe..c644f5fe8332f 100644 Binary files a/guide/pictures/config_dialog_info_tab.png and b/guide/pictures/config_dialog_info_tab.png differ diff --git a/guide/pictures/config_dialog_main_tab.png b/guide/pictures/config_dialog_main_tab.png index 089bf87f0c0b3..9044d074cdbde 100644 Binary files a/guide/pictures/config_dialog_main_tab.png and b/guide/pictures/config_dialog_main_tab.png differ diff --git a/guide/pictures/config_dialog_time_tab.png b/guide/pictures/config_dialog_time_tab.png index a1ee1a0d52590..f4d444b14a8d4 100644 Binary files a/guide/pictures/config_dialog_time_tab.png and b/guide/pictures/config_dialog_time_tab.png differ diff --git a/guide/pictures/config_dialog_tools_tab.png b/guide/pictures/config_dialog_tools_tab.png index eb4296815f21f..cdde27d1b084c 100644 Binary files a/guide/pictures/config_dialog_tools_tab.png and b/guide/pictures/config_dialog_tools_tab.png differ diff --git a/guide/pictures/location_dialog.png b/guide/pictures/location_dialog.png index fc74ae7c3aeb2..1411bda8b69a1 100644 Binary files a/guide/pictures/location_dialog.png and b/guide/pictures/location_dialog.png differ diff --git a/plugins/RemoteSync/src/SyncClientHandlers.cpp b/plugins/RemoteSync/src/SyncClientHandlers.cpp index 8253763c270f1..8269dfa8d79ae 100644 --- a/plugins/RemoteSync/src/SyncClientHandlers.cpp +++ b/plugins/RemoteSync/src/SyncClientHandlers.cpp @@ -208,7 +208,7 @@ bool ClientLocationHandler::handleMessage(QDataStream &stream, SyncProtocol::tPa //create a normal observer core->setObserver(new StelObserver(msg.stelLocation)); } - emit core->targetLocationChanged(msg.stelLocation); + emit core->targetLocationChanged(msg.stelLocation, QString()); emit core->locationChanged(core->getCurrentLocation()); diff --git a/plugins/RemoteSync/src/SyncServerEventSenders.cpp b/plugins/RemoteSync/src/SyncServerEventSenders.cpp index f1a43e7690dc8..4c76df51a0d7c 100644 --- a/plugins/RemoteSync/src/SyncServerEventSenders.cpp +++ b/plugins/RemoteSync/src/SyncServerEventSenders.cpp @@ -59,7 +59,8 @@ Time TimeEventSender::constructMessage() LocationEventSender::LocationEventSender() { - connect(core,SIGNAL(targetLocationChanged(StelLocation)), this, SLOT(reactToStellariumEvent())); + //connect(core,&StelCore::targetLocationChanged, this, &LocationEventSender::reactToStellariumEvent); + connect(core,&StelCore::locationChanged, this, &LocationEventSender::reactToStellariumEvent); } Location LocationEventSender::constructMessage() diff --git a/src/core/StelCore.cpp b/src/core/StelCore.cpp index 1a2ca6b8bae3e..29a84a6aba99c 100644 --- a/src/core/StelCore.cpp +++ b/src/core/StelCore.cpp @@ -1091,7 +1091,9 @@ void StelCore::returnToDefaultLocation() StelLocationMgr& locationMgr = StelApp::getInstance().getLocationMgr(); StelLocation loc = locationMgr.locationForString(defaultLocationID); if (loc.isValid()) - moveObserverTo(loc, 0.); + moveObserverTo(loc, 1., 2.); + else + qDebug() << "StelCore::returnToDefaultLocation: Location " << loc.serializeToLine().replace('\t', '|') << "is invalid. Store an entry from the locations list as default location."; } void StelCore::returnToHome() @@ -1231,7 +1233,7 @@ void StelCore::moveObserverToSelected() if (!results.isEmpty()) loc = results.value(results.firstKey()); // ...and use it! - moveObserverTo(loc); + moveObserverTo(loc, 1, 1, pl->getEnglishName()); } } else @@ -1240,15 +1242,10 @@ void StelCore::moveObserverToSelected() if (ni) { // We need to move to the nomenclature item's host planet. - StelLocation loc; // = getCurrentLocation(); - loc.planetName = ni->getPlanet()->getEnglishName(); - loc.name=ni->getEnglishName(); - loc.state = ""; - loc.setLongitude(ni->getLongitude()); - loc.setLatitude(ni->getLatitude()); - loc.lightPollutionLuminance = 0; + StelLocation loc(ni->getEnglishName(), "", "", ni->getPlanet()->getEnglishName(), ni->getLongitude(), ni->getLatitude(), 0, 0, getCurrentTimeZone(), 1, 'X', ni->getPlanet()->getEnglishName()); + loc.lightPollutionLuminance = 0; // be dead sure it's zero! - moveObserverTo(loc); + moveObserverTo(loc, 1, 1, pl->getEnglishName()); objmgr->unSelect(); // no use to keep it: Marker will flicker around the screen. } } @@ -1285,7 +1282,8 @@ void StelCore::setObserver(StelObserver *obs) // Smoothly move the observer to the given location void StelCore::moveObserverTo(const StelLocation& target, double duration, double durationIfPlanetChange, const QString &landscapeID) { - double d = (getCurrentLocation().planetName==target.planetName) ? duration : durationIfPlanetChange; + const double d = (getCurrentLocation().planetName==target.planetName) ? duration : durationIfPlanetChange; + //qDebug() << "StelCore::moveObserverTo" << target.name << "in" << d << "seconds with Landscape" << landscapeID ; if (d>0.) { StelLocation curLoc = getCurrentLocation(); @@ -1321,7 +1319,7 @@ void StelCore::moveObserverTo(const StelLocation& target, double duration, doubl } } } - emit targetLocationChanged(target, landscapeID); + emit targetLocationChanged(target, landscapeID); // inform others about our next location. E.g., let LandscapeMgr load a new landscape. emit locationChanged(getCurrentLocation()); } @@ -2021,7 +2019,9 @@ void StelCore::updateTime(double deltaTime) position = newObs; } if (position->update(deltaTime)) + { emit locationChanged(getCurrentLocation()); + } // Position of sun and all the satellites (ie planets) // GZ maybe setting this static can speedup a bit? diff --git a/src/core/StelCore.hpp b/src/core/StelCore.hpp index 71f4c9206634b..4b7c8575e0eca 100644 --- a/src/core/StelCore.hpp +++ b/src/core/StelCore.hpp @@ -793,8 +793,9 @@ public slots: signals: //! This signal is emitted when the observer location has changed. void locationChanged(const StelLocation&); - //! This signal is emitted whenever the targeted location changes. The second parameter can transmit a landscapeID. - void targetLocationChanged(const StelLocation&, const QString& = QString()); + //! This signal is emitted whenever the targeted location changes, i.e., at the onset of location transitions. + //! The second parameter can transmit a landscapeID or should be QString(). + void targetLocationChanged(const StelLocation& loc, const QString& id); //! This signal is emitted when the current timezone name is changed. void currentTimeZoneChanged(const QString& tz); //! This signal is emitted when custom timezone use is activated (true) or deactivated (false). diff --git a/src/core/StelLocation.cpp b/src/core/StelLocation.cpp index ef5862d81336d..70fbe66705404 100644 --- a/src/core/StelLocation.cpp +++ b/src/core/StelLocation.cpp @@ -57,6 +57,14 @@ StelLocation::StelLocation(const QString &lName, const QString &lState, const QS { } +StelLocation::StelLocation(const QString &lName, const QString &lState, const QString &lRegion, const QString &plName, const float lng, const float lat, const int alt, + const int populationK, const QString &timeZone, const int bortleIndex, const QChar roleKey, const QString &landscapeID) + : StelLocation(lName, lState, lRegion, lng, lat, alt, populationK, timeZone, bortleIndex, roleKey, landscapeID) +{ + planetName=plName; +} + + // Output the location as a string ready to be stored in the user_location file QString StelLocation::serializeToLine() const { diff --git a/src/core/StelLocation.hpp b/src/core/StelLocation.hpp index 6b9751b8eed9a..0246b3038433f 100644 --- a/src/core/StelLocation.hpp +++ b/src/core/StelLocation.hpp @@ -31,10 +31,11 @@ class StelLocation { public: StelLocation() : altitude(0), population(0), role('X'), isUserLocation(true), longitude(0.f), latitude(0.f) {} - //! constructor for ad-hoc locations. + //! constructors for ad-hoc locations. The first, shorter version is only for earth locations //! @arg lName location name //! @arg lState may be usedful if region has more than one such name //! @arg lRegion must be the long name of UN UM49 only! (E.g., "Western Europe") + //! @arg plName planetName. This must be identical to the englishName of a solar system object. //! @arg lng geographical longitude, east-positive, degrees //! @arg lat geographical latitude, north-positive, degrees //! @arg alt altitude above mean sea level @@ -45,6 +46,8 @@ class StelLocation //! @arg landscapeID a fitting landscape StelLocation(const QString &lName, const QString &lState, const QString &lRegion, const float lng, const float lat, const int alt, const int populationK, const QString &timeZone, const int bortleIndex, const QChar roleKey='X', const QString &landscapeID=QString()); + StelLocation(const QString &lName, const QString &lState, const QString &lRegion, const QString &plName, const float lng, const float lat, const int alt, + const int populationK, const QString &timeZone, const int bortleIndex, const QChar roleKey, const QString &landscapeID); //! Return a short string which can be used in a list view. QString getID() const; diff --git a/src/core/StelLocationMgr.cpp b/src/core/StelLocationMgr.cpp index 4378966792f45..5152aac1e0f35 100644 --- a/src/core/StelLocationMgr.cpp +++ b/src/core/StelLocationMgr.cpp @@ -17,11 +17,13 @@ */ #include "StelLocationMgr.hpp" +#include "SolarSystem.hpp" #include "StelLocationMgr_p.hpp" #include "StelApp.hpp" #include "StelCore.hpp" #include "StelFileMgr.hpp" +#include "StelModuleMgr.hpp" #include "StelUtils.hpp" #include "StelJsonParser.hpp" @@ -491,6 +493,10 @@ StelLocationMgr::StelLocationMgr() #endif // Init to Paris France because it's the center of the world. lastResortLocation = locationForString(conf->value("init_location/last_location", "Paris, Western Europe").toString()); + + planetName="Earth"; + planetSurfaceMap=QImage(":/graphicGui/miscWorldMap.jpg"); + connect(StelApp::getInstance().getCore(), SIGNAL(locationChanged(StelLocation)), this, SLOT(changePlanetMapForLocation(StelLocation))); } StelLocationMgr::~StelLocationMgr() @@ -1075,8 +1081,8 @@ void StelLocationMgr::changeLocationFromGPSQuery(const StelLocation &locin) loc.name=QString("GPS %1%2 %3%4") .arg(loc.getLatitude()<0?"S":"N").arg(qRound(abs(loc.getLatitude()))) .arg(loc.getLongitude()<0?"W":"E").arg(qRound(abs(loc.getLongitude()))); - - core->moveObserverTo(loc, 0.0, 0.0); + QColor color=getColorForCoordinates(loc.getLongitude(), loc.getLatitude()); + core->moveObserverTo(loc, 0.0, 0.0, QString("ZeroColor(%1)").arg(Vec3f(color).toStr())); if (nmeaHelper) { if (verbose) @@ -1154,7 +1160,9 @@ void StelLocationMgr::changeLocationFromNetworkLookup() // Ensure that ipTimeZone is a valid IANA timezone name! QTimeZone ipTZ(ipTimeZone.toUtf8()); core->setCurrentTimeZone( !ipTZ.isValid() || ipTimeZone.isEmpty() ? "LMST" : ipTimeZone); - core->moveObserverTo(loc, 0.0, 0.0); + QColor color=getColorForCoordinates(loc.getLongitude(), loc.getLatitude()); + core->moveObserverTo(loc, 0.0, 0.0, QString("ZeroColor(%1)").arg(Vec3f(color).toStr())); + QSettings* conf = StelApp::getInstance().getSettings(); conf->setValue("init_location/last_location", QString("%1, %2").arg(latitude).arg(longitude)); } @@ -1162,7 +1170,7 @@ void StelLocationMgr::changeLocationFromNetworkLookup() { qDebug() << "Failure getting IP-based location: answer is in not acceptable format! Error: " << e.what() << "\nLet's use Paris, France as default location..."; - core->moveObserverTo(getLastResortLocation(), 0.0, 0.0); // Answer is not in JSON format! A possible block by DNS server or firewall + core->moveObserverTo(getLastResortLocation(), 0.0, 0.0, "guereins"); // Answer is not in JSON format! A possible block by DNS server or firewall } } else @@ -1173,7 +1181,7 @@ void StelLocationMgr::changeLocationFromNetworkLookup() networkReply->deleteLater(); } -LocationMap StelLocationMgr::pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees) +LocationMap StelLocationMgr::pickLocationsNearby(const QString &planetName, const float longitude, const float latitude, const float radiusDegrees) { QMap results; QMapIterator iter(locations); @@ -1190,7 +1198,7 @@ LocationMap StelLocationMgr::pickLocationsNearby(const QString planetName, const return results; } -LocationMap StelLocationMgr::pickLocationsInRegion(const QString region) +LocationMap StelLocationMgr::pickLocationsInRegion(const QString ®ion) { QMap results; QMapIterator iter(locations); @@ -1324,13 +1332,13 @@ QStringList StelLocationMgr::getRegionNames(const QString& planet) const return allregions; } -QString StelLocationMgr::pickRegionFromCountryCode(const QString countryCode) +QString StelLocationMgr::pickRegionFromCountryCode(const QString &countryCode) { QMap::ConstIterator i = countryCodeToRegionMap.find(countryCode); return (i!=countryCodeToRegionMap.constEnd()) ? i.value() : QString(); } -QString StelLocationMgr::pickRegionFromCountry(const QString country) +QString StelLocationMgr::pickRegionFromCountry(const QString &country) { QMap::ConstIterator i = countryNameToCodeMap.find(country); QString code = (i!=countryNameToCodeMap.constEnd()) ? i.value() : QString(); @@ -1556,3 +1564,38 @@ QStringList StelLocationMgr::getAllTimezoneNames() const ret.sort(); return ret; } + +// To be connected from StelCore::locationChanged(loc) +void StelLocationMgr::changePlanetMapForLocation(StelLocation loc) +{ + if (loc.planetName==planetName) + return; + + planetName=loc.planetName; + if (planetName=="Earth") + planetSurfaceMap=QImage(":/graphicGui/miscWorldMap.jpg"); + else + { + SolarSystem *ssm=GETSTELMODULE(SolarSystem); + PlanetP p=ssm->searchByEnglishName(loc.planetName); // nullptr for "SpaceShip" transitions + QString mapName="textures/" + (p ? p->getTextMapName() : planetName) + ".png"; + + if (!planetSurfaceMap.load(StelFileMgr::findFile(mapName, StelFileMgr::File))) + { + // texture not found. Use a gray pixel. + planetSurfaceMap=QImage(16,16,QImage::Format_RGB32); + planetSurfaceMap.fill(QColor(64, 64, 64)); + } + } +} + +QColor StelLocationMgr::getColorForCoordinates(const double lng, const double lat) const +{ + QPoint imgPoint( (lng+180.)/ 360. * planetSurfaceMap.width(), + (90.-lat) / 180. * planetSurfaceMap.height()); + + // Sample the map pixel color. Use a small box to avoid 1-pixel surprises. + QImage sampledPix=planetSurfaceMap.copy(QRect(imgPoint-QPoint(1,1), QSize(2,2))).scaled(1,1); + return sampledPix.pixelColor(0,0); + +} diff --git a/src/core/StelLocationMgr.hpp b/src/core/StelLocationMgr.hpp index b5690bcbed307..c3674660b1586 100644 --- a/src/core/StelLocationMgr.hpp +++ b/src/core/StelLocationMgr.hpp @@ -24,6 +24,7 @@ #include #include #include +#include #ifdef Q_OS_WIN #include #endif @@ -91,17 +92,17 @@ class StelLocationMgr : public QObject bool deleteUserLocation(const QString& id); //! Find list of locations within @param radiusDegrees of selected (usually screen-clicked) coordinates. - LocationMap pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees); + LocationMap pickLocationsNearby(const QString& planetName, const float longitude, const float latitude, const float radiusDegrees); //! Find list of locations in a particular region only. - LocationMap pickLocationsInRegion(const QString region); + LocationMap pickLocationsInRegion(const QString& region); //! return a QStringList of region names by planet (return all list of regions if planet name is empty) QStringList getRegionNames(const QString& planet = "") const; //! Pick region name from ISO 3166-1 two-letter country codes - static QString pickRegionFromCountryCode(const QString countryCode); + static QString pickRegionFromCountryCode(const QString& countryCode); //! Pick region name from country English name - static QString pickRegionFromCountry(const QString country); + static QString pickRegionFromCountry(const QString& country); //! Pick region name from region code static QString pickRegionFromCode(int regionCode); @@ -136,6 +137,9 @@ public slots: //! return a QStringList of valid timezone names in Stellarium's location database. QStringList getAllTimezoneNames() const; + //! Retrieve a color from coordinate lookup into the current planet texture (or specialized earth map) + QColor getColorForCoordinates(const double lng, const double lat) const; + #ifdef ENABLE_GPS //! Try to get a location from GPS lookup. //! This prefers GPSD on non-Windows platforms, and uses Qt positioning with a NMEA serial device otherwise @@ -171,6 +175,8 @@ public slots: private slots: //! Process answer from online lookup of IP address void changeLocationFromNetworkLookup(); + //! To be connected from StelCore::locationChanged(loc) + void changePlanetMapForLocation(StelLocation loc); #ifdef ENABLE_GPS void changeLocationFromGPSQuery(const StelLocation& loc); void gpsQueryError(const QString& err); @@ -206,6 +212,12 @@ private slots: StelLocation lastResortLocation; + //! Used to sample a color from our current planet's surface map. + //! This must be kept in-sync with the map shown in the LocationDialog. + QImage planetSurfaceMap; + //! Auxiliary to the surface map. This tracks whether we actually have to load a new image. + QString planetName; + GPSLookupHelper *nmeaHelper,*libGpsHelper; #ifdef Q_OS_WIN QGeoPositionInfoSource *positionSource=Q_NULLPTR; diff --git a/src/core/StelObject.cpp b/src/core/StelObject.cpp index 557a48fc6a55f..a8522e08ca81d 100644 --- a/src/core/StelObject.cpp +++ b/src/core/StelObject.cpp @@ -27,6 +27,7 @@ #include "StelSkyDrawer.hpp" #include "RefractionExtinction.hpp" #include "StelLocation.hpp" +#include "StelObserver.hpp" #include "SolarSystem.hpp" #include "StelModuleMgr.hpp" #include "LandscapeMgr.hpp" @@ -360,6 +361,8 @@ QString StelObject::getCommonInfoString(const StelCore *core, const InfoStringGr { StelApp& app = StelApp::getInstance(); StelObjectMgr* omgr=GETSTELMODULE(StelObjectMgr); + const StelLocation currentLocation=core->getCurrentLocation(); + const bool onTransitionToNewLocation=core->getCurrentObserver()->isTraveling(); const bool withAtmosphere = core->getSkyDrawer()->getFlagHasAtmosphere(); const bool withDecimalDegree = app.getFlagShowDecimalDegrees(); const bool useSouthAzimuth = app.getFlagSouthAzimuthUsage(); @@ -702,12 +705,13 @@ QString StelObject::getCommonInfoString(const StelCore *core, const InfoStringGr } res += getExtraInfoStrings(flags&SiderealTime).join(""); res += omgr->getExtraInfoStrings(flags&SiderealTime).join(""); - if (withTables && !(flags&RTSTime && getType()!=QStringLiteral("Satellite"))) + if (withTables && !(flags&RTSTime && !onTransitionToNewLocation && getType()!=QStringLiteral("Satellite") && currentLocation.role!='o')) res += ""; } - if (flags&RTSTime && getType()!=QStringLiteral("Satellite") && !currentPlanet.contains("observer", Qt::CaseInsensitive) && !(core->getCurrentLocation().name.contains("->"))) + if (flags&RTSTime && getType()!=QStringLiteral("Satellite") && currentLocation.role!='o' && !onTransitionToNewLocation) { + const bool isSun = (getEnglishName()=="Sun"); const double currentJD = core->getJD(); const double utcShift = core->getUTCOffset(currentJD) / 24.; // Fix DST shift... Vec4d rts = getRTSTime(core); @@ -717,7 +721,6 @@ QString StelObject::getCommonInfoString(const StelCore *core, const InfoStringGr const QString dash = QChar(0x2014); double sunrise = 0.; double sunset = 24.; - const bool isSun = (getEnglishName()=="Sun"); double hour(0); int year, month, day, currentdate; diff --git a/src/core/StelObjectMgr.hpp b/src/core/StelObjectMgr.hpp index 52f8c6f48abe8..d101bb956703a 100644 --- a/src/core/StelObjectMgr.hpp +++ b/src/core/StelObjectMgr.hpp @@ -124,7 +124,7 @@ class StelObjectMgr : public StelModule //! Get the list of objects which was recently selected by the user. const QList& getSelectedObject() const {return lastSelectedObjects;} - //! Return the list objects of type "withType" which was recently selected by the user. + //! Return the list objects of type "type" which was recently selected by the user. //! @param type return only objects of the given type QList getSelectedObject(const QString& type) const; diff --git a/src/core/StelObserver.cpp b/src/core/StelObserver.cpp index 9cded37cf1ec9..3b1391395947e 100644 --- a/src/core/StelObserver.cpp +++ b/src/core/StelObserver.cpp @@ -234,9 +234,11 @@ Mat4d StelObserver::getRotEquatorialToVsop87(void) const return getHomePlanet()->getRotEquatorialToVsop87(); } +// The transit can be cut short by feeding atimeToGo, a value smaller than the transition time SpaceShipObserver::SpaceShipObserver(const StelLocation& startLoc, const StelLocation& target, double atransitSeconds, double atimeToGo) : StelObserver(startLoc), moveStartLocation(startLoc), moveTargetLocation(target), artificialPlanet(Q_NULLPTR), timeToGo(atimeToGo), transitSeconds(atransitSeconds) { + Q_ASSERT((atimeToGo<0) || (atimeToGo>=0 && atimeToGo<=atransitSeconds)); if(timeToGo<0.0) timeToGo = transitSeconds; @@ -262,6 +264,13 @@ SpaceShipObserver::SpaceShipObserver(const StelLocation& startLoc, const StelLoc artificialPlanet = QSharedPointer(artPlanet); } planet = targetPlanet; + // avoid confusion with debug messages... + currentLocation.region=QString(); + currentLocation.state=QString(); + currentLocation.isUserLocation=true; + currentLocation.role='X'; + currentLocation.landscapeKey=moveTargetLocation.landscapeKey; + currentLocation.ianaTimeZone=moveTargetLocation.ianaTimeZone; } SpaceShipObserver::~SpaceShipObserver() @@ -273,6 +282,7 @@ SpaceShipObserver::~SpaceShipObserver() bool SpaceShipObserver::update(double deltaTime) { if (timeToGo <= 0.) return false; // Already over. + if (deltaTime==0.) return false; timeToGo -= deltaTime; SolarSystem* ss = GETSTELMODULE(SolarSystem); @@ -281,21 +291,6 @@ bool SpaceShipObserver::update(double deltaTime) { timeToGo = 0.; currentLocation = moveTargetLocation; - LandscapeMgr* lmgr = GETSTELMODULE(LandscapeMgr); - - // we have to avoid auto-select landscape in case the selected new landscape is on our target planet (true if landscape sets location). (LP:#1700199) - if ( (lmgr->getFlagLandscapeAutoSelection()) && !(lmgr->getFlagLandscapeSetsLocation()) ) - { - QString pType = ss->getPlanetType(currentLocation.planetName); - // If we have a landscape for target planet then set it or check and use - // landscape type of target planet, otherwise use default landscape - if (lmgr->getAllLandscapeNames().indexOf(currentLocation.planetName)>0) - lmgr->setCurrentLandscapeName(currentLocation.planetName); - else if (lmgr->getAllLandscapeIDs().indexOf(pType)>0) - lmgr->setCurrentLandscapeID(pType); - else - lmgr->setCurrentLandscapeID(lmgr->getDefaultLandscapeID()); - } } else { @@ -314,7 +309,7 @@ bool SpaceShipObserver::update(double deltaTime) const float moveToMult = 1.f-static_cast(timeToGo/transitSeconds); currentLocation.setLatitude( moveStartLocation.getLatitude() - moveToMult*(moveStartLocation.getLatitude()-moveTargetLocation.getLatitude())); currentLocation.setLongitude(moveStartLocation.getLongitude() - moveToMult*(moveStartLocation.getLongitude()-moveTargetLocation.getLongitude())); - currentLocation.altitude = int(moveStartLocation.altitude - moveToMult*(moveStartLocation.altitude-moveTargetLocation.altitude)); + currentLocation.altitude = int(moveStartLocation.altitude - moveToMult*(moveStartLocation.altitude-moveTargetLocation.altitude)); } return true; } diff --git a/src/core/StelObserver.hpp b/src/core/StelObserver.hpp index fe0fa85c3c0ec..205b20dc3f9af 100644 --- a/src/core/StelObserver.hpp +++ b/src/core/StelObserver.hpp @@ -92,14 +92,14 @@ class SpaceShipObserver : public StelObserver Q_OBJECT public: SpaceShipObserver(const StelLocation& startLoc, const StelLocation& target, double transitSeconds=1., double timeToGo=-1.0); - ~SpaceShipObserver() Q_DECL_OVERRIDE; - - //! Update StelObserver info if needed. Default implementation does nothing. - virtual bool update(double deltaTime) Q_DECL_OVERRIDE; - virtual const QSharedPointer getHomePlanet() const Q_DECL_OVERRIDE; - virtual bool isObserverLifeOver() const Q_DECL_OVERRIDE {return timeToGo <= 0.;} - virtual bool isTraveling() const Q_DECL_OVERRIDE {return !isObserverLifeOver();} - virtual StelObserver* getNextObserver() const Q_DECL_OVERRIDE {return new StelObserver(moveTargetLocation);} + ~SpaceShipObserver() override; + + //! Update StelObserver info. This advances the position in "flight" (simple transition) towards target + bool update(double deltaTime) override; + const QSharedPointer getHomePlanet() const override; + bool isObserverLifeOver() const override {return timeToGo <= 0.;} + bool isTraveling() const override {return !isObserverLifeOver();} + StelObserver* getNextObserver() const override {return new StelObserver(moveTargetLocation);} //! Returns the target location StelLocation getTargetLocation() const { return moveTargetLocation; } diff --git a/src/core/modules/AtmospherePreetham.hpp b/src/core/modules/AtmospherePreetham.hpp index e0bf30c5e421c..1c028f4ea4c51 100644 --- a/src/core/modules/AtmospherePreetham.hpp +++ b/src/core/modules/AtmospherePreetham.hpp @@ -53,7 +53,7 @@ class AtmospherePreetham : public Atmosphere void update(double deltaTime) {fader.update(static_cast(deltaTime*1000));} bool isLoading() const override { return false; } bool isReadyToRender() const override { return true; } - LoadingStatus stepDataLoading() override { return {0,0}; } + LoadingStatus stepDataLoading() override { return {1,1}; } private: Vec4i viewport; diff --git a/src/core/modules/Landscape.cpp b/src/core/modules/Landscape.cpp index 006837d339c2e..31be95d053a8d 100644 --- a/src/core/modules/Landscape.cpp +++ b/src/core/modules/Landscape.cpp @@ -1486,6 +1486,11 @@ float LandscapePolygonal::getOpacity(Vec3d azalt) const if (horizonPolygon->contains(azalt)) return 1.0f; else return 0.0f; } +void LandscapePolygonal::setGroundColor(const Vec3f &color) +{ + groundColor=color; +} + //////////////////////////////////////////////////////////////////////////////////////// // LandscapeFisheye // diff --git a/src/core/modules/Landscape.hpp b/src/core/modules/Landscape.hpp index ba717f9fac401..ecab09de56666 100644 --- a/src/core/modules/Landscape.hpp +++ b/src/core/modules/Landscape.hpp @@ -393,6 +393,8 @@ class LandscapePolygonal : public Landscape virtual void load(const QSettings& landscapeIni, const QString& landscapeId) Q_DECL_OVERRIDE; virtual void draw(StelCore* core, bool onlyPolygon) Q_DECL_OVERRIDE; virtual float getOpacity(Vec3d azalt) const Q_DECL_OVERRIDE; + // To allow ad-hoc "zero" landscapes with color from map + void setGroundColor(const Vec3f &color); private: // we have inherited: horizonFileName, horizonPolygon, horizonPolygonLineColor Vec3f groundColor; //! specified in landscape.ini[landscape]ground_color. diff --git a/src/core/modules/LandscapeMgr.cpp b/src/core/modules/LandscapeMgr.cpp index 0b64bb3c997f1..0d3df1ff33583 100644 --- a/src/core/modules/LandscapeMgr.cpp +++ b/src/core/modules/LandscapeMgr.cpp @@ -422,7 +422,7 @@ void LandscapeMgr::update(double deltaTime) // Use no more than 1/60th of a second for this batch of loading QElapsedTimer timer; timer.start(); - Atmosphere::LoadingStatus status; + Atmosphere::LoadingStatus status={1,1}; while(loadingAtmosphere->isLoading() && timer.elapsed() < 1000/60) status = loadingAtmosphere->stepDataLoading(); if(loadingAtmosphere->isLoading()) @@ -895,6 +895,12 @@ bool LandscapeMgr::setCurrentLandscapeID(const QString& id, const double changeL if(id==currentLandscapeID) return false; + if (!getAllLandscapeIDs().contains(id)) + { + qDebug() << "LandscapeMgr::setCurrentLandscapeID: unknown landscape" << id << ", using 'zero'"; + return setCurrentLandscapeID("zero", changeLocationDuration); + } + Landscape* newLandscape; // There is a slight chance that we switch back to oldLandscape while oldLandscape is still fading away. @@ -1140,66 +1146,89 @@ void LandscapeMgr::onLocationChanged(const StelLocation &loc) { //this was previously logic in ViewDialog, but should really be on a non-GUI layer StelCore* core = StelApp::getInstance().getCore(); - float lum; - if (!loc.planetName.contains("Earth")) // location not on Earth... - lum = 0; - else if(loc.lightPollutionLuminance.isValid()) - lum = loc.lightPollutionLuminance.toFloat(); - else // ...or it is an observatory, or it is an unknown location - lum = loc.DEFAULT_LIGHT_POLLUTION_LUMINANCE; - + float lum=0.; // location not on Earth... + if (loc.planetName.contains("Earth")) + { + if(loc.lightPollutionLuminance.isValid()) + lum = loc.lightPollutionLuminance.toFloat(); + else // ...or it is an observatory, or it is an unknown location + lum = loc.DEFAULT_LIGHT_POLLUTION_LUMINANCE; + } core->getSkyDrawer()->setLightPollutionLuminance(lum); } } +// Load landscapeID, but do not load its associated location. +// If landscapeID is empty but flagLandscapeAutoSelection is true, load a location fitting to loc's planet. void LandscapeMgr::onTargetLocationChanged(const StelLocation &loc, const QString& landscapeID) { -// if (loc.planetName != currentPlanetName) + //qDebug() << "LandscapeMgr::onTargetLocationChanged:" << loc.serializeToLine().replace('\t', '|') << "Landscape requested:" << landscapeID; + if (!landscapeID.isEmpty() && getAllLandscapeIDs().contains(landscapeID)) { - if (!landscapeID.isEmpty()) - setCurrentLandscapeID(landscapeID); - else if (flagLandscapeAutoSelection) - { - // If we have a landscape for selected planet then set it, otherwise use zero horizon landscape - const bool landscapeSetsLocation = getFlagLandscapeSetsLocation(); - setFlagLandscapeSetsLocation(false); - if (getAllLandscapeNames().indexOf(loc.planetName)>0) - setCurrentLandscapeName(loc.planetName); - else - setCurrentLandscapeID("zero"); - setFlagLandscapeSetsLocation(landscapeSetsLocation); - } - currentPlanetName = loc.planetName; + const bool landscapeSetsLocation = getFlagLandscapeSetsLocation(); + setFlagLandscapeSetsLocation(false); + setCurrentLandscapeID(landscapeID); + setFlagLandscapeSetsLocation(landscapeSetsLocation); + } + else if(landscapeID.startsWith("ZeroColor(")) + { + // Load a zero landscape and recolor it. + // This can happen when clicking on the map. The point on the map can be sampled for color (e.g., desert, greengrass, ocean blue, polar white, ...) + const bool landscapeSetsLocation = getFlagLandscapeSetsLocation(); + setFlagLandscapeSetsLocation(false); + setCurrentLandscapeID("zero"); + Vec3f color(0.3); + static const QRegularExpression zeroColor("^ZeroColor\\(([0-9].[0-9]+,[0-9].[0-9]+,[0-9].[0-9]+)\\)$"); + QRegularExpressionMatch match=zeroColor.match(landscapeID); + if (match.hasMatch()) + color=Vec3f(match.captured(1)); + else + qDebug() << "Cannot extract color from landscapeID" << landscapeID; + LandscapePolygonal *l=static_cast(landscape); + l->setGroundColor(color); + setFlagLandscapeSetsLocation(landscapeSetsLocation); + } + else if (flagLandscapeAutoSelection && (loc.planetName != currentPlanetName)) + { + //qDebug() << "landscapeID empty. Try planet name" << loc.planetName << "or zero"; + // If we have a landscape for selected planet then set it, otherwise use zero horizon landscape + const bool landscapeSetsLocation = getFlagLandscapeSetsLocation(); + setFlagLandscapeSetsLocation(false); + if (getAllLandscapeNames().indexOf(loc.planetName)>0) + setCurrentLandscapeName(loc.planetName); + else + setCurrentLandscapeID("zero"); + setFlagLandscapeSetsLocation(landscapeSetsLocation); + } - if (loc.role==QChar('o')) // observer? + if (loc.role==QChar('o')) // observer? + { + if (flagEnvironmentAutoEnabling) { - if (flagEnvironmentAutoEnabling) - { - setFlagAtmosphere(false); - setFlagFog(false); - setFlagLandscape(false); - setFlagCardinalPoints(false); - //setFlagOrdinalsPoints(false); - //setFlagOrdinals16WRPoints(false); - } + setFlagAtmosphere(false); + setFlagFog(false); + setFlagLandscape(false); + setFlagCardinalPoints(false); // suppresses all } - else + } + else + { + SolarSystem* ssystem = static_cast(StelApp::getInstance().getModuleMgr().getModule("SolarSystem")); + PlanetP pl = ssystem->searchByEnglishName(loc.planetName); + if (pl && flagEnvironmentAutoEnabling && currentPlanetName!=loc.planetName) { - SolarSystem* ssystem = static_cast(StelApp::getInstance().getModuleMgr().getModule("SolarSystem")); - PlanetP pl = ssystem->searchByEnglishName(loc.planetName); - if (pl && flagEnvironmentAutoEnabling) - { - QSettings* conf = StelApp::getInstance().getSettings(); - setFlagAtmosphere(pl->hasAtmosphere() && conf->value("landscape/flag_atmosphere", true).toBool()); - setFlagFog(pl->hasAtmosphere() && conf->value("landscape/flag_fog", true).toBool()); - setFlagLandscape(true); - setFlagCardinalPoints(conf->value("viewing/flag_cardinal_points", true).toBool()); - setFlagOrdinalPoints(conf->value("viewing/flag_ordinal_points", true).toBool()); - setFlagOrdinal16WRPoints(conf->value("viewing/flag_16wcr_points", false).toBool()); - setFlagOrdinal32WRPoints(conf->value("viewing/flag_32wcr_points", false).toBool()); - } + QSettings* conf = StelApp::getInstance().getSettings(); + setFlagAtmosphere(pl->hasAtmosphere() && conf->value("landscape/flag_atmosphere", true).toBool()); + setFlagFog(pl->hasAtmosphere() && conf->value("landscape/flag_fog", true).toBool()); + setFlagLandscape(conf->value("landscape/flag_landscape", true).toBool()); + setFlagCardinalPoints(conf->value("viewing/flag_cardinal_points", true).toBool()); + setFlagOrdinalPoints(conf->value("viewing/flag_ordinal_points", true).toBool()); + setFlagOrdinal16WRPoints(conf->value("viewing/flag_16wcr_points", false).toBool()); + setFlagOrdinal32WRPoints(conf->value("viewing/flag_32wcr_points", false).toBool()); } } + currentPlanetName = loc.planetName; + //qDebug() << "LandscapeMgr::onTargetLocationChanged done" ; } void LandscapeMgr::setFlagFog(const bool displayed) diff --git a/src/core/modules/LandscapeMgr.hpp b/src/core/modules/LandscapeMgr.hpp index 5c402e0e22291..3a10ad45889e8 100644 --- a/src/core/modules/LandscapeMgr.hpp +++ b/src/core/modules/LandscapeMgr.hpp @@ -149,7 +149,9 @@ class LandscapeMgr : public StelModule WRITE setAtmosphereModelPath NOTIFY atmosphereModelPathChanged) Q_PROPERTY(QString defaultAtmosphereModelPath - READ getDefaultAtmosphereModelPath) + READ getDefaultAtmosphereModelPath + SCRIPTABLE false + CONSTANT) Q_PROPERTY(bool atmosphereShowMySkyStoppedWithError READ getAtmosphereShowMySkyStoppedWithError WRITE setAtmosphereShowMySkyStoppedWithError @@ -251,7 +253,8 @@ class LandscapeMgr : public StelModule WRITE setCurrentLandscapeID NOTIFY currentLandscapeChanged) Q_PROPERTY(QStringList allLandscapeNames - READ getAllLandscapeNames) + READ getAllLandscapeNames + NOTIFY landscapesChanged) Q_PROPERTY(QString currentLandscapeName READ getCurrentLandscapeName WRITE setCurrentLandscapeName @@ -736,8 +739,13 @@ public slots: private slots: //! Reacts to StelCore::locationChanged. + //! If flagLightPollutionFromDatabase is active, + //! this applies light pollution information from the new location void onLocationChanged(const StelLocation &loc); - //! To be connected to StelCore::targetLocationChanged + //! To be connected to StelCore::targetLocationChanged. + //! This sets landscape with landscapeID. + //! If that is empty and flagLandscapeAutoSelection==true, set a landscape fitting to loc's planet. + //! Does not set loc itself! void onTargetLocationChanged(const StelLocation &loc, const QString &landscapeID); //! Translate labels to new language settings. @@ -779,13 +787,14 @@ private slots: QString messageToShow; QTimer* messageTimer = nullptr; - // Define whether the observer location is to be updated when the landscape is updated. + //! Define whether the observer location is to be updated when the landscape is updated and includes location info. bool flagLandscapeSetsLocation; + //! Define whether on location change onto another planet a landscape for the new planet shall be loaded. bool flagLandscapeAutoSelection; bool flagLightPollutionFromDatabase; - bool atmosphereNoScatter; // true to suppress actual blue-sky rendering but keep refraction & extinction + bool atmosphereNoScatter; //!< true to suppress actual blue-sky rendering but keep refraction & extinction //! control drawing of a Polygonal line, if one is defined. bool flagPolyLineDisplayedOnly; diff --git a/src/core/modules/Planet.cpp b/src/core/modules/Planet.cpp index 8aa8f1f531dfe..1e9d3e94365b7 100644 --- a/src/core/modules/Planet.cpp +++ b/src/core/modules/Planet.cpp @@ -952,7 +952,7 @@ QString Planet::getInfoStringPeriods(const StelCore *core, const InfoStringGroup Vec4d Planet::getHourlyProperMotion(const StelCore *core) const { - if (core->getCurrentObserver()->isObserverLifeOver()) + if (core->getCurrentObserver()->isTraveling()) return Vec4d(0.); else { @@ -1184,6 +1184,9 @@ SolarEclipseData::SolarEclipseData(double JD, double &dRatio, double &latDeg, QString Planet::getInfoStringExtra(const StelCore *core, const InfoStringGroup& flags) const { + if (core->getCurrentObserver()->isTraveling()) // transition to elsewhere: report nothing. + return QString(); + QString str; QTextStream oss(&str); @@ -1936,6 +1939,20 @@ QVector Planet::getCandidatesForShadow() const void Planet::computePosition(const double dateJDE, const Vec3d &aberrationPush) { + // Having hundreds of Minor Planets makes this very slow. Especially on transitions between locations (StelCore::moveObserverTo()) + // it seems acceptable to disable position updates for minor bodies. + // TODO: Maybe test for target location and allow updates in this case. + StelCore *core=StelApp::getInstance().getCore(); + bool isTransitioning=false; + if (core) + { + const StelObserver *obs=core->getCurrentObserver(); + if (obs) + isTransitioning=obs->isTraveling(); + } + if (isTransitioning && orbitPtr) + return; + if (fabs(lastJDE-dateJDE)>deltaJDE) { coordFunc(dateJDE, eclipticPos, eclipticVelocity, orbitPtr); @@ -5006,11 +5023,11 @@ void Planet::setApparentMagnitudeAlgorithm(QString algorithm) // NOTE: Limitation for efficiency: If this is a planet moon from another planet, we compute RTS for the parent planet instead! Vec4d Planet::getClosestRTSTime(const StelCore *core, const double altitude) const { - const StelLocation loc=core->getCurrentLocation(); - if (loc.name.contains("->")) // a spaceship + if (core->getCurrentObserver()->isTraveling()) // transition to elsewhere return Vec4d(0., 0., 0., -1000.); // Keep time in sync (method from line 592) to fix slow down of time when the moon is selected + const StelLocation loc=core->getCurrentLocation(); const double currentJD = core->getJDOfLastJDUpdate(); const qint64 millis = core->getMilliSecondsOfLastJDUpdate(); const double currentJDE = core->getJDE(); @@ -5338,6 +5355,10 @@ Vec4d Planet::getClosestRTSTime(const StelCore *core, const double altitude) con Vec4d Planet::getRTSTime(const StelCore *core, const double altitude) const { + // During transitions, return invalid results and save lots of time. + if (core->getCurrentObserver()->isTraveling()) + return Vec4d(0., 0., 0., -1000.); + // Keep time in sync (method from line 592) to fix slow down of time when the moon is selected const double currentJD = core->getJDOfLastJDUpdate(); const qint64 millis = core->getMilliSecondsOfLastJDUpdate(); diff --git a/src/gui/AstroCalcDialog.cpp b/src/gui/AstroCalcDialog.cpp index 3f12b1896b830..f1e785bd8c66c 100644 --- a/src/gui/AstroCalcDialog.cpp +++ b/src/gui/AstroCalcDialog.cpp @@ -28,6 +28,7 @@ #include "StelUtils.hpp" #include "StelTranslator.hpp" #include "StelLocaleMgr.hpp" +#include "StelLocationMgr.hpp" #include "StelFileMgr.hpp" #include "AngleSpinBox.hpp" #include "SolarSystem.hpp" @@ -362,6 +363,8 @@ void AstroCalcDialog::createDialogContent() connect(objectMgr, SIGNAL(selectedObjectChanged(StelModule::StelModuleSelectAction)), this, SLOT(setRTSCelestialBodyName())); // Tab: Eclipses + ui->eclipseYearsSpinBox->setValue(conf->value("astrocalc/eclipse_future_years", 10).toInt()); + connect(ui->eclipseYearsSpinBox, QOverload::of(&QSpinBox::valueChanged), this, [=](int val){conf->setValue("astrocalc/eclipse_future_years", val);}); // Make that a permanent decision. initListLunarEclipse(); enableLunarEclipsesButtons(buttonState); connect(ui->lunareclipsesCalculateButton, SIGNAL(clicked()), this, SLOT(generateLunarEclipses())); @@ -1041,10 +1044,10 @@ void AstroCalcDialog::saveCelestialPositionsCategory(int index) currentCelestialPositions(); } -void AstroCalcDialog::fillCelestialPositionTable(QString objectName, QString RA, QString Dec, double magnitude, - QString angularSize, QString angularSizeToolTip, QString extraData, - QString extraDataToolTip, QString transitTime, QString maxElevation, - QString sElongation, QString objectType) +void AstroCalcDialog::fillCelestialPositionTable(const QString &objectName, const QString &RA, const QString &Dec, double magnitude, + const QString &angularSize, const QString &angularSizeToolTip, const QString &extraData, + const QString &extraDataToolTip, const QString &transitTime, const QString &maxElevation, + QString &sElongation, const QString &objectType) { ACCelPosTreeWidgetItem* treeItem = new ACCelPosTreeWidgetItem(ui->celestialPositionsTreeWidget); treeItem->setText(CColumnName, objectName); @@ -1468,7 +1471,7 @@ QString AstroCalcDialog::getSelectedObjectNameI18n(StelObjectP selectedObject) return name; } -void AstroCalcDialog::fillHECPositionTable(QString objectName, QChar objectSymbol, QString latitude, QString longitude, double distance) +void AstroCalcDialog::fillHECPositionTable(const QString &objectName, const QChar objectSymbol, const QString &latitude, const QString &longitude, const double distance) { AHECPosTreeWidgetItem* treeItem = new AHECPosTreeWidgetItem(ui->hecPositionsTreeWidget); treeItem->setText(HECColumnName, objectName); @@ -1576,7 +1579,7 @@ void AstroCalcDialog::currentHECPositions() drawHECGraph(); } -void AstroCalcDialog::drawHECGraph(QString selectedObject) +void AstroCalcDialog::drawHECGraph(const QString &selectedObject) { QScatterSeries *seriesPlanets = new QScatterSeries(); QScatterSeries *seriesSelectedPlanet = new QScatterSeries(); @@ -1717,25 +1720,7 @@ void AstroCalcDialog::selectCurrentEphemeride(const QModelIndex& modelIndex) // Find the object const QString name = modelIndex.sibling(modelIndex.row(), EphemerisCOName).data(Qt::UserRole).toString(); const double JD = modelIndex.sibling(modelIndex.row(), EphemerisDate).data(Qt::UserRole).toDouble(); - - if (objectMgr->findAndSelectI18n(name) || objectMgr->findAndSelect(name)) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + goToObject(name, JD); } void AstroCalcDialog::setEphemerisHeaderNames() @@ -2272,27 +2257,9 @@ void AstroCalcDialog::cleanupRTS() void AstroCalcDialog::selectCurrentRTS(const QModelIndex& modelIndex) { // Find the object - QString name = modelIndex.sibling(modelIndex.row(), RTSCOName).data(Qt::UserRole).toString(); - double JD = modelIndex.sibling(modelIndex.row(), RTSTransitDate).data(Qt::UserRole).toDouble(); - - if (objectMgr->findAndSelectI18n(name) || objectMgr->findAndSelect(name)) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + const QString name = modelIndex.sibling(modelIndex.row(), RTSCOName).data(Qt::UserRole).toString(); + const double JD = modelIndex.sibling(modelIndex.row(), RTSTransitDate).data(Qt::UserRole).toDouble(); + goToObject(name, JD); } void AstroCalcDialog::setRTSCelestialBodyName() @@ -2475,23 +2442,18 @@ LunarEclipseParameters lunarEclipseContacts(double JD, bool beforeMaximum, int e const double ydot = (y2 - y1) * 6.; const double n2 = xdot*xdot+ydot*ydot; const double delta = (x*ydot-y*xdot)/sqrt(n2); - double dt = -(x*xdot+y*ydot)/n2; - double semiDuration = sqrt((L*L-delta*delta)/n2); + const double semiDuration = sqrt((L*L-delta*delta)/n2); + result.dt = -(x*xdot+y*ydot)/n2; if (beforeMaximum) - dt-=semiDuration; + result.dt-=semiDuration; else - dt+=semiDuration; + result.dt+=semiDuration; - double positionAngle = atan2(x, y); - if (positionAngle<0) positionAngle += 2.*M_PI; - double axisDistance = sqrt(x*x+y*y)*M_PI_180/3600.; + result.positionAngle = StelUtils::fmodpos(atan2(x, y), 2.*M_PI); + result.axisDistance = sqrt(x*x+y*y)*M_PI_180/3600.; core->setJD(JD); core->update(0); - result.dt = dt; - result.positionAngle = positionAngle; - result.axisDistance = axisDistance; - return result; } @@ -2737,72 +2699,49 @@ LunarEclipseIteration::LunarEclipseIteration(double &JD, double &positionAngle, void AstroCalcDialog::selectCurrentLunarEclipseDate(const QModelIndex& modelIndex) { - double JDMid = modelIndex.sibling(modelIndex.row(), LunarEclipseDate).data(Qt::UserRole).toDouble(); - if (objectMgr->findAndSelectI18n("Moon") || objectMgr->findAndSelect("Moon")) - { - core->setJD(JDMid); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + const double JDMid = modelIndex.sibling(modelIndex.row(), LunarEclipseDate).data(Qt::UserRole).toDouble(); + goToObject("Moon", JDMid); } void AstroCalcDialog::selectCurrentLunarEclipse(const QModelIndex& modelIndex) { initListLunarEclipseContact(); const bool saveTopocentric = core->getUseTopocentricCoordinates(); - double currentJD = core->getJD(); + const double currentJD = core->getJD(); static SolarSystem* ssystem = GETSTELMODULE(SolarSystem); PlanetP moon = ssystem->getMoon(); const bool useSouthAzimuth = StelApp::getInstance().getFlagSouthAzimuthUsage(); const bool withDecimalDegree = StelApp::getInstance().getFlagShowDecimalDegrees(); - QPair coordStrings; - QString altitudeStr, azimuthStr, positionAngleStr, distanceStr, latitudeStr, longitudeStr; - double JDMid = modelIndex.sibling(modelIndex.row(), LunarEclipseDate).data(Qt::UserRole).toDouble(); - double uMag = modelIndex.sibling(modelIndex.row(), LunarEclipseUMag).data(Qt::UserRole).toDouble(); - double JD = JDMid; + const double JDMid = modelIndex.sibling(modelIndex.row(), LunarEclipseDate).data(Qt::UserRole).toDouble(); + const double uMag = modelIndex.sibling(modelIndex.row(), LunarEclipseUMag).data(Qt::UserRole).toDouble(); // Compute time and other data of contacts - double x,y,L1,L2,L3,latitude,longitude, positionAngle=0, axisDistance=0; - bool event = false; LunarEclipseParameters eclipseData; for (int i = 0; i < 7; i++) { + double x,y,L1,L2,L3,latitude,longitude, positionAngle=0, axisDistance=0; + bool event = false; + double JD = JDMid; if (i==0) { - JD = JDMid; LunarEclipseIteration(JD,positionAngle,axisDistance,true,0); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); event = true; } else if (i==1 && uMag>0.) { - JD = JDMid; LunarEclipseIteration(JD,positionAngle,axisDistance,true,1); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); event = true; } else if (i==2 && uMag>=1.) { - JD = JDMid; LunarEclipseIteration(JD,positionAngle,axisDistance,true,2); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); event = true; } else if (i==3) { - JD = JDMid; eclipseData = lunarEclipseContacts(JD,true,2); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); positionAngle = eclipseData.positionAngle; @@ -2811,21 +2750,18 @@ void AstroCalcDialog::selectCurrentLunarEclipse(const QModelIndex& modelIndex) } else if (i==4 && uMag>=1.) { - JD = JDMid; LunarEclipseIteration(JD,positionAngle,axisDistance,false,2); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); event = true; } else if (i==5 && uMag>0.) { - JD = JDMid; LunarEclipseIteration(JD,positionAngle,axisDistance,false,1); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); event = true; } else if (i==6) { - JD = JDMid; LunarEclipseIteration(JD,positionAngle,axisDistance,false,0); LunarEclipseBessel(x,y,L1,L2,L3,latitude,longitude); event = true; @@ -2833,30 +2769,15 @@ void AstroCalcDialog::selectCurrentLunarEclipse(const QModelIndex& modelIndex) if (event) { ACLunarEclipseContactsTreeWidgetItem* treeItem = new ACLunarEclipseContactsTreeWidgetItem(ui->lunareclipsecontactsTreeWidget); - switch (i) - { - case 0: - treeItem->setText(LunarEclipseContact, QString(q_("Moon enters penumbra"))); - break; - case 1: - treeItem->setText(LunarEclipseContact, QString(q_("Moon enters umbra"))); - break; - case 2: - treeItem->setText(LunarEclipseContact, QString(q_("Total eclipse begins"))); - break; - case 3: - treeItem->setText(LunarEclipseContact, QString(q_("Maximum eclipse"))); - break; - case 4: - treeItem->setText(LunarEclipseContact, QString(q_("Total eclipse ends"))); - break; - case 5: - treeItem->setText(LunarEclipseContact, QString(q_("Moon leaves umbra"))); - break; - case 6: - treeItem->setText(LunarEclipseContact, QString(q_("Moon leaves penumbra"))); - break; - } + QStringList events={ + q_("Moon enters penumbra"), + q_("Moon enters umbra"), + q_("Total eclipse begins"), + q_("Maximum eclipse"), + q_("Total eclipse ends"), + q_("Moon leaves umbra"), + q_("Moon leaves penumbra")}; + treeItem->setText(LunarEclipseContact, events.at(i)); treeItem->setText(LunarEclipseContactDate, QString("%1 %2").arg(localeMgr->getPrintableDateLocal(JD), localeMgr->getPrintableTimeLocal(JD))); treeItem->setData(LunarEclipseContactDate, Qt::UserRole, JD); core->setJD(JD); @@ -2864,21 +2785,22 @@ void AstroCalcDialog::selectCurrentLunarEclipse(const QModelIndex& modelIndex) core->update(0); double az, alt; StelUtils::rectToSphe(&az, &alt, moon->getAltAzPosAuto(core)); - coordStrings = getStringCoordinates(moon->getAltAzPosAuto(core), true, useSouthAzimuth, withDecimalDegree); - azimuthStr = coordStrings.first; - altitudeStr = coordStrings.second; + QPair coordStrings = getStringCoordinates(moon->getAltAzPosAuto(core), true, useSouthAzimuth, withDecimalDegree); + QString azimuthStr = coordStrings.first; + QString altitudeStr = coordStrings.second; treeItem->setText(LunarEclipseContactAltitude, altitudeStr); treeItem->setData(LunarEclipseContactAltitude, Qt::UserRole, alt); treeItem->setText(LunarEclipseContactAzimuth, azimuthStr); treeItem->setData(LunarEclipseContactAzimuth, Qt::UserRole, az); - latitudeStr = StelUtils::decDegToLatitudeStr(latitude, !withDecimalDegree); - longitudeStr = StelUtils::decDegToLongitudeStr(longitude, true, false, !withDecimalDegree); + QString latitudeStr = StelUtils::decDegToLatitudeStr(latitude, !withDecimalDegree); + QString longitudeStr = StelUtils::decDegToLongitudeStr(longitude, true, false, !withDecimalDegree); treeItem->setText(LunarEclipseContactLatitude, latitudeStr); treeItem->setData(LunarEclipseContactLatitude, Qt::UserRole, latitude); treeItem->setToolTip(LunarEclipseContactLatitude, q_("Geographic latitude where the Moon appears in the zenith")); treeItem->setText(LunarEclipseContactLongitude, longitudeStr); treeItem->setData(LunarEclipseContactLatitude, Qt::UserRole, longitude); treeItem->setToolTip(LunarEclipseContactLongitude, q_("Geographic longitude where the Moon appears in the zenith")); + QString positionAngleStr, distanceStr; if (withDecimalDegree) { positionAngleStr = StelUtils::radToDecDegStr(positionAngle, 3, false, true); @@ -2911,7 +2833,6 @@ void AstroCalcDialog::selectCurrentLunarEclipse(const QModelIndex& modelIndex) LunarEclipseContactLongitude, LunarEclipseContactPA, LunarEclipseContactDistance}) treeItem->setTextAlignment(column, Qt::AlignRight); } - event = false; } // adjust the column width @@ -2925,28 +2846,9 @@ void AstroCalcDialog::selectCurrentLunarEclipse(const QModelIndex& modelIndex) void AstroCalcDialog::selectCurrentLunarEclipseContact(const QModelIndex& modelIndex) { - double JD = modelIndex.sibling(modelIndex.row(), LunarEclipseContactDate).data(Qt::UserRole).toDouble(); - if (objectMgr->findAndSelectI18n("Moon") || objectMgr->findAndSelect("Moon")) - { - if (JD!=0) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } - } + const double JD = modelIndex.sibling(modelIndex.row(), LunarEclipseContactDate).data(Qt::UserRole).toDouble(); + if (JD!=0) + goToObject("Moon", JD); } void AstroCalcDialog::saveLunarEclipses() @@ -3094,16 +2996,13 @@ LocalSEparams localSolarEclipse(double JD,int contact,bool central) { if (ce > 0.) cfi = contact * std::sqrt(ce); const double m = sqrt(u * u + v * v); - const double magnitude = (L1 - m) / (L1 + L2); - const double altitude = std::asin(rc*std::cos(d)*std::cos(theta)+rs*std::sin(d))*M_180_PI; - const double dt = (L * cfi / std::sqrt(udot*udot + vdot*vdot)) - (u*udot + v*vdot)/n2; - result.dt = dt; + result.magnitude = (L1 - m) / (L1 + L2); + result.altitude = std::asin(rc*std::cos(d)*std::cos(theta)+rs*std::sin(d))*M_180_PI; + result.dt = (L * cfi / std::sqrt(udot*udot + vdot*vdot)) - (u*udot + v*vdot)/n2; result.L1 = L1; result.L2 = L2; result.ce = ce; - result.magnitude = magnitude; - result.altitude = altitude; return result; } @@ -3609,9 +3508,7 @@ void AstroCalcDialog::generateSolarEclipsesLocal() if (eclipseData.L2 < 0.) { eclipseTypeStr = qc_("Total", "eclipse type"); - JD = JD3; - JD3 = JD2; - JD2 = JD; + qSwap(JD2, JD3); } else eclipseTypeStr = qc_("Annular", "eclipse type"); @@ -3728,8 +3625,6 @@ void AstroCalcDialog::selectCurrentSolarEclipse(const QModelIndex& modelIndex) double JD = JDMid; // Compute time and other data of contacts - double dRatio,latDeg,lngDeg,altitude,pathWidth,duration,magnitude; - bool event = false; bool nonCentralEclipse = false; core->setJD(JD); core->update(0); @@ -3742,6 +3637,8 @@ void AstroCalcDialog::selectCurrentSolarEclipse(const QModelIndex& modelIndex) for (int i = 0; i < 5; i++) { + double dRatio,latDeg,lngDeg,altitude,pathWidth,duration,magnitude; + bool event = false; if (i==0) // P1 { JD = getJDofContact(JDMid,true,true,true,true); @@ -3911,7 +3808,6 @@ void AstroCalcDialog::selectCurrentSolarEclipse(const QModelIndex& modelIndex) treeItem->setTextAlignment(SolarEclipseContactType, Qt::AlignLeft); } ui->solareclipsecontactsTreeWidget->setColumnHidden(7,true); - event = false; } core->setJD(currentJD); core->setUseTopocentricCoordinates(saveTopocentric); @@ -3936,26 +3832,11 @@ void AstroCalcDialog::selectCurrentSolarEclipseContact(const QModelIndex& modelI const bool greatest = modelIndex.sibling(modelIndex.row(), SolarEclipseContact).data(Qt::UserRole).toBool(); StelLocation contactLoc(greatest ? q_("Greatest eclipse’s point") : q_("Eclipse’s contact point"), "", "", lon, lat, 10, 0, "LMST", 1, 'X'); - core->moveObserverTo(contactLoc, 0., 0., "zero"); // use a neutral horizon to avoid confusion. - - if (objectMgr->findAndSelectI18n(q_("Sun")) || objectMgr->findAndSelect("Sun")) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + // Find landscape color at the spot + StelLocationMgr* locationMgr = &StelApp::getInstance().getLocationMgr(); + QColor color=locationMgr->getColorForCoordinates(lon, lat); + core->moveObserverTo(contactLoc, 2., 2., QString("ZeroColor(%1)").arg(Vec3f(color).toStr())); // use a neutral horizon but environmental color to avoid confusion. + goToObject("Sun", JD); } void AstroCalcDialog::saveSolarEclipses() @@ -3983,43 +3864,27 @@ void AstroCalcDialog::selectCurrentSolarEclipseDate(const QModelIndex& modelInde const float lon = modelIndex.sibling(modelIndex.row(), SolarEclipseLongitude).data(Qt::UserRole).toFloat(); StelLocation maxLoc(q_("Greatest eclipse’s point"), "", "", lon, lat, 10, 0, "LMST", 1, 'X'); - core->moveObserverTo(maxLoc, 0., 0., "zero"); // use a neutral horizon to avoid confusion. - if (objectMgr->findAndSelectI18n(q_("Sun")) || objectMgr->findAndSelect("Sun")) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + qDebug() << "AstroCalcDialog::selectCurrentSolarEclipseDate(" << modelIndex; + qDebug() << "Moving to MaxLoc ..."; + // Find landscape color at the spot + StelLocationMgr* locationMgr = &StelApp::getInstance().getLocationMgr(); + QColor color=locationMgr->getColorForCoordinates(lon, lat); + core->moveObserverTo(maxLoc, 2., 2., QString("ZeroColor(%1)").arg(Vec3f(color).toStr())); // use a neutral horizon but environmental color to avoid confusion. + goToObject("Sun", JD); + qDebug() << "Moving to MaxLoc ... done"; } QPair AstroCalcDialog::getRiseSetLineCoordinates(bool first, double x,double y,double d,double L,double mu) { // Source: Explanatory Supplement to the Astronomical Ephemeris // and the American Ephemeris and Nautical Almanac (1961) - QPair coordinates; static SolarSystem* ssystem = GETSTELMODULE(SolarSystem); static const double f = 1.0 - ssystem->getEarth()->getOneMinusOblateness(); // flattening static const double ff = 1./(1.-f); - double m2 = x*x+y*y; - double cgm = (m2+1.-L*L)/(2.*std::sqrt(m2)); - if (std::abs(cgm)>1.) - { - coordinates.first = 99.; - coordinates.second = 0.; - } - else + const double m2 = x*x+y*y; + const double cgm = (m2+1.-L*L)/(2.*std::sqrt(m2)); + QPair coordinates(99., 0.); + if (std::abs(cgm)<=1.) { double gamma = std::acos(cgm)+std::atan2(x,y); if (!first) @@ -4044,46 +3909,34 @@ QPair AstroCalcDialog::getShadowOutlineCoordinates(double angle, { // Source: Explanatory Supplement to the Astronomical Ephemeris // and the American Ephemeris and Nautical Almanac (1961) - QPair coordinates; static SolarSystem* ssystem = GETSTELMODULE(SolarSystem); static const double f = 1.0 - ssystem->getEarth()->getOneMinusOblateness(); // flattening static const double e2 = f*(2.-f); static const double ff = 1./(1.-f); - double rho1 = std::sqrt(1.-e2*std::cos(d)*std::cos(d)); - double sd1 = std::sin(d)/rho1; - double cd1 = std::sqrt(1.-e2)*std::cos(d)/rho1; - double xi0 = x-L*std::sin(angle); - double eta0 = y-L*std::cos(angle); - double zeta0 = 1.-xi0*xi0-eta0*eta0; - if (zeta0 < 0) - { - coordinates.first = 99.; - coordinates.second = 0.; - } - else + const double rho1 = std::sqrt(1.-e2*std::cos(d)*std::cos(d)); + const double sd1 = std::sin(d)/rho1; + const double cd1 = std::sqrt(1.-e2)*std::cos(d)/rho1; + const double xi0 = x-L*std::sin(angle); + const double eta0 = y-L*std::cos(angle); + const double zeta0 = 1.-xi0*xi0-eta0*eta0; + + QPair coordinates(99., 0.); + if (zeta0 >= 0) { - double L1 = L-zeta0*tf; - double xi = x-L1*std::sin(angle); - double eta1 = (y-L1*std::cos(angle))/rho1; - double pp = 1.-xi*xi-eta1*eta1; - if (pp < 0) - { - coordinates.first = 99.; - coordinates.second = 0.; - } - else + const double L1 = L-zeta0*tf; + const double xi = x-L1*std::sin(angle); + const double eta1 = (y-L1*std::cos(angle))/rho1; + const double pp = 1.-xi*xi-eta1*eta1; + + if (pp >= 0) { - double zeta0 = std::sqrt(pp); - double L1 = L-zeta0*tf; - double xi = x-L1*std::sin(angle); - double eta1 = (y-L1*std::cos(angle))/rho1; - double pp = 1.-xi*xi-eta1*eta1; - if (pp < 0) - { - coordinates.first = 99.; - coordinates.second = 0.; - } - else + const double zeta0 = std::sqrt(pp); + const double L1 = L-zeta0*tf; + const double xi = x-L1*std::sin(angle); + const double eta1 = (y-L1*std::cos(angle))/rho1; + const double pp = 1.-xi*xi-eta1*eta1; + + if (pp >= 0) { double zeta1 = std::sqrt(pp); double b = -eta1*sd1+zeta1*cd1; @@ -4107,7 +3960,6 @@ QPair AstroCalcDialog::getMaximumEclipseAtRiseSet(bool first, do { // Source: Explanatory Supplement to the Astronomical Ephemeris // and the American Ephemeris and Nautical Almanac (1961) - QPair coordinates; static SolarSystem* ssystem = GETSTELMODULE(SolarSystem); static const double f = 1.0 - ssystem->getEarth()->getOneMinusOblateness(); // flattening static const double ff = 1./(1.-f); @@ -4121,19 +3973,20 @@ QPair AstroCalcDialog::getMaximumEclipseAtRiseSet(bool first, do double qa = std::atan2(bdot,cdot); if (!first) // there are two parts of the curve qa += M_PI; - double sgqa = x*std::cos(qa)-y*std::sin(qa); + const double sgqa = x*std::cos(qa)-y*std::sin(qa); + + QPair coordinates(99., 0.); if (std::abs(sgqa)<1.) { - double gqa = std::asin(sgqa); - double ga = gqa+qa; - double xxia = x-std::sin(ga); - double yetaa = y-std::cos(ga); + const double gqa = std::asin(sgqa); + const double ga = gqa+qa; + const double xxia = x-std::sin(ga); + const double yetaa = y-std::cos(ga); if (xxia*xxia+yetaa*yetaa < L1*L1) { double b = -std::cos(ga)*std::sin(d); double theta = std::atan2(std::sin(ga),b)*M_180_PI; - double lngDeg = theta-mu; - lngDeg = StelUtils::fmodpos(lngDeg, 360.); + double lngDeg = StelUtils::fmodpos(theta-mu, 360.); if (lngDeg > 180.) lngDeg -= 360.; double sfn1 = std::cos(ga)*std::cos(d); double cfn1 = std::sqrt(1.-sfn1*sfn1); @@ -4141,16 +3994,6 @@ QPair AstroCalcDialog::getMaximumEclipseAtRiseSet(bool first, do coordinates.first = std::atan(latDeg)*M_180_PI; coordinates.second = lngDeg; } - else - { - coordinates.first = 99.; - coordinates.second = 0.; - } - } - else - { - coordinates.first = 99.; - coordinates.second = 0.; } return coordinates; } @@ -4966,27 +4809,8 @@ void AstroCalcDialog::enableSolarEclipsesLocalButtons(bool enable) void AstroCalcDialog::selectCurrentSolarEclipseLocal(const QModelIndex& modelIndex) { // Find the Sun - QString name = "Sun"; - double JD = modelIndex.sibling(modelIndex.row(), SolarEclipseLocalDate).data(Qt::UserRole).toDouble(); - - if (objectMgr->findAndSelectI18n(name) || objectMgr->findAndSelect(name)) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + const double JD = modelIndex.sibling(modelIndex.row(), SolarEclipseLocalDate).data(Qt::UserRole).toDouble(); + goToObject("Sun", JD); } void AstroCalcDialog::saveSolarEclipsesLocal() @@ -5107,15 +4931,12 @@ LocalTransitparams localTransit(double JD, int contact, bool central, PlanetP ob const double vdot = ydot - etadot; const double n2 = udot * udot + vdot * vdot; const double delta = (u * vdot - udot * v) / sqrt(udot * udot + vdot * vdot); - L1 = L1 - zeta * tf1; - L2 = L2 - zeta * tf2; - double L = L1; - if (central) L = L2; + L1 -= zeta * tf1; + L2 -= zeta * tf2; + const double L = central ? L2 : L1; const double sfi = delta/L; const double ce = 1.- sfi*sfi; - double cfi = 0.; - if (ce > 0.) - cfi = contact * sqrt(ce); + const double cfi = (ce > 0.) ? contact * sqrt(ce) : 0.; const double m = sqrt(u * u + v * v); const double magnitude = (L1 - m) / (L1 + L2); const double altitude = asin(rc*cos(d)*cos(theta)+rs*sin(d)) / M_PI_180; @@ -5148,7 +4969,7 @@ TransitBessel::TransitBessel(PlanetP object, double &besX, double &besY, const double sdistanceAu = ssystem->getSun()->getEquinoxEquatorialPos(core).norm(); static const double earthRadius = ssystem->getEarth()->getEquatorialRadius()*AU; // Planet's distance in Earth's radius - double pdistanceER = object->getEquinoxEquatorialPos(core).norm() * AU / earthRadius; + const double pdistanceER = object->getEquinoxEquatorialPos(core).norm() * AU / earthRadius; // Greenwich Apparent Sidereal Time const double gast = get_apparent_sidereal_time(core->getJD(), core->getJDE()); // Avoid bug for special cases happen around Vernal Equinox @@ -5660,27 +5481,9 @@ void AstroCalcDialog::enableTransitsButtons(bool enable) void AstroCalcDialog::selectCurrentTransit(const QModelIndex& modelIndex) { // Find the planet - QString name = modelIndex.sibling(modelIndex.row(), TransitPlanet).data(Qt::UserRole).toString(); - double JD = modelIndex.sibling(modelIndex.row(), TransitDate).data(Qt::UserRole).toDouble(); - - if (objectMgr->findAndSelectI18n(name) || objectMgr->findAndSelect(name)) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - // Can't point to home planet - if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - else - { - GETSTELMODULE(StelObjectMgr)->unSelect(); - } - } - } + const QString name = modelIndex.sibling(modelIndex.row(), TransitPlanet).data(Qt::UserRole).toString(); + const double JD = modelIndex.sibling(modelIndex.row(), TransitDate).data(Qt::UserRole).toDouble(); + goToObject(name, JD); } void AstroCalcDialog::saveTransits() @@ -6662,18 +6465,8 @@ void AstroCalcDialog::selectCurrentPhenomen(const QModelIndex& modelIndex) QString name = ui->object1ComboBox->currentData().toString(); if (modelIndex.sibling(modelIndex.row(), PhenomenaType).data().toString().contains(q_("Opposition"), Qt::CaseInsensitive)) name = modelIndex.sibling(modelIndex.row(), PhenomenaObject2).data().toString(); - double JD = modelIndex.sibling(modelIndex.row(), PhenomenaDate).data(Qt::UserRole).toDouble(); - - if (objectMgr->findAndSelectI18n(name) || objectMgr->findAndSelect(name)) - { - core->setJD(JD); - const QList newSelected = objectMgr->getSelectedObject(); - if (!newSelected.empty()) - { - mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); - mvMgr->setFlagTracking(true); - } - } + const double JD = modelIndex.sibling(modelIndex.row(), PhenomenaDate).data(Qt::UserRole).toDouble(); + goToObject(name, JD); } void AstroCalcDialog::calculatePhenomena() @@ -6742,15 +6535,15 @@ void AstroCalcDialog::calculatePhenomena() case PHCInterstellarObjects: { static const QMapmap = { - {PHCAsteroids, Planet::isAsteroid}, - {PHCPlutinos, Planet::isPlutino}, - {PHCComets, Planet::isComet}, - {PHCDwarfPlanets, Planet::isDwarfPlanet}, - {PHCCubewanos, Planet::isCubewano}, + {PHCAsteroids, Planet::isAsteroid}, + {PHCPlutinos, Planet::isPlutino}, + {PHCComets, Planet::isComet}, + {PHCDwarfPlanets, Planet::isDwarfPlanet}, + {PHCCubewanos, Planet::isCubewano}, {PHCScatteredDiscObjects, Planet::isSDO}, - {PHCOortCloudObjects, Planet::isOCO}, - {PHCSednoids, Planet::isSednoid}, - {PHCInterstellarObjects, Planet::isInterstellar}}; + {PHCOortCloudObjects, Planet::isOCO}, + {PHCSednoids, Planet::isSednoid}, + {PHCInterstellarObjects, Planet::isInterstellar}}; const Planet::PlanetType pType = map.value(obj2Type, Planet::isUNDEFINED); for (const auto& object : allObjects) @@ -7012,9 +6805,9 @@ void AstroCalcDialog::savePhenomena() saveTableAsXLSX(fileData.first, ui->phenomenaTreeWidget, phenomenaHeader, q_("Phenomena"), q_("Phenomena")); } -void AstroCalcDialog::fillPhenomenaTableVis(QString phenomenType, double JD, QString firstObjectName, float firstObjectMagnitude, - QString secondObjectName, float secondObjectMagnitude, QString separation, QString elevation, - QString elongation, QString angularDistance, QString elongTooltip, QString angDistTooltip) +void AstroCalcDialog::fillPhenomenaTableVis(const QString &phenomenType, double JD, const QString &firstObjectName, float firstObjectMagnitude, + const QString &secondObjectName, float secondObjectMagnitude, const QString &separation, const QString &elevation, + QString &elongation, const QString &angularDistance, const QString &elongTooltip, const QString &angDistTooltip) { ACPhenTreeWidgetItem* treeItem = new ACPhenTreeWidgetItem(ui->phenomenaTreeWidget); treeItem->setText(PhenomenaType, phenomenType); @@ -7123,8 +6916,8 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const { if ((d1 < d2 && s1 <= s2) || (d1 > d2 && s1 > s2)) { - // The passage of the celestial body in front of another of greater apparent diameter - phenomenType = qc_("Transit", "passage of the celestial body"); + // The passage of a celestial body in front of another of greater apparent diameter + phenomenType = qc_("Transit", "passage of a celestial body in front of another"); } else phenomenType = q_("Occultation"); @@ -7153,7 +6946,7 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const } } - QString elongStr = ""; + QString elongStr; if (((object1 == sun || object2 == sun) && mode==PhenomenaTypeIndex::Conjunction) || (object2 == sun && mode==PhenomenaTypeIndex::Opposition)) elongStr = dash; else @@ -7168,24 +6961,18 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const elongStr = StelUtils::radToDmsStr(elongation, true); } - QString angDistStr = ""; - if (planet != earth) + QString angDistStr; + if (planet != earth || object1 == moon || object2 == moon) angDistStr = dash; else { - if (object1 == moon || object2 == moon) - angDistStr = dash; + double angularDistance = object1->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); + if (mode==1) // calculate elongation for the second object in this case! + angularDistance = object2->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); + if (withDecimalDegree) + angDistStr = StelUtils::radToDecDegStr(angularDistance, 5, false, true); else - { - double angularDistance = object1->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); - if (mode==1) // calculate elongation for the second object in this case! - angularDistance = object2->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); - - if (withDecimalDegree) - angDistStr = StelUtils::radToDecDegStr(angularDistance, 5, false, true); - else - angDistStr = StelUtils::radToDmsStr(angularDistance, true); - } + angDistStr = StelUtils::radToDmsStr(angularDistance, true); } QString elongationInfo = q_("Angular distance from the Sun"); @@ -7250,7 +7037,7 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const occultation = true; } - QString elongStr = ""; + QString elongStr; if (object1 == sun) elongStr = dash; else @@ -7261,21 +7048,16 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const elongStr = StelUtils::radToDmsStr(object1->getElongation(core->getObserverHeliocentricEclipticPos()), true); } - QString angDistStr = ""; - if (planet != earth) + QString angDistStr; + if (planet != earth || object1 == moon) angDistStr = dash; else { - if (object1 == moon) - angDistStr = dash; + double angularDistance = object1->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); + if (withDecimalDegree) + angDistStr = StelUtils::radToDecDegStr(angularDistance, 5, false, true); else - { - double angularDistance = object1->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); - if (withDecimalDegree) - angDistStr = StelUtils::radToDecDegStr(angularDistance, 5, false, true); - else - angDistStr = StelUtils::radToDmsStr(angularDistance, true); - } + angDistStr = StelUtils::radToDmsStr(angularDistance, true); } QString commonName = object2->getNameI18n(); @@ -7341,8 +7123,8 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const { if ((d1 < d2 && s1 <= s2) || (d1 > d2 && s1 > s2)) { - // The passage of the celestial body in front of another of greater apparent diameter - phenomenType = qc_("Transit", "passage of the celestial body"); + // The passage of a celestial body in front of another of greater apparent diameter + phenomenType = qc_("Transit", "passage of a celestial body in front of another"); } else phenomenType = q_("Occultation"); @@ -7374,7 +7156,7 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const } } - QString elongStr = ""; + QString elongStr; if (object1 == sun) elongStr = dash; else @@ -7385,21 +7167,16 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const elongStr = StelUtils::radToDmsStr(object1->getElongation(core->getObserverHeliocentricEclipticPos()), true); } - QString angDistStr = ""; - if (planet != earth) + QString angDistStr; + if (planet != earth || object1 == moon) angDistStr = dash; else { - if (object1 == moon) - angDistStr = dash; + double angularDistance = object1->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); + if (withDecimalDegree) + angDistStr = StelUtils::radToDecDegStr(angularDistance, 5, false, true); else - { - double angularDistance = object1->getJ2000EquatorialPos(core).angle(moon->getJ2000EquatorialPos(core)); - if (withDecimalDegree) - angDistStr = StelUtils::radToDecDegStr(angularDistance, 5, false, true); - else - angDistStr = StelUtils::radToDmsStr(angularDistance, true); - } + angDistStr = StelUtils::radToDmsStr(angularDistance, true); } QString commonName = object2->getNameI18n(); @@ -7429,11 +7206,9 @@ void AstroCalcDialog::fillPhenomenaTable(const QMap list, const } } -double AstroCalcDialog::findInitialStep(double startJD, double stopJD, QStringList objects) +double AstroCalcDialog::findInitialStep(double startJD, double stopJD, QStringList &objects) { - double limit, step = (stopJD - startJD) / 16.0; static const QRegularExpression mp("^[(](\\d+)[)]\\s(.+)$"); - static const QMap steps = { { "Moon", 0.25 }, { "C/", 0.5 }, @@ -7450,9 +7225,12 @@ double AstroCalcDialog::findInitialStep(double startJD, double stopJD, QStringLi { "Pluto", 20.0 }, }; + double limit=10.; +#if (QT_VERSION>=QT_VERSION_CHECK(6,0,0)) + if (objects.contains(mp)) +#else if (objects.indexOf(mp)>=0) - limit = 10.; - else +#endif { limit = 24.8 * 365.25; QMap::const_iterator it=steps.constBegin(); @@ -7464,6 +7242,7 @@ double AstroCalcDialog::findInitialStep(double startJD, double stopJD, QStringLi } } + double step = (stopJD - startJD) / 16.0; if (step > limit) step = limit; @@ -8295,48 +8074,55 @@ void AstroCalcDialog::populateWutGroups() QListWidget* category = ui->wutCategoryListWidget; category->blockSignals(true); - const QMap wutCatsMap = { - { q_("Planets"), EWPlanets }, { q_("Bright stars"), EWBrightStars }, { q_("Bright nebulae"), EWBrightNebulae }, - { q_("Dark nebulae"), EWDarkNebulae }, { q_("Galaxies"), EWGalaxies }, { q_("Open star clusters"), EWOpenStarClusters }, - { q_("Asteroids"), EWAsteroids }, { q_("Comets"), EWComets }, { q_("Plutinos"), EWPlutinos }, { q_("Dwarf planets"), EWDwarfPlanets }, - { q_("Cubewanos"), EWCubewanos }, { q_("Scattered disc objects"), EWScatteredDiscObjects }, { q_("Oort cloud objects"), EWOortCloudObjects }, - { q_("Sednoids"), EWSednoids }, { q_("Planetary nebulae"), EWPlanetaryNebulae }, { q_("Bright double stars"), EWBrightDoubleStars }, - { q_("Bright variable stars"), EWBrightVariableStars }, { q_("Bright stars with high proper motion"), EWBrightStarsWithHighProperMotion }, - { q_("Symbiotic stars"), EWSymbioticStars }, { q_("Emission-line stars"), EWEmissionLineStars }, { q_("Supernova candidates"), EWSupernovaeCandidates }, - { q_("Supernova remnant candidates"), EWSupernovaeRemnantCandidates }, { q_("Supernova remnants"), EWSupernovaeRemnants }, - { q_("Clusters of galaxies"), EWClustersOfGalaxies }, { q_("Interstellar objects"), EWInterstellarObjects }, - { q_("Globular star clusters"), EWGlobularStarClusters }, { q_("Regions of the sky"), EWRegionsOfTheSky }, { q_("Active galaxies"), EWActiveGalaxies }, - { q_("Interacting galaxies"), EWInteractingGalaxies }, { q_("Deep-sky objects"), EWDeepSkyObjects }, { q_("Messier objects"), EWMessierObjects }, - { q_("NGC/IC objects"), EWNGCICObjects }, { q_("Caldwell objects"), EWCaldwellObjects }, { q_("Herschel 400 objects"), EWHerschel400Objects }, - { q_("Algol-type eclipsing systems"), EWAlgolTypeVariableStars }, { q_("The classical cepheids"), EWClassicalCepheidsTypeVariableStars }, - { q_("Bright carbon stars"), EWCarbonStars }, { q_("Bright barium stars"), EWBariumStars } - }; - QMapIterator i(wutCatsMap); - wutCategories.clear(); - // generic categories - while (i.hasNext()) - { - i.next(); - wutCategories.insert(i.key(), i.value()); - } - - // specific categories - if (moduleMgr.isPluginLoaded("Pulsars")) - { - // Add the category when pulsars is visible - if (propMgr->getProperty("Pulsars.pulsarsVisible")->getValue().toBool()) - wutCategories.insert(q_("Pulsars"), EWPulsars); - } - if (moduleMgr.isPluginLoaded("Exoplanets")) - { - // Add the category when exoplanets is visible - if (propMgr->getProperty("Exoplanets.showExoplanets")->getValue().toBool()) - wutCategories.insert(q_("Exoplanetary systems"), EWExoplanetarySystems); - } + wutCategories = { + { q_("Planets"), EWPlanets}, + { q_("Bright stars"), EWBrightStars}, + { q_("Bright nebulae"), EWBrightNebulae}, + { q_("Dark nebulae"), EWDarkNebulae}, + { q_("Galaxies"), EWGalaxies}, + { q_("Open star clusters"), EWOpenStarClusters}, + { q_("Asteroids"), EWAsteroids}, + { q_("Comets"), EWComets}, + { q_("Plutinos"), EWPlutinos}, + { q_("Dwarf planets"), EWDwarfPlanets}, + { q_("Cubewanos"), EWCubewanos}, + { q_("Scattered disc objects"), EWScatteredDiscObjects}, + { q_("Oort cloud objects"), EWOortCloudObjects}, + { q_("Sednoids"), EWSednoids}, + { q_("Planetary nebulae"), EWPlanetaryNebulae}, + { q_("Bright double stars"), EWBrightDoubleStars}, + { q_("Bright variable stars"), EWBrightVariableStars}, + { q_("Bright stars with high proper motion"), EWBrightStarsWithHighProperMotion}, + { q_("Symbiotic stars"), EWSymbioticStars}, + { q_("Emission-line stars"), EWEmissionLineStars}, + { q_("Supernova candidates"), EWSupernovaeCandidates}, + { q_("Supernova remnant candidates"), EWSupernovaeRemnantCandidates}, + { q_("Supernova remnants"), EWSupernovaeRemnants}, + { q_("Clusters of galaxies"), EWClustersOfGalaxies}, + { q_("Interstellar objects"), EWInterstellarObjects}, + { q_("Globular star clusters"), EWGlobularStarClusters}, + { q_("Regions of the sky"), EWRegionsOfTheSky}, + { q_("Active galaxies"), EWActiveGalaxies}, + { q_("Interacting galaxies"), EWInteractingGalaxies}, + { q_("Deep-sky objects"), EWDeepSkyObjects}, + { q_("Messier objects"), EWMessierObjects}, + { q_("NGC/IC objects"), EWNGCICObjects}, + { q_("Caldwell objects"), EWCaldwellObjects}, + { q_("Herschel 400 objects"), EWHerschel400Objects}, + { q_("Algol-type eclipsing systems"), EWAlgolTypeVariableStars}, + { q_("The classical cepheids"), EWClassicalCepheidsTypeVariableStars}, + { q_("Bright carbon stars"), EWCarbonStars}, + { q_("Bright barium stars"), EWBariumStars}}; if (moduleMgr.isPluginLoaded("Novae")) wutCategories.insert(q_("Bright nova stars"), EWBrightNovaStars); if (moduleMgr.isPluginLoaded("Supernovae")) wutCategories.insert(q_("Bright supernova stars"), EWBrightSupernovaStars); + // Add the Pulsars category when pulsars are visible + if (moduleMgr.isPluginLoaded("Pulsars") && propMgr->getProperty("Pulsars.pulsarsVisible")->getValue().toBool()) + wutCategories.insert(q_("Pulsars"), EWPulsars); + // Add the Exoplanets category when exoplanets are visible + if (moduleMgr.isPluginLoaded("Exoplanets") && propMgr->getProperty("Exoplanets.showExoplanets")->getValue().toBool()) + wutCategories.insert(q_("Exoplanetary systems"), EWExoplanetarySystems); category->clear(); category->addItems(wutCategories.keys()); @@ -8452,7 +8238,7 @@ void AstroCalcDialog::enableAngularLimits(bool enable) ui->wutMatchingObjectsTreeWidget->hideColumn(WUTAngularSize); // special case! } -void AstroCalcDialog::fillWUTTable(QString objectName, QString designation, float magnitude, Vec4d RTSTime, double maxElevation, double angularSize, QString constellation, QString otype, bool decimalDegrees) +void AstroCalcDialog::fillWUTTable(const QString &objectName, const QString &designation, float magnitude, const Vec4d &RTSTime, double maxElevation, double angularSize, const QString &constellation, const QString &otype, bool decimalDegrees) { QString sAngularSize = dash; QString sRise = dash; @@ -8489,7 +8275,7 @@ void AstroCalcDialog::fillWUTTable(QString objectName, QString designation, floa treeItem->setText(WUTSetTime, sSet); treeItem->setTextAlignment(WUTSetTime, Qt::AlignRight); - double angularSizeRad = angularSize * M_PI / 180.; + double angularSizeRad = angularSize * M_PI_180; if (angularSize>0.0) { if (decimalDegrees) @@ -9109,7 +8895,7 @@ void AstroCalcDialog::calculateWutObjects() break; } - for (const auto& object : catDSO) + for (const auto& object : qAsConst(catDSO)) { mag = object->getVMagnitude(core); if (mag <= magLimit && object->isAboveRealHorizon(core)) @@ -9170,8 +8956,8 @@ void AstroCalcDialog::selectWutObject(const QModelIndex &index) if (index.isValid()) { // Find the object - QString wutObjectEnglisName = index.sibling(index.row(),WUTObjectName).data(Qt::UserRole).toString(); - if (objectMgr->findAndSelectI18n(wutObjectEnglisName) || objectMgr->findAndSelect(wutObjectEnglisName)) + QString wutObjectEnglishName = index.sibling(index.row(), WUTObjectName).data(Qt::UserRole).toString(); + if (objectMgr->findAndSelect(wutObjectEnglishName)) { const QList newSelected = objectMgr->getSelectedObject(); if (!newSelected.empty()) @@ -9692,3 +9478,25 @@ QList AstroCalcDialog::getSelectedMinorPlanets() return planets; } + +void AstroCalcDialog::goToObject(const QString &name, const double JD) +{ + if (objectMgr->findAndSelectI18n(name) || objectMgr->findAndSelect(name)) + { + core->setJD(JD); + const QList newSelected = objectMgr->getSelectedObject(); + if (!newSelected.empty()) + { + // Can't point to home planet + if (newSelected[0]->getEnglishName() != core->getCurrentLocation().planetName) + { + mvMgr->moveToObject(newSelected[0], mvMgr->getAutoMoveDuration()); + mvMgr->setFlagTracking(true); + } + else + { + GETSTELMODULE(StelObjectMgr)->unSelect(); + } + } + } +} diff --git a/src/gui/AstroCalcDialog.hpp b/src/gui/AstroCalcDialog.hpp index 31c18e509213b..235c862b01d92 100644 --- a/src/gui/AstroCalcDialog.hpp +++ b/src/gui/AstroCalcDialog.hpp @@ -286,7 +286,7 @@ private slots: void selectCurrentCelestialPosition(const QModelIndex &modelIndex); void currentHECPositions(); - void drawHECGraph(QString selectedObject = ""); + void drawHECGraph(const QString &selectedObject = ""); void saveHECPositions(); void selectCurrentHECPosition(const QModelIndex &modelIndex); void markCurrentHECPosition(const QModelIndex &modelIndex); @@ -584,19 +584,22 @@ private slots: double getCustomTimeStep(); void reGenerateEphemeris(bool withSelection); + //! Finding and selecting an object by its name in specific JD + void goToObject(const QString &name, const double JD); + //! Format RA/Dec or Az/Alt coordinates into nice strings. //! @arg horizontal coord are horizontal (alt-azimuthal). Use degrees/degrees. Else use Hours/degrees. //! @arg southAzimuth (relevant only for horizontal=true) count azimuth from south. //! @arg decimalDegrees use decimal format, not DMS/HMS //! @return QPair(lngStr, latStr) formatted output strings static QPair getStringCoordinates(const Vec3d &coord, const bool horizontal, const bool southAzimuth, const bool decimalDegrees); - void fillWUTTable(QString objectName, QString designation, float magnitude, Vec4d RTSTime, double maxElevation, - double angularSize, QString constellation, QString otype, bool decimalDegrees = false); - void fillCelestialPositionTable(QString objectName, QString RA, QString Dec, double magnitude, - QString angularSize, QString angularSizeToolTip, QString extraData, - QString extraDataToolTip, QString transitTime, QString maxElevation, - QString sElongation, QString objectType); - void fillHECPositionTable(QString objectName, QChar objectSymbol, QString latitude, QString longitude, double distance); + void fillWUTTable(const QString &objectName, const QString &designation, float magnitude, const Vec4d &RTSTime, double maxElevation, + double angularSize, const QString &constellation, const QString &otype, bool decimalDegrees = false); + void fillCelestialPositionTable(const QString &objectName, const QString &RA, const QString &Dec, double magnitude, + const QString &angularSize, const QString &angularSizeToolTip, const QString &extraData, + const QString &extraDataToolTip, const QString &transitTime, const QString &maxElevation, + QString &sElongation, const QString &objectType); + void fillHECPositionTable(const QString &objectName, const QChar objectSymbol, const QString &latitude, const QString &longitude, const double distance); //! Calculation conjunctions and oppositions. //! @note Ported from KStars, should be improved, because this feature calculates @@ -607,7 +610,7 @@ private slots: //! Finding the angular distance between two celestial bodies at some Julian date double findDistance(double JD, PlanetP object1, StelObjectP object2, int mode); //! Finding the initial time steps for interactions - double findInitialStep(double startJD, double stopJD, QStringList objects); + double findInitialStep(double startJD, double stopJD, QStringList &objects); //! Finding the celestial event bool findPrecise(QPair* out, PlanetP object1, StelObjectP object2, double JD, double step, int prevSign, int mode); //! Wrapper for filling the table of phenomena between planet and star @@ -618,9 +621,9 @@ private slots: //! @note modes: 0 - conjunction, 1 - opposition, 2 - greatest elongation void fillPhenomenaTable(const QMap list, const PlanetP object1, const PlanetP object2, int mode); //! Filling the table of phenomena - void fillPhenomenaTableVis(QString phenomenType, double JD, QString firstObjectName, float firstObjectMagnitude, - QString secondObjectName, float secondObjectMagnitude, QString separation, QString elevation, - QString elongation, QString angularDistance, QString elongTooltip="", QString angDistTooltip=""); + void fillPhenomenaTableVis(const QString &phenomenType, double JD, const QString &firstObjectName, float firstObjectMagnitude, + const QString &secondObjectName, float secondObjectMagnitude, const QString &separation, const QString &elevation, + QString &elongation, const QString &angularDistance, const QString &elongTooltip="", const QString &angDistTooltip=""); //! Calculation of greatest elongations QMap findGreatestElongationApproach(PlanetP& object1, StelObjectP& object2, double startJD, double stopJD); bool findPreciseGreatestElongation(QPair* out, PlanetP object1, StelObjectP object2, double JD, double stopJD, double step); diff --git a/src/gui/ConfigurationDialog.cpp b/src/gui/ConfigurationDialog.cpp index b67003a04c453..5eb127f6f1c53 100644 --- a/src/gui/ConfigurationDialog.cpp +++ b/src/gui/ConfigurationDialog.cpp @@ -397,9 +397,6 @@ void ConfigurationDialog::createDialogContent() connect(mainView, SIGNAL(sizeChanged(const QSize&)), this, SLOT(updateDpiTooltip())); updateDpiTooltip(); - connectBoolProperty(ui->autoEnableEnvironmentCheckBox, "LandscapeMgr.flagEnvironmentAutoEnabling"); - connectBoolProperty(ui->autoChangeLandscapesCheckBox, "LandscapeMgr.flagLandscapeAutoSelection"); - // script tab controls #ifdef ENABLE_SCRIPTING StelScriptMgr& scriptMgr = StelApp::getInstance().getScriptMgr(); diff --git a/src/gui/LocationDialog.cpp b/src/gui/LocationDialog.cpp index babd2bfd5a785..0a589f9f64e22 100644 --- a/src/gui/LocationDialog.cpp +++ b/src/gui/LocationDialog.cpp @@ -19,6 +19,7 @@ */ #include "Dialog.hpp" +#include "StelModuleMgr.hpp" #include "LandscapeMgr.hpp" #include "LocationDialog.hpp" #include "StelLocationMgr.hpp" @@ -132,7 +133,7 @@ void LocationDialog::createDialogContent() // Connect all the QT signals connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close())); connect(ui->TitleBar, SIGNAL(movedTo(QPoint)), this, SLOT(handleMovedTo(QPoint))); - connect(ui->mapWidget, SIGNAL(positionChanged(double, double)), this, SLOT(setLocationFromMap(double, double))); + connect(ui->mapWidget, SIGNAL(positionChanged(double, double, const QColor&)), this, SLOT(setLocationFromMap(double, double, const QColor&)), Qt::UniqueConnection); connect(ui->addLocationToListPushButton, SIGNAL(clicked()), this, SLOT(addCurrentLocationToList())); connect(ui->deleteLocationFromListPushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentLocationFromList())); @@ -189,6 +190,8 @@ void LocationDialog::createDialogContent() ui->timeZoneNameComboBox->setEnabled(core->getUseCustomTimeZone()); connect(ui->useCustomTimeZoneCheckBox, SIGNAL(clicked(bool)), this, SLOT(updateTimeZoneControls(bool))); connect(core, SIGNAL(currentTimeZoneChanged(QString)), this, SLOT(setTimezone(QString))); + connectBoolProperty(ui->autoEnableEnvironmentCheckBox, "LandscapeMgr.flagEnvironmentAutoEnabling"); + connectBoolProperty(ui->autoChangeLandscapesCheckBox, "LandscapeMgr.flagLandscapeAutoSelection"); connectEditSignals(); @@ -196,7 +199,8 @@ void LocationDialog::createDialogContent() // In case this dialog is called up before going to an "observer", we need to update a few UI elements: updateFromProgram(core->getCurrentLocation()); - connect(core, SIGNAL(targetLocationChanged(StelLocation)), this, SLOT(updateFromProgram(StelLocation))); // Fill with actually selected location! + // This connection only updates the dialog with new coordinates, not the landscape + connect(core, &StelCore::targetLocationChanged, this, [=](const StelLocation &loc, const QString &id){updateFromProgram(loc);}); // Fill with actually selected location! connect(ui->pushButtonReturnToDefault, &QPushButton::clicked, this, [=]{ static StelMovementMgr *mMgr=GETSTELMODULE(StelMovementMgr); @@ -205,7 +209,7 @@ void LocationDialog::createDialogContent() this->setLocationUIvisible(true); // restore UI core->returnToDefaultLocation(); mMgr->resetInitViewPos(); - lMgr->setCurrentLandscapeID(lMgr->getDefaultLandscapeID(), 0.); + lMgr->setCurrentLandscapeID(lMgr->getDefaultLandscapeID(), 1.); }); ui->citySearchLineEdit->setFocus(); @@ -302,6 +306,14 @@ void LocationDialog::setLocationUIvisible(bool visible) ui->labelName->setVisible(visible); ui->frame_citylist->setVisible(visible); ui->mapWidget->setMarkerVisible(visible); + if(visible) + { + connect(ui->mapWidget, SIGNAL(positionChanged(double, double, const QColor&)), this, SLOT(setLocationFromMap(double, double, const QColor&)), Qt::UniqueConnection); + } + else + { + disconnect(ui->mapWidget, SIGNAL(positionChanged(double, double, const QColor&)), this, SLOT(setLocationFromMap(double, double, const QColor&))); + } ui->addLocationToListPushButton->setVisible(visible); ui->deleteLocationFromListPushButton->setVisible(visible); } @@ -492,7 +504,7 @@ void LocationDialog::populateTimeZonesList() // Special sort for UTC+XX:YY time zones: we want them // to go from the most negative to the most positive. - const auto utcRegEx = QRegularExpression("^UTC([+-])(\\d\\d):(\\d\\d)$"); + static const QRegularExpression utcRegEx("^UTC([+-])(\\d\\d):(\\d\\d)$"); std::vector utcOffsets; for(int n = 0; n < tzNames.size();) { @@ -606,7 +618,7 @@ void LocationDialog::setLocationFromList(const QModelIndex& index) // This calls indirectly updateFromProgram() } -void LocationDialog::setLocationFromMap(double longitude, double latitude) +void LocationDialog::setLocationFromMap(double longitude, double latitude, const QColor &color) { StelCore *core = StelApp::getInstance().getCore(); if (core->getUseCustomTimeZone()) @@ -617,7 +629,11 @@ void LocationDialog::setLocationFromMap(double longitude, double latitude) loc.setLongitude(longitude); loc.name= QString("%1, %2").arg(loc.getLatitude()).arg(loc.getLongitude()); // Force a preliminary name setFieldsFromLocation(loc); - core->moveObserverTo(loc, 0.); + if (loc.planetName=="Earth") + core->moveObserverTo(loc, 0., 1., GETSTELMODULE(LandscapeMgr)->getFlagLandscapeAutoSelection() ? QString("ZeroColor(%1)").arg(Vec3f(color).toStr()) : QString()); + else + core->moveObserverTo(loc, 0., 1., loc.planetName); // Loads a default landscape for the planet. + // Only for locations on Earth: set zone to LMST. // TODO: Find a way to lookup (lon,lat)->country->timezone. @@ -640,19 +656,20 @@ void LocationDialog::moveToAnotherPlanet() reportEdit(); StelLocation loc = locationFromFields(); StelCore* stelCore = StelApp::getInstance().getCore(); - StelModule* lMgr = StelApp::getInstance().getModule("LandscapeMgr"); + LandscapeMgr *lMgr = GETSTELMODULE(LandscapeMgr); populateRegionList(loc.planetName); if (loc.planetName != stelCore->getCurrentLocation().planetName) { setFieldsFromLocation(loc); - if (lMgr->property("flagLandscapeAutoSelection").toBool()) + if (lMgr->getFlagLandscapeAutoSelection()) { - // If we have a landscape for selected planet then set it, otherwise use default landscape + // If we have a landscape for selected planet then set it, otherwise use zero landscape // Details: https://bugs.launchpad.net/stellarium/+bug/1173254 - if (lMgr->property("allLandscapeNames").toStringList().indexOf(loc.planetName)>0) - lMgr->setProperty("currentLandscapeName", loc.planetName); + if (lMgr->getAllLandscapeNames().contains(loc.planetName)) + lMgr->setCurrentLandscapeName(loc.planetName); // TODO: Why not setCurrentLandscapeID? else - lMgr->setProperty("currentLandscapeID", lMgr->property("defaultLandscapeID")); + //lMgr->setProperty("currentLandscapeID", lMgr->property("defaultLandscapeID")); + lMgr->setCurrentLandscapeID("zero"); // harmonize with LandscapeMgr::onTargetLocationChanged() } // populate site list with sites only from that planet, or full list for Earth (faster than removing the ~50 non-Earth positions...). @@ -676,6 +693,7 @@ void LocationDialog::moveToAnotherPlanet() ui->citySearchLineEdit->setFocus(); // If we change to an Observer "planet", auto-select and focus on the observed object. + StelObjectMgr *soMgr=GETSTELMODULE(StelObjectMgr); SolarSystem *ss=GETSTELMODULE(SolarSystem); PlanetP planet=nullptr; if (ss) @@ -685,7 +703,6 @@ void LocationDialog::moveToAnotherPlanet() setLocationUIvisible(false); loc.role=QChar('o'); // Mark this ad-hoc location as "observer". - StelObjectMgr *soMgr=GETSTELMODULE(StelObjectMgr); if (soMgr) { soMgr->findAndSelect(planet->getParent()->getEnglishName()); @@ -697,9 +714,16 @@ void LocationDialog::moveToAnotherPlanet() GETSTELMODULE(StelMovementMgr)->setFlagTracking(false); setLocationUIvisible(true); GETSTELMODULE(StelMovementMgr)->resetInitViewPos(); + // Get rid of selection if we are standing on it... + if (soMgr) + { + const QList& selection=soMgr->getSelectedObject(); + if (!selection.isEmpty() && selection[0]->getEnglishName()==loc.planetName) + soMgr->unSelect(); + } } - stelCore->moveObserverTo(loc, 0., 0.); + stelCore->moveObserverTo(loc, 0., 0., loc.planetName); } // Planet transition time also set to null to prevent ugliness when // "use landscape location" is enabled for that planet's landscape. --BM @@ -711,7 +735,7 @@ void LocationDialog::setLocationFromCoords(int i) Q_UNUSED(i) reportEdit(); StelLocation loc = locationFromFields(); - StelApp::getInstance().getCore()->moveObserverTo(loc, 0.); + StelApp::getInstance().getCore()->moveObserverTo(loc, 0.); // No landscape update: This may be used for finetuning within a landscape //Update the position of the map pointer ui->mapWidget->setMarkerPos(loc.getLongitude(), loc.getLatitude()); } @@ -964,11 +988,26 @@ void LocationDialog::resetLocationList() //reset search before setting model, prevents unnecessary search in full list ui->citySearchLineEdit->setText(""); // https://wiki.qt.io/Technical_FAQ#Why_does_the_memory_keep_increasing_when_repeatedly_pasting_text_and_calling_clear.28.29_in_a_QLineEdit.3F ui->citySearchLineEdit->setFocus(); - proxyModel->setSourceModel(allModel); + + // populate site list with sites only from that planet, or full list for Earth (faster than removing the ~50 non-Earth positions...). + StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr(); + StelLocation loc = locationFromFields(); + if (loc.planetName == "Earth") + { + proxyModel->setSourceModel(allModel); + } + else + { + LocationMap results = locMgr.pickLocationsNearby(loc.planetName, 0.0f, 0.0f, 180.0f); + pickedModel->setStringList(results.keys()); + proxyModel->setSourceModel(pickedModel); + ui->regionNameComboBox->setCurrentIndex(ui->regionNameComboBox->findData("", Qt::UserRole, Qt::MatchCaseSensitive)); + } + proxyModel->sort(0, Qt::AscendingOrder); } -// called when user clicks in the country combobox and selects a country. The locations in the list are updated to select only sites in that country. +// called when user clicks in the region combobox and selects a region. The locations in the list are updated to select only sites in that region. void LocationDialog::filterSitesByRegion() { QString region=ui->regionNameComboBox->currentData(Qt::UserRole).toString(); diff --git a/src/gui/LocationDialog.hpp b/src/gui/LocationDialog.hpp index 658a725dd5138..af353c2e9bf8e 100644 --- a/src/gui/LocationDialog.hpp +++ b/src/gui/LocationDialog.hpp @@ -105,8 +105,10 @@ private slots: void updateFromProgram(const StelLocation& newLocation); //! Called when the map is clicked. - //! create new list for places nearby and feed into location list box. - void setLocationFromMap(double longitude, double latitude); + //! Creates new list for places nearby and feed into location list box. + //! Sets lolcation to the clicked location + //! Also signals (for locations on Earth only) to LandscapeMgr to load zero landscape with just the color of the clicked point. + void setLocationFromMap(double longitude, double latitude, const QColor &color); //! Called when the user activates an item from the locations list. void setLocationFromList(const QModelIndex& index); diff --git a/src/gui/MapWidget.cpp b/src/gui/MapWidget.cpp index ee4b21ba3fa1e..efe6d9e469f43 100644 --- a/src/gui/MapWidget.cpp +++ b/src/gui/MapWidget.cpp @@ -22,6 +22,8 @@ #include #include #include +#include "StelLocationMgr.hpp" +#include "StelApp.hpp" namespace { @@ -58,7 +60,11 @@ void MapWidget::mousePressEvent(QMouseEvent* event) const auto lat = (pos.y() - mapRect.center().y()) / mapRect.height() * -180; const auto lon = (pos.x() - mapRect.center().x()) / mapRect.width() * 360; - emit positionChanged(lon, lat); + + StelLocationMgr* locationMgr = &StelApp::getInstance().getLocationMgr(); + QColor color=locationMgr->getColorForCoordinates(lon, lat); + + emit positionChanged(lon, lat, color); } void MapWidget::setMap(const QPixmap &map) diff --git a/src/gui/MapWidget.hpp b/src/gui/MapWidget.hpp index c20ae02674ff6..d6c4e408a060c 100644 --- a/src/gui/MapWidget.hpp +++ b/src/gui/MapWidget.hpp @@ -44,8 +44,8 @@ class MapWidget : public QWidget void setMap(const QPixmap &map); signals: - //! Signal emitted when we click on the map - void positionChanged(double longitude, double latitude); + //! Signal emitted when we click on the map. It also delivers the color value at the clicked point. + void positionChanged(double longitude, double latitude, const QColor &color); protected: void mousePressEvent(QMouseEvent* event) override; diff --git a/src/gui/configurationDialog.ui b/src/gui/configurationDialog.ui index afe920eb8a513..80e52030637e8 100644 --- a/src/gui/configurationDialog.ui +++ b/src/gui/configurationDialog.ui @@ -2037,16 +2037,6 @@ - - - - Auto-enable atmosphere and landscape when selecting a celestial body in the location window. - - - Auto-enabling for the environment - - - @@ -2125,16 +2115,6 @@ - - - - Automatic change of landscape when planet is changed - - - Auto select landscapes - - - diff --git a/src/gui/locationDialogGui.ui b/src/gui/locationDialogGui.ui index ea15a6976fb56..d8d10c7035f0f 100644 --- a/src/gui/locationDialogGui.ui +++ b/src/gui/locationDialogGui.ui @@ -6,8 +6,8 @@ 0 0 - 630 - 542 + 699 + 511 @@ -518,46 +518,27 @@ 6 - - + + - Latitude: + Longitude: - - + + - 100 + 180 24 - Enter the elevation in meter + You can enter values in decimal degrees, or using dms format, for example: +1d 12m 8s Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - m - - - -2000 - - - 200000 - - - 100 - - - - - - - Get location from Network - @@ -567,10 +548,34 @@ - - + + + + + 0 + 0 + + - Elevation: + Get location from GPS + + + true + + + false + + + 3500 + + + 3500 + + + Qt::ToolButtonTextOnly + + + false @@ -590,57 +595,68 @@ - - + + - Longitude: + Latitude: - - + + + + Get location from Network + + + + + - 180 + 100 24 - You can enter values in decimal degrees, or using dms format, for example: +1d 12m 8s + Enter the elevation in meter Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + m + + + -2000 + + + 200000 + + + 100 + - - + + + + Elevation: + + + + + - + 0 0 - - Get location from GPS - - - true - - - false - - - 3500 - - - 3500 - - - Qt::ToolButtonTextOnly + + Automatic change of landscape when planet or location is changed - - false + + Auto-select landscapes @@ -696,7 +712,7 @@ - + 0 0 @@ -761,6 +777,12 @@ true + + + 0 + 0 + + true @@ -772,7 +794,7 @@ - + 0 0 @@ -814,6 +836,16 @@ + + + + Auto-enable atmosphere when planet is changed + + + Auto-enable atmosphere + + +