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"
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.
39 * The range from west to east.
44 * The range from south to north.
49 GeoBounds() = default;
52 GeoBounds(const GeoPoint pt
)
53 :longitude(pt
.longitude
, pt
.longitude
),
54 latitude(pt
.latitude
, pt
.latitude
) {}
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
) {}
62 * Construct an instance that is "invalid", i.e. IsValid() will
63 * return false. The return value must not be used in any
67 static GeoBounds
Invalid() {
68 return GeoBounds(GeoPoint::Invalid());
72 * Set this instance to "invalid", i.e. IsValid() will return false.
73 * The return value must not be used in any calculation.
76 latitude
.end
= Angle::FullCircle();
79 constexpr Angle
GetWest() const {
80 return longitude
.start
;
83 constexpr Angle
GetEast() const {
87 constexpr Angle
GetSouth() const {
88 return latitude
.start
;
91 constexpr Angle
GetNorth() const {
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
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
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
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?
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
);
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
196 GeoBounds
Scale(fixed factor
) const;