File indexing completed on 2024-05-05 03:49:51

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2007-2008 Inge Wallin <ingwa@kde.org>
0004 // SPDX-FileCopyrightText: 2007-2012 Torsten Rahn <rahn@kde.org>
0005 //
0006 
0007 
0008 #ifndef MARBLE_ABSTRACTPROJECTION_H
0009 #define MARBLE_ABSTRACTPROJECTION_H
0010 
0011 
0012 /** @file
0013  * This file contains the headers for AbstractProjection.
0014  *
0015  * @author Inge Wallin  <inge@lysator.liu.se>
0016  * @author Torsten Rahn <rahn@kde.org>
0017  */
0018 
0019 #include <QVector>
0020 
0021 #include "GeoDataCoordinates.h"
0022 #include "marble_export.h"
0023 
0024 class QIcon;
0025 class QPainterPath;
0026 class QPolygonF;
0027 class QRect;
0028 class QString;
0029 
0030 namespace Marble
0031 {
0032 
0033 // The manhattan distance in pixels at which extra nodes get created for tessellation.
0034 static const int tessellationPrecision = 10;
0035 static const int latLonAltBoxSamplingRate = 4;
0036 
0037 class GeoDataLineString;
0038 class GeoDataLatLonAltBox;
0039 class ViewportParams;
0040 class AbstractProjectionPrivate;
0041 
0042 
0043 /**
0044  * @short A base class for all projections in Marble.
0045  */
0046 
0047 class MARBLE_EXPORT AbstractProjection
0048 {
0049     // Not a QObject so far because we don't need to send signals.
0050  public:
0051     enum SurfaceType {
0052         Cylindrical,
0053         Pseudocylindrical,
0054         Hybrid,
0055         Conical,
0056         Pseudoconical,
0057         Azimuthal
0058     };
0059 
0060     enum PreservationType {
0061         NoPreservation,
0062         Conformal,
0063         EqualArea
0064     };
0065 
0066     /**
0067      * @brief Construct a new AbstractProjection.
0068      */
0069     AbstractProjection();
0070 
0071     virtual ~AbstractProjection();
0072 
0073     /**
0074      * @brief Returns the user-visible name of the projection.
0075      *
0076      * Example: "Mercator"
0077      */
0078     virtual QString name() const = 0;
0079 
0080     /**
0081      * @brief Returns a short user description of the projection
0082      * that can be used in tooltips or dialogs.
0083      */
0084     virtual QString description() const = 0;
0085 
0086     /**
0087      * @brief Returns an icon for the projection.
0088      */
0089     virtual QIcon icon() const = 0;
0090 
0091     /**
0092      * @brief Returns the maximum (northern) latitude that is mathematically defined and reasonable.
0093      *
0094      * Example: For many projections the value will represent +90 degrees in Radian.
0095      * In the case of Mercator this value will equal +85.05113 degrees in Radian.
0096      */
0097     virtual qreal  maxValidLat() const;
0098 
0099     /**
0100      * @brief Returns the arbitrarily chosen maximum (northern) latitude.
0101      * By default this value is equal to the value defined inside maxValidLat().
0102      * In general this value can only be smaller or equal to maxValidLat().
0103      */
0104     qreal  maxLat()  const;
0105     void setMaxLat( qreal maxLat );
0106 
0107     /**
0108      * @brief Returns the minimum (southern) latitude that is mathematically defined and reasonable.
0109      *
0110      * Example: For many projections the value will represent -90 degrees in Radian.
0111      * In the case of Mercator this value will equal -85.05113 degrees in Radian.
0112      */
0113     virtual qreal  minValidLat() const;
0114 
0115     /**
0116      * @brief Returns the arbitrarily chosen minimum (southern) latitude.
0117      * By default this value is equal to the value defined inside minValidLat().
0118      * In general this value can only be larger or equal to minValidLat().
0119      */
0120     qreal  minLat()  const;
0121     void setMinLat( qreal minLat );
0122 
0123     /**
0124      * @brief Returns whether the projection allows for wrapping in x direction (along the longitude scale).
0125      *
0126      * Example: Cylindrical projections allow for repeating.
0127      */
0128     virtual bool   repeatableX() const;
0129 
0130     /**
0131      * @brief Returns whether the projection allows to navigate seamlessly "over" the pole.
0132      *
0133      * Example: Azimuthal projections.
0134      */
0135     virtual bool   traversablePoles()  const;
0136     virtual bool   traversableDateLine()  const;
0137 
0138     virtual SurfaceType surfaceType() const = 0; 
0139 
0140     virtual PreservationType preservationType() const;
0141 
0142     // The projection surface can have different orientations:
0143     // - normal: the surface's axis of symmetry matches the Earth's axis
0144     // - transverse: orthogonally oriented compared to the Earth's axis
0145     // - oblique: somewhere in between
0146 
0147     virtual bool isOrientedNormal() const;
0148 
0149     /**
0150      * @brief Defines whether a projection is supposed to be clipped to a certain radius.
0151      *
0152      * Example: The Gnomonic projection is clipped to a circle of a certain clipping radius
0153      * (although it's mathematically defined beyond that radius).
0154      */
0155     virtual bool isClippedToSphere() const;
0156 
0157     virtual qreal clippingRadius() const;
0158 
0159     /**
0160      * @brief Get the screen coordinates corresponding to geographical coordinates in the map.
0161      * @param lon    the lon coordinate of the requested pixel position in radians
0162      * @param lat    the lat coordinate of the requested pixel position in radians
0163      * @param viewport the viewport parameters
0164      * @param x      the x coordinate of the pixel is returned through this parameter
0165      * @param y      the y coordinate of the pixel is returned through this parameter
0166      * @return @c true  if the geographical coordinates are visible on the screen
0167      *         @c false if the geographical coordinates are not visible on the screen
0168      *
0169      * @see ViewportParams
0170      */
0171     bool screenCoordinates( const qreal lon, const qreal lat,
0172                             const ViewportParams *viewport,
0173                             qreal& x, qreal& y ) const;
0174 
0175     /**
0176      * @brief Get the screen coordinates corresponding to geographical coordinates in the map.
0177      *
0178      * @param geopoint the point on earth, including altitude, that we want the coordinates for.
0179      * @param viewport the viewport parameters
0180      * @param x      the x coordinate of the pixel is returned through this parameter
0181      * @param y      the y coordinate of the pixel is returned through this parameter
0182      * @param globeHidesPoint  whether the point gets hidden on the far side of the earth
0183      *
0184      * @return @c true  if the geographical coordinates are visible on the screen
0185      *         @c false if the geographical coordinates are not visible on the screen
0186      *
0187      * @see ViewportParams
0188      */
0189     virtual bool screenCoordinates( const GeoDataCoordinates &geopoint, 
0190                                     const ViewportParams *viewport,
0191                                     qreal &x, qreal &y, 
0192                                     bool &globeHidesPoint ) const = 0;
0193 
0194     // Will just call the virtual version with a dummy globeHidesPoint.
0195     bool screenCoordinates( const GeoDataCoordinates &geopoint, 
0196                             const ViewportParams *viewport,
0197                             qreal &x, qreal &y ) const;
0198 
0199     /**
0200      * @brief Get the coordinates of screen points for geographical coordinates in the map.
0201      *
0202      * @param coordinates the point on earth, including altitude, that we want the coordinates for.
0203      * @param viewport the viewport parameters
0204      * @param x      the x coordinates of the pixels are returned through this parameter
0205      * @param y      the y coordinate of the pixel is returned through this parameter
0206      * @param pointRepeatNum      the amount of times that a single geographical
0207                                   point gets represented on the map
0208      * @param size   the size
0209      * @param globeHidesPoint  whether the point gets hidden on the far side of the earth
0210      *
0211      * @return @c true  if the geographical coordinates are visible on the screen
0212      *         @c false if the geographical coordinates are not visible on the screen
0213      *
0214      * @see ViewportParams
0215      */
0216     virtual bool screenCoordinates( const GeoDataCoordinates &coordinates,
0217                                     const ViewportParams *viewport,
0218                                     qreal *x, qreal &y, int &pointRepeatNum,
0219                                     const QSizeF& size,
0220                                     bool &globeHidesPoint ) const = 0;
0221 
0222     virtual bool screenCoordinates( const GeoDataLineString &lineString,
0223                             const ViewportParams *viewport,
0224                             QVector<QPolygonF*> &polygons ) const = 0;
0225 
0226     /**
0227      * @brief Get the earth coordinates corresponding to a pixel in the map.
0228      * @param x      the x coordinate of the pixel
0229      * @param y      the y coordinate of the pixel
0230      * @param viewport the viewport parameters
0231      * @param lon    the longitude angle is returned through this parameter
0232      * @param lat    the latitude angle is returned through this parameter
0233      * @param unit   the unit of the angles for lon and lat.
0234      * @return @c true  if the pixel (x, y) is within the globe
0235      *         @c false if the pixel (x, y) is outside the globe, i.e. in space.
0236      */
0237     virtual bool geoCoordinates( const int x, const int y,
0238                                  const ViewportParams *viewport,
0239                                  qreal& lon, qreal& lat,
0240                                  GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree ) const = 0;
0241 
0242 
0243     /**
0244      * @brief Returns a GeoDataLatLonAltBox bounding box of the given screenrect inside the given viewport.
0245      */
0246     virtual GeoDataLatLonAltBox latLonAltBox( const QRect& screenRect,
0247                                               const ViewportParams *viewport ) const;
0248 
0249     /**
0250      * @brief Returns whether the projected data fully obstructs the current viewport.
0251      * In this case there are no black areas visible around the actual map.
0252      * This case allows for performance optimizations.
0253      */
0254     virtual bool mapCoversViewport( const ViewportParams *viewport ) const = 0;
0255 
0256     /**
0257      * @brief Returns the shape/outline of a map projection.
0258      * This call allows e.g. to draw the default background color of the map itself.
0259      *
0260      * Example: For an azimuthal projection a circle is returned at low zoom values.
0261      */
0262     virtual QPainterPath mapShape( const ViewportParams *viewport ) const = 0;
0263 
0264     QRegion mapRegion( const ViewportParams *viewport ) const;
0265 
0266  protected:
0267      const QScopedPointer<AbstractProjectionPrivate> d_ptr;
0268      explicit AbstractProjection( AbstractProjectionPrivate* dd );
0269 
0270  private:
0271      Q_DECLARE_PRIVATE(AbstractProjection)
0272      Q_DISABLE_COPY( AbstractProjection )
0273 };
0274 
0275 }
0276 
0277 #endif