1 /***************************************************************************
2 * This file is part of Tecorrec. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * Tecorrec is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * Tecorrec is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with Tecorrec. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
25 * @brief Geographical coordinates.
36 /// Use doubles for angles.
37 typedef double tcGeoAngle
;
42 tcGeoAngleDMS(tcGeoAngle angle
, bool latitude
)
45 positive
= (angle
>= 0.0);
50 angle
*= 180.0 / M_PI
;
51 degrees
= (int)floor(angle
);
54 arcmins
= (int)floor(angle
);
56 arcsecs
= angle
* 60.0;
59 operator QString () const
61 return QObject::tr("%1\xB0%2'%3\"%4", "degrees, arcminutes, arcseconds, N/S/E/W")
63 .arg(arcmins
, 2, 10, QLatin1Char('0'))
64 .arg(arcsecs
, 5, 'f', 2, QLatin1Char('0'))
66 ? (positive
? QObject::tr("N", "north") : QObject::tr("S", "south"))
67 : (positive
? QObject::tr("E", "east") : QObject::tr("W", "west"))
78 /// Geographical coordinates.
84 * Constructors + destructor
87 /// Primary constructor.
94 /// Primary constructor.
95 tcGeo(const tcGeoAngle lon
, const tcGeoAngle lat
)
101 /// Primary constructor.
102 explicit tcGeo(const maths::Vector
<2,double> lonlat
)
103 : m_longitude(lonlat
[0])
104 , m_latitude(lonlat
[1])
108 /// Construct from a vector.
109 template <typename T
>
110 tcGeo(maths::Vector
<3,T
> vec
, bool normalized
)
116 m_longitude
= atan2(vec
[0], -vec
[1]);
117 m_latitude
= asin(vec
[2]);
124 /// Convert to a 2d position vector with same values.
125 operator maths::Vector
<2,double> () const
127 return maths::Vector
<2,double>(m_longitude
, m_latitude
);
130 /// Convert to a 3d direction vector.
131 operator maths::Vector
<3,float> () const
133 float z
= sinf(m_latitude
);
134 float xy
= cosf(m_latitude
);
135 return maths::Vector
<3,float>(xy
*sinf(m_longitude
), -xy
*cosf(m_longitude
), z
);
138 /// Convert to a 3d direction vector.
139 operator maths::Vector
<3,double> () const
141 //return this->operator maths::Matrix<3,double>() * maths::Vector<3,double>(0.0, 0.0, 1.0);
142 double z
= sin(m_latitude
);
143 double xy
= cos(m_latitude
);
144 return maths::Vector
<3,double>(xy
*sin(m_longitude
), -xy
*cos(m_longitude
), z
);
147 /// Convert to a rotation matrix.
148 operator maths::Matrix
<3,double> () const
150 return maths::Matrix
<3,double>(
151 maths::RotateRadMatrix44('x', m_latitude
-M_PI
/2)
153 maths::RotateRadMatrix44('z', -m_longitude
)
155 double sina
= sin(m_longitude
);
156 double cosa
= cos(m_longitude
);
157 double sine
= sin(m_latitude
-M_PI
/2);
158 double cose
= cos(m_latitude
-M_PI
/2);
160 [[cos(a), sin(a), 0],
161 [-sin(a) cos(-1/2 PI+e),cos(a) cos(-1/2 PI+e), sin(-1/2 PI+e)],
162 [sin(a) sin(-1/2 PI+e), -cos(a) sin(-1/2 PI+e),cos(-1/2 PI+e)]]
164 return maths::Matrix
<3,double>(
166 maths::Vector
<3,double>(cosa
, -sina
*cose
, sina
*sine
),
168 maths::Vector
<3,double>(sina
, cosa
*cose
, -cosa
*sine
),
170 maths::Vector
<3,double>(0.0, sine
, cose
)
178 /// Get the longitude.
179 tcGeoAngle
lon() const
183 /// Get the azimuth (longitude).
184 tcGeoAngle
azim() const
189 /// Get the latitude.
190 tcGeoAngle
lat() const
194 /// Get the elevation (latitude).
195 tcGeoAngle
elev() const
200 /// Get a textual description.
201 QString
describe() const
203 tcGeoAngleDMS
dmsLon(m_longitude
, false);
204 tcGeoAngleDMS
dmsLat(m_latitude
, true);
205 return QString("%1 %2").arg(dmsLat
).arg(dmsLon
);
212 /// Set the longitude.
213 void setLon(const tcGeoAngle lon
)
217 /// Set the azimuth (longitude).
218 void setAzim(const tcGeoAngle lon
)
223 /// Set the latitude.
224 void setLat(const tcGeoAngle lat
)
228 /// Set the elevation (latitude).
229 void setElev(const tcGeoAngle lat
)
234 /// Set the longitude and latitude.
235 void setLonLat(const tcGeoAngle lon
, const tcGeoAngle lat
)
240 /// Set the azimuth (longitude) and elevation (latitude).
241 void setAzimElev(const tcGeoAngle lon
, const tcGeoAngle lat
)
251 tcGeo
operator + (const tcGeo
& other
) const
253 return tcGeo(m_longitude
+ other
.m_longitude
,
254 m_latitude
+ other
.m_latitude
);
256 tcGeo
operator - (const tcGeo
& other
) const
258 return tcGeo(m_longitude
- other
.m_longitude
,
259 m_latitude
- other
.m_latitude
);
261 tcGeo
operator * (const tcGeoAngle factor
) const
263 return tcGeo(m_longitude
* factor
,
264 m_latitude
* factor
);
266 tcGeo
operator / (const tcGeoAngle factor
) const
268 return tcGeo(m_longitude
/ factor
,
269 m_latitude
/ factor
);
271 maths::Vector
<2,double> operator / (const tcGeo
& other
) const
273 return maths::Vector
<2,double>(m_longitude
/ other
.m_longitude
,
274 m_latitude
/ other
.m_latitude
);
276 tcGeo
operator * (const maths::Vector
<2,double>& other
) const
278 return tcGeo(m_longitude
* other
[0],
279 m_latitude
* other
[1]);
283 return sqrt(m_longitude
*m_longitude
+ m_latitude
*m_latitude
);
292 /** East-West geographical coordinate.
295 tcGeoAngle m_longitude
;
297 /** North-South geographical coordinate.
300 tcGeoAngle m_latitude
;