SectorZone: add attribute arc_boundary
[xcsoar.git] / src / Geo / GeoPoint.hpp
blob0bd9bec6c704a341772a4baf1d07f20c44faa914
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #ifndef XCSOAR_GeoPoint_HPP
26 #define XCSOAR_GeoPoint_HPP
28 #include "Math/Angle.hpp"
29 #include "Rough/RoughAltitude.hpp"
30 #include "Compiler.h"
32 #include <type_traits>
34 struct GeoVector;
36 /**
37 * Geodetic coordinate expressed as Longitude and Latitude angles.
39 struct GeoPoint {
40 Angle longitude;
41 Angle latitude;
43 /**
44 * Non-initialising constructor.
46 GeoPoint() = default;
48 /**
49 * Constructor (supplied location)
51 * @param _Longitude Longitude of point
52 * @param _Latitude Latitude of point
54 * @return Initialised object
56 constexpr
57 GeoPoint(const Angle _longitude, const Angle _latitude) :
58 longitude(_longitude), latitude(_latitude) {}
60 /**
61 * Construct an instance at the origin of the coordinate system.
62 * This is used to initialise the simulator when there is no better
63 * reference (home, map center). The goal is to bootstrap the
64 * simulator when XCSoar is launched for the first time with an
65 * empty profile; it is pretty useless for anything else.
67 constexpr
68 static GeoPoint Zero() {
69 return GeoPoint(Angle::Zero(), Angle::Zero());
72 /**
73 * Construct an instance that is "invalid", i.e. IsValid() will
74 * return false. The return value must not be used in any
75 * calculation. This method may be used to explicitly declare a
76 * GeoPoint attribute as "invalid".
78 constexpr
79 static GeoPoint Invalid() {
80 return GeoPoint(Angle::Zero(), Angle::FullCircle());
83 /**
84 * Set this instance to "invalid", i.e. IsValid() will
85 * return false. The return value must not be used in any
86 * calculation. This method may be used to explicitly declare a
87 * GeoPoint attribute as "invalid".
89 void SetInvalid() {
90 longitude = Angle::Zero();
91 latitude = Angle::FullCircle();
94 /**
95 * Check if this object is "valid". Returns false when it was
96 * constructed by Invalid(). This is not an extensive plausibility
97 * check; it is only designed to catch instances created by
98 * Invalid().
100 constexpr
101 bool IsValid() const {
102 return latitude <= Angle::HalfCircle();
106 * Normalize the values, so this object can be used properly in
107 * calculations, without unintended side effects (such as -1 degrees
108 * vs 359 degrees). This modification is in-place.
110 GeoPoint &Normalize() {
111 longitude = longitude.AsDelta();
113 if (latitude < -Angle::QuarterCircle())
114 latitude = -Angle::QuarterCircle();
115 else if (latitude > Angle::QuarterCircle())
116 latitude = Angle::QuarterCircle();
118 return *this;
122 * Find location a parametric distance along a vector from this point
124 * @param delta Vector to feed in
125 * @param t Parametric distance along delta to add [0,1]
127 * @return Location of point
129 gcc_pure
130 GeoPoint Parametric(const GeoPoint &delta, const fixed t) const;
133 * Find location interpolated from this point towards end
135 * @param end Endpoint of interpolation
136 * @param t Parametric distance along this to end [0,1]
138 * @return Location of point
140 gcc_pure
141 GeoPoint Interpolate(const GeoPoint &end, const fixed t) const;
144 * Multiply a point by a factor (used for deltas)
146 * @param x Factor to magnify
148 * @return Modified point
150 gcc_pure
151 GeoPoint operator* (const fixed x) const {
152 GeoPoint res = *this;
153 res.longitude *= x;
154 res.latitude *= x;
155 return res;
159 * Add a delta to a point
161 * @param delta Delta to add
163 * @return Modified point
165 gcc_pure
166 GeoPoint operator+ (const GeoPoint &delta) const {
167 GeoPoint res = *this;
168 res.longitude += delta.longitude;
169 res.latitude += delta.latitude;
170 return res;
174 * Add a delta to a point
176 * @param delta Delta to add
178 * @return Modified point
180 const GeoPoint& operator+= (const GeoPoint &delta) {
181 longitude += delta.longitude;
182 latitude += delta.latitude;
183 return *this;
187 * Subtracts a delta from a point
189 * @param delta Delta to subtract
191 * @return Modified point
193 gcc_pure
194 GeoPoint operator- (const GeoPoint &delta) const {
195 GeoPoint res = *this;
196 res.longitude -= delta.longitude;
197 res.latitude -= delta.latitude;
198 return res.Normalize();
202 * Calculate great circle distance from this to the other
204 * @param other Other location
206 * @return Distance (m)
208 gcc_pure
209 fixed Distance(const GeoPoint &other) const;
212 * Calculate great circle initial bearing from this to the other
214 * @param other Other location
216 * @return Bearing (deg)
218 gcc_pure
219 Angle Bearing(const GeoPoint &other) const;
222 * Calculate great circle distance and initial bearing from this to the other
224 gcc_pure
225 GeoVector DistanceBearing(const GeoPoint &other) const;
228 * Find distance along a great-circle path that this point
229 * is projected to
231 * @param from Start location
232 * @param to End location
234 * @return Distance (m) along from-to line
236 gcc_pure
237 fixed ProjectedDistance(const GeoPoint &from, const GeoPoint &to) const;
240 * Find point a set distance along a great-circle path towards
241 * a destination
243 * @param destination End location
244 * @param distance distance (m)
246 * @return Location of point
248 gcc_pure
249 GeoPoint IntermediatePoint(const GeoPoint &destination,
250 const fixed distance) const;
253 * Find the nearest great-circle middle point between this point and
254 * the specified one.
256 gcc_pure
257 GeoPoint Middle(const GeoPoint &other) const;
260 * Test whether two points are co-located
262 * @param other Point to compare
264 * @return True if coincident
266 constexpr
267 bool Equals(const GeoPoint other) const {
268 return longitude == other.longitude && latitude == other.latitude;
272 * Test whether two points are co-located
274 * @param other Point to compare
276 * @return True if coincident
278 constexpr
279 bool operator== (const GeoPoint other) const {
280 return Equals(other);
284 * Test whether two points are not co-located
286 * @param other Point to compare
288 * @return True if coincident
290 constexpr
291 bool operator !=(const GeoPoint &other) const {
292 return !Equals(other);
296 * Rank two points according to longitude, then latitude
298 * @param other Point to compare to
300 * @return True if this point is further left (or if equal, lower) than the other
302 gcc_pure
303 bool Sort(const GeoPoint &other) const;
306 static_assert(std::is_trivial<GeoPoint>::value, "type is not trivial");
309 * Extension of GeoPoint for altitude (3d location in spherical space)
311 struct AGeoPoint: public GeoPoint {
312 /**< Nav reference altitude (m) */
313 RoughAltitude altitude;
315 AGeoPoint() = default;
317 constexpr
318 AGeoPoint(const GeoPoint p, const RoughAltitude alt)
319 :GeoPoint(p),altitude(alt) {};
322 static_assert(std::is_trivial<AGeoPoint>::value, "type is not trivial");
324 #endif