// SPDX-License-Identifier: LGPL-2.1-or-later
//
// SPDX-FileCopyrightText: 2007-2008 Inge Wallin <ingwa@kde.org>
// SPDX-FileCopyrightText: 2007-2012 Torsten Rahn <rahn@kde.org>
//
#ifndef MARBLE_ABSTRACTPROJECTION_H
#define MARBLE_ABSTRACTPROJECTION_H
/** @file
* This file contains the headers for AbstractProjection.
*
* @author Inge Wallin <inge@lysator.liu.se>
* @author Torsten Rahn <rahn@kde.org>
*/
#include <QList>
#include "GeoDataCoordinates.h"
#include "marble_export.h"
class QIcon;
class QPainterPath;
class QPolygonF;
class QRect;
class QString;
namespace Marble
{
// The manhattan distance in pixels at which extra nodes get created for tessellation.
static const int tessellationPrecision = 10;
static const int latLonAltBoxSamplingRate = 4;
class GeoDataLineString;
class GeoDataLatLonAltBox;
class ViewportParams;
class AbstractProjectionPrivate;
/**
* @short A base class for all projections in Marble.
*/
class MARBLE_EXPORT AbstractProjection
{
// Not a QObject so far because we don't need to send signals.
public:
enum SurfaceType {
Cylindrical,
Pseudocylindrical,
Hybrid,
Conical,
Pseudoconical,
Azimuthal
};
enum PreservationType {
NoPreservation,
Conformal,
EqualArea
};
/**
* @brief Construct a new AbstractProjection.
*/
AbstractProjection();
virtual ~AbstractProjection();
/**
* @brief Returns the user-visible name of the projection.
*
* Example: "Mercator"
*/
virtual QString name() const = 0;
/**
* @brief Returns a short user description of the projection
* that can be used in tooltips or dialogs.
*/
virtual QString description() const = 0;
/**
* @brief Returns an icon for the projection.
*/
virtual QIcon icon() const = 0;
/**
* @brief Returns the maximum (northern) latitude that is mathematically defined and reasonable.
*
* Example: For many projections the value will represent +90 degrees in Radian.
* In the case of Mercator this value will equal +85.05113 degrees in Radian.
*/
virtual qreal maxValidLat() const;
/**
* @brief Returns the arbitrarily chosen maximum (northern) latitude.
* By default this value is equal to the value defined inside maxValidLat().
* In general this value can only be smaller or equal to maxValidLat().
*/
qreal maxLat() const;
void setMaxLat(qreal maxLat);
/**
* @brief Returns the minimum (southern) latitude that is mathematically defined and reasonable.
*
* Example: For many projections the value will represent -90 degrees in Radian.
* In the case of Mercator this value will equal -85.05113 degrees in Radian.
*/
virtual qreal minValidLat() const;
/**
* @brief Returns the arbitrarily chosen minimum (southern) latitude.
* By default this value is equal to the value defined inside minValidLat().
* In general this value can only be larger or equal to minValidLat().
*/
qreal minLat() const;
void setMinLat(qreal minLat);
/**
* @brief Returns whether the projection allows for wrapping in x direction (along the longitude scale).
*
* Example: Cylindrical projections allow for repeating.
*/
virtual bool repeatableX() const;
/**
* @brief Returns whether the projection allows to navigate seamlessly "over" the pole.
*
* Example: Azimuthal projections.
*/
virtual bool traversablePoles() const;
virtual bool traversableDateLine() const;
virtual SurfaceType surfaceType() const = 0;
virtual PreservationType preservationType() const;
// The projection surface can have different orientations:
// - normal: the surface's axis of symmetry matches the Earth's axis
// - transverse: orthogonally oriented compared to the Earth's axis
// - oblique: somewhere in between
virtual bool isOrientedNormal() const;
/**
* @brief Defines whether a projection is supposed to be clipped to a certain radius.
*
* Example: The Gnomonic projection is clipped to a circle of a certain clipping radius
* (although it's mathematically defined beyond that radius).
*/
virtual bool isClippedToSphere() const;
virtual qreal clippingRadius() const;
/**
* @brief Get the screen coordinates corresponding to geographical coordinates in the map.
* @param lon the lon coordinate of the requested pixel position in radians
* @param lat the lat coordinate of the requested pixel position in radians
* @param viewport the viewport parameters
* @param x the x coordinate of the pixel is returned through this parameter
* @param y the y coordinate of the pixel is returned through this parameter
* @return @c true if the geographical coordinates are visible on the screen
* @c false if the geographical coordinates are not visible on the screen
*
* @see ViewportParams
*/
bool screenCoordinates(const qreal lon, const qreal lat, const ViewportParams *viewport, qreal &x, qreal &y) const;
/**
* @brief Get the screen coordinates corresponding to geographical coordinates in the map.
*
* @param geopoint the point on earth, including altitude, that we want the coordinates for.
* @param viewport the viewport parameters
* @param x the x coordinate of the pixel is returned through this parameter
* @param y the y coordinate of the pixel is returned through this parameter
* @param globeHidesPoint whether the point gets hidden on the far side of the earth
*
* @return @c true if the geographical coordinates are visible on the screen
* @c false if the geographical coordinates are not visible on the screen
*
* @see ViewportParams
*/
virtual bool screenCoordinates(const GeoDataCoordinates &geopoint, const ViewportParams *viewport, qreal &x, qreal &y, bool &globeHidesPoint) const = 0;
// Will just call the virtual version with a dummy globeHidesPoint.
bool screenCoordinates(const GeoDataCoordinates &geopoint, const ViewportParams *viewport, qreal &x, qreal &y) const;
/**
* @brief Get the coordinates of screen points for geographical coordinates in the map.
*
* @param coordinates the point on earth, including altitude, that we want the coordinates for.
* @param viewport the viewport parameters
* @param x the x coordinates of the pixels are returned through this parameter
* @param y the y coordinate of the pixel is returned through this parameter
* @param pointRepeatNum the amount of times that a single geographical
point gets represented on the map
* @param size the size
* @param globeHidesPoint whether the point gets hidden on the far side of the earth
*
* @return @c true if the geographical coordinates are visible on the screen
* @c false if the geographical coordinates are not visible on the screen
*
* @see ViewportParams
*/
virtual bool screenCoordinates(const GeoDataCoordinates &coordinates,
const ViewportParams *viewport,
qreal *x,
qreal &y,
int &pointRepeatNum,
const QSizeF &size,
bool &globeHidesPoint) const = 0;
virtual bool screenCoordinates(const GeoDataLineString &lineString, const ViewportParams *viewport, QList<QPolygonF *> &polygons) const = 0;
/**
* @brief Get the earth coordinates corresponding to a pixel in the map.
* @param x the x coordinate of the pixel
* @param y the y coordinate of the pixel
* @param viewport the viewport parameters
* @param lon the longitude angle is returned through this parameter
* @param lat the latitude angle is returned through this parameter
* @param unit the unit of the angles for lon and lat.
* @return @c true if the pixel (x, y) is within the globe
* @c false if the pixel (x, y) is outside the globe, i.e. in space.
*/
virtual bool geoCoordinates(const int x,
const int y,
const ViewportParams *viewport,
qreal &lon,
qreal &lat,
GeoDataCoordinates::Unit unit = GeoDataCoordinates::Degree) const = 0;
/**
* @brief Returns a GeoDataLatLonAltBox bounding box of the given screenrect inside the given viewport.
*/
virtual GeoDataLatLonAltBox latLonAltBox(const QRect &screenRect, const ViewportParams *viewport) const;
/**
* @brief Returns whether the projected data fully obstructs the current viewport.
* In this case there are no black areas visible around the actual map.
* This case allows for performance optimizations.
*/
virtual bool mapCoversViewport(const ViewportParams *viewport) const = 0;
/**
* @brief Returns the shape/outline of a map projection.
* This call allows e.g. to draw the default background color of the map itself.
*
* Example: For an azimuthal projection a circle is returned at low zoom values.
*/
virtual QPainterPath mapShape(const ViewportParams *viewport) const = 0;
QRegion mapRegion(const ViewportParams *viewport) const;
protected:
const QScopedPointer<AbstractProjectionPrivate> d_ptr;
explicit AbstractProjection(AbstractProjectionPrivate *dd);
private:
Q_DECLARE_PRIVATE(AbstractProjection)
Q_DISABLE_COPY(AbstractProjection)
};
}
#endif
|