File indexing completed on 2025-01-05 03:58:56
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2007 Andrew Manson <g.real.ate@gmail.com> 0004 // SPDX-FileCopyrightText: 2008-2009 Torsten Rahn <rahn@kde.org> 0005 // 0006 0007 0008 #ifndef MARBLE_GEODATALATLONBOX_H 0009 #define MARBLE_GEODATALATLONBOX_H 0010 0011 0012 #include "MarbleGlobal.h" 0013 0014 #include "GeoDataObject.h" 0015 #include "GeoDataCoordinates.h" 0016 0017 #include "digikam_export.h" 0018 0019 namespace Marble 0020 { 0021 0022 class GeoDataLatLonBoxPrivate; 0023 0024 class GeoDataLineString; 0025 0026 /** 0027 * @short A class that defines a 2D bounding box for geographic data. 0028 * 0029 * GeoDataLatLonBox is a 2D bounding box that describes a geographic area 0030 * in terms of latitude and longitude. 0031 * 0032 * The bounding box gets described by assigning the northern, southern, 0033 * eastern and western boundary. 0034 * So usually the value of the eastern boundary is bigger than the 0035 * value of the western boundary. 0036 * 0037 * This is also true if the GeoDataLatLonBox covers the whole longitude 0038 * range from 180 deg West to 180 deg East. Notably in this case 0039 * the bounding box crosses the date line. 0040 * 0041 * If the GeoDataLatLonBox does not cover the whole longitude range but still 0042 * crosses the date line then the eastern boundary has got a smaller value than 0043 * the western one. 0044 */ 0045 0046 class DIGIKAM_EXPORT GeoDataLatLonBox : public GeoDataObject 0047 { 0048 friend bool DIGIKAM_EXPORT operator==( GeoDataLatLonBox const& lhs, GeoDataLatLonBox const& rhs ); 0049 friend bool DIGIKAM_EXPORT operator!=( GeoDataLatLonBox const& lhs, GeoDataLatLonBox const& rhs ); 0050 0051 public: 0052 GeoDataLatLonBox(); 0053 GeoDataLatLonBox( qreal north, qreal south, qreal east, qreal west, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0054 GeoDataLatLonBox( const GeoDataLatLonBox & ); 0055 ~GeoDataLatLonBox() override; 0056 0057 GeoDataLatLonBox& operator=( const GeoDataLatLonBox& other ); 0058 0059 /// Provides type information for downcasting a GeoData 0060 const char* nodeType() const override; 0061 0062 /** 0063 * @brief Get the northern boundary of the bounding box. 0064 * @return the latitude of the northern boundary. 0065 */ 0066 qreal north( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0067 void setNorth( const qreal north, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0068 0069 /** 0070 * @brief Get the southern boundary of the bounding box. 0071 * @return the latitude of the southern boundary. 0072 */ 0073 qreal south( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0074 void setSouth( const qreal south, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0075 0076 /** 0077 * @brief Get the eastern boundary of the bounding box. 0078 * @return the longitude of the eastern boundary. 0079 */ 0080 qreal east( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0081 void setEast( const qreal east, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0082 0083 /** 0084 * @brief Get the western boundary of the bounding box. 0085 * @return the longitude of the western boundary. 0086 */ 0087 qreal west( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0088 void setWest( const qreal west, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0089 0090 /** 0091 * @brief Get the rotation of the bounding box. 0092 * @return the rotation of the bounding box. 0093 */ 0094 qreal rotation( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0095 void setRotation( const qreal rotation, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0096 0097 void boundaries( qreal &north, qreal &south, qreal &east, qreal &west, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0098 void setBoundaries( qreal north, qreal south, qreal east, qreal west, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0099 0100 /** 0101 * @brief Changes the differences between the boundaries and the center by the given factor, keeping the center unchanged 0102 * @param verticalFactor Vertical scale factor (affects north and south boundaries) 0103 * @param horizontalFactor Horizontal scale factor (affects west and east boundaries) 0104 */ 0105 void scale(qreal verticalFactor, qreal horizontalFactor) const; 0106 GeoDataLatLonBox scaled(qreal verticalFactor, qreal horizontalFactor) const; 0107 0108 /** 0109 * @brief Get the width of the longitude interval 0110 * @return the angle covered by the longitude range. 0111 */ 0112 qreal width( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0113 0114 /** 0115 * @brief Get the width of the longitude interval. East and west parameters are in radians. 0116 * @return the angle covered by the longitude range in given unit. 0117 */ 0118 static qreal width( qreal east, qreal west, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0119 0120 /** 0121 * @brief Get the height of the latitude interval 0122 * @return the angle covered by the latitude range. 0123 */ 0124 qreal height( GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ) const; 0125 0126 /** 0127 * @brief Get the height of the latitude interval. North and south parameters are in radians. 0128 * @return the angle covered by the latitude range in given unit. 0129 */ 0130 static qreal height( qreal north, qreal south, GeoDataCoordinates::Unit unit = GeoDataCoordinates::Radian ); 0131 0132 /** 0133 * @brief Detect whether the bounding box crosses the IDL. 0134 * @return @c true the bounding box crosses the +/-180 deg longitude. 0135 * @c false the bounding box doesn't cross the +/-180 deg longitude. 0136 */ 0137 bool crossesDateLine() const; 0138 0139 /** 0140 * @brief Detect whether the bounding box crosses the IDL. 0141 * @param east radians east. 0142 * @param west radians west. 0143 * @return @c true the bounding box crosses the +/-180 deg longitude. 0144 * @c false the bounding box doesn't cross the +/-180 deg longitude. 0145 */ 0146 static bool crossesDateLine(qreal east, qreal west); 0147 0148 /** 0149 * @brief returns the center of this box 0150 * @return a coordinate, face-center of the box 0151 */ 0152 virtual GeoDataCoordinates center() const; 0153 0154 /** 0155 * @brief Detect whether the bounding box contains one of the poles. 0156 * @return @c true the bounding box contains one of the poles. 0157 * @c false the bounding box doesn't contain one of the poles. 0158 */ 0159 bool containsPole( Pole pole = AnyPole ) const; 0160 0161 virtual bool contains( const GeoDataCoordinates & ) const; 0162 bool contains( const GeoDataLatLonBox & ) const; 0163 0164 /** 0165 * @brief Detect whether the bounding box contains a point of given lon and lat. 0166 * @param lon longitude in radians. 0167 * @param lat latitude in radians. 0168 * @return true if the box contains given point, false otherwise 0169 */ 0170 bool contains(qreal lon, qreal lat) const; //Optimized version for overlay painting 0171 0172 virtual bool intersects( const GeoDataLatLonBox & ) const; 0173 0174 /** 0175 * @brief Returns the bounding LatLonBox of this box with the given one. 0176 */ 0177 GeoDataLatLonBox united( const GeoDataLatLonBox& other) const; 0178 0179 /** 0180 * @return Returns the smallest bounding box that contains this LatLonBox rotated with its given angle. 0181 */ 0182 GeoDataLatLonBox toCircumscribedRectangle() const; 0183 0184 /** 0185 * @brief Create the smallest bounding box from a line string. 0186 * @return the smallest bounding box that contains the linestring. 0187 */ 0188 static GeoDataLatLonBox fromLineString( const GeoDataLineString& lineString ); 0189 0190 /** 0191 * @brief Indicates whether the bounding box only contains a single 2D point ("singularity"). 0192 * @return Return value is true if the height and the width of the bounding box equal zero. 0193 */ 0194 virtual bool isNull() const; 0195 0196 /** 0197 * @brief Indicates whether the bounding box is not initialised (and contains nothing). 0198 * @return Return value is true if bounding box is not initialised. 0199 */ 0200 virtual bool isEmpty() const; 0201 0202 /** 0203 * @brief Indicates whether two bounding boxes are roughly equal. 0204 * The factor specifies the margin threshold relative to the left handside 0205 * bounding box within which both bounding boxes are considered equal. 0206 * @return Return value is true if both bounding box are approximately equal. 0207 */ 0208 static bool fuzzyCompare(const GeoDataLatLonBox& lhs, 0209 const GeoDataLatLonBox& rhs, 0210 const qreal factor = 0.01); 0211 0212 /** 0213 * @brief Resets the bounding box to its uninitialised state (and thus contains nothing). 0214 */ 0215 virtual void clear(); 0216 0217 GeoDataLatLonBox operator|( const GeoDataLatLonBox& other ) const; 0218 0219 /** 0220 * @brief Unites this bounding box with the given one. 0221 * @return Returns a reference to self. 0222 */ 0223 GeoDataLatLonBox& operator |=( const GeoDataLatLonBox& other) ; 0224 0225 /// Serialize the contents of the feature to @p stream. 0226 void pack( QDataStream& stream ) const override; 0227 /// Unserialize the contents of the feature from @p stream. 0228 void unpack( QDataStream& stream ) override; 0229 0230 private: 0231 GeoDataLatLonBoxPrivate * const d; 0232 static const GeoDataLatLonBox empty; 0233 }; 0234 0235 } 0236 0237 Q_DECLARE_METATYPE( Marble::GeoDataLatLonBox ) 0238 0239 #endif