summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Angelelli <paolo.angelelli@qt.io>2017-07-06 09:53:21 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-07-17 12:40:30 +0000
commitb02916a5568d57eda767ca930dcdb366179250bc (patch)
treea5cf227e6f70faf5b931a4a122b53f37a8a6b8cc
parentd4cb4961ed0a15d0746d96da38228787658d87bd (diff)
downloadqtlocation-b02916a5568d57eda767ca930dcdb366179250bc.tar.gz
Fix Map.toCoordinate always clamping y values to 0
This patch allows to call toCoordinate also on negative y values, given that the y value is still below the horizon. If not, the y value will be clamped to the "minimum unprojectable y value", a value that is clamped to 0. Task-number: QTBUG-61813 Change-Id: I177d3b459b6eaf827daf860b7d4011511a7e76ee Reviewed-by: Alex Blasche <alexander.blasche@qt.io> Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
-rw-r--r--src/location/maps/qgeoprojection.cpp37
-rw-r--r--src/location/maps/qgeoprojection_p.h3
2 files changed, 32 insertions, 8 deletions
diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp
index 783193ed..07747a31 100644
--- a/src/location/maps/qgeoprojection.cpp
+++ b/src/location/maps/qgeoprojection.cpp
@@ -201,14 +201,25 @@ QDoubleVector2D QGeoProjectionWebMercator::wrappedMapProjectionToItemPosition(co
QDoubleVector2D QGeoProjectionWebMercator::itemPositionToWrappedMapProjection(const QDoubleVector2D &itemPosition) const
{
QDoubleVector2D pos = itemPosition;
- // when the camera is tilted, picking a point above the horizon returns a coordinate behind the camera
- if (pos.y() < m_minimumUnprojectableY)
- pos.setY(m_minimumUnprojectableY);
pos *= QDoubleVector2D(m_1_viewportWidth, m_1_viewportHeight);
pos *= 2.0;
pos -= QDoubleVector2D(1.0,1.0);
- return viewportToWrappedMapProjection(pos);
+ double s;
+ QDoubleVector2D res = viewportToWrappedMapProjection(pos, s);
+
+ // a positive s means a point behind the camera. So do it again, after clamping Y. See QTBUG-61813
+ if (s > 0.0) {
+ pos = itemPosition;
+ // when the camera is tilted, picking a point above the horizon returns a coordinate behind the camera
+ pos.setY(m_minimumUnprojectableY);
+ pos *= QDoubleVector2D(m_1_viewportWidth, m_1_viewportHeight);
+ pos *= 2.0;
+ pos -= QDoubleVector2D(1.0,1.0);
+ res = viewportToWrappedMapProjection(pos, s);
+ }
+
+ return res;
}
/* Default implementations */
@@ -306,10 +317,16 @@ QList<QDoubleVector2D> QGeoProjectionWebMercator::visibleRegion() const
return m_visibleRegion;
}
+QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const
+{
+ double s;
+ return viewportToWrappedMapProjection(itemPosition, s);
+}
+
/*
actual implementation of itemPositionToWrappedMapProjection
*/
-QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const
+QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const
{
QDoubleVector2D pos = itemPosition;
pos *= QDoubleVector2D(m_halfWidth, m_halfHeight);
@@ -321,7 +338,7 @@ QDoubleVector2D QGeoProjectionWebMercator::viewportToWrappedMapProjection(const
QDoubleVector3D ray = p - m_eye;
ray.normalize();
- return (xyPlane.lineIntersection(m_eye, ray) / m_sideLength).toVector2D();
+ return (xyPlane.lineIntersection(m_eye, ray, s) / m_sideLength).toVector2D();
}
void QGeoProjectionWebMercator::setupCamera()
@@ -528,9 +545,15 @@ QGeoProjectionWebMercator::Plane::Plane(const QDoubleVector3D &planePoint, const
QDoubleVector3D QGeoProjectionWebMercator::Plane::lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection) const
{
+ double s;
+ return lineIntersection(linePoint, lineDirection, s);
+}
+
+QDoubleVector3D QGeoProjectionWebMercator::Plane::lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection, double &s) const
+{
QDoubleVector3D w = linePoint - m_point;
// s = -n.dot(w) / n.dot(u). p = p0 + su; u is lineDirection
- double s = QDoubleVector3D::dotProduct(-m_normal, w) / QDoubleVector3D::dotProduct(m_normal, lineDirection);
+ s = QDoubleVector3D::dotProduct(-m_normal, w) / QDoubleVector3D::dotProduct(m_normal, lineDirection);
return linePoint + lineDirection * s;
}
diff --git a/src/location/maps/qgeoprojection_p.h b/src/location/maps/qgeoprojection_p.h
index 3a0dec1d..7d306eea 100644
--- a/src/location/maps/qgeoprojection_p.h
+++ b/src/location/maps/qgeoprojection_p.h
@@ -128,7 +128,7 @@ public:
QList<QDoubleVector2D> visibleRegion() const Q_DECL_OVERRIDE;
inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition) const;
-
+ inline QDoubleVector2D viewportToWrappedMapProjection(const QDoubleVector2D &itemPosition, double &s) const;
private:
void setupCamera();
void updateVisibleRegion();
@@ -151,6 +151,7 @@ public:
Plane(const QDoubleVector3D &planePoint, const QDoubleVector3D &planeNormal);
QDoubleVector3D lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection) const;
+ inline QDoubleVector3D lineIntersection(const QDoubleVector3D &linePoint, const QDoubleVector3D &lineDirection, double &s) const;
Line2D planeXYIntersection() const;
bool isValid() const;