summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Zotti <Georg.Zotti@univie.ac.at>2022-01-16 18:44:56 +0100
committerGitHub <noreply@github.com>2022-01-16 18:44:56 +0100
commitb3e6faedd3c455161a4c255b9478139353a8ce94 (patch)
tree8648cc4b956eb086acf96287fcee1502297f0582
parentcacd5271f3793be10facd1a156e0deef745a9eae (diff)
Fix nomenclature longitudes (#2158)
* Hopefully east/west counting problem solved * Add infostring details about used coordinate system * Change latitudes of special points to follow the planetocentric convention. * Also don't attempt to interpret the latitudes from the WGPSN as planetographic - they are already planetocentric! * Cosmetic improvements for coordinates of planetary features - Added human readable format for coordinates of planetary features - Added support decimal coordinates for planetary features * Fix getAngularSize(): must be apparent semidiameter or half of apparent size. also * Better selection priority * RTS for NomenclatureItems: same as their planets. * Shifted Tethys texture by 1/2 (correct longitudes) * Added unit tests for 2 new methods of coordinates conversion * Simplified setFlagLabels - Removed useless update(), and activated in the Mgr class - Now we have soft in/out * avoid useless GL state changes and other tests * SUG: added description of planetary coordinate systems. Co-authored-by: Alexander V. Wolf <alex.v.wolf@gmail.com>
-rw-r--r--guide/app_nomenclature.tex134
-rw-r--r--guide/structure.tex1
-rw-r--r--src/core/StelObject.cpp2
-rw-r--r--src/core/StelPainter.cpp9
-rw-r--r--src/core/StelPainter.hpp4
-rw-r--r--src/core/StelUtils.cpp48
-rw-r--r--src/core/StelUtils.hpp12
-rw-r--r--src/core/modules/NomenclatureItem.cpp220
-rw-r--r--src/core/modules/NomenclatureItem.hpp65
-rw-r--r--src/core/modules/NomenclatureMgr.cpp30
-rw-r--r--src/core/modules/NomenclatureMgr.hpp2
-rw-r--r--src/core/modules/Planet.cpp16
-rw-r--r--src/core/modules/Planet.hpp15
-rw-r--r--src/core/modules/SpecialMarkersMgr.cpp23
-rw-r--r--src/tests/testConversions.cpp96
-rw-r--r--src/tests/testConversions.hpp2
-rw-r--r--textures/tethys.pngbin220697 -> 229124 bytes
17 files changed, 554 insertions, 125 deletions
diff --git a/guide/app_nomenclature.tex b/guide/app_nomenclature.tex
index 71d287e2a4..e2a6f23905 100644
--- a/guide/app_nomenclature.tex
+++ b/guide/app_nomenclature.tex
@@ -2,6 +2,7 @@
% A. Wolf 2017
% 20171029 AW: A first version of text
% 20171210 GZ: small changes for finalization.
+% 20220105 GZ: Add info on coordinate systems
\chapter{Planetary nomenclature}
\label{ch:Nomenclature}
@@ -66,6 +67,137 @@ size of planetary feature & float & kilometers\\\bottomrule
Vesta 15201 _("Caesonia","crater") AA 31.20117 249.93457 104.23
\end{configfile}
+\section{Planetary Coordinate Systems}
+\label{sec:Nomenclature:CoordinateSystems}
+
+When we observe the Moon or another planet from Earth (or actually
+from anywhere), we can see only about half of the surface of the
+spheroid body at any time. Foreshortening further prevents us from
+observing surface features along the planet's visible limb. Therefore
+it is important to know the coordinates of the center of the apparent
+disk, given by the \indexterm{central meridian} and latitude. In
+addition, we can also compute the \indexterm{subsolar point}, where
+the sun is visible in the zenith, and which provides the center of the
+illuminated hemisphere. This is not the center of the visible disk! A
+part of the illuminated hemisphere is generally on the far side of the
+planet.
+
+The north pole of the planets is the pole of rotation directed towards
+the north of the invariable plane (near the ecliptic) of the Solar
+system. Most planets are rotating in the same sense as they are moving
+around the sun. This is called
+\indexterm[rotation,prograde]{prograde}. Seen from the north side of
+the ecliptic, they rotate counterclockwise. Only a few objects, most
+notable Venus, are rotating clockwise, i.e.,
+\indexterm[rotation,retrograde]{retrograde}.
+
+For historical reasons, there are several ways to count
+longitudes. Just like the terrestrial zero meridian has been defined
+as that one running through Greenwich observatory\footnote{In earlier
+ times, at least each seafaring nation had its own zero meridian,
+ usually running through an official observatory.}, the zero meridian
+on rocky bodies like the Moon or Mars is usually defined by some
+surface feature like a small crater. For the gas planets, the rotation
+of the magnetic field is usually given to define the central
+meridian. Starting from this central meridian, we can count longitudes
+in both directions. For the Moon, which shows always (almost, see
+\ref{sec:Concepts:PlanetCoordinates}) the same side towards Earth, we
+count western and eastern longitudes from the central meridian towards
+the trailing or leading edge of its daily motion,
+respectively. (Seeing the Moon through an unguided telescope, we first
+see the eastern longitudes from $\approx 90^\circ$ to $0^\circ$, then
+the western longitudes from $0^\circ$ to $\approx 90^\circ$.)
+Alternatively we can count the western longitudes as negative. The
+counting continues to the (invisible) far side of the Moon where one
+meridian has an Eastern longitude of $+180^\circ=-180^\circ$.
+
+For other objects, historically, Mars was the first planet to be
+mapped with cartographic coordinates. Its rotational period of just
+over 24.5 hours allows to follow its rotation and observe only a
+slight change in appearance every day. It appeared natural to count
+the central meridian so that central longitude increased as time
+passed. Just like on Earth, as time passes, increasingly western
+longitudes receive sunlight and also become visible. Therefore these
+\indexterm[coordinates,planetographic]{planetographic} longitudes are
+counted towards the west on planets with prograde rotation. On
+planets with retrograde rotation like Venus, these longitudes are
+counted eastward.
+
+In contrast, current convention on Earth is to count geographic
+longitudes eastward.
+
+The information about coordinates for center and subsolar points in
+the information displayed for a planet is counted in this
+planetographic sense.
+
+Another convention are
+\indexterm[coordinates,planetocentric]{planetocentric coordinates}
+where longitudes are always counted positively towards the east. East
+is defined as going counterclockwise as seen from the north pole,
+which is itself defined as the one pole more closely aligned with
+Earth's north pole. The latest maps and data for Mars are using
+planetocentric data, i.e., eastern longitudes.
+
+For clarity, therefore coordinates are often explicitly written with ``E'' and
+``W'' instead of signed numbers.
+
+
+Another difference between planetographic and planetocentric
+coordinates is that the latter model the planet as simple sphere,
+ignoring the (usually small) flattening of the planet bodies.
+
+The surface coordinate systems defined by the WGPSN\footnote{IAU
+ Working Group for Planetary System Nomenclature --
+ \url{https://planetarynames.wr.usgs.gov/}} and used in Stellarium
+follows are shown in table
+\ref{tab:Nomenclature:coordinates}\footnote{\url{https://planetarynames.wr.usgs.gov/TargetCoordinates},
+ visited Jan.5, 2022}. However, given that the WGPSN publishes their
+data only with planetocentric latitudes, Stellarium provides planetocentric latitudes
+in the information panel for surface features.
+
+\begin{table}
+\begin{tabular}{lll>{$}r<{$}@{\ldots}>{$}l<{$} l}
+Target &\multicolumn{4}{c}{Coordinate Systems}&Control Networks\\
+ \hline
+Amalthea & Planetographic & +West & 0 & +360 & \\
+Ariel & Planetocentric & +East & 0 & +360 & \\
+Callisto & Planetographic & +West & 0 & +360 & \\
+Charon & Planetocentric & +East & 0 & +360 & Charon \\
+Deimos & Planetographic & +West & 0 & +360 & \\
+Dione & Planetographic & +West & 0 & +360 & \\
+Enceladus & Planetographic & +West & 0 & +360 & \\
+Epimetheus & Planetographic & +West & 0 & +360 & \\
+Europa & Planetographic & +West & 0 & +360 & \\
+Ganymede & Planetographic & +West & 0 & +360 & \\
+Hyperion & Planetographic & +West & 0 & +360 & \\
+Iapetus & Planetographic & +West & 0 & +360 & \\
+Io & Planetographic & +West & 0 & +360 & Voyager/Galileo SSI \\
+Janus & Planetographic & +West & 0 & +360 & \\
+Mars & Planetocentric & +East & 0 & +360 & MDIM 2.1 \\ % current as of Stellarium 0.21.3
+Mercury & Planetographic & +West & 0 & +360 & MESSENGER Team \\
+Mimas & Planetographic & +West & 0 & +360 & \\
+Miranda & Planetocentric & +East & 0 & +360 & \\
+Moon & Planetographic & +East & -180 & +180 & LOLA 2011, ULCN 2005 \\
+Oberon & Planetocentric & +East & 0 & +360 & \\
+Phobos & Planetographic & +West & 0 & +360 & \\
+Phoebe & Planetographic & +West & 0 & +360 & \\
+Pluto & Planetocentric & +East & 0 & +360 & Pluto \\
+Proteus & Planetographic & +West & 0 & +360 & \\
+Puck & Planetocentric & +East & 0 & +360 & \\
+Rhea & Planetographic & +West & 0 & +360 & \\
+Tethys & Planetographic & +West & 0 & +360 & \\
+Thebe & Planetographic & +West & 0 & +360 & \\
+Titan & Planetographic & +West & 0 & +360 & \\
+Titania & Planetocentric & +East & 0 & +360 & \\
+Triton & Planetographic & +East & 0 & +360 & \\
+Umbriel & Planetocentric & +East & 0 & +360 & \\
+Venus & Planetocentric & +East & 0 & +360 &
+\end{tabular}
+ \caption{Coordinate systems used by the WGPSN}
+ \label{tab:Nomenclature:coordinates}
+\end{table}
+
+
\section{How names are approved by the IAU}
\label{sec:Nomenclature:ApprovingNames}\index{IAU}
When images are first obtained of the surface of a planet or satellite, a theme for naming features is chosen
@@ -76,7 +208,7 @@ or geologic formations. Anyone may suggest that a specific name be considered by
If the members of the task group agree that the name is appropriate, it can be retained for use
when there is a request from a member of the scientific community that a specific feature be named.
Names successfully reviewed by a task group are submitted to the IAU Working Group for Planetary System
-Nomenclature (WGPSN)\footnote{Working Group for Planetary System Nomenclature -- \url{https://planetarynames.wr.usgs.gov/}}.
+Nomenclature (WGPSN).
Upon successful review by the members of the WGPSN, names are considered provisionally approved and can be
used on maps and in publications as long as the provisional status is clearly stated.
Provisional names are then presented for adoption to the IAU's General Assembly, which met triennially in the past,
diff --git a/guide/structure.tex b/guide/structure.tex
index 7a18438cdb..4f10b7ff24 100644
--- a/guide/structure.tex
+++ b/guide/structure.tex
@@ -258,6 +258,7 @@
% BIBLIOGRAPHY AND INDEX
%----------------------------------------------------------------------------------------
+\usepackage{csquotes} % recommended when using biblatex and babel
%\usepackage[style=numeric,citestyle=numeric,sorting=nyt,sortcites=true,autopunct=true,autolang=hyphen,hyperref=true,abbreviate=false,backref=true,backend=biber]{biblatex}
\usepackage[style=authoryear-comp,citestyle=authoryear,natbib=true,sorting=nyt,sortcites=true,autopunct=true,autolang=hyphen,hyperref=true,abbreviate=false,backref=true,backend=biber]{biblatex}
\addbibresource{guide.bib} % BibTeX bibliography file
diff --git a/src/core/StelObject.cpp b/src/core/StelObject.cpp
index 31b968a574..d15c156d7b 100644
--- a/src/core/StelObject.cpp
+++ b/src/core/StelObject.cpp
@@ -143,7 +143,7 @@ bool StelObject::isAboveRealHorizon(const StelCore *core) const
float StelObject::getVMagnitude(const StelCore* core) const
{
Q_UNUSED(core)
- return 99;
+ return 99.f;
}
Vec4d StelObject::getRTSTime(const StelCore *core, const double altitude) const
diff --git a/src/core/StelPainter.cpp b/src/core/StelPainter.cpp
index df67a65d89..5bfb583297 100644
--- a/src/core/StelPainter.cpp
+++ b/src/core/StelPainter.cpp
@@ -233,6 +233,15 @@ void StelPainter::setBlending(bool enableBlending, GLenum blendSrc, GLenum blend
}
}
+bool StelPainter::getBlending(GLenum *src, GLenum *dst) const
+{
+ if (dst!=Q_NULLPTR)
+ *dst=glState.blendDst;
+ if (src!=Q_NULLPTR)
+ *src=glState.blendSrc;
+ return glState.blend;
+}
+
void StelPainter::setDepthTest(bool enable)
{
if(glState.depthTest != enable)
diff --git a/src/core/StelPainter.hpp b/src/core/StelPainter.hpp
index b04fc2adfa..84571037ea 100644
--- a/src/core/StelPainter.hpp
+++ b/src/core/StelPainter.hpp
@@ -255,6 +255,10 @@ public:
//! the StelPainter is destroyed.
void setBlending(bool enableBlending, GLenum blendSrc = GL_SRC_ALPHA, GLenum blendDst = GL_ONE_MINUS_SRC_ALPHA);
+ //! Retrieve current blending configuration
+ //! It is useful to preserve and restore these settings with setBlending() later.
+ bool getBlending(GLenum *src=Q_NULLPTR, GLenum *dst=Q_NULLPTR) const;
+
void setDepthTest(bool enable);
void setDepthMask(bool enable);
diff --git a/src/core/StelUtils.cpp b/src/core/StelUtils.cpp
index ede71d9cc6..364c2d9687 100644
--- a/src/core/StelUtils.cpp
+++ b/src/core/StelUtils.cpp
@@ -380,6 +380,54 @@ QString decDegToDmsStr(const double angle)
return QString("%1%2%3%4\'%5\"").arg(sign?'+':'-').arg(d).arg(QChar(0x00B0)).arg(m,2,10,QLatin1Char('0')).arg(static_cast<unsigned int>(s),2,10,QLatin1Char('0'));
}
+// Convert latitude in decimal degrees to a dms formatted string.
+QString decDegToLatitudeStr(const double latitude, bool dms)
+{
+ bool sign;
+ double s;
+ unsigned int d, m;
+ decDegToDms(latitude, sign, d, m, s);
+ // Important note: we use untranslatable designations for North and South directions,
+ // because on some languages (e.g. Russian) the name of direction is
+ // followed the value of latitude.
+ // Example: N50.036 = 50.036 с.ш. (Russian; "с.ш." = "n.l." (northern latitude))
+ if (dms)
+ return QString("%1%2%3%4\'%5\"").arg(sign ? 'N' : 'S').arg(d).arg(QChar(0x00B0)).arg(m,2,10,QLatin1Char('0')).arg(static_cast<unsigned int>(s),2,10,QLatin1Char('0'));
+ else
+ return QString("%1%2%3").arg(sign ? 'N' : 'S').arg(QString::number(fabs(latitude), 'f', 4), QChar(0x00B0));
+}
+
+// default values as for Earth
+QString decDegToLongitudeStr(const double longitude, bool eastPositive, bool semiSphere, bool dms)
+{
+ bool sign;
+ double s, longMod = longitude;
+ unsigned int d, m;
+ QString positive, negative;
+ if (eastPositive)
+ {
+ positive = "E";
+ negative = "W";
+ }
+ else
+ {
+ longMod = fmodpos(360.-longitude, 360.); // avoid 360.0 for the poles!
+ positive = "W";
+ negative = "E";
+ }
+ if (semiSphere)
+ longMod = longitude > 180. ? longitude-360. : longitude;
+ decDegToDms(longMod, sign, d, m, s);
+ // Important note: we use untranslatable designations for East and West directions,
+ // because on some languages (e.g. Russian) the name of direction is
+ // followed the value of longitude.
+ // Example: E82.136 = 82.136 в.д. (Russian; "в.д." = "e.l." (eastern longitude))
+ if (dms)
+ return QString("%1%2%3%4\'%5\"").arg(sign ? positive : negative).arg(d).arg(QChar(0x00B0)).arg(m,2,10,QLatin1Char('0')).arg(static_cast<unsigned int>(s),2,10,QLatin1Char('0'));
+ else
+ return QString("%1%2%3").arg(sign ? positive : negative).arg(QString::number(fabs(longMod), 'f', 4), QChar(0x00B0));
+}
+
// Convert a dms formatted string to an angle in radian
double dmsStrToRad(const QString& s)
{
diff --git a/src/core/StelUtils.hpp b/src/core/StelUtils.hpp
index 9de4dc22d2..be04f1bab2 100644
--- a/src/core/StelUtils.hpp
+++ b/src/core/StelUtils.hpp
@@ -187,6 +187,18 @@ namespace StelUtils
//! @param angle input angle in decimal degrees
QString decDegToDmsStr(const double angle);
+ //! Convert latitude in decimal degrees to a dms formatted string or use decimal values.
+ //! @param latitude in decimal degrees
+ //! @param dms set true to use DMS formatted string
+ QString decDegToLatitudeStr(const double latitude, bool dms = true);
+
+ //! Convert longitude in decimal degrees to a dms formatted string.
+ //! @param longitude in decimal degrees
+ //! @param eastPositive set true to counting East direction positive
+ //! @param semiSphere set true to use -180..180 degrees range (0..360 degrees otherwise)
+ //! @param dms set true to use DMS formatted string
+ QString decDegToLongitudeStr(const double longitude, bool eastPositive = true, bool semiSphere = true, bool dms = true);
+
//! Convert a dms formatted string to an angle in radian
//! @param s The input string
double dmsStrToRad(const QString& s);
diff --git a/src/core/modules/NomenclatureItem.cpp b/src/core/modules/NomenclatureItem.cpp
index f78ce1e0f7..403a64668e 100644
--- a/src/core/modules/NomenclatureItem.cpp
+++ b/src/core/modules/NomenclatureItem.cpp
@@ -31,6 +31,7 @@
const QString NomenclatureItem::NOMENCLATURE_TYPE = QStringLiteral("NomenclatureItem");
Vec3f NomenclatureItem::color = Vec3f(0.1f,1.0f,0.1f);
bool NomenclatureItem::hideLocalNomenclature = false;
+LinearFader NomenclatureItem::labelsFader;
NomenclatureItem::NomenclatureItem(PlanetP nPlanet,
int nId,
@@ -153,29 +154,27 @@ QString NomenclatureItem::getNomenclatureTypeDescription(NomenclatureItemType nT
float NomenclatureItem::getSelectPriority(const StelCore* core) const
{
- float priority = StelObject::getSelectPriority(core);
- if (getFlagLabels())
- {
- const float scale = getAngularSizeRatio(core);
- if (planet->getVMagnitude(core)>=20.f || (planet->getJ2000EquatorialPos(core).lengthSquared() < getJ2000EquatorialPos(core).lengthSquared()))
- {
- // The feature on far-side of the planet or the planet is too faint for view
- // (in deep shadow for example), so let's disable selecting the nomenclature
- priority += 25.f;
- }
- else if (scale>=0.015f)
- {
- // The item may be good selectable when it over 37px size only
- //priority -= (20.f + scale*100.f);
- priority = planet->getSelectPriority(core) - scale*100.f;
- if (nType>=NomenclatureItemType::niSpecialPointPole)
- priority -= 10.f;
- }
- else
- priority -= 2.f;
- }
+ if (!getFlagLabels()) // disable if switched off.
+ return 1.e12f;
+
+ // Exclude if the planet is too faint for view (in deep shadow for example),
+ // or if feature is on far-side of the planet
+ if (planet->getVMagnitude(core)>=20.f || (planet->getJ2000EquatorialPos(core).lengthSquared() < getJ2000EquatorialPos(core).lengthSquared()))
+ return 1.e12f;
+
+ // Start with a priority just slightly lower than the carrier planet,
+ // so that clicking on the planet in halo does not select any feature point.
+ float priority=planet->getSelectPriority(core)+5.f;
+ // check visibility of feature
+ const float scale = getAngularDiameterRatio(core);
+ const float planetScale = 2.f*static_cast<float>(planet->getAngularSize(core))/core->getProjection(StelCore::FrameJ2000)->getFov();
+
+ // Require the planet to cover 1/10 of the screen to make it worth clicking on features.
+ // scale 0.04 is equal to the rendering criterion. Allow 0.02 for clicking on smaller features.
+ if ((scale>0.02f) && planetScale > 0.1f)
+ priority -= 5.f + 4.f * scale;
else
- priority += 1.e12f; // suppress selection if switched off.
+ priority+=1.e12f; // disallow selection
return priority;
}
@@ -205,6 +204,7 @@ QString NomenclatureItem::getInfoString(const StelCore* core, const InfoStringGr
{
QString str;
QTextStream oss(&str);
+ const bool withDecimalDegree = StelApp::getInstance().getFlagShowDecimalDegrees();
if (flags&Name)
{
@@ -240,41 +240,43 @@ QString NomenclatureItem::getInfoString(const StelCore* core, const InfoStringGr
if (flags&Extra)
{
- if (nType < NomenclatureItemType::niSpecialPointPole)
+ const QString cType = isPlanetocentric() ? q_("Planetocentric coordinates") : q_("Planetographic coordinates");
+ QString sLong = StelUtils::decDegToLongitudeStr(longitude, isEastPositive(), is180(), !withDecimalDegree),
+ sLat = StelUtils::decDegToLatitudeStr(latitude, !withDecimalDegree);
+ if (nType>=NomenclatureItemType::niSpecialPointEast && planet->getEnglishName()=="Jupiter")
{
- // TODO for 0.22.0 It seems the (numerical) planetary longitudes of NomenclatureItems are off by (usually) 360-longitude.
- // For 0.21.3 we must now hide the coordinates for the special points, but fix this ASAP.
- QString sLong = StelUtils::decDegToDmsStr(longitude), sLat = StelUtils::decDegToDmsStr(latitude);
- if (nType>=NomenclatureItemType::niSpecialPointEast && planet->getEnglishName()=="Jupiter")
+ // Due to Jupiter's issues around GRS shift we must repeat some calculations here.
+ double lng=0., lat=0.;
+ // East/West points are assumed to be along the equator, on the planet rim. Start with sub-observer point
+ if (nType==NomenclatureItemType::niSpecialPointEast || nType==NomenclatureItemType::niSpecialPointWest)
{
- // Due to Jupiter's issues around GRS shift we must repeat some calculations here.
- double lng=0., lat=0.;
- // East/West points are assumed to be along the equator, on the planet rim. Start with sub-observer point
- if (nType==NomenclatureItemType::niSpecialPointEast || nType==NomenclatureItemType::niSpecialPointWest)
- {
- QPair<Vec4d, Vec3d> subObs = planet->getSubSolarObserverPoints(core, false);
- lng = - subObs.first[2] * M_180_PI + ((nType==NomenclatureItemType::niSpecialPointEast) ? 90. : -90.);
- Q_ASSERT(lat==0.);
- }
- // Center and Subsolar points are similar.
- if (nType==NomenclatureItemType::niSpecialPointCenter || nType==NomenclatureItemType::niSpecialPointSubSolar)
- {
- QPair<Vec4d, Vec3d> subObs = planet->getSubSolarObserverPoints(core, false);
- lat = M_180_PI * (nType==NomenclatureItemType::niSpecialPointCenter ? subObs.first[1]: subObs.second[1]);
- lng = - M_180_PI * (nType==NomenclatureItemType::niSpecialPointCenter ? subObs.first[2]: subObs.second[2]);
- }
- lng = StelUtils::fmodpos(lng, 360.);
- sLong = StelUtils::decDegToDmsStr(360.-lng);
- sLat = StelUtils::decDegToDmsStr(lat);
+ QPair<Vec4d, Vec3d> subObs = planet->getSubSolarObserverPoints(core, false);
+ lng = - subObs.first[2] * M_180_PI + ((nType==NomenclatureItemType::niSpecialPointEast) ? 90. : -90.);
+ Q_ASSERT(lat==0.);
}
- oss << QString("%1: %2/%3<br/>").arg(q_("Planetographic long./lat."), sLong, sLat);
+ // Center and Subsolar points are similar.
+ if (nType==NomenclatureItemType::niSpecialPointCenter || nType==NomenclatureItemType::niSpecialPointSubSolar)
+ {
+ QPair<Vec4d, Vec3d> subObs = planet->getSubSolarObserverPoints(core, false);
+ lat = M_180_PI * (nType==NomenclatureItemType::niSpecialPointCenter ? subObs.first[1]: subObs.second[1]);
+ lng = - M_180_PI * (nType==NomenclatureItemType::niSpecialPointCenter ? subObs.first[2]: subObs.second[2]);
+ }
+ lng = StelUtils::fmodpos(lng, 360.);
+ sLong = StelUtils::decDegToLongitudeStr(360.-lng, isEastPositive(), is180(), !withDecimalDegree);
+ sLat = StelUtils::decDegToLatitudeStr(lat, !withDecimalDegree);
}
+ oss << QString("%1: %2/%3<br/>").arg(cType, sLat, sLong);
oss << QString("%1: %2<br/>").arg(q_("Celestial body"), planet->getNameI18n());
QString description = getNomenclatureTypeDescription(nType, planet->getEnglishName());
if (nType!=NomenclatureItem::niUNDEFINED && nType<NomenclatureItem::niSpecialPointPole && !description.isEmpty())
oss << QString("%1: %2<br/>").arg(q_("Landform description"), description);
if (planet->getEnglishName()!="Jupiter") // we must exclude this for now due to Jupiter's "off" rotation
oss << QString("%1: %2°<br/>").arg(q_("Solar altitude"), QString::number(getSolarAltitude(core), 'f', 1));
+
+ // DEBUG output. This should help defining valid criteria for selection priority.
+ // oss << QString("Planet angular size (semidiameter!): %1''<br/>").arg(QString::number(planet->getAngularSize(core)*3600.));
+ // oss << QString("Angular size: %1''<br/>").arg(QString::number(getAngularSize(core)*3600.));
+ // oss << QString("Angular size ratio: %1<br/>").arg(QString::number(static_cast<double>(getAngularDiameterRatio(core)), 'f', 5));
}
postProcessInfoString(str, flags);
@@ -313,21 +315,20 @@ Vec3d NomenclatureItem::getJ2000EquatorialPos(const StelCore* core) const
{
longitude = - subObs.first[2] * M_180_PI;
if (planet->isRotatingRetrograde()) longitude *= -1;
- latitude = subObs.first[1] * M_180_PI; // or first[0]???
+ latitude = subObs.first[0] * M_180_PI; // all IAU WGPSN data are planetocentric (spherical)
}
else
{
longitude = - subObs.second[2] * M_180_PI;
if (planet->isRotatingRetrograde()) longitude *= -1;
- latitude = subObs.second[1] * M_180_PI; // or second[0]???
+ latitude = subObs.second[0] * M_180_PI; // all IAU WGPSN data are planetocentric (spherical)
}
longitude=StelUtils::fmodpos(longitude, 360.);
// rebuild XYZpc
StelUtils::spheToRect(longitude * M_PI_180, latitude * M_PI_180, XYZpc);
}
// Calculate the radius of the planet at the item's position. It is necessary to re-scale it
- Vec4d rect = planet->getRectangularCoordinates(longitude, latitude);
- Vec3d XYZ0 = XYZpc * (rect[3] * static_cast<double>(planet->getSphereScale()));
+ Vec3d XYZ0 = XYZpc * planet->getEquatorialRadius() * static_cast<double>(planet->getSphereScale());
// TODO2: intersect properly with OBJ bodies! (LP:1723742)
/* We have to calculate feature's coordinates in VSOP87 (this is Ecliptic J2000 coordinates).
@@ -339,32 +340,21 @@ Vec3d NomenclatureItem::getJ2000EquatorialPos(const StelCore* core) const
return XYZ;
}
-float NomenclatureItem::getVMagnitude(const StelCore* core) const
-{
- Q_UNUSED(core);
- return 99.f;
-}
-
+// Return apparent semidiameter
double NomenclatureItem::getAngularSize(const StelCore* core) const
{
- return std::atan2(size*planet->getSphereScale()/AU, getJ2000EquatorialPos(core).length()) * M_180_PI;
+ return std::atan2(0.5*size*planet->getSphereScale()/AU, getJ2000EquatorialPos(core).length()) * M_180_PI;
}
-float NomenclatureItem::getAngularSizeRatio(const StelCore *core) const
+float NomenclatureItem::getAngularDiameterRatio(const StelCore *core) const
{
- return static_cast<float>(getAngularSize(core))/core->getProjection(StelCore::FrameJ2000)->getFov();
-}
-
-void NomenclatureItem::update(double deltaTime)
-{
- labelsFader.update(static_cast<int>(deltaTime*1000));
+ return static_cast<float>(2.*getAngularSize(core))/core->getProjection(StelCore::FrameJ2000)->getFov();
}
void NomenclatureItem::draw(StelCore* core, StelPainter *painter)
{
- if (!getFlagLabels())
- return;
-
+ // Called by NomenclatureMgr, so we don't need to check if labelsFader is true.
+ // The painter has been set to enable blending.
const Vec3d equPos = planet->getJ2000EquatorialPos(core);
Vec3d XYZ = getJ2000EquatorialPos(core);
@@ -381,7 +371,7 @@ void NomenclatureItem::draw(StelCore* core, StelPainter *painter)
// check visibility of feature
Vec3d srcPos;
- const float scale = getAngularSizeRatio(core);
+ const float scale = getAngularDiameterRatio(core);
NomenclatureItem::NomenclatureItemType niType = getNomenclatureType();
if (painter->getProjector()->projectCheck(XYZ, srcPos) && (equPos.lengthSquared() >= XYZ.lengthSquared())
&& (scale>0.04f && (scale<0.5f || niType>=NomenclatureItem::niSpecialPointPole )))
@@ -389,7 +379,7 @@ void NomenclatureItem::draw(StelCore* core, StelPainter *painter)
float brightness=(getSolarAltitude(core)<0. ? 0.25f : 1.0f);
if (niType>=NomenclatureItem::niSpecialPointPole)
brightness = 0.5f;
- painter->setColor(color*brightness, 1.0f);
+ painter->setColor(color*brightness, labelsFader.getInterstate());
painter->drawCircle(static_cast<float>(srcPos[0]), static_cast<float>(srcPos[1]), 2.f);
painter->drawText(static_cast<float>(srcPos[0]), static_cast<float>(srcPos[1]), nameI18n, 0, 5.f, 5.f, false);
}
@@ -471,6 +461,82 @@ NomenclatureItem::NomenclatureItemType NomenclatureItem::getNomenclatureItemType
}
QMap<NomenclatureItem::NomenclatureItemType, QString> NomenclatureItem::niTypeStringMap;
QMap<NomenclatureItem::NomenclatureItemType, QString> NomenclatureItem::niTypeDescriptionMap;
+NomenclatureItem::PlanetCoordinateOrientation NomenclatureItem::getPlanetCoordinateOrientation(QString planetName)
+{
+ // data from https://planetarynames.wr.usgs.gov/TargetCoordinates.
+ // Commented away where they are equal to te default value.
+ static const QMap<QString, NomenclatureItem::PlanetCoordinateOrientation> niPCOMap = {
+ //{"Amalthea" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Ariel" , NomenclatureItem::pcoPlanetocentricEast360 },
+ //{"Callisto" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Charon" , NomenclatureItem::pcoPlanetocentricEast360 },
+ //{"Deimos" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Dione" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Enceladus" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Epimetheus" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Europa" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Ganymede" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Hyperion" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Iapetus" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Io" , NomenclatureItem::pcoPlanetographicWest360 }, // Voyager/Galileo SSI
+ //{"Janus" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Mars" , NomenclatureItem::pcoPlanetocentricEast360 }, // MDIM 2.1
+ //{"Mercury" , NomenclatureItem::pcoPlanetographicWest360 }, // Preliminary MESSENGER MESSENGER Team
+ //{"Mimas" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Miranda" , NomenclatureItem::pcoPlanetocentricEast360 },
+ {"Moon" , NomenclatureItem::pcoPlanetographicEast180 }, // LOLA 2011 ULCN 2005
+ {"Oberon" , NomenclatureItem::pcoPlanetocentricEast360 },
+ //{"Phobos" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Phoebe" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Pluto" , NomenclatureItem::pcoPlanetocentricEast360 },
+ //{"Proteus" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Puck" , NomenclatureItem::pcoPlanetocentricEast360 },
+ //{"Rhea" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Tethys" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Thebe" , NomenclatureItem::pcoPlanetographicWest360 },
+ //{"Titan" , NomenclatureItem::pcoPlanetographicWest360 },
+ {"Titania" , NomenclatureItem::pcoPlanetocentricEast360 },
+ {"Triton" , NomenclatureItem::pcoPlanetographicEast360 },
+ {"Umbriel" , NomenclatureItem::pcoPlanetocentricEast360 },
+ {"Venus" , NomenclatureItem::pcoPlanetocentricEast360 }};
+ return niPCOMap.value(planetName, NomenclatureItem::pcoPlanetographicWest360);
+}
+
+NomenclatureItem::PlanetCoordinateOrientation NomenclatureItem::getPlanetCoordinateOrientation() const
+{
+ return getPlanetCoordinateOrientation(planet->getEnglishName());
+}
+
+bool NomenclatureItem::isPlanetocentric(PlanetCoordinateOrientation pco)
+{
+ // Our data is already converted to be planetocentric.
+ //return pco & 0x100;
+ Q_UNUSED(pco)
+ return true;
+}
+bool NomenclatureItem::isEastPositive(PlanetCoordinateOrientation pco)
+{
+ return pco & 0x010;
+}
+bool NomenclatureItem::is180(PlanetCoordinateOrientation pco)
+{
+ return pco & 0x001;
+}
+bool NomenclatureItem::isPlanetocentric() const
+{
+ // Our data is already converted to be planetocentric.
+ // return isPlanetocentric(getPlanetCoordinateOrientation());
+ return true;
+}
+bool NomenclatureItem::isEastPositive() const
+{
+ return isEastPositive(getPlanetCoordinateOrientation());
+}
+bool NomenclatureItem::is180() const
+{
+ return is180(getPlanetCoordinateOrientation());
+}
+
void NomenclatureItem::createNameLists()
{
niTypeStringMap = {
@@ -714,3 +780,17 @@ void NomenclatureItem::createNameLists()
{ niSpecialPointCenter, ""},
{ niSpecialPointSubSolar, ""}};
}
+
+// Compute times of nearest rise, transit and set of the current Planet.
+// @param core the currently active StelCore object
+// @param altitude (optional; default=0) altitude of the object, degrees.
+// Setting this to -6. for the Sun will find begin and end for civil twilight.
+// @return Vec4d - time of rise, transit and set closest to current time; JD.
+// @note The fourth element flags particular conditions:
+// * +100. for circumpolar objects. Rise and set give lower culmination times.
+// * -100. for objects never rising. Rise and set give transit times.
+// * -1000. is used as "invalid" value. The result should then not be used.
+Vec4d NomenclatureItem::getRTSTime(const StelCore* core, const double altitude) const
+{
+ return planet->getRTSTime(core, altitude);
+}
diff --git a/src/core/modules/NomenclatureItem.hpp b/src/core/modules/NomenclatureItem.hpp
index 27599025b5..f2f69ae973 100644
--- a/src/core/modules/NomenclatureItem.hpp
+++ b/src/core/modules/NomenclatureItem.hpp
@@ -35,6 +35,14 @@
class StelPainter;
+//! Class which contains data about one Nomenclature entry from the IAU database at https://planetarynames.wr.usgs.gov/
+//! There is a confusing variety of planetographic vs. planetocentric coordinate systems,
+//! counting longitudes in eastern or western direction, or counting from 0...360 degrees or from -180...+180 degrees.
+//! The actual data were taken from https://planetarynames.wr.usgs.gov/GIS_Downloads
+//! and include eastward-positive planetocentric coordinates, i.a. all bodies are treated as spheres. However, according to
+//! https://planetarynames.wr.usgs.gov/TargetCoordinates on some objects at least the longitudes should be counted west-positive,
+//! a convention which we should follow closely. Note that for Mars the traditional west-positive counting has recently been inverted,
+//! and longitudes are now counted east-positive like on earth.
class NomenclatureItem : public StelObject
{
friend class NomenclatureMgr;
@@ -110,6 +118,20 @@ public:
};
Q_ENUM(NomenclatureItemType)
+ // Describes the orientation of the given feature coordinates
+ enum PlanetCoordinateOrientation
+ {
+ pcoPlanetographicWest360 = 0x000,
+ pcoPlanetographicWest180 = 0x001,
+ pcoPlanetographicEast360 = 0x010,
+ pcoPlanetographicEast180 = 0x011,
+ pcoPlanetocentricWest360 = 0x100,
+ pcoPlanetocentricWest180 = 0x101,
+ pcoPlanetocentricEast360 = 0x110,
+ pcoPlanetocentricEast180 = 0x111
+ };
+ Q_ENUM(PlanetCoordinateOrientation)
+
NomenclatureItem(PlanetP nPlanet, int nId, const QString& nName, const QString& nContext, NomenclatureItemType nItemType, double nLatitude, double nLongitude, double nSize);
virtual ~NomenclatureItem() Q_DECL_OVERRIDE;
@@ -132,9 +154,9 @@ public:
virtual QString getInfoString(const StelCore* core, const InfoStringGroup& flags) const Q_DECL_OVERRIDE;
virtual Vec3f getInfoColor(void) const Q_DECL_OVERRIDE;
virtual Vec3d getJ2000EquatorialPos(const StelCore*) const Q_DECL_OVERRIDE;
- //! Get the visual magnitude of a nomenclature item. Dummy method, returns 99.
- virtual float getVMagnitude(const StelCore* core) const Q_DECL_OVERRIDE;
- //! Get the angular size of nomenclature item.
+ //! Return the angular radius of a circle containing the feature as seen from the observer
+ //! with the circle center assumed to be at getJ2000EquatorialPos().
+ //! @return radius in degree. This value is half of the apparent angular size of the object, and is independent of the current FOV.
virtual double getAngularSize(const StelCore* core) const Q_DECL_OVERRIDE;
//! Get the localized name of nomenclature item.
virtual QString getNameI18n(void) const Q_DECL_OVERRIDE;
@@ -145,12 +167,21 @@ public:
//! Translate feature name using the passed translator
virtual void translateName(const StelTranslator &trans);
+ //! Compute times of nearest rise, transit and set of the item's current Planet.
+ //! @param core the currently active StelCore object
+ //! @param altitude (optional; default=0) altitude of the object, degrees.
+ //! @return Vec4d - time of rise, transit and set closest to current time; JD.
+ //! @note The fourth element flags particular conditions:
+ //! * +100. for circumpolar objects. Rise and set give lower culmination times.
+ //! * -100. for objects never rising. Rise and set give transit times.
+ //! * -1000. is used as "invalid" value. The result should then not be used.
+ virtual Vec4d getRTSTime(const StelCore* core, const double altitude=0.) const Q_DECL_OVERRIDE;
+
void draw(StelCore* core, StelPainter *painter);
NomenclatureItemType getNomenclatureType() const { return nType;}
- void update(double deltaTime);
- void setFlagLabels(bool b){ labelsFader = b; }
- bool getFlagLabels(void) const { return labelsFader==true;}
+ static void setFlagLabels(bool b){ labelsFader = b; }
+ static bool getFlagLabels(void){ return labelsFader;}
void setFlagHideLocalNomenclature(bool b) { hideLocalNomenclature=b; }
bool getFlagHideLocalNomenclature() const { return hideLocalNomenclature; }
//QString getEnglishPlanetName(void) const {return planet->getEnglishName();}
@@ -176,11 +207,29 @@ private:
static bool hideLocalNomenclature;
// ratio of angular size of feature to the FOV
- float getAngularSizeRatio(const StelCore *core) const;
+ float getAngularDiameterRatio(const StelCore *core) const;
static QString getNomenclatureTypeLatinString(NomenclatureItemType nType);
static QString getNomenclatureTypeString(NomenclatureItemType nType);
static QString getNomenclatureTypeDescription(NomenclatureItemType nType, QString englishName);
+ //! Returns the description of the feature coordinates where available, or pcoPlanetographicWest360.
+ //! The default value ensures valid central meridian data for the gas giants.
+ static PlanetCoordinateOrientation getPlanetCoordinateOrientation(QString planetName);
+ PlanetCoordinateOrientation getPlanetCoordinateOrientation() const;
+ //! return whether counting sense of the coordinates is positive towards the east
+ static bool isEastPositive(PlanetCoordinateOrientation pco);
+ //! return whether coordinates are planetocentric (and not planetographic)
+ //! Given that the source data are planetocentric, this returns always true.
+ static bool isPlanetocentric(PlanetCoordinateOrientation pco);
+ //! return whether longitudes shall be counted from -180 to +180 degrees (and not 0...360 degrees)
+ static bool is180(PlanetCoordinateOrientation pco);
+ //! return whether counting sense of the coordinates is positive towards the east
+ bool isEastPositive() const;
+ //! return whether coordinates are planetocentric (and not planetographic).
+ //! Given that the source data are planetocentric, this returns always true.
+ bool isPlanetocentric() const;
+ //! return whether longitudes shall be counted from -180 to +180 degrees (and not 0...360 degrees)
+ bool is180() const;
static QMap<NomenclatureItemType, QString>niTypeStringMap;
static QMap<NomenclatureItemType, QString>niTypeDescriptionMap;
@@ -192,7 +241,7 @@ private:
mutable double longitude; // degrees. Declared mutable to allow change in otherwise const methods (for special points)
double size; // km
- LinearFader labelsFader;
+ static LinearFader labelsFader;
};
#endif // NOMENCLATUREITEM_HPP
diff --git a/src/core/modules/NomenclatureMgr.cpp b/src/core/modules/NomenclatureMgr.cpp
index 3f87d0adc0..0f100a99a1 100644
--- a/src/core/modules/NomenclatureMgr.cpp
+++ b/src/core/modules/NomenclatureMgr.cpp
@@ -92,10 +92,10 @@ void NomenclatureMgr::updateNomenclatureData()
void NomenclatureMgr::loadSpecialNomenclature()
{
int featureId = 50000;
- QList<PlanetP> ss = ssystem->getAllPlanets();
+ const QList<PlanetP> ss = ssystem->getAllPlanets();
for (const auto& p: ss)
{
- double size = p->getEquatorialRadius()*AU*0.25; // formal radius of point is 25% of equatorial radius
+ const double size = p->getEquatorialRadius()*AU*0.25; // formal radius of point is 25% of equatorial radius
NomenclatureItemP nomNP = NomenclatureItemP(new NomenclatureItem(p, featureId, N_("North Pole"), "", NomenclatureItem::niSpecialPointPole, 90., 0., size));
if (!nomNP.isNull())
nomenclatureItems.insert(p, nomNP);
@@ -151,7 +151,7 @@ void NomenclatureMgr::loadNomenclature()
QRegularExpression ctxRx("(.*)\",\\s*\"(.*)");
QString surfNamesFile = StelFileMgr::findFile("data/nomenclature.dat"); // compressed version of file nomenclature.fab
- if (!surfNamesFile.isEmpty()) // OK, the file is exist!
+ if (!surfNamesFile.isEmpty()) // OK, the file exists!
{
// Open file
QFile planetSurfNamesFile(surfNamesFile);
@@ -254,7 +254,7 @@ void NomenclatureMgr::loadNomenclature()
faultPlanets.removeDuplicates();
int err = faultPlanets.size();
if (err>0)
- qDebug() << "WARNING - The next planets to assign nomenclature items is not found:" << faultPlanets.join(", ");
+ qDebug() << "WARNING - These planets to assign nomenclature items were not found:" << faultPlanets.join(", ");
}
}
@@ -268,6 +268,14 @@ void NomenclatureMgr::draw(StelCore* core)
{
StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
StelPainter painter(prj);
+ painter.setBlending(true);
+
+ if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
+ drawPointer(core, painter);
+
+ if (NomenclatureItem::labelsFader.getInterstate()<=0.f)
+ return;
+
painter.setFont(font);
const SphericalCap& viewportRegion = painter.getProjector()->getBoundingCap();
@@ -295,9 +303,6 @@ void NomenclatureMgr::draw(StelCore* core)
nItem->draw(core, &painter);
}
}
-
- if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
- drawPointer(core, painter);
}
void NomenclatureMgr::drawPointer(StelCore* core, StelPainter& painter)
@@ -315,7 +320,6 @@ void NomenclatureMgr::drawPointer(StelCore* core, StelPainter& painter)
painter.setColor(obj->getInfoColor());
texPointer->bind();
- painter.setBlending(true);
painter.drawSprite2dMode(static_cast<float>(screenpos[0]), static_cast<float>(screenpos[1]), 13.f, static_cast<float>(StelApp::getInstance().getTotalRunTime()*40.));
}
}
@@ -491,20 +495,14 @@ void NomenclatureMgr::setFlagLabels(bool b)
{
if (getFlagLabels() != b)
{
- for (const auto& i : qAsConst(nomenclatureItems))
- i->setFlagLabels(b);
+ NomenclatureItem::setFlagLabels(b);
emit nomenclatureDisplayedChanged(b);
}
}
bool NomenclatureMgr::getFlagLabels() const
{
- for (const auto& i : nomenclatureItems)
- {
- if (i->getFlagLabels())
- return true;
- }
- return false;
+ return NomenclatureItem::getFlagLabels();
}
void NomenclatureMgr::setFlagHideLocalNomenclature(bool b)
diff --git a/src/core/modules/NomenclatureMgr.hpp b/src/core/modules/NomenclatureMgr.hpp
index 1ae87be78a..35d3f17154 100644
--- a/src/core/modules/NomenclatureMgr.hpp
+++ b/src/core/modules/NomenclatureMgr.hpp
@@ -57,7 +57,7 @@ public:
// Methods defined in the StelModule class
virtual void init() Q_DECL_OVERRIDE;
virtual void deinit() Q_DECL_OVERRIDE;
- virtual void update(double) Q_DECL_OVERRIDE{;}
+ virtual void update(double deltaTime) Q_DECL_OVERRIDE {NomenclatureItem::labelsFader.update(static_cast<int>(deltaTime*1000));}
virtual void draw(StelCore* core) Q_DECL_OVERRIDE;
virtual void drawPointer(StelCore* core, StelPainter& painter);
virtual double getCallOrder(StelModuleActionName actionName) const Q_DECL_OVERRIDE;
diff --git a/src/core/modules/Planet.cpp b/src/core/modules/Planet.cpp
index 12726b8f6e..85b852fa78 100644
--- a/src/core/modules/Planet.cpp
+++ b/src/core/modules/Planet.cpp
@@ -371,18 +371,18 @@ void Planet::setIAUMoonNumber(QString designation)
QString Planet::getEnglishName() const
{
- if (!iauMoonNumber.isEmpty())
- return QString("%1 (%2)").arg(englishName).arg(iauMoonNumber);
- else
- return englishName;
+ if (!iauMoonNumber.isEmpty())
+ return QString("%1 (%2)").arg(englishName, iauMoonNumber);
+ else
+ return englishName;
}
QString Planet::getNameI18n() const
{
- if (!iauMoonNumber.isEmpty())
- return QString("%1 (%2)").arg(nameI18).arg(iauMoonNumber);
- else
- return nameI18;
+ if (!iauMoonNumber.isEmpty())
+ return QString("%1 (%2)").arg(nameI18, iauMoonNumber);
+ else
+ return nameI18;
}
const QString Planet::getContextString() const
diff --git a/src/core/modules/Planet.hpp b/src/core/modules/Planet.hpp
index 23b5df809c..69d189c1f9 100644
--- a/src/core/modules/Planet.hpp
+++ b/src/core/modules/Planet.hpp
@@ -366,7 +366,10 @@ public:
//! @param longDeg longitude of location, degrees. (currently unused. Set to 0.)
//! @param latDeg planetographic latitude, degrees.
//! @param altMetres altitude above ellipsoid surface (metres)
- //! @return [rhoCosPhiPrime*a, rhoSinPhiPrime*a, phiPrime, rho*a] where a=equatorial radius
+ //! @return [rhoCosPhiPrime*a, rhoSinPhiPrime*a, phiPrime, rho*a]
+ //! where a=equatorial radius [AU]
+ //! phiPrime=planetocentric latitude
+ //! rho*a=planetocentric distance of point [AU]
Vec4d getRectangularCoordinates(const double longDeg, const double latDeg, const double altMetres=0.) const;
//! Get the phase angle (radians) for an observer at pos obsPos in heliocentric coordinates (in AU)
@@ -385,6 +388,10 @@ public:
static float getPAsun(const Vec3d &sunPos, const Vec3d &objPos);
//! Get planetographic coordinates of subsolar and sub-observer points.
+ //! These are defined so that over time the longitude of the central meridian increases.
+ //! This means longitudes are counted positive towards the west for direct rotators and positive
+ //! towards the East for negative rotators (e.g. Venus). Other cartographic conventions may have
+ //! to be followed elsewhere in the program, though. (e.g. planetary feature nomenclature!)
//! Only meaningful for earth-bound observers.
//! Source: Explanatory Supplement 2013, 10.4.1
//! @param jupiterGraphical Jupiter requires special treatment because its LII coordinate system does not
@@ -397,9 +404,9 @@ public:
//! second[0] = 10.26 phi_s [rad] Planetocentric latitude of sub-solar point
//! second[1] = 10.26 phi'_s [rad] Planetographic latitude of sub-solar point
//! second[2] = 10.26 lambda'_s [rad] Planetographic longitude of sub-solar point (0..2pi)
- //! Note: For the Moon, it is more common to give Libration angles, where L=-lambda'_e, B=phi'_e.
- //! Note: For Jupiter, this returns central meridian in L_II.
- //! Note: For Saturn, this returns central meridian in L_III (rotation of magnetic field).
+ //! @note: For the Moon, it is more common to give Libration angles, where L=-lambda'_e, B=phi'_e.
+ //! @note: For Jupiter, this returns central meridian in L_II.
+ //! @note: For Saturn, this returns central meridian in L_III (rotation of magnetic field).
QPair<Vec4d, Vec3d> getSubSolarObserverPoints(const StelCore *core, bool jupiterGraphical=false) const;
//! returns if planet has retrograde rotation
diff --git a/src/core/modules/SpecialMarkersMgr.cpp b/src/core/modules/SpecialMarkersMgr.cpp
index 71b6de5f12..04e2ac57aa 100644
--- a/src/core/modules/SpecialMarkersMgr.cpp
+++ b/src/core/modules/SpecialMarkersMgr.cpp
@@ -92,7 +92,8 @@ void SpecialSkyMarker::draw(StelCore *core) const
// Initialize a painter and set openGL state
StelPainter sPainter(prj);
StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams();
- sPainter.setColor(color, fader);
+ sPainter.setBlending(true);
+ sPainter.setColor(color, fader.getInterstate());
Vec2i centerScreen(prj->getViewportPosX() + prj->getViewportWidth() / 2, prj->getViewportPosY() + prj->getViewportHeight() / 2);
/////////////////////////////////////////////////
@@ -117,7 +118,7 @@ void SpecialSkyMarker::draw(StelCore *core) const
case FOV_CIRCULAR:
{
const double pixelsPerRad = static_cast<double>(prj->getPixelPerRadAtCenter());
- sPainter.drawCircle(centerScreen[0], centerScreen[1], 0.5f * pixelsPerRad * static_cast<float>(M_PI/180) * (angularSize[0]));
+ sPainter.drawCircle(centerScreen[0], centerScreen[1], 0.5f * static_cast<float>((M_PI/180.) * pixelsPerRad * angularSize[0]));
/*
* NOTE: uncomment the code for display FOV value in top right corner of marker
@@ -172,24 +173,23 @@ void SpecialSkyMarker::draw(StelCore *core) const
{
Vec3d pos, screenPos;
const int f = (StelApp::getInstance().getFlagSouthAzimuthUsage() ? 180 : 0);
- const float ppx = core->getCurrentStelProjectorParams().devicePixelsPerPixel;
- sPainter.setBlending(true);
+ const float ppx = static_cast<float>(core->getCurrentStelProjectorParams().devicePixelsPerPixel);
sPainter.setLineSmooth(true);
for(int i=0; i<360; i++)
{
- float a = i*M_PI/180;
- pos.set(sin(a),cos(a), 0.f);
- float h = -0.002;
+ double a = i*M_PI/180;
+ pos.set(sin(a),cos(a), 0.);
+ double h = -0.002;
if (i % 15 == 0)
{
h = -0.02; // the size of the mark every 15 degrees
QString s = QString("%1").arg((i+90+f)%360);
- float shiftx = ppx*sPainter.getFontMetrics().width(s) / 2.;
- float shifty = ppx*sPainter.getFontMetrics().height() / 2.;
- sPainter.drawText(pos, s, 0, -shiftx, shifty, false);
+ float shiftx = ppx*sPainter.getFontMetrics().boundingRect(s).width() *0.5f;
+ float shifty = ppx*sPainter.getFontMetrics().height() *0.5f;
+ sPainter.drawText(pos, s, 0, -shiftx, shifty);
}
else if (i % 5 == 0)
{
@@ -202,14 +202,11 @@ void SpecialSkyMarker::draw(StelCore *core) const
sPainter.drawGreatCircleArc(pos, Vec3d(pos[0], pos[1], h), Q_NULLPTR);
}
}
- sPainter.setBlending(false);
- sPainter.setLineSmooth(false);
}
break;
}
}
-
SpecialMarkersMgr::SpecialMarkersMgr()
{
setObjectName("SpecialMarkersMgr");
diff --git a/src/tests/testConversions.cpp b/src/tests/testConversions.cpp
index b45de44e12..6d599a8477 100644
--- a/src/tests/testConversions.cpp
+++ b/src/tests/testConversions.cpp
@@ -548,9 +548,99 @@ void TestConversions::testDDToDMSStr()
QString DMS = StelUtils::decDegToDmsStr(angle);
QVERIFY2(DMS==expDMS, qPrintable(QString("%1 degrees = %2 (expected %3)")
- .arg(QString::number(angle, 'f', 5))
- .arg(DMS)
- .arg(expDMS)));
+ .arg(QString::number(angle, 'f', 5), DMS, expDMS)));
+ }
+}
+
+void TestConversions::testDDToLatitudeStr()
+{
+ QVariantList data;
+ // case 1
+ data << 0. << true << "N0°00'00\"";
+ data << 10. << true << "N10°00'00\"";
+ data << -13.5 << true << "S13°30'00\"";
+ data << -90.1 << true << "S90°06'00\"";
+ data << 360.6 << true << "N360°36'00\"";
+ data << -0.01 << true << "S0°00'36\"";
+ // case 2
+ data << 0. << false << "N0.0000°";
+ data << 10. << false << "N10.0000°";
+ data << -13.5 << false << "S13.5000°";
+ data << -90.1 << false << "S90.1000°";
+ data << 360.6 << false << "N360.6000°";
+ data << -0.01 << false << "S0.0100°";
+
+ while (data.count()>=3)
+ {
+ double angle = data.takeFirst().toDouble();
+ bool useDMSfmt = data.takeFirst().toBool();
+ QString expDMS = data.takeFirst().toString();
+ QString DMS = StelUtils::decDegToLatitudeStr(angle, useDMSfmt);
+
+ QVERIFY2(DMS==expDMS, qPrintable(QString("%1 degrees = %2 (expected %3)").arg(QString::number(angle, 'f', 5), DMS, expDMS)));
+ }
+}
+
+void TestConversions::testDDToLongitudeStr()
+{
+ QVariantList data;
+ // case 1
+ data << 0. << true << true << true << "E0°00'00\"";
+ data << 10. << true << true << true << "E10°00'00\"";
+ data << -13.5 << true << true << true << "W13°30'00\"";
+ data << -90.1 << true << true << true << "W90°06'00\"";
+ data << 270.6 << true << true << true << "W89°24'00\"";
+ data << 360.6 << true << true << true << "E0°36'00\"";
+ data << -0.01 << true << true << true << "W0°00'36\"";
+ // case 2
+ data << 0. << true << true << false << "E0.0000°";
+ data << 10. << true << true << false << "E10.0000°";
+ data << -13.5 << true << true << false << "W13.5000°";
+ data << -90.1 << true << true << false << "W90.1000°";
+ data << 270.6 << true << true << false << "W89.4000°";
+ data << 360.6 << true << true << false << "E0.6000°";
+ data << -0.01 << true << true << false << "W0.0100°";
+ // case 3
+ data << 0. << false << true << true << "W0°00'00\"";
+ data << 10. << false << true << true << "W10°00'00\"";
+ data << -13.5 << false << true << true << "E13°30'00\"";
+ data << -90.1 << false << true << true << "E90°06'00\"";
+ data << 270.6 << false << true << true << "E89°24'00\"";
+ data << 360.6 << false << true << true << "W0°36'00\"";
+ data << -0.01 << false << true << true << "E0°00'36\"";
+ // case 4
+ data << 0. << false << true << false << "W0.0000°";
+ data << 10. << false << true << false << "W10.0000°";
+ data << -13.5 << false << true << false << "E13.5000°";
+ data << -90.1 << false << true << false << "E90.1000°";
+ data << 270.6 << false << true << false << "E89.4000°";
+ data << 360.6 << false << true << false << "W0.6000°";
+ data << -0.01 << false << true << false << "E0.0100°";
+ // case 5
+ data << 0. << true << false << true << "E0°00'00\"";
+ data << 10. << true << false << true << "E10°00'00\"";
+ data << -13.5 << true << false << true << "W13°30'00\"";
+ data << -90.1 << true << false << true << "W90°06'00\"";
+ data << 270.6 << true << false << true << "E270°36'00\"";
+ data << -0.01 << true << false << true << "W0°00'36\"";
+ // case 6
+ data << 0. << true << false << false << "E0.0000°";
+ data << 10. << true << false << false << "E10.0000°";
+ data << -13.5 << true << false << false << "W13.5000°";
+ data << -90.1 << true << false << false << "W90.1000°";
+ data << 270.6 << true << false << false << "E270.6000°";
+ data << -0.01 << true << false << false << "W0.0100°";
+
+ while (data.count()>=5)
+ {
+ double angle = data.takeFirst().toDouble();
+ bool eastPositive = data.takeFirst().toBool();
+ bool semiSphere = data.takeFirst().toBool();
+ bool useDMSfmt = data.takeFirst().toBool();
+ QString expDMS = data.takeFirst().toString();
+ QString DMS = StelUtils::decDegToLongitudeStr(angle, eastPositive, semiSphere, useDMSfmt);
+
+ QVERIFY2(DMS==expDMS, qPrintable(QString("%1 degrees = %2 (expected %3)").arg(QString::number(angle, 'f', 5), DMS, expDMS)));
}
}
diff --git a/src/tests/testConversions.hpp b/src/tests/testConversions.hpp
index 6976e2298a..74d502287d 100644
--- a/src/tests/testConversions.hpp
+++ b/src/tests/testConversions.hpp
@@ -38,6 +38,8 @@ private slots:
void testRadToDMSPStr();
void testDDToDMS();
void testDDToDMSStr();
+ void testDDToLatitudeStr();
+ void testDDToLongitudeStr();
void testRadToDD();
void testStringCoordinateToRad();
void testHMSToHours();
diff --git a/textures/tethys.png b/textures/tethys.png
index 32abdd92f7..6094e94480 100644
--- a/textures/tethys.png
+++ b/textures/tethys.png
Binary files differ