13#include <QPainterPath>
16#include "MarbleDebug.h"
17#include "GeoDataLatLonAltBox.h"
21#include "GnomonicProjection.h"
22#include "LambertAzimuthalProjection.h"
23#include "AzimuthalEquidistantProjection.h"
24#include "StereographicProjection.h"
25#include "VerticalPerspectiveProjection.h"
31class ViewportParamsPrivate
34 ViewportParamsPrivate( Projection projection,
35 qreal centerLongitude, qreal centerLatitude,
39 static const AbstractProjection *abstractProjection( Projection projection );
43 Projection m_projection;
44 const AbstractProjection *m_currentProjection;
47 qreal m_centerLongitude;
48 qreal m_centerLatitude;
50 Quaternion m_planetAxis;
51 matrix m_planetAxisMatrix;
53 qreal m_angularResolution;
59 GeoDataLatLonAltBox m_viewLatLonAltBox;
61 static const SphericalProjection s_sphericalProjection;
62 static const EquirectProjection s_equirectProjection;
63 static const MercatorProjection s_mercatorProjection;
64 static const GnomonicProjection s_gnomonicProjection;
65 static const StereographicProjection s_stereographicProjection;
66 static const LambertAzimuthalProjection s_lambertAzimuthalProjection;
67 static const AzimuthalEquidistantProjection s_azimuthalEquidistantProjection;
68 static const VerticalPerspectiveProjection s_verticalPerspectiveProjection;
70 GeoDataCoordinates m_focusPoint;
73const SphericalProjection ViewportParamsPrivate::s_sphericalProjection;
74const EquirectProjection ViewportParamsPrivate::s_equirectProjection;
75const MercatorProjection ViewportParamsPrivate::s_mercatorProjection;
76const GnomonicProjection ViewportParamsPrivate::s_gnomonicProjection;
77const StereographicProjection ViewportParamsPrivate::s_stereographicProjection;
78const LambertAzimuthalProjection ViewportParamsPrivate::s_lambertAzimuthalProjection;
79const AzimuthalEquidistantProjection ViewportParamsPrivate::s_azimuthalEquidistantProjection;
80const VerticalPerspectiveProjection ViewportParamsPrivate::s_verticalPerspectiveProjection;
82ViewportParamsPrivate::ViewportParamsPrivate( Projection projection,
83 qreal centerLongitude, qreal centerLatitude,
86 : m_projection( projection ),
87 m_currentProjection( abstractProjection( projection ) ),
88 m_centerLongitude( centerLongitude ),
89 m_centerLatitude( centerLatitude ),
94 m_angularResolution(4.0 / abs(m_radius)),
101const AbstractProjection *ViewportParamsPrivate::abstractProjection(Projection projection)
103 switch ( projection ) {
105 return &s_sphericalProjection;
107 return &s_equirectProjection;
109 return &s_mercatorProjection;
111 return &s_gnomonicProjection;
113 return &s_stereographicProjection;
115 return &s_lambertAzimuthalProjection;
117 return &s_azimuthalEquidistantProjection;
119 return &s_verticalPerspectiveProjection;
126ViewportParams::ViewportParams()
127 : d( new ViewportParamsPrivate(
Spherical, 0, 0, 2000,
QSize( 100, 100 ) ) )
129 centerOn( d->m_centerLongitude, d->m_centerLatitude );
132ViewportParams::ViewportParams( Projection projection,
133 qreal centerLongitude, qreal centerLatitude,
136 : d( new ViewportParamsPrivate( projection, centerLongitude, centerLatitude, radius, size ) )
138 centerOn( d->m_centerLongitude, d->m_centerLatitude );
141ViewportParams::~ViewportParams()
151Projection ViewportParams::projection()
const
153 return d->m_projection;
156const AbstractProjection *ViewportParams::currentProjection()
const
158 return d->m_currentProjection;
161void ViewportParams::setProjection(Projection newProjection)
163 d->m_projection = newProjection;
164 d->m_currentProjection = ViewportParamsPrivate::abstractProjection( newProjection );
169 centerOn( d->m_centerLongitude, d->m_centerLatitude );
172int ViewportParams::polarity()
const
176 GeoDataCoordinates northPole( 0.0, +currentProjection()->maxLat() );
177 GeoDataCoordinates southPole( 0.0, -currentProjection()->maxLat() );
179 bool globeHidesN, globeHidesS;
183 currentProjection()->screenCoordinates( northPole,
this,
184 x, yN, globeHidesN );
185 currentProjection()->screenCoordinates( southPole,
this,
186 x, yS, globeHidesS );
191 if ( !globeHidesN && !globeHidesS ) {
200 if ( !globeHidesN && yN < height() / 2 ) {
203 if ( !globeHidesN && yN > height() / 2 ) {
206 if ( !globeHidesS && yS > height() / 2 ) {
209 if ( !globeHidesS && yS < height() / 2 ) {
217int ViewportParams::radius()
const
222void ViewportParams::setRadius(
int newRadius)
224 if ( newRadius > 0 ) {
225 d->m_dirtyBox =
true;
227 d->m_radius = newRadius;
228 d->m_angularResolution = 4.0 / d->m_radius;
232void ViewportParams::centerOn( qreal lon, qreal lat )
234 if ( !d->m_currentProjection->traversablePoles() ) {
235 if ( lat > d->m_currentProjection->maxLat() )
236 lat = d->m_currentProjection->maxLat();
238 if ( lat < d->m_currentProjection->minLat() )
239 lat = d->m_currentProjection->minLat();
243 while ( lat < -M_PI )
249 while ( lon < -M_PI )
252 d->m_centerLongitude = lon;
253 d->m_centerLatitude = lat;
255 const Quaternion
roll = Quaternion::fromEuler( 0, 0, d->m_heading );
256 const Quaternion quat = Quaternion::fromEuler( -lat, lon, 0.0 );
258 d->m_planetAxis = quat *
roll;
259 d->m_planetAxis.normalize();
261 d->m_dirtyBox =
true;
262 d->m_planetAxis.inverse().toMatrix( d->m_planetAxisMatrix );
263 d->m_planetAxis.normalize();
266void ViewportParams::setHeading( qreal heading )
268 d->m_heading = heading;
270 const Quaternion
roll = Quaternion::fromEuler( 0, 0, heading );
272 const qreal centerLat = centerLatitude();
273 const qreal centerLon = centerLongitude();
275 const Quaternion quat = Quaternion::fromEuler( -centerLat, centerLon, 0 );
277 d->m_planetAxis = quat *
roll;
278 d->m_planetAxis.normalize();
280 d->m_dirtyBox =
true;
281 d->m_planetAxis.inverse().toMatrix( d->m_planetAxisMatrix );
282 d->m_planetAxis.normalize();
285qreal ViewportParams::heading()
const
290Quaternion ViewportParams::planetAxis()
const
292 return d->m_planetAxis;
295const matrix &ViewportParams::planetAxisMatrix()
const
297 return d->m_planetAxisMatrix;
300int ViewportParams::width()
const
302 return d->m_size.width();
305int ViewportParams::height()
const
307 return d->m_size.height();
310QSize ViewportParams::size()
const
316void ViewportParams::setWidth(
int newWidth)
318 setSize(
QSize( newWidth, height() ) );
321void ViewportParams::setHeight(
int newHeight)
323 setSize(
QSize( width(), newHeight ) );
326void ViewportParams::setSize(
const QSize& newSize)
328 if ( newSize == d->m_size )
331 d->m_dirtyBox =
true;
339qreal ViewportParams::centerLongitude()
const
341 return d->m_centerLongitude;
344qreal ViewportParams::centerLatitude()
const
346 return d->m_centerLatitude;
349const GeoDataLatLonAltBox& ViewportParams::viewLatLonAltBox()
const
352 d->m_viewLatLonAltBox = d->m_currentProjection->latLonAltBox(
QRect(
QPoint( 0, 0 ),
355 d->m_dirtyBox =
false;
358 return d->m_viewLatLonAltBox;
361GeoDataLatLonAltBox ViewportParams::latLonAltBox(
const QRect &screenRect )
const
363 return d->m_currentProjection->latLonAltBox( screenRect,
this );
366qreal ViewportParams::angularResolution()
const
371 return d->m_angularResolution;
374bool ViewportParams::resolves (
const GeoDataLatLonBox &latLonBox, qreal pixel )
const
376 return latLonBox.
width() + latLonBox.height() > pixel * d->m_angularResolution;
380bool ViewportParams::resolves (
const GeoDataLatLonAltBox &latLonAltBox, qreal pixel, qreal altitude )
const
382 return latLonAltBox.width() + latLonAltBox.height() > pixel * d->m_angularResolution
383 || latLonAltBox.maxAltitude() - latLonAltBox.minAltitude() > altitude;
386bool ViewportParams::resolves (
const GeoDataCoordinates &coord1,
387 const GeoDataCoordinates &coord2 )
const
390 coord1.geoCoordinates( lon1, lat1 );
393 coord2.geoCoordinates( lon2, lat2 );
396 return ( fabs( lon2 - lon1 ) + fabs( lat2 - lat1 ) > d->m_angularResolution );
400bool ViewportParams::screenCoordinates(
const qreal lon,
const qreal lat,
401 qreal &x, qreal &y )
const
403 return d->m_currentProjection->screenCoordinates( lon, lat,
this, x, y );
408 bool &globeHidesPoint )
const
410 return d->m_currentProjection->screenCoordinates( geopoint,
this, x, y, globeHidesPoint );
414 qreal &x, qreal &y )
const
416 return d->m_currentProjection->screenCoordinates( geopoint,
this, x, y );
420 qreal *x, qreal &y,
int &pointRepeatNum,
422 bool &globeHidesPoint )
const
424 return d->m_currentProjection->screenCoordinates( coordinates,
this, x, y, pointRepeatNum, size, globeHidesPoint );
431 return d->m_currentProjection->screenCoordinates( lineString,
this, polygons );
434bool ViewportParams::geoCoordinates(
const int x,
const int y,
435 qreal &lon, qreal &lat,
438 return d->m_currentProjection->geoCoordinates( x, y,
this, lon, lat, unit );
441bool ViewportParams::mapCoversViewport()
const
443 return d->m_currentProjection->mapCoversViewport(
this );
448 return d->m_currentProjection->mapShape(
this );
451QRegion ViewportParams::mapRegion()
const
453 return d->m_currentProjection->mapRegion(
this );
458 if (d->m_focusPoint.isValid()) {
459 return d->m_focusPoint;
462 const qreal lon = d->m_centerLongitude;
463 const qreal lat = d->m_centerLatitude;
472 d->m_focusPoint = focusPoint;
475void ViewportParams::resetFocusPoint()
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.
Unit
enum used constructor to specify the units used
A LineString that allows to store a contiguous set of line segments.
QAction * roll(const QObject *recvr, const char *slot, QObject *parent)
Binds a QML item to a specific geodetic location in screen coordinates.
@ 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.