SectorZone: add attribute arc_boundary
[xcsoar.git] / src / Geo / GeoBounds.hpp
blob2027f037385f3af745013b4e6a3195e2f20e1dcd
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.
24 #ifndef XCSOAR_GEO_RECT_HPP
25 #define XCSOAR_GEO_RECT_HPP
27 #include "Math/ARange.hpp"
28 #include "GeoPoint.hpp"
29 #include "Compiler.h"
31 /**
32 * A rectangle on earth's surface with very simple semantics. Similar
33 * to the RECT struct, it is bounded by four orthogonal lines. Its
34 * goal is to perform fast overlap checks, e.g. to determine if an
35 * object is visible on the screen.
37 class GeoBounds {
38 /**
39 * The range from west to east.
41 AngleRange longitude;
43 /**
44 * The range from south to north.
46 AngleRange latitude;
48 public:
49 GeoBounds() = default;
51 constexpr
52 GeoBounds(const GeoPoint pt)
53 :longitude(pt.longitude, pt.longitude),
54 latitude(pt.latitude, pt.latitude) {}
56 constexpr
57 GeoBounds(const GeoPoint north_west, const GeoPoint south_east)
58 :longitude(north_west.longitude, south_east.longitude),
59 latitude(south_east.latitude, north_west.latitude) {}
61 /**
62 * Construct an instance that is "invalid", i.e. IsValid() will
63 * return false. The return value must not be used in any
64 * calculation.
66 constexpr
67 static GeoBounds Invalid() {
68 return GeoBounds(GeoPoint::Invalid());
71 /**
72 * Set this instance to "invalid", i.e. IsValid() will return false.
73 * The return value must not be used in any calculation.
75 void SetInvalid() {
76 latitude.end = Angle::FullCircle();
79 constexpr Angle GetWest() const {
80 return longitude.start;
83 constexpr Angle GetEast() const {
84 return longitude.end;
87 constexpr Angle GetSouth() const {
88 return latitude.start;
91 constexpr Angle GetNorth() const {
92 return latitude.end;
95 constexpr GeoPoint GetNorthWest() const {
96 return GeoPoint(GetWest(), GetNorth());
99 constexpr GeoPoint GetNorthEast() const {
100 return GeoPoint(GetEast(), GetNorth());
103 constexpr GeoPoint GetSouthWest() const {
104 return GeoPoint(GetWest(), GetSouth());
107 constexpr GeoPoint GetSouthEast() const {
108 return GeoPoint(GetEast(), GetSouth());
112 * Check if this object is "valid". Returns false when it was
113 * constructed by Invalid(). This is not an extensive plausibility
114 * check; it is only designed to catch instances created by
115 * Invalid().
117 constexpr
118 bool IsValid() const {
119 return latitude.end <= Angle::HalfCircle();
122 constexpr bool IsEmpty() const {
123 return longitude.IsEmpty() || latitude.IsEmpty();
126 Angle GetWidth() const {
127 return longitude.GetLength();
130 Angle GetHeight() const {
131 return latitude.GetLength();
135 * Returns the geographic width of the object (west to east) at its
136 * center in metres.
138 gcc_pure
139 fixed GetGeoWidth() const {
140 const Angle middle_latitude = latitude.GetMiddle();
141 return GeoPoint(GetWest(), middle_latitude)
142 .Distance(GeoPoint(GetEast(), middle_latitude));
146 * Returns the geographic height of the object (south to north) in
147 * metres.
149 gcc_pure
150 fixed GetGeoHeight() const {
151 return GetNorthWest().Distance(GetSouthWest());
154 void Extend(const GeoPoint pt);
156 bool IsInside(Angle _longitude, Angle _latitude) const {
157 return longitude.IsInside(_longitude) && latitude.IsInside(_latitude);
160 bool IsInside(const GeoPoint pt) const {
161 return IsInside(pt.longitude, pt.latitude);
164 bool IsInside(const GeoBounds &interior) const {
165 return longitude.IsInside(interior.longitude) &&
166 latitude.IsInside(interior.latitude);
170 * Does this GeoBounds instance overlap with the specified one?
172 gcc_pure
173 bool Overlaps(const GeoBounds &other) const {
174 return longitude.Overlaps(other.longitude) &&
175 latitude.Overlaps(other.latitude);
179 * Set this object to the intersection of this and the other object.
181 * @return false if the two objects do not overlap; in this case,
182 * the object is left in an undefined state
184 bool IntersectWith(const GeoBounds &other);
186 gcc_pure
187 GeoPoint GetCenter() const;
190 * Returns a scaled version of the GeoBounds.
191 * The bounds are scaled around the center by the given factor.
192 * @param factor The scaling factor
193 * @return A scaled version of the GeoBounds
195 gcc_pure
196 GeoBounds Scale(fixed factor) const;
199 #endif