diff options
-rw-r--r-- | src/imports/location/qdeclarativegeomap.cpp | 82 | ||||
-rw-r--r-- | src/imports/location/qdeclarativegeomap_p.h | 11 | ||||
-rw-r--r-- | src/location/maps/qgeocameracapabilities.cpp | 59 | ||||
-rw-r--r-- | src/location/maps/qgeocameracapabilities_p.h | 6 | ||||
-rw-r--r-- | src/location/maps/qgeocameradata.cpp | 18 | ||||
-rw-r--r-- | src/location/maps/qgeocameradata_p.h | 3 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 2 |
7 files changed, 177 insertions, 4 deletions
diff --git a/src/imports/location/qdeclarativegeomap.cpp b/src/imports/location/qdeclarativegeomap.cpp index fb5a2472..7182bb21 100644 --- a/src/imports/location/qdeclarativegeomap.cpp +++ b/src/imports/location/qdeclarativegeomap.cpp @@ -312,8 +312,11 @@ void QDeclarativeGeoMap::initialize() bool centerHasChanged = false; bool bearingHasChanged = false; bool tiltHasChanged = false; + bool fovHasChanged = false; bool minTiltHasChanged = false; bool maxTiltHasChanged = false; + bool minFovHasChanged = false; + bool maxFovHasChanged = false; QGeoCoordinate center = m_cameraData.center(); @@ -321,6 +324,11 @@ void QDeclarativeGeoMap::initialize() double bearing = m_cameraData.bearing(); double tilt = m_cameraData.tilt(); + double fov = m_cameraData.fieldOfView(); // Must be 45.0 + if (m_map->cameraCapabilities().minimumFieldOfView() != 1) + minFovHasChanged = true; + if (m_map->cameraCapabilities().maximumFieldOfView() != 179) + maxFovHasChanged = true; if (m_map->cameraCapabilities().minimumTilt() != 0) minTiltHasChanged = true; if (m_map->cameraCapabilities().maximumTilt() != 89) @@ -334,6 +342,12 @@ void QDeclarativeGeoMap::initialize() tiltHasChanged = true; } + m_cameraData.setFieldOfView(qBound(m_map->cameraCapabilities().minimumFieldOfView(), + fov, + m_map->cameraCapabilities().maximumFieldOfView())); + if (fov != m_cameraData.fieldOfView()) + fovHasChanged = true; + // set latitude boundary check m_maximumViewportLatitude = m_map->maximumCenterLatitudeAtZoom(m_cameraData); @@ -357,11 +371,20 @@ void QDeclarativeGeoMap::initialize() if (tiltHasChanged) emit tiltChanged(m_cameraData.tilt()); + if (fovHasChanged) + emit fieldOfViewChanged(m_cameraData.fieldOfView()); + if (minTiltHasChanged) emit minimumTiltChanged(m_map->cameraCapabilities().minimumTilt()); if (maxTiltHasChanged) emit maximumTiltChanged(m_map->cameraCapabilities().maximumTilt()); + + if (minFovHasChanged) + emit minimumFieldOfViewChanged(m_map->cameraCapabilities().minimumFieldOfView()); + + if (maxFovHasChanged) + emit maximumFieldOfViewChanged(m_map->cameraCapabilities().maximumFieldOfView()); } /*! @@ -842,6 +865,65 @@ qreal QDeclarativeGeoMap::tilt() const } /*! + \qmlproperty real QtLocation::Map::fieldOfView + + This property holds the field of view of the camera used to look at the map, in degrees. + If the plugin property of the map is not set, or the plugin does not support mapping, the value is 45 degrees. + + Note that changing this value implicitly changes also the distance between the camera and the map, + so that, at a tilting angle of 0 degrees, the resulting image is identical for any value used for this property. + + For more information about this parameter, consult the Wikipedia articles about \l {https://en.wikipedia.org/wiki/Field_of_view} {Field of view} and + \l {https://en.wikipedia.org/wiki/Angle_of_view} {Angle of view}. + + \since Qt Location 5.9 +*/ +void QDeclarativeGeoMap::setFieldOfView(qreal fieldOfView) +{ + fieldOfView = qBound(minimumFieldOfView(), fieldOfView, maximumFieldOfView()); + if (m_cameraData.fieldOfView() == fieldOfView) + return; + + m_cameraData.setFieldOfView(fieldOfView); + if (m_map) + m_map->setCameraData(m_cameraData); + emit fieldOfViewChanged(fieldOfView); +} + +qreal QDeclarativeGeoMap::fieldOfView() const +{ + return m_cameraData.fieldOfView(); +} + +/*! + \qmlproperty bool QtLocation::Map::minimumFieldOfView + This property holds the minimum field of view that the map supports. + If the plugin property of the map is not set, or the plugin does not support mapping, this property is 1. + + \since Qt Location 5.9 +*/ +qreal QDeclarativeGeoMap::minimumFieldOfView() const +{ + if (!m_map) + return 1; + return m_map->cameraCapabilities().minimumFieldOfView(); +} + +/*! + \qmlproperty bool QtLocation::Map::maximumFieldOfView + This property holds the maximum field of view that the map supports. + If the plugin property of the map is not set, or the plugin does not support mapping, this property is 179. + + \since Qt Location 5.9 +*/ +qreal QDeclarativeGeoMap::maximumFieldOfView() const +{ + if (!m_map) + return 179; + return m_map->cameraCapabilities().maximumFieldOfView(); +} + +/*! \qmlproperty bool QtLocation::Map::bearingSupported This property indicates if the Map supports bearing. diff --git a/src/imports/location/qdeclarativegeomap_p.h b/src/imports/location/qdeclarativegeomap_p.h index 71538e42..b85daf1a 100644 --- a/src/imports/location/qdeclarativegeomap_p.h +++ b/src/imports/location/qdeclarativegeomap_p.h @@ -81,6 +81,9 @@ class QDeclarativeGeoMap : public QQuickItem Q_PROPERTY(qreal maximumTilt READ maximumTilt NOTIFY maximumTiltChanged) Q_PROPERTY(qreal bearing READ bearing WRITE setBearing NOTIFY bearingChanged) Q_PROPERTY(qreal tilt READ tilt WRITE setTilt NOTIFY tiltChanged) + Q_PROPERTY(qreal fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged) + Q_PROPERTY(qreal minimumFieldOfView READ minimumFieldOfView NOTIFY minimumFieldOfViewChanged) + Q_PROPERTY(qreal maximumFieldOfView READ maximumFieldOfView NOTIFY minimumFieldOfViewChanged) Q_PROPERTY(QDeclarativeGeoMapType *activeMapType READ activeMapType WRITE setActiveMapType NOTIFY activeMapTypeChanged) Q_PROPERTY(QQmlListProperty<QDeclarativeGeoMapType> supportedMapTypes READ supportedMapTypes NOTIFY supportedMapTypesChanged) @@ -120,6 +123,11 @@ public: void setTilt(qreal tilt); qreal tilt() const; + void setFieldOfView(qreal fieldOfView); + qreal fieldOfView() const; + qreal minimumFieldOfView() const; + qreal maximumFieldOfView() const; + bool isBearingSupported() const; bool isTiltingSupported() const; qreal minimumTilt() const; @@ -178,10 +186,13 @@ Q_SIGNALS: void colorChanged(const QColor &color); void bearingChanged(qreal bearing); void tiltChanged(qreal tilt); + void fieldOfViewChanged(qreal fieldOfView); void bearingSupportChanged(bool bearingSupport); void tiltingSupportChanged(bool tiltingSupport); void minimumTiltChanged(qreal minimumTilt); void maximumTiltChanged(qreal maximumTilt); + void minimumFieldOfViewChanged(qreal minimumFieldOfView); + void maximumFieldOfViewChanged(qreal maximumFieldOfView); protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE ; diff --git a/src/location/maps/qgeocameracapabilities.cpp b/src/location/maps/qgeocameracapabilities.cpp index fca12a5c..568476fd 100644 --- a/src/location/maps/qgeocameracapabilities.cpp +++ b/src/location/maps/qgeocameracapabilities.cpp @@ -70,6 +70,8 @@ public: double minTilt_; double maxTilt_; int tileSize_; + double minimumFieldOfView_; + double maximumFieldOfView_; }; QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate() @@ -81,7 +83,9 @@ QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate() maxZoom_(0.0), minTilt_(0.0), maxTilt_(0.0), - tileSize_(256) {} + tileSize_(256), + minimumFieldOfView_(45.0), // Defaulting to a fixed FOV of 45 degrees. Too large FOVs cause the loading of too many tiles + maximumFieldOfView_(45.0) {} QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate(const QGeoCameraCapabilitiesPrivate &other) @@ -94,7 +98,9 @@ QGeoCameraCapabilitiesPrivate::QGeoCameraCapabilitiesPrivate(const QGeoCameraCap maxZoom_(other.maxZoom_), minTilt_(other.minTilt_), maxTilt_(other.maxTilt_), - tileSize_(other.tileSize_) {} + tileSize_(other.tileSize_), + minimumFieldOfView_(other.minimumFieldOfView_), + maximumFieldOfView_(other.maximumFieldOfView_) {} QGeoCameraCapabilitiesPrivate::~QGeoCameraCapabilitiesPrivate() {} @@ -113,6 +119,8 @@ QGeoCameraCapabilitiesPrivate &QGeoCameraCapabilitiesPrivate::operator = (const minTilt_ = other.minTilt_; maxTilt_ = other.maxTilt_; tileSize_ = other.tileSize_; + minimumFieldOfView_ = other.minimumFieldOfView_; + maximumFieldOfView_ = other.maximumFieldOfView_; return *this; } @@ -349,4 +357,51 @@ double QGeoCameraCapabilities::maximumTilt() const return d->maxTilt_; } +/*! + Sets the minimum field of view supported by the associated plugin to \a minimumFieldOfView. + The value is in degrees and is clamped against a [1, 179] range. + + \since 5.9 +*/ +void QGeoCameraCapabilities::setMinimumFieldOfView(double minimumFieldOfView) +{ + d->minimumFieldOfView_ = qBound(1.0, minimumFieldOfView, 179.0); + d->valid_ = true; +} + +/*! + Returns the minimum field of view supported by the associated plugin. + The value is in degrees. + + \since 5.9 +*/ +double QGeoCameraCapabilities::minimumFieldOfView() const +{ + return d->minimumFieldOfView_; +} + +/*! + Sets the maximum field of view supported by the associated plugin to \a maximumFieldOfView. + The value is in degrees and is clamped against a [1, 179] range. + + \since 5.9 +*/ +void QGeoCameraCapabilities::setMaximumFieldOfView(double maximumFieldOfView) +{ + d->maximumFieldOfView_ = maximumFieldOfView; + d->valid_ = true; +} + +/*! + Returns the maximum field of view supported by the associated plugin. + The value is in degrees. + + \since 5.9 +*/ +double QGeoCameraCapabilities::maximumFieldOfView() const +{ + return d->maximumFieldOfView_; +} + + QT_END_NAMESPACE diff --git a/src/location/maps/qgeocameracapabilities_p.h b/src/location/maps/qgeocameracapabilities_p.h index 7de6ece0..c9da53e9 100644 --- a/src/location/maps/qgeocameracapabilities_p.h +++ b/src/location/maps/qgeocameracapabilities_p.h @@ -91,6 +91,12 @@ public: void setMaximumTilt(double maximumTilt); double maximumTilt() const; + void setMinimumFieldOfView(double minimumFieldOfView); + double minimumFieldOfView() const; + + void setMaximumFieldOfView(double maximumFieldOfView); + double maximumFieldOfView() const; + bool isValid() const; private: diff --git a/src/location/maps/qgeocameradata.cpp b/src/location/maps/qgeocameradata.cpp index 0d4c273e..ecf7d46a 100644 --- a/src/location/maps/qgeocameradata.cpp +++ b/src/location/maps/qgeocameradata.cpp @@ -55,6 +55,7 @@ public: double m_bearing; double m_tilt; double m_roll; + double m_fieldOfView; double m_zoomLevel; }; @@ -64,6 +65,7 @@ QGeoCameraDataPrivate::QGeoCameraDataPrivate() m_bearing(0.0), m_tilt(0.0), m_roll(0.0), + m_fieldOfView(45.0), m_zoomLevel(0.0) {} QGeoCameraDataPrivate::QGeoCameraDataPrivate(const QGeoCameraDataPrivate &rhs) @@ -72,6 +74,7 @@ QGeoCameraDataPrivate::QGeoCameraDataPrivate(const QGeoCameraDataPrivate &rhs) m_bearing(rhs.m_bearing), m_tilt(rhs.m_tilt), m_roll(rhs.m_roll), + m_fieldOfView(rhs.m_fieldOfView), m_zoomLevel(rhs.m_zoomLevel) {} QGeoCameraDataPrivate &QGeoCameraDataPrivate::operator = (const QGeoCameraDataPrivate &rhs) @@ -82,7 +85,8 @@ QGeoCameraDataPrivate &QGeoCameraDataPrivate::operator = (const QGeoCameraDataPr m_center = rhs.m_center; m_bearing = rhs.m_bearing; m_tilt = rhs.m_tilt; - m_roll = rhs.m_roll;; + m_roll = rhs.m_roll; + m_fieldOfView = rhs.m_fieldOfView; m_zoomLevel = rhs.m_zoomLevel; return *this; @@ -94,6 +98,7 @@ bool QGeoCameraDataPrivate::operator == (const QGeoCameraDataPrivate &rhs) const && (m_bearing == rhs.m_bearing) && (m_tilt == rhs.m_tilt) && (m_roll == rhs.m_roll) + && (m_fieldOfView == rhs.m_fieldOfView) && (m_zoomLevel == rhs.m_zoomLevel)); } @@ -123,6 +128,7 @@ QVariant cameraInterpolator(const QGeoCameraData &start, result.setBearing(sf * start.bearing() + ef * end.bearing()); result.setTilt(sf * start.tilt() + ef * end.tilt()); result.setRoll(sf * start.roll() + ef * end.roll()); + result.setFieldOfView(sf * start.fieldOfView() + ef * end.fieldOfView()); result.setZoomLevel(sf * start.zoomLevel() + ef * end.zoomLevel()); return QVariant::fromValue(result); @@ -201,6 +207,16 @@ double QGeoCameraData::roll() const return d->m_roll; } +void QGeoCameraData::setFieldOfView(double fieldOfView) +{ + d->m_fieldOfView = fieldOfView; +} + +double QGeoCameraData::fieldOfView() const +{ + return d->m_fieldOfView; +} + void QGeoCameraData::setZoomLevel(double zoomFactor) { d->m_zoomLevel = zoomFactor; diff --git a/src/location/maps/qgeocameradata_p.h b/src/location/maps/qgeocameradata_p.h index c245fbfd..4912ec3e 100644 --- a/src/location/maps/qgeocameradata_p.h +++ b/src/location/maps/qgeocameradata_p.h @@ -82,6 +82,9 @@ public: void setRoll(double roll); double roll() const; + void setFieldOfView(double fieldOfView); + double fieldOfView() const; + // Zoom level is intended to be relative to a tileSize of 256^2 pixels. // E.g., a zoom level of 0 must result in a mapWidth of 256, and so on. void setZoomLevel(double zoomLevel); diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp index b33f180f..a54eee54 100644 --- a/src/location/maps/qgeoprojection.cpp +++ b/src/location/maps/qgeoprojection.cpp @@ -263,7 +263,7 @@ void QGeoProjectionWebMercator::setupCamera() double altitude = f / (2.0 * z) ; //aperture(90 / 2) = 1 - m_aperture = 0.41421356237309503; // For a field of view of 45 degrees, as 90 is loading too many tiles + m_aperture = tan(QLocationUtils::radians(m_cameraData.fieldOfView()) * 0.5); // calculate eye m_eye = m_center; m_eye.setZ(altitude * defaultTileSize / m_aperture); |