1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: http://www.qt.io/licensing/ 5 ** 6 ** This file is part of the QtLocation module of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL3$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see http://www.qt.io/terms-conditions. For further 15 ** information use the contact form at http://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPLv3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or later as published by the Free 28 ** Software Foundation and appearing in the file LICENSE.GPL included in 29 ** the packaging of this file. Please review the following information to 30 ** ensure the GNU General Public License version 2.0 requirements will be 31 ** met: http://www.gnu.org/licenses/gpl-2.0.html. 32 ** 33 ** $QT_END_LICENSE$ 34 ** 35 ****************************************************************************/ 36 37 #ifndef QGEOPROJECTION_H 38 #define QGEOPROJECTION_H 39 40 // 41 // W A R N I N G 42 // ------------- 43 // 44 // This file is not part of the Qt API. It exists purely as an 45 // implementation detail. This header file may change from version to 46 // version without notice, or even be removed. 47 // 48 // We mean it. 49 // 50 51 #include <QtLocation/private/qlocationglobal_p.h> 52 #include <QtLocation/private/qgeocameradata_p.h> 53 #include <QtPositioning/private/qdoublematrix4x4_p.h> 54 #include <QtPositioning/QGeoShape> 55 #include <QMatrix4x4> 56 #include <QTransform> 57 58 QT_BEGIN_NAMESPACE 59 60 class Q_LOCATION_PRIVATE_EXPORT QGeoProjection 61 { 62 public: 63 enum ProjectionGroup { 64 ProjectionOther, 65 ProjectionCylindrical, 66 ProjectionPseudocylindrical, 67 ProjectionAzimuthal, 68 ProjectionPseudoazimuthal, 69 ProjectionConic, 70 ProjectionPseudoconic 71 //Polyhedral 72 //Retroazimuthal 73 }; 74 75 enum Datum { 76 DatumUnknown, 77 DatumWGS84, 78 DatumSphere 79 }; 80 81 enum ProjectionType { 82 ProjectionUnknown, 83 ProjectionGeneralPerspective, 84 ProjectionWebMercator 85 }; 86 87 QGeoProjection(); 88 virtual ~QGeoProjection(); 89 90 virtual void setVisibleArea(const QRectF &visibleArea) = 0; 91 virtual void setViewportSize(const QSize &size) = 0; 92 virtual void setCameraData(const QGeoCameraData &cameraData, bool force = true) = 0; 93 virtual QGeoCameraData cameraData() const = 0; 94 95 // returns the minimum zoom at the current viewport size 96 virtual double minimumZoom() const = 0; 97 virtual double maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const = 0; 98 virtual double minimumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const = 0; 99 100 virtual QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const = 0; 101 virtual QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const = 0; 102 103 virtual ProjectionGroup projectionGroup() const = 0; 104 virtual Datum datum() const = 0; 105 virtual ProjectionType projectionType() const = 0; 106 107 // Returns the new map center after anchoring coordinate to anchorPoint on the screen 108 virtual QGeoCoordinate anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const; 109 110 virtual QGeoShape visibleRegion() const; 111 virtual bool setBearing(qreal bearing, const QGeoCoordinate &coordinate); 112 virtual QMatrix4x4 projectionTransformation() const = 0; // This brings a mercator coord into the correct viewport coordinate. 113 virtual QMatrix4x4 projectionTransformation_centered() const = 0; // Same as projectionTransformation, but the center of the camera is around 0,0. 114 // Requires subsequent shifting of the geometry to fit such camera. 115 virtual const QMatrix4x4 &qsgTransform() const = 0; 116 virtual QDoubleVector3D centerMercator() const = 0; 117 118 void setItemToWindowTransform(const QTransform &itemToWindowTransform); 119 virtual QTransform itemToWindowTransform() const; 120 121 QTransform m_itemToWindowTransform; 122 mutable bool m_qsgTransformDirty = true; 123 }; 124 125 class Q_LOCATION_PRIVATE_EXPORT QGeoProjectionWebMercator : public QGeoProjection 126 { 127 public: 128 QGeoProjectionWebMercator(); 129 ~QGeoProjectionWebMercator(); 130 131 // From QGeoProjection 132 double minimumZoom() const override; 133 QMatrix4x4 projectionTransformation() const override; 134 QMatrix4x4 projectionTransformation_centered() const override; 135 const QMatrix4x4 &qsgTransform() const override; 136 QDoubleVector3D centerMercator() const override; 137 138 double maximumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const override; 139 double minimumCenterLatitudeAtZoom(const QGeoCameraData &cameraData) const override; 140 141 void setVisibleArea(const QRectF &visibleArea) override; 142 void setViewportSize(const QSize &size) override; 143 void setCameraData(const QGeoCameraData &cameraData, bool force = true) override; 144 QGeoCameraData cameraData() const override; 145 146 QGeoCoordinate itemPositionToCoordinate(const QDoubleVector2D &pos, bool clipToViewport = true) const override; 147 QDoubleVector2D coordinateToItemPosition(const QGeoCoordinate &coordinate, bool clipToViewport = true) const override; 148 149 QGeoProjection::ProjectionGroup projectionGroup() const override; 150 QGeoProjection::Datum datum() const override; 151 QGeoProjection::ProjectionType projectionType() const override; 152 153 QGeoCoordinate anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint) const override; 154 bool setBearing(qreal bearing, const QGeoCoordinate &coordinate) override; 155 156 QGeoShape visibleRegion() const override; 157 158 // Specific to QGeoProjectionWebMercator 159 double mapWidth() const; // The size of the underlying map, at the current zoom level. 160 double mapHeight() const; 161 162 QDoubleVector2D geoToMapProjection(const QGeoCoordinate &coordinate) const; 163 QGeoCoordinate mapProjectionToGeo(const QDoubleVector2D &projection) const; 164 165 int projectionWrapFactor(const QDoubleVector2D &projection) const; 166 QDoubleVector2D wrapMapProjection(const QDoubleVector2D &projection) const; 167 QDoubleVector2D unwrapMapProjection(const QDoubleVector2D &wrappedProjection) const; 168 169 QDoubleVector2D wrappedMapProjectionToItemPosition(const QDoubleVector2D &wrappedProjection) const; 170 QDoubleVector2D itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const; 171 172 QDoubleVector2D geoToWrappedMapProjection(const QGeoCoordinate &coordinate) const; 173 QGeoCoordinate wrappedMapProjectionToGeo(const QDoubleVector2D &wrappedProjection) const; 174 QMatrix4x4 quickItemTransformation(const QGeoCoordinate &coordinate, const QPointF &anchorPoint, qreal zoomLevel) const; 175 176 bool isProjectable(const QDoubleVector2D &wrappedProjection) const; 177 QList<QDoubleVector2D> visibleGeometry() const; 178 QList<QDoubleVector2D> visibleGeometryExpanded() const; 179 QList<QDoubleVector2D> projectableGeometry() const; 180 181 inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const; 182 inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const; 183 184 QPair<QGeoCoordinate, qreal> fitViewportToGeoRectangle(const QGeoRectangle &rectangle, 185 const QMargins &margins) const; 186 187 private: 188 void setupCamera(); 189 void updateVisibleRegion(); 190 191 public: 192 struct Line2D 193 { 194 Line2D(); 195 Line2D(const QDoubleVector2D &linePoint, const QDoubleVector2D &lineDirection); 196 197 bool isValid() const; 198 199 QDoubleVector2D m_point; 200 QDoubleVector2D m_direction; 201 }; 202 203 struct Plane 204 { 205 Plane(); 206 Plane(const QDoubleVector3D &planePoint, const QDoubleVector3D &planeNormal); 207 208 QDoubleVector3D lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection) const; 209 inline QDoubleVector3D lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection, double &s) const; 210 Line2D planeXYIntersection() const; 211 bool isValid() const; 212 213 QDoubleVector3D m_point; 214 QDoubleVector3D m_normal; 215 }; 216 217 #ifdef QT_LOCATION_DEBUG 218 public: 219 #else 220 protected: 221 #endif 222 QGeoCameraData m_cameraData; 223 double m_mapEdgeSize; 224 double m_minimumZoom; 225 // mercator to camera transform for coordinates (not tiles!) 226 double m_cameraCenterXMercator; 227 double m_cameraCenterYMercator; 228 229 // cameraToScreen transform 230 double m_viewportWidth; // in pixels 231 double m_viewportHeight; // in pixels 232 double m_1_viewportWidth; 233 double m_1_viewportHeight; 234 235 QDoubleMatrix4x4 m_cameraMatrix; 236 QDoubleMatrix4x4 m_cameraMatrix0; 237 QDoubleMatrix4x4 m_transformation; 238 QDoubleMatrix4x4 m_transformation0; 239 QDoubleMatrix4x4 m_quickItemTransformation; 240 QDoubleVector3D m_eye; 241 QDoubleVector3D m_up; 242 QDoubleVector3D m_center; 243 QDoubleVector3D m_view; 244 QDoubleVector3D m_viewNormalized; 245 QDoubleVector3D m_side; 246 QDoubleVector3D m_centerNearPlane; 247 double m_sideLengthPixels; // map edge size at integer zoom level 248 double m_aperture; 249 double m_nearPlane; 250 double m_farPlane; 251 double m_halfWidth; 252 double m_halfHeight; 253 double m_minimumUnprojectableY; 254 double m_verticalEstateToSkip; 255 256 // For the clipping region 257 QDoubleVector3D m_centerMercator; 258 QDoubleVector3D m_eyeMercator; 259 QDoubleVector3D m_eyeMercator0; 260 QDoubleVector3D m_viewMercator; 261 QDoubleVector3D m_upMercator; 262 QDoubleVector3D m_sideMercator; 263 QDoubleVector3D m_centerNearPlaneMercator; 264 double m_nearPlaneMercator; 265 Line2D m_nearPlaneMapIntersection; 266 267 QList<QDoubleVector2D> m_visibleRegion; 268 QList<QDoubleVector2D> m_visibleRegionExpanded; 269 QList<QDoubleVector2D> m_projectableRegion; 270 bool m_visibleRegionDirty; 271 272 mutable QMatrix4x4 m_qsgTransform; 273 QRectF m_visibleArea; 274 275 Q_DISABLE_COPY(QGeoProjectionWebMercator) 276 }; 277 278 QT_END_NAMESPACE 279 280 #endif // QGEOPROJECTION_H 281