12#include <QPainterPath>
15#include "AzimuthalEquidistantProjection.h"
17#include "GeoDataLatLonAltBox.h"
18#include "GnomonicProjection.h"
19#include "LambertAzimuthalProjection.h"
20#include "MarbleDebug.h"
23#include "StereographicProjection.h"
24#include "VerticalPerspectiveProjection.h"
29class ViewportParamsPrivate
32 ViewportParamsPrivate(
Projection projection, qreal centerLongitude, qreal centerLatitude,
int radius,
const QSize &size);
34 static const AbstractProjection *abstractProjection(
Projection projection);
39 const AbstractProjection *m_currentProjection;
42 qreal m_centerLongitude;
43 qreal m_centerLatitude;
45 Quaternion m_planetAxis;
46 matrix m_planetAxisMatrix;
48 qreal m_angularResolution;
53 GeoDataLatLonAltBox m_viewLatLonAltBox;
55 static const SphericalProjection s_sphericalProjection;
56 static const EquirectProjection s_equirectProjection;
57 static const MercatorProjection s_mercatorProjection;
58 static const GnomonicProjection s_gnomonicProjection;
59 static const StereographicProjection s_stereographicProjection;
60 static const LambertAzimuthalProjection s_lambertAzimuthalProjection;
61 static const AzimuthalEquidistantProjection s_azimuthalEquidistantProjection;
62 static const VerticalPerspectiveProjection s_verticalPerspectiveProjection;
64 GeoDataCoordinates m_focusPoint;
76ViewportParamsPrivate::ViewportParamsPrivate(
Projection projection, qreal centerLongitude, qreal centerLatitude,
int radius,
const QSize &size)
77 : m_projection(projection)
78 , m_currentProjection(abstractProjection(projection))
79 , m_centerLongitude(centerLongitude)
80 , m_centerLatitude(centerLatitude)
83 , m_planetAxisMatrix()
85 , m_angularResolution(4.0 / abs(m_radius))
88 , m_viewLatLonAltBox()
92const AbstractProjection *ViewportParamsPrivate::abstractProjection(Projection projection)
96 return &s_sphericalProjection;
98 return &s_equirectProjection;
100 return &s_mercatorProjection;
102 return &s_gnomonicProjection;
104 return &s_stereographicProjection;
106 return &s_lambertAzimuthalProjection;
108 return &s_azimuthalEquidistantProjection;
110 return &s_verticalPerspectiveProjection;
116ViewportParams::ViewportParams()
117 : d(new ViewportParamsPrivate(
Spherical, 0, 0, 2000,
QSize(100, 100)))
119 centerOn(d->m_centerLongitude, d->m_centerLatitude);
122ViewportParams::ViewportParams(Projection projection, qreal centerLongitude, qreal centerLatitude,
int radius,
const QSize &size)
123 : d(new ViewportParamsPrivate(projection, centerLongitude, centerLatitude, radius, size))
125 centerOn(d->m_centerLongitude, d->m_centerLatitude);
128ViewportParams::~ViewportParams()
136Projection ViewportParams::projection()
const
138 return d->m_projection;
141const AbstractProjection *ViewportParams::currentProjection()
const
143 return d->m_currentProjection;
146void ViewportParams::setProjection(Projection newProjection)
148 d->m_projection = newProjection;
149 d->m_currentProjection = ViewportParamsPrivate::abstractProjection(newProjection);
154 centerOn(d->m_centerLongitude, d->m_centerLatitude);
157int ViewportParams::polarity()
const
164 bool globeHidesN, globeHidesS;
168 currentProjection()->screenCoordinates(northPole,
this, x, yN, globeHidesN);
169 currentProjection()->screenCoordinates(southPole,
this, x, yS, globeHidesS);
174 if (!globeHidesN && !globeHidesS) {
182 if (!globeHidesN && yN < height() / 2) {
185 if (!globeHidesN && yN > height() / 2) {
188 if (!globeHidesS && yS > height() / 2) {
191 if (!globeHidesS && yS < height() / 2) {
199int ViewportParams::radius()
const
207 d->m_dirtyBox =
true;
209 d->m_radius = newRadius;
210 d->m_angularResolution = 4.0 / d->m_radius;
214void ViewportParams::centerOn(qreal lon, qreal lat)
216 if (!d->m_currentProjection->traversablePoles()) {
217 if (lat > d->m_currentProjection->maxLat())
218 lat = d->m_currentProjection->maxLat();
220 if (lat < d->m_currentProjection->minLat())
221 lat = d->m_currentProjection->minLat();
234 d->m_centerLongitude = lon;
235 d->m_centerLatitude = lat;
237 const Quaternion
roll = Quaternion::fromEuler(0, 0, d->m_heading);
238 const Quaternion quat = Quaternion::fromEuler(-lat, lon, 0.0);
240 d->m_planetAxis = quat *
roll;
241 d->m_planetAxis.normalize();
243 d->m_dirtyBox =
true;
244 d->m_planetAxis.inverse().toMatrix(d->m_planetAxisMatrix);
245 d->m_planetAxis.normalize();
248void ViewportParams::setHeading(qreal heading)
250 d->m_heading = heading;
252 const Quaternion
roll = Quaternion::fromEuler(0, 0, heading);
254 const qreal centerLat = centerLatitude();
255 const qreal centerLon = centerLongitude();
257 const Quaternion quat = Quaternion::fromEuler(-centerLat, centerLon, 0);
259 d->m_planetAxis = quat *
roll;
260 d->m_planetAxis.normalize();
262 d->m_dirtyBox =
true;
263 d->m_planetAxis.inverse().toMatrix(d->m_planetAxisMatrix);
264 d->m_planetAxis.normalize();
267qreal ViewportParams::heading()
const
272Quaternion ViewportParams::planetAxis()
const
274 return d->m_planetAxis;
277const matrix &ViewportParams::planetAxisMatrix()
const
279 return d->m_planetAxisMatrix;
282int ViewportParams::width()
const
284 return d->m_size.width();
287int ViewportParams::height()
const
289 return d->m_size.height();
292QSize ViewportParams::size()
const
297void ViewportParams::setWidth(
int newWidth)
299 setSize(
QSize(newWidth, height()));
302void ViewportParams::setHeight(
int newHeight)
304 setSize(
QSize(width(), newHeight));
307void ViewportParams::setSize(
const QSize &newSize)
309 if (newSize == d->m_size)
312 d->m_dirtyBox =
true;
320qreal ViewportParams::centerLongitude()
const
322 return d->m_centerLongitude;
325qreal ViewportParams::centerLatitude()
const
327 return d->m_centerLatitude;
330const GeoDataLatLonAltBox &ViewportParams::viewLatLonAltBox()
const
333 d->m_viewLatLonAltBox = d->m_currentProjection->latLonAltBox(
QRect(
QPoint(0, 0), d->m_size),
this);
334 d->m_dirtyBox =
false;
337 return d->m_viewLatLonAltBox;
340GeoDataLatLonAltBox ViewportParams::latLonAltBox(
const QRect &screenRect)
const
342 return d->m_currentProjection->latLonAltBox(screenRect,
this);
345qreal ViewportParams::angularResolution()
const
350 return d->m_angularResolution;
353bool ViewportParams::resolves(
const GeoDataLatLonBox &latLonBox, qreal pixel)
const
355 return latLonBox.
width() + latLonBox.height() > pixel * d->m_angularResolution;
358bool ViewportParams::resolves(
const GeoDataLatLonAltBox &latLonAltBox, qreal pixel, qreal altitude)
const
360 return latLonAltBox.width() + latLonAltBox.height() > pixel * d->m_angularResolution || latLonAltBox.maxAltitude() - latLonAltBox.minAltitude() > altitude;
372 return (fabs(lon2 - lon1) + fabs(lat2 - lat1) > d->m_angularResolution);
377 return d->m_currentProjection->screenCoordinates(lon, lat,
this, x, y);
382 return d->m_currentProjection->screenCoordinates(geopoint,
this, x, y, globeHidesPoint);
387 return d->m_currentProjection->screenCoordinates(geopoint,
this, x, y);
395 bool &globeHidesPoint)
const
397 return d->m_currentProjection->screenCoordinates(coordinates,
this, x, y, pointRepeatNum, size, globeHidesPoint);
402 return d->m_currentProjection->screenCoordinates(lineString,
this, polygons);
407 return d->m_currentProjection->geoCoordinates(x, y,
this, lon, lat, unit);
410bool ViewportParams::mapCoversViewport()
const
412 return d->m_currentProjection->mapCoversViewport(
this);
417 return d->m_currentProjection->mapShape(
this);
420QRegion ViewportParams::mapRegion()
const
422 return d->m_currentProjection->mapRegion(
this);
427 if (d->m_focusPoint.isValid()) {
428 return d->m_focusPoint;
430 const qreal lon = d->m_centerLongitude;
431 const qreal lat = d->m_centerLatitude;
433 return {lon, lat, 0.0, GeoDataCoordinates::Radian};
This file contains the headers for EquirectProjection.
This file contains the headers for MercatorProjection.
This file contains the headers for SphericalProjection.
This file contains the headers for ViewportParams.
A 3d point representation.
void geoCoordinates(qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit) const
use this function to get the longitude and latitude with one call - use the unit parameter to switch ...
A class to implement the spherical projection used by the "Globe" view.
A class to implement the Equirectangular projection used by the "Flat Map" view.
A 3d point representation.
Unit
enum used constructor to specify the units used
A LineString that allows to store a contiguous set of line segments.
A class to implement the spherical projection used by the "Globe" view.
A class to implement the spherical projection used by the "Globe" view.
A class to implement the Mercator projection.
A class to implement the spherical projection used by the "Globe" view.
A class to implement the spherical projection used by the "Globe" view.
A class to implement the spherical projection used by the "Globe" view.
bool screenCoordinates(const qreal lon, const qreal lat, qreal &x, qreal &y) const
Get the screen coordinates corresponding to geographical coordinates in the map.
void setFocusPoint(const GeoDataCoordinates &focusPoint)
Change the point of focus, overridding any previously set focus point.
void setRadius(int radius)
Change the radius of the planet.
void resetFocusPoint()
Invalidate any focus point set with setFocusPoint.
bool geoCoordinates(const int x, const int y, qreal &lon, qreal &lat, GeoDataCoordinates::Unit unit=GeoDataCoordinates::Degree) const
Get the earth coordinates corresponding to a pixel in the map.
GeoDataCoordinates focusPoint() const
QAction * roll(const QObject *recvr, const char *slot, QObject *parent)
Binds a QML item to a specific geodetic location in screen coordinates.
Projection
This enum is used to choose the projection shown in the view.
@ Mercator
Mercator projection.
@ VerticalPerspective
Vertical perspective projection.
@ AzimuthalEquidistant
Azimuthal Equidistant projection.
@ Gnomonic
Gnomonic projection.
@ LambertAzimuthal
Lambert Azimuthal Equal-Area projection.
@ Equirectangular
Flat projection ("plate carree")
@ Spherical
Spherical projection ("Orthographic")
@ Stereographic
Stereographic projection.