diff options
Diffstat (limited to 'src/location/maps')
-rw-r--r-- | src/location/maps/maps.pri | 6 | ||||
-rw-r--r-- | src/location/maps/qdoublevector2d.cpp | 132 | ||||
-rw-r--r-- | src/location/maps/qdoublevector2d_p.h | 240 | ||||
-rw-r--r-- | src/location/maps/qdoublevector3d.cpp | 187 | ||||
-rw-r--r-- | src/location/maps/qdoublevector3d_p.h | 294 | ||||
-rw-r--r-- | src/location/maps/qgeocameratiles.cpp | 746 | ||||
-rw-r--r-- | src/location/maps/qgeocameratiles_p.h | 92 | ||||
-rw-r--r-- | src/location/maps/qgeofrustum.cpp | 11 | ||||
-rw-r--r-- | src/location/maps/qgeofrustum_p.h | 41 | ||||
-rw-r--r-- | src/location/maps/qgeomap.cpp | 790 | ||||
-rw-r--r-- | src/location/maps/qgeomap_p_p.h | 103 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection.cpp | 15 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection2d.cpp | 28 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection2d_p.h | 8 | ||||
-rw-r--r-- | src/location/maps/qgeoprojection_p.h | 16 |
15 files changed, 1821 insertions, 888 deletions
diff --git a/src/location/maps/maps.pri b/src/location/maps/maps.pri index 548b177b..520fb004 100644 --- a/src/location/maps/maps.pri +++ b/src/location/maps/maps.pri @@ -23,7 +23,10 @@ PUBLIC_HEADERS += \ maps/qgeotilespec.h PRIVATE_HEADERS += \ + maps/qdoublevector2d_p.h \ + maps/qdoublevector3d_p.h \ maps/qgeocameradata_p.h \ + maps/qgeocameratiles_p.h \ maps/qgeocodereply_p.h \ maps/qgeocodingmanagerengine_p.h \ maps/qgeocodingmanager_p.h \ @@ -51,7 +54,10 @@ PRIVATE_HEADERS += \ maps/qgeotilespec_p.h SOURCES += \ + maps/qdoublevector2d.cpp \ + maps/qdoublevector3d.cpp \ maps/qgeocameradata.cpp \ + maps/qgeocameratiles.cpp \ maps/qgeocodereply.cpp \ maps/qgeocodingmanager.cpp \ maps/qgeocodingmanagerengine.cpp \ diff --git a/src/location/maps/qdoublevector2d.cpp b/src/location/maps/qdoublevector2d.cpp new file mode 100644 index 00000000..b5a87553 --- /dev/null +++ b/src/location/maps/qdoublevector2d.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" +#include <QtCore/qdebug.h> +#include <QtCore/qmath.h> + +QT_BEGIN_NAMESPACE + +QDoubleVector2D::QDoubleVector2D(const QDoubleVector3D& vector) +{ + xp = vector.xp; + yp = vector.yp; +} + +double QDoubleVector2D::length() const +{ + return qSqrt(xp * xp + yp * yp); +} + +double QDoubleVector2D::lengthSquared() const +{ + return xp * xp + yp * yp; +} + +QDoubleVector2D QDoubleVector2D::normalized() const +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp); + if (qFuzzyIsNull(len - 1.0)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / qSqrt(len); + else + return QDoubleVector2D(); +} + +void QDoubleVector2D::normalize() +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp); + if (qFuzzyIsNull(len - 1.0) || qFuzzyIsNull(len)) + return; + + len = qSqrt(len); + + xp /= len; + yp /= len; +} + +double QDoubleVector2D::dotProduct(const QDoubleVector2D& v1, const QDoubleVector2D& v2) +{ + return v1.xp * v2.xp + v1.yp * v2.yp; +} + +QDoubleVector3D QDoubleVector2D::toVector3D() const +{ + return QDoubleVector3D(xp, yp, 0.0); +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug dbg, const QDoubleVector2D &vector) +{ + dbg.nospace() << "QDoubleVector2D(" << vector.x() << ", " << vector.y() << ')'; + return dbg.space(); +} + +#endif + +#ifndef QT_NO_DATASTREAM + +QDataStream &operator<<(QDataStream &stream, const QDoubleVector2D &vector) +{ + stream << double(vector.x()) << double(vector.y()); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QDoubleVector2D &vector) +{ + double x, y; + stream >> x; + stream >> y; + vector.setX(double(x)); + vector.setY(double(y)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +QT_END_NAMESPACE diff --git a/src/location/maps/qdoublevector2d_p.h b/src/location/maps/qdoublevector2d_p.h new file mode 100644 index 00000000..a8d05667 --- /dev/null +++ b/src/location/maps/qdoublevector2d_p.h @@ -0,0 +1,240 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDOUBLEVECTOR2D_P_H +#define QDOUBLEVECTOR2D_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QVector2D> + +#include <QtCore/qmetatype.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QDoubleVector3D; + +class QDoubleVector2D +{ +public: + QDoubleVector2D(); + explicit QDoubleVector2D(const QVector2D &vector); + QDoubleVector2D(double xpos, double ypos); + explicit QDoubleVector2D(const QDoubleVector3D& vector); + + operator QVector2D() const; + + bool isNull() const; + + double x() const; + double y() const; + + void setX(double x); + void setY(double y); + + double length() const; + double lengthSquared() const; + + QDoubleVector2D normalized() const; + void normalize(); + + QDoubleVector2D &operator+=(const QDoubleVector2D &vector); + QDoubleVector2D &operator-=(const QDoubleVector2D &vector); + QDoubleVector2D &operator*=(double factor); + QDoubleVector2D &operator*=(const QDoubleVector2D &vector); + QDoubleVector2D &operator/=(double divisor); + + static double dotProduct(const QDoubleVector2D& v1, const QDoubleVector2D& v2); + + friend inline bool operator==(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend inline bool operator!=(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend inline const QDoubleVector2D operator+(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend inline const QDoubleVector2D operator-(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend inline const QDoubleVector2D operator*(double factor, const QDoubleVector2D &vector); + friend inline const QDoubleVector2D operator*(const QDoubleVector2D &vector, double factor); + friend inline const QDoubleVector2D operator*(const QDoubleVector2D &v1, const QDoubleVector2D &v2); + friend inline const QDoubleVector2D operator-(const QDoubleVector2D &vector); + friend inline const QDoubleVector2D operator/(const QDoubleVector2D &vector, double divisor); + + friend inline bool qFuzzyCompare(const QDoubleVector2D& v1, const QDoubleVector2D& v2); + + QDoubleVector3D toVector3D() const; + +private: + double xp, yp; + + friend class QDoubleVector3D; +}; + +Q_DECLARE_TYPEINFO(QDoubleVector2D, Q_MOVABLE_TYPE); + +inline QDoubleVector2D::QDoubleVector2D() : xp(0.0), yp(0.0) {} + +inline QDoubleVector2D::QDoubleVector2D(const QVector2D &vector) : xp(vector.x()), yp(vector.y()) {} + +inline QDoubleVector2D::QDoubleVector2D(double xpos, double ypos) : xp(xpos), yp(ypos) {} + +inline QDoubleVector2D::operator QVector2D() const +{ + return QVector2D(xp, yp); +} + +inline bool QDoubleVector2D::isNull() const +{ + return qIsNull(xp) && qIsNull(yp); +} + +inline double QDoubleVector2D::x() const { return double(xp); } +inline double QDoubleVector2D::y() const { return double(yp); } + +inline void QDoubleVector2D::setX(double aX) { xp = aX; } +inline void QDoubleVector2D::setY(double aY) { yp = aY; } + +inline QDoubleVector2D &QDoubleVector2D::operator+=(const QDoubleVector2D &vector) +{ + xp += vector.xp; + yp += vector.yp; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator-=(const QDoubleVector2D &vector) +{ + xp -= vector.xp; + yp -= vector.yp; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator*=(double factor) +{ + xp *= factor; + yp *= factor; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator*=(const QDoubleVector2D &vector) +{ + xp *= vector.xp; + yp *= vector.yp; + return *this; +} + +inline QDoubleVector2D &QDoubleVector2D::operator/=(double divisor) +{ + xp /= divisor; + yp /= divisor; + return *this; +} + +inline bool operator==(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return v1.xp == v2.xp && v1.yp == v2.yp; +} + +inline bool operator!=(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return v1.xp != v2.xp || v1.yp != v2.yp; +} + +inline const QDoubleVector2D operator+(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return QDoubleVector2D(v1.xp + v2.xp, v1.yp + v2.yp); +} + +inline const QDoubleVector2D operator-(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return QDoubleVector2D(v1.xp - v2.xp, v1.yp - v2.yp); +} + +inline const QDoubleVector2D operator*(double factor, const QDoubleVector2D &vector) +{ + return QDoubleVector2D(vector.xp * factor, vector.yp * factor); +} + +inline const QDoubleVector2D operator*(const QDoubleVector2D &vector, double factor) +{ + return QDoubleVector2D(vector.xp * factor, vector.yp * factor); +} + +inline const QDoubleVector2D operator*(const QDoubleVector2D &v1, const QDoubleVector2D &v2) +{ + return QDoubleVector2D(v1.xp * v2.xp, v1.yp * v2.yp); +} + +inline const QDoubleVector2D operator-(const QDoubleVector2D &vector) +{ + return QDoubleVector2D(-vector.xp, -vector.yp); +} + +inline const QDoubleVector2D operator/(const QDoubleVector2D &vector, double divisor) +{ + return QDoubleVector2D(vector.xp / divisor, vector.yp / divisor); +} + +inline bool qFuzzyCompare(const QDoubleVector2D& v1, const QDoubleVector2D& v2) +{ + return qFuzzyCompare(v1.xp, v2.xp) && qFuzzyCompare(v1.yp, v2.yp); +} + +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QDoubleVector2D &vector); +#endif + +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QDoubleVector2D &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QDoubleVector2D &); +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/location/maps/qdoublevector3d.cpp b/src/location/maps/qdoublevector3d.cpp new file mode 100644 index 00000000..6f0e708e --- /dev/null +++ b/src/location/maps/qdoublevector3d.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qdoublevector3d_p.h" +#include "qdoublevector2d_p.h" +#include <QtCore/qmath.h> +#include <QtCore/qdebug.h> + +QT_BEGIN_NAMESPACE + +QDoubleVector3D::QDoubleVector3D(const QDoubleVector2D& vector) +{ + xp = vector.xp; + yp = vector.yp; + zp = 0.0; +} + +QDoubleVector3D::QDoubleVector3D(const QDoubleVector2D& vector, double zpos) +{ + xp = vector.xp; + yp = vector.yp; + zp = zpos; +} + +QDoubleVector3D QDoubleVector3D::normalized() const +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp) + + double(zp) * double(zp); + if (qFuzzyIsNull(len - 1.0)) + return *this; + else if (!qFuzzyIsNull(len)) + return *this / qSqrt(len); + else + return QDoubleVector3D(); +} + +void QDoubleVector3D::normalize() +{ + // Need some extra precision if the length is very small. + double len = double(xp) * double(xp) + + double(yp) * double(yp) + + double(zp) * double(zp); + if (qFuzzyIsNull(len - 1.0) || qFuzzyIsNull(len)) + return; + + len = qSqrt(len); + + xp /= len; + yp /= len; + zp /= len; +} + +double QDoubleVector3D::dotProduct(const QDoubleVector3D& v1, const QDoubleVector3D& v2) +{ + return v1.xp * v2.xp + v1.yp * v2.yp + v1.zp * v2.zp; +} + +QDoubleVector3D QDoubleVector3D::crossProduct(const QDoubleVector3D& v1, const QDoubleVector3D& v2) +{ + return QDoubleVector3D(v1.yp * v2.zp - v1.zp * v2.yp, + v1.zp * v2.xp - v1.xp * v2.zp, + v1.xp * v2.yp - v1.yp * v2.xp); +} + +QDoubleVector3D QDoubleVector3D::normal(const QDoubleVector3D& v1, const QDoubleVector3D& v2) +{ + return crossProduct(v1, v2).normalized(); +} + +QDoubleVector3D QDoubleVector3D::normal + (const QDoubleVector3D& v1, const QDoubleVector3D& v2, const QDoubleVector3D& v3) +{ + return crossProduct((v2 - v1), (v3 - v1)).normalized(); +} + +double QDoubleVector3D::distanceToPlane + (const QDoubleVector3D& plane, const QDoubleVector3D& normal) const +{ + return dotProduct(*this - plane, normal); +} + +double QDoubleVector3D::distanceToPlane + (const QDoubleVector3D& plane1, const QDoubleVector3D& plane2, const QDoubleVector3D& plane3) const +{ + QDoubleVector3D n = normal(plane2 - plane1, plane3 - plane1); + return dotProduct(*this - plane1, n); +} + +double QDoubleVector3D::distanceToLine + (const QDoubleVector3D& point, const QDoubleVector3D& direction) const +{ + if (direction.isNull()) + return (*this - point).length(); + QDoubleVector3D p = point + dotProduct(*this - point, direction) * direction; + return (*this - p).length(); +} + +QDoubleVector2D QDoubleVector3D::toVector2D() const +{ + return QDoubleVector2D(xp, yp); +} + +double QDoubleVector3D::length() const +{ + return qSqrt(xp * xp + yp * yp + zp * zp); +} + +double QDoubleVector3D::lengthSquared() const +{ + return xp * xp + yp * yp + zp * zp; +} + +#ifndef QT_NO_DEBUG_STREAM + +QDebug operator<<(QDebug dbg, const QDoubleVector3D &vector) +{ + dbg.nospace() << "QDoubleVector3D(" + << vector.x() << ", " << vector.y() << ", " << vector.z() << ')'; + return dbg.space(); +} + +#endif + +#ifndef QT_NO_DATASTREAM + +QDataStream &operator<<(QDataStream &stream, const QDoubleVector3D &vector) +{ + stream << double(vector.x()) << double(vector.y()) + << double(vector.z()); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QDoubleVector3D &vector) +{ + double x, y, z; + stream >> x; + stream >> y; + stream >> z; + vector.setX(double(x)); + vector.setY(double(y)); + vector.setZ(double(z)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +QT_END_NAMESPACE diff --git a/src/location/maps/qdoublevector3d_p.h b/src/location/maps/qdoublevector3d_p.h new file mode 100644 index 00000000..26c426bf --- /dev/null +++ b/src/location/maps/qdoublevector3d_p.h @@ -0,0 +1,294 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QDOUBLEVECTOR3D_P_H +#define QDOUBLEVECTOR3D_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QVector3D> + +#include <QtCore/qmetatype.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +class QDoubleVector2D; + +class QDoubleVector3D +{ +public: + QDoubleVector3D(); + QDoubleVector3D(double xpos, double ypos, double zpos); + explicit QDoubleVector3D(const QVector3D &vector); + QDoubleVector3D(const QDoubleVector2D& vector); + QDoubleVector3D(const QDoubleVector2D& vector, double zpos); + + operator QVector3D() const; + + bool isNull() const; + + double x() const; + double y() const; + double z() const; + + void setX(double x); + void setY(double y); + void setZ(double z); + + double get(int i) const; + void set(int i, double value); + + double length() const; + double lengthSquared() const; + + QDoubleVector3D normalized() const; + void normalize(); + + QDoubleVector3D &operator+=(const QDoubleVector3D &vector); + QDoubleVector3D &operator-=(const QDoubleVector3D &vector); + QDoubleVector3D &operator*=(double factor); + QDoubleVector3D &operator*=(const QDoubleVector3D& vector); + QDoubleVector3D &operator/=(double divisor); + + static double dotProduct(const QDoubleVector3D& v1, const QDoubleVector3D& v2); + static QDoubleVector3D crossProduct(const QDoubleVector3D& v1, const QDoubleVector3D& v2); + static QDoubleVector3D normal(const QDoubleVector3D& v1, const QDoubleVector3D& v2); + static QDoubleVector3D normal + (const QDoubleVector3D& v1, const QDoubleVector3D& v2, const QDoubleVector3D& v3); + + double distanceToPlane(const QDoubleVector3D& plane, const QDoubleVector3D& normal) const; + double distanceToPlane(const QDoubleVector3D& plane1, const QDoubleVector3D& plane2, const QDoubleVector3D& plane3) const; + double distanceToLine(const QDoubleVector3D& point, const QDoubleVector3D& direction) const; + + friend inline bool operator==(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend inline bool operator!=(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend inline const QDoubleVector3D operator+(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend inline const QDoubleVector3D operator-(const QDoubleVector3D &v1, const QDoubleVector3D &v2); + friend inline const QDoubleVector3D operator*(double factor, const QDoubleVector3D &vector); + friend inline const QDoubleVector3D operator*(const QDoubleVector3D &vector, double factor); + friend const QDoubleVector3D operator*(const QDoubleVector3D &v1, const QDoubleVector3D& v2); + friend inline const QDoubleVector3D operator-(const QDoubleVector3D &vector); + friend inline const QDoubleVector3D operator/(const QDoubleVector3D &vector, double divisor); + + friend inline bool qFuzzyCompare(const QDoubleVector3D& v1, const QDoubleVector3D& v2); + + QDoubleVector2D toVector2D() const; + +private: + double xp, yp, zp; + + friend class QDoubleVector2D; +}; + +Q_DECLARE_TYPEINFO(QDoubleVector3D, Q_MOVABLE_TYPE); + +inline QDoubleVector3D::QDoubleVector3D() : xp(0.0), yp(0.0), zp(0.0) {} + +inline QDoubleVector3D::QDoubleVector3D(const QVector3D &vector) : xp(vector.x()), yp(vector.y()), zp(vector.z()) {} + +inline QDoubleVector3D::QDoubleVector3D(double xpos, double ypos, double zpos) : xp(xpos), yp(ypos), zp(zpos) {} + +inline QDoubleVector3D::operator QVector3D() const +{ + return QVector3D(xp, yp, zp); +} + +inline bool QDoubleVector3D::isNull() const +{ + return qIsNull(xp) && qIsNull(yp) && qIsNull(zp); +} + +inline double QDoubleVector3D::x() const { return xp; } +inline double QDoubleVector3D::y() const { return yp; } +inline double QDoubleVector3D::z() const { return zp; } + +inline void QDoubleVector3D::setX(double aX) { xp = aX; } +inline void QDoubleVector3D::setY(double aY) { yp = aY; } +inline void QDoubleVector3D::setZ(double aZ) { zp = aZ; } + +inline double QDoubleVector3D::get(int i) const +{ + switch (i) { + case 0: + return xp; + case 1: + return yp; + case 2: + return zp; + default: + return 0.0; + } +} + +inline void QDoubleVector3D::set(int i, double value) +{ + switch (i) { + case 0: + xp = value; + break; + case 1: + yp = value; + break; + case 2: + zp = value; + break; + default: + break; + } +} + +inline QDoubleVector3D &QDoubleVector3D::operator+=(const QDoubleVector3D &vector) +{ + xp += vector.xp; + yp += vector.yp; + zp += vector.zp; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator-=(const QDoubleVector3D &vector) +{ + xp -= vector.xp; + yp -= vector.yp; + zp -= vector.zp; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator*=(double factor) +{ + xp *= factor; + yp *= factor; + zp *= factor; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator*=(const QDoubleVector3D& vector) +{ + xp *= vector.xp; + yp *= vector.yp; + zp *= vector.zp; + return *this; +} + +inline QDoubleVector3D &QDoubleVector3D::operator/=(double divisor) +{ + xp /= divisor; + yp /= divisor; + zp /= divisor; + return *this; +} + +inline bool operator==(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return v1.xp == v2.xp && v1.yp == v2.yp && v1.zp == v2.zp; +} + +inline bool operator!=(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return v1.xp != v2.xp || v1.yp != v2.yp || v1.zp != v2.zp; +} + +inline const QDoubleVector3D operator+(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return QDoubleVector3D(v1.xp + v2.xp, v1.yp + v2.yp, v1.zp + v2.zp); +} + +inline const QDoubleVector3D operator-(const QDoubleVector3D &v1, const QDoubleVector3D &v2) +{ + return QDoubleVector3D(v1.xp - v2.xp, v1.yp - v2.yp, v1.zp - v2.zp); +} + +inline const QDoubleVector3D operator*(double factor, const QDoubleVector3D &vector) +{ + return QDoubleVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor); +} + +inline const QDoubleVector3D operator*(const QDoubleVector3D &vector, double factor) +{ + return QDoubleVector3D(vector.xp * factor, vector.yp * factor, vector.zp * factor); +} + +inline const QDoubleVector3D operator*(const QDoubleVector3D &v1, const QDoubleVector3D& v2) +{ + return QDoubleVector3D(v1.xp * v2.xp, v1.yp * v2.yp, v1.zp * v2.zp); +} + +inline const QDoubleVector3D operator-(const QDoubleVector3D &vector) +{ + return QDoubleVector3D(-vector.xp, -vector.yp, -vector.zp); +} + +inline const QDoubleVector3D operator/(const QDoubleVector3D &vector, double divisor) +{ + return QDoubleVector3D(vector.xp / divisor, vector.yp / divisor, vector.zp / divisor); +} + +inline bool qFuzzyCompare(const QDoubleVector3D& v1, const QDoubleVector3D& v2) +{ + return qFuzzyCompare(v1.xp, v2.xp) && + qFuzzyCompare(v1.yp, v2.yp) && + qFuzzyCompare(v1.zp, v2.zp); +} + +#ifndef QT_NO_DEBUG_STREAM +Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QDoubleVector3D &vector); +#endif + +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QDoubleVector3D &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QDoubleVector3D &); +#endif + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif diff --git a/src/location/maps/qgeocameratiles.cpp b/src/location/maps/qgeocameratiles.cpp new file mode 100644 index 00000000..7f5c2c33 --- /dev/null +++ b/src/location/maps/qgeocameratiles.cpp @@ -0,0 +1,746 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qgeocameratiles_p.h" + +#include "qgeocameradata_p.h" +#include "qgeoprojection_p.h" +#include "qgeotilespec.h" + +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" + +#include "qgeomaptype.h" + +#include <QVector> + +#include <QDebug> + +#include <cmath> + +QT_BEGIN_NAMESPACE + +struct Frustum { + QDoubleVector3D topLeftNear; + QDoubleVector3D topLeftFar; + QDoubleVector3D topRightNear; + QDoubleVector3D topRightFar; + QDoubleVector3D bottomLeftNear; + QDoubleVector3D bottomLeftFar; + QDoubleVector3D bottomRightNear; + QDoubleVector3D bottomRightFar; +}; + +typedef QVector<QDoubleVector3D> Polygon; + +class QGeoCameraTilesPrivate { +public: + QGeoCameraTilesPrivate(QSharedPointer<QGeoProjection> projection); + ~QGeoCameraTilesPrivate(); + + QSharedPointer<QGeoProjection> projection_; + QString pluginString_; + QGeoMapType mapType_; + QGeoCameraData camera_; + QSize screenSize_; + int tileSize_; + int maxZoom_; + QSet<QGeoTileSpec> tiles_; + + void updateMetadata(); + void updateGeometry(); + + double sideLength() const; + + Frustum frustum() const; + + class LengthSorter { + public: + QDoubleVector3D base; + bool operator()(const QDoubleVector3D &lhs, const QDoubleVector3D &rhs) { + return (lhs - base).lengthSquared() < (rhs - base).lengthSquared(); + } + }; + + void appendZIntersects(const QDoubleVector3D &start, const QDoubleVector3D &end, double z, QVector<QDoubleVector3D> &results) const; + Polygon frustumFootprint(const Frustum &frustum) const; + + QPair<Polygon, Polygon> splitPolygonAtAxisValue(const Polygon &polygon, int axis, double value) const; + QPair<Polygon, Polygon> clipFootprintToMap(const Polygon &footprint) const; + + QList<QPair<double, int> > tileIntersections(double p1, int t1, double p2, int t2) const; + QSet<QGeoTileSpec> tilesFromPolygon(const Polygon &polygon) const; + + struct TileMap + { + TileMap(int minY, int maxY); + + int size; + int minY; + int maxY; + QVector<int> minX; + QVector<int> maxX; + + void add(int tileX, int tileY); + }; +}; + +QGeoCameraTiles::QGeoCameraTiles(QSharedPointer<QGeoProjection> projection) + : d_ptr(new QGeoCameraTilesPrivate(projection)) {} + +QGeoCameraTiles::~QGeoCameraTiles() +{ + delete d_ptr; +} + +void QGeoCameraTiles::setCamera(const QGeoCameraData &camera) +{ + Q_D(QGeoCameraTiles); + + if (d->camera_ == camera) + return; + + d->camera_ = camera; + d->updateGeometry(); +} + +void QGeoCameraTiles::setScreenSize(const QSize &size) +{ + Q_D(QGeoCameraTiles); + + if (d->screenSize_ == size) + return; + + d->screenSize_ = size; + d->updateGeometry(); +} + +void QGeoCameraTiles::setPluginString(const QString &pluginString) +{ + Q_D(QGeoCameraTiles); + + if (d->pluginString_ == pluginString) + return; + + d->pluginString_ = pluginString; + d->updateMetadata(); +} + +void QGeoCameraTiles::setMapType(const QGeoMapType &mapType) +{ + Q_D(QGeoCameraTiles); + + if (d->mapType_ == mapType) + return; + + d->mapType_ = mapType; + d->updateMetadata(); +} + +void QGeoCameraTiles::setTileSize(int tileSize) +{ + Q_D(QGeoCameraTiles); + + if (d->tileSize_ == tileSize) + return; + + d->tileSize_ = tileSize; + d->updateGeometry(); +} + +void QGeoCameraTiles::setMaximumZoomLevel(int maxZoom) +{ + Q_D(QGeoCameraTiles); + + if (d->maxZoom_ == maxZoom) + return; + + d->maxZoom_ = maxZoom; + d->updateGeometry(); +} + +QSet<QGeoTileSpec> QGeoCameraTiles::tiles() const +{ + Q_D(const QGeoCameraTiles); + + return d->tiles_; +} + +QGeoCameraTilesPrivate::QGeoCameraTilesPrivate(QSharedPointer<QGeoProjection> projection) + : projection_(projection) {} + +QGeoCameraTilesPrivate::~QGeoCameraTilesPrivate() {} + +void QGeoCameraTilesPrivate::updateMetadata() +{ + typedef QSet<QGeoTileSpec>::const_iterator iter; + + QSet<QGeoTileSpec> newTiles; + + iter i = tiles_.constBegin(); + iter end = tiles_.constEnd(); + + for (; i != end; ++i) { + QGeoTileSpec tile = *i; + newTiles.insert(QGeoTileSpec(pluginString_, mapType_.mapId(), tile.zoom(), tile.x(), tile.y())); + } + + tiles_ = newTiles; +} + +void QGeoCameraTilesPrivate::updateGeometry() +{ + tiles_.clear(); + + // Find the frustum from the camera / screen / viewport information + Frustum f = frustum(); + + // Find the polygon where the frustum intersects the plane of the map + Polygon footprint = frustumFootprint(f); + + // Clip the polygon to the map, split it up if it cross the dateline + QPair<Polygon, Polygon> polygons = clipFootprintToMap(footprint); + + if (!polygons.first.isEmpty()) { + tiles_.unite(tilesFromPolygon(polygons.first)); + } + + if (!polygons.second.isEmpty()) { + tiles_.unite(tilesFromPolygon(polygons.second)); + } +} + +double QGeoCameraTilesPrivate::sideLength() const +{ + return double(1 << camera_.zoomLevel()); +} + +Frustum QGeoCameraTilesPrivate::frustum() const +{ + int zpow2 = 1 << camera_.zoomLevel(); + + QDoubleVector3D center = zpow2 * projection_->coordToMercator(camera_.center()); + center.setZ(0.0); + + double f = qMin(screenSize_.width(), screenSize_.height()) / (1.0 * tileSize_); + + double z = pow(2.0, camera_.zoomFactor() - camera_.zoomLevel()); + + double altitude = f / (2.0 * z); + QDoubleVector3D eye = center; + eye.setZ(altitude); + + QDoubleVector3D view = eye - center; + QDoubleVector3D side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0)); + QDoubleVector3D up = QDoubleVector3D::normal(side, view); + + double nearPlane = zpow2 / (1.0 * tileSize_ * (1 << maxZoom_)); + double farPlane = 3.0; + + double aspectRatio = 1.0 * screenSize_.width() / screenSize_.height(); + + double hn = 0.0; + double wn = 0.0; + double hf = 0.0; + double wf = 0.0; + + // fixes field of view at 45 degrees + // this assumes that viewSize = 2*nearPlane x 2*nearPlane + + if (aspectRatio > 1.0) { + hn = 2 * nearPlane; + wn = hn * aspectRatio; + + hf = 2 * farPlane; + wf = hf * aspectRatio; + } else { + wn = 2 * nearPlane; + hn = wn / aspectRatio; + + wf = 2 * farPlane; + hf = wf / aspectRatio; + } + + QDoubleVector3D d = center - eye; + d.normalize(); + up.normalize(); + QDoubleVector3D right = QDoubleVector3D::normal(d, up); + + QDoubleVector3D cf = eye + d * farPlane; + QDoubleVector3D cn = eye + d * nearPlane; + + Frustum frustum; + + frustum.topLeftFar = cf + (up * hf / 2) - (right * wf / 2); + frustum.topRightFar = cf + (up * hf / 2) + (right * wf / 2); + frustum.bottomLeftFar = cf - (up * hf / 2) - (right * wf / 2); + frustum.bottomRightFar = cf - (up * hf / 2) + (right * wf / 2); + + frustum.topLeftNear = cn + (up * hn / 2) - (right * wn / 2); + frustum.topRightNear = cn + (up * hn / 2) + (right * wn / 2); + frustum.bottomLeftNear = cn - (up * hn / 2) - (right * wn / 2); + frustum.bottomRightNear = cn - (up * hn / 2) + (right * wn / 2); + + return frustum; +} + +void QGeoCameraTilesPrivate::appendZIntersects(const QDoubleVector3D &start, + const QDoubleVector3D &end, + double z, + QVector<QDoubleVector3D> &results) const +{ + if (start.z() == end.z()) { + if (start.z() == z) { + results.append(start); + results.append(end); + } + } else { + double f = (start.z() - z) / (start.z() - end.z()); + if ((0 <= f) && (f <= 1.0)) { + results.append((1 - f) * start + f * end); + } + } +} + +// Returns the intersection of the plane of the map and the camera frustum as a right handed polygon +Polygon QGeoCameraTilesPrivate::frustumFootprint(const Frustum &frustum) const +{ + Polygon points; + points.reserve(24); + + appendZIntersects(frustum.topLeftNear, frustum.topLeftFar, 0.0, points); + appendZIntersects(frustum.topRightNear, frustum.topRightFar, 0.0, points); + appendZIntersects(frustum.bottomLeftNear, frustum.bottomLeftFar, 0.0, points); + appendZIntersects(frustum.bottomRightNear, frustum.bottomRightFar, 0.0, points); + + appendZIntersects(frustum.topLeftNear, frustum.bottomLeftNear, 0.0, points); + appendZIntersects(frustum.bottomLeftNear, frustum.bottomRightNear, 0.0, points); + appendZIntersects(frustum.bottomRightNear, frustum.topRightNear, 0.0, points); + appendZIntersects(frustum.topRightNear, frustum.topLeftNear, 0.0, points); + + appendZIntersects(frustum.topLeftFar, frustum.bottomLeftFar, 0.0, points); + appendZIntersects(frustum.bottomLeftFar, frustum.bottomRightFar, 0.0, points); + appendZIntersects(frustum.bottomRightFar, frustum.topRightFar, 0.0, points); + appendZIntersects(frustum.topRightFar, frustum.topLeftFar, 0.0, points); + + if (points.isEmpty()) + return points; + + // sort points into a right handed polygon + + LengthSorter sorter; + + // - initial sort to remove duplicates + sorter.base = points.first(); + qSort(points.begin(), points.end(), sorter); + for (int i = points.size() - 1; i > 0; --i) { + if (points.at(i) == points.at(i - 1)) + points.remove(i); + } + + // - proper sort + // - start with the first point, put it in the sorted part of the list + // - add the nearest unsorted point to the last sorted point to the end + // of the sorted points + Polygon::iterator i; + for (i = points.begin(); i != points.end(); ++i) { + sorter.base = *i; + if (i + 1 != points.end()) + qSort(i + 1, points.end(), sorter); + } + + // - determine if what we have is right handed + int size = points.size(); + if (size >= 3) { + QDoubleVector3D normal = QDoubleVector3D::normal(points.at(1) - points.at(0), + points.at(2) - points.at(1)); + // - if not, reverse the list + if (normal.z() < 0.0) { + int halfSize = size / 2; + for (int i = 0; i < halfSize; ++i) { + QDoubleVector3D spare = points.at(i); + points[i] = points[size - 1 - i]; + points[size - 1 - i] = spare; + } + } + } + + return points; +} + +QPair<Polygon, Polygon> QGeoCameraTilesPrivate::splitPolygonAtAxisValue(const Polygon &polygon, int axis, double value) const +{ + Polygon polygonBelow; + Polygon polygonAbove; + + int size = polygon.size(); + + if (size == 0) { + return QPair<Polygon, Polygon>(polygonBelow, polygonAbove); + } + + QVector<int> comparisons = QVector<int>(polygon.size()); + + for (int i = 0; i < size; ++i) { + double v = polygon.at(i).get(axis); + if (qFuzzyCompare(v - value + 1.0, 1.0)) { + comparisons[i] = 0; + } else { + if (v < value) { + comparisons[i] = -1; + } else if (value < v) { + comparisons[i] = 1; + } + } + } + + for (int index = 0; index < size; ++index) { + int prevIndex = index - 1; + if (prevIndex < 0) + prevIndex += size; + int nextIndex = (index + 1) % size; + + int prevComp = comparisons[prevIndex]; + int comp = comparisons[index]; + int nextComp = comparisons[nextIndex]; + + if (comp == 0) { + if (prevComp == -1) { + polygonBelow.append(polygon.at(index)); + if (nextComp == 1) { + polygonAbove.append(polygon.at(index)); + } + } else if (prevComp == 1) { + polygonAbove.append(polygon.at(index)); + if (nextComp == -1) { + polygonBelow.append(polygon.at(index)); + } + } else if (prevComp == 0) { + if (nextComp == -1) { + polygonBelow.append(polygon.at(index)); + } else if (nextComp == 1) { + polygonAbove.append(polygon.at(index)); + } else if (nextComp == 0) { + // do nothing + } + } + } else { + if (comp == -1) { + polygonBelow.append(polygon.at(index)); + } else if (comp == 1) { + polygonAbove.append(polygon.at(index)); + } + + // there is a point between this and the next point + // on the polygon that lies on the splitting line + // and should be added to both the below and above + // polygons + if ((nextComp != 0) && (nextComp != comp)) { + QDoubleVector3D p1 = polygon.at(index); + QDoubleVector3D p2 = polygon.at(nextIndex); + + double p1v = p1.get(axis); + double p2v = p2.get(axis); + + double f = (p1v - value) / (p1v - p2v); + + if (((0 <= f) && (f <= 1.0)) + || qFuzzyCompare(f + 1.0, 1.0) + || qFuzzyCompare(f + 1.0, 2.0) ) { + QDoubleVector3D midPoint = (1.0 - f) * p1 + f * p2; + polygonBelow.append(midPoint); + polygonAbove.append(midPoint); + } + } + } + } + + return QPair<Polygon, Polygon>(polygonBelow, polygonAbove); +} + + +QPair<Polygon, Polygon> QGeoCameraTilesPrivate::clipFootprintToMap(const Polygon &footprint) const +{ + bool clipX0 = false; + bool clipX1 = false; + bool clipY0 = false; + bool clipY1 = false; + + double side = sideLength(); + + typedef Polygon::iterator iter; + typedef Polygon::const_iterator const_iter; + + const_iter i = footprint.constBegin(); + const_iter end = footprint.constEnd(); + for (; i != end; ++i) { + QDoubleVector3D p = *i; + if (p.x() < 0.0) + clipX0 = true; + if (side < p.x()) + clipX1 = true; + if (p.y() < 0.0) + clipY0 = true; + if (side < p.y()) + clipY1 = true; + } + + Polygon results = footprint; + + if (clipY0) { + results = splitPolygonAtAxisValue(results, 1, 0.0).second; + } + + if (clipY1) { + results = splitPolygonAtAxisValue(results, 1, side).first; + } + + if (clipX0) { + if (clipX1) { + results = splitPolygonAtAxisValue(results, 0, 0.0).second; + results = splitPolygonAtAxisValue(results, 0, side).first; + return QPair<Polygon, Polygon>(results, Polygon()); + } else { + QPair<Polygon, Polygon> pair = splitPolygonAtAxisValue(results, 0, 0.0); + for (int i = 0; i < pair.first.size(); ++i) { + pair.first[i].setX(pair.first.at(i).x() + side); + } + return pair; + } + } else { + if (clipX1) { + QPair<Polygon, Polygon> pair = splitPolygonAtAxisValue(results, 0, side); + for (int i = 0; i < pair.second.size(); ++i) { + pair.second[i].setX(pair.second.at(i).x() - side); + } + return pair; + } else { + return QPair<Polygon, Polygon>(results, Polygon()); + } + } + +} + +QList<QPair<double, int> > QGeoCameraTilesPrivate::tileIntersections(double p1, int t1, double p2, int t2) const +{ + if (t1 == t2) { + QList<QPair<double, int> > results = QList<QPair<double, int> >(); + results.append(QPair<double, int>(0.0, t1)); + return results; + } + + int step = 1; + if (t1 > t2) { + step = -1; + } + + int size = 1 + ((t2 - t1) / step); + + QList<QPair<double, int> > results = QList<QPair<double, int> >(); + + results.append(QPair<double, int>(0.0, t1)); + + if (step == 1) { + for (int i = 1; i < size; ++i) { + double f = (t1 + i - p1) / (p2 - p1); + results.append(QPair<double, int>(f, t1 + i)); + } + } else { + for (int i = 1; i < size; ++i) { + double f = (t1 - i + 1 - p1) / (p2 - p1); + results.append(QPair<double, int>(f, t1 - i)); + } + } + + return results; +} + +QSet<QGeoTileSpec> QGeoCameraTilesPrivate::tilesFromPolygon(const Polygon &polygon) const +{ + int numPoints = polygon.size(); + + if (numPoints == 0) + return QSet<QGeoTileSpec>(); + + int zoomLevel = camera_.zoomLevel(); + + int minY = -1; + int maxY = -1; + + int zpow2 = 1 << zoomLevel; + + QVector<int> tilesX(polygon.size()); + QVector<int> tilesY(polygon.size()); + + double side = sideLength(); + + for (int i = 0; i < numPoints; ++i) { + + QDoubleVector2D p = polygon.at(i).toVector2D(); + + int x = 0; + int y = 0; + + if (qFuzzyCompare(p.x(), side)) + x = zpow2 - 1; + else + x = static_cast<int>(p.x()) % zpow2; + + if (qFuzzyCompare(p.y(), side)) + y = zpow2 - 1; + else + y = static_cast<int>(p.y()) % zpow2; + + if (minY == -1) { + minY = y; + maxY = y; + } else { + minY = qMin(minY, y); + maxY = qMax(maxY, y); + } + + tilesX[i] = x; + tilesY[i] = y; + } + + QGeoCameraTilesPrivate::TileMap map(minY, maxY); + + for (int i1 = 0; i1 < numPoints; ++i1) { + int i2 = (i1 + 1) % numPoints; + + QList<QPair<double, int> > xIntersects + = tileIntersections(polygon.at(i1).get(0), + tilesX.at(i1), + polygon.at(i2).get(0), + tilesX.at(i2)); + + QList<QPair<double, int> > yIntersects + = tileIntersections(polygon.at(i1).get(1), + tilesY.at(i1), + polygon.at(i2).get(1), + tilesY.at(i2)); + + int x = xIntersects.takeFirst().second; + int y = yIntersects.takeFirst().second; + + map.add(x, y); + + while (!xIntersects.isEmpty() && !yIntersects.isEmpty()) { + QPair<double, int> nextX = xIntersects.first(); + QPair<double, int> nextY = yIntersects.first(); + if (nextX.first < nextY.first) { + x = nextX.second; + map.add(x, y); + xIntersects.removeFirst(); + } else if (nextX.first > nextY.first) { + y = nextY.second; + map.add(x, y); + yIntersects.removeFirst(); + } else { + map.add(x, nextY.second); + map.add(nextX.second, y); + x = nextX.second; + y = nextY.second; + map.add(x, y); + xIntersects.removeFirst(); + yIntersects.removeFirst(); + } + } + + while (!xIntersects.isEmpty()) { + x = xIntersects.takeFirst().second; + map.add(x, y); + } + + while (!yIntersects.isEmpty()) { + y = yIntersects.takeFirst().second; + map.add(x, y); + } + } + + QSet<QGeoTileSpec> results; + + int size = map.minX.size(); + for (int i = 0; i < size; ++i) { + int y = map.minY + i; + int minX = map.minX[i]; + int maxX = map.maxX[i]; + for (int x = minX; x <= maxX; ++x) { + results.insert(QGeoTileSpec(pluginString_, mapType_.mapId(), zoomLevel, x, y)); + } + } + + return results; +} + +QGeoCameraTilesPrivate::TileMap::TileMap(int minY, int maxY) + : size(0), + minY(minY), + maxY(maxY), + minX(maxY - minY + 1, -1), + maxX(maxY - minY + 1, -1) +{} + +void QGeoCameraTilesPrivate::TileMap::add(int tileX, int tileY) +{ + int index = tileY - minY; + int min = minX.at(index); + int max = maxX.at(index); + + if (min == -1) { + min = tileX; + max = tileX; + minX[index] = min; + maxX[index] = max; + size += 1; + } else { + int oldSize = (max - min); + int min2 = qMin(min, tileX); + if (min2 != min) + minX[index] = min2; + int max2 = qMax(max, tileX); + if (max2 != max) + maxX[index] = max2; + int newSize = (max2 - min2); + size += (newSize - oldSize); + } +} + +QT_END_NAMESPACE diff --git a/src/location/maps/qgeocameratiles_p.h b/src/location/maps/qgeocameratiles_p.h new file mode 100644 index 00000000..4f83317e --- /dev/null +++ b/src/location/maps/qgeocameratiles_p.h @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtLocation module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef QGEOCAMERATILES_P_H +#define QGEOCAMERATILES_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtLocation/qlocationglobal.h> +#include <QSharedPointer> +#include <QSet> +#include <QSize> +#include <QSizeF> + +QT_BEGIN_NAMESPACE + +class QGeoProjection; +class QGeoCameraData; +class QGeoTileSpec; +class QGeoMapType; + +class QGeoCameraTilesPrivate; + +class Q_LOCATION_EXPORT QGeoCameraTiles { +public: + QGeoCameraTiles(QSharedPointer<QGeoProjection> projection); + ~QGeoCameraTiles(); + + void setCamera(const QGeoCameraData &camera); + void setScreenSize(const QSize &size); + void setPluginString(const QString &pluginString); + void setMapType(const QGeoMapType &mapType); + + void setTileSize(int tileSize); + void setMaximumZoomLevel(int maxZoom); + + QSet<QGeoTileSpec> tiles() const; + +private: + QGeoCameraTilesPrivate *d_ptr; + Q_DECLARE_PRIVATE(QGeoCameraTiles) +}; + +QT_END_NAMESPACE + +#endif // QGEOCAMERATILES_P_H diff --git a/src/location/maps/qgeofrustum.cpp b/src/location/maps/qgeofrustum.cpp index 8d4bb290..35adc33e 100644 --- a/src/location/maps/qgeofrustum.cpp +++ b/src/location/maps/qgeofrustum.cpp @@ -68,14 +68,15 @@ void QGeoFrustum::update(const QGLCamera *camera, double aspectRatio, bool updat hf_ = wf_ / aspectRatio; } - QVector3D p = camera->eye(); - QVector3D d = camera->center() - camera->eye(); + QDoubleVector3D p = QDoubleVector3D(camera->eye()); + QDoubleVector3D d = QDoubleVector3D(camera->center()) - p; d.normalize(); - QVector3D up = camera->upVector(); + QDoubleVector3D up = QDoubleVector3D(camera->upVector()); + up.normalize(); - QVector3D right = QVector3D::normal(d, up); + QDoubleVector3D right = QDoubleVector3D::normal(d, up); cf_ = p + d * camera->farPlane(); tlf_ = cf_ + (up * hf_ / 2) - (right * wf_ / 2); @@ -117,7 +118,7 @@ void QGeoFrustum::update(const QGLCamera *camera, double aspectRatio, bool updat planeHash_.insert(QGeoFrustum::Planes(QGeoFrustum::Bottom), pb); } -bool QGeoFrustum::contains(const QVector3D ¢er, double radius) const +bool QGeoFrustum::contains(const QDoubleVector3D ¢er, double radius) const { if (planeHash_.isEmpty()) return false; diff --git a/src/location/maps/qgeofrustum_p.h b/src/location/maps/qgeofrustum_p.h index 1e0a3fa1..7d3553b7 100644 --- a/src/location/maps/qgeofrustum_p.h +++ b/src/location/maps/qgeofrustum_p.h @@ -52,11 +52,12 @@ // We mean it. // -#include <QVector3D> #include <QHash> #include <Qt3D/qplane3d.h> +#include "qdoublevector3d_p.h" + QT_BEGIN_NAMESPACE class QGLCamera; @@ -87,30 +88,30 @@ public: void update(const QGLCamera *camera, double aspectRatio, bool updatePlanes = false); - bool contains(const QVector3D ¢er, double radius) const; + bool contains(const QDoubleVector3D ¢er, double radius) const; - QVector3D topLeftNear() const { + QDoubleVector3D topLeftNear() const { return tln_; } - QVector3D topLeftFar() const { + QDoubleVector3D topLeftFar() const { return tlf_; } - QVector3D bottomLeftNear() const { + QDoubleVector3D bottomLeftNear() const { return bln_; } - QVector3D bottomLeftFar() const { + QDoubleVector3D bottomLeftFar() const { return blf_; } - QVector3D topRightNear() const { + QDoubleVector3D topRightNear() const { return trn_; } - QVector3D topRightFar() const { + QDoubleVector3D topRightFar() const { return trf_; } - QVector3D bottomRightNear() const { + QDoubleVector3D bottomRightNear() const { return brn_; } - QVector3D bottomRightFar() const { + QDoubleVector3D bottomRightFar() const { return brf_; } @@ -119,19 +120,19 @@ public: private: double hf_; double wf_; - QVector3D cf_; - QVector3D tlf_; - QVector3D trf_; - QVector3D blf_; - QVector3D brf_; + QDoubleVector3D cf_; + QDoubleVector3D tlf_; + QDoubleVector3D trf_; + QDoubleVector3D blf_; + QDoubleVector3D brf_; double hn_; double wn_; - QVector3D cn_; - QVector3D tln_; - QVector3D trn_; - QVector3D bln_; - QVector3D brn_; + QDoubleVector3D cn_; + QDoubleVector3D tln_; + QDoubleVector3D trn_; + QDoubleVector3D bln_; + QDoubleVector3D brn_; QHash<Planes, QPlane3D> planeHash_; }; diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp index 7f98902c..81f249c6 100644 --- a/src/location/maps/qgeomap.cpp +++ b/src/location/maps/qgeomap.cpp @@ -47,6 +47,10 @@ #include "qgeoprojection2d_p.h" #include "qgeotile_p.h" #include "qgeomapcontroller_p.h" +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" + +#include "qgeocameratiles_p.h" #include "qgeomappingmanager.h" @@ -199,124 +203,6 @@ const QGeoMapType QGeoMap::activeMapType() const return d->activeMapType(); } -//------------------------------------------------------------// - -TileMap::TileMap(int minY, int maxY) - : size(0), - minY(minY), - maxY(maxY), - minX(maxY - minY + 1, -1), - maxX(maxY - minY + 1, -1) -{} - -void TileMap::adjust(int tileX, int tileY) -{ - int index = tileY - minY; - int min = minX.at(index); - int max = maxX.at(index); - - if (min == -1) { - min = tileX; - max = tileX; - minX[index] = min; - maxX[index] = max; - size += 1; - } else { - int oldSize = (max - min); - int min2 = qMin(min, tileX); - if (min2 != min) - minX[index] = min2; - int max2 = qMax(max, tileX); - if (max2 != max) - maxX[index] = max2; - int newSize = (max2 - min2); - size += (newSize - oldSize); - } -} - -IntersectGenerator::IntersectGenerator(const QGeoMapPrivate *mp, - double p1, - double p2, - int t1, - int t2, - IntersectGenerator::Axis axis, - int zoomLevel) - : mp_(mp), - axis_(axis), - zoomLevel_(zoomLevel) -{ - if (t1 == t2) { - hasNext_ = false; - return; - } - - bool inc = true; - if (axis_ == IntersectGenerator::XAxis) { - inc = (0 < (p2 - p1)); - } else { - inc = (0 < (p1 - p2)); - } - - step_ = 1; - adjust_ = 0; - if (!inc) { - step_ = -1; - adjust_ = -1; - } - - first_ = p1; - denom_ = p2 - p1; - - current_ = t1; - end_ = t2 + step_; - - hasNext_ = true; - - generateValue(); -} - -bool IntersectGenerator::hasNext() const -{ - return hasNext_; -} - -QPair<double, int> IntersectGenerator::value() const -{ - return value_; -} - -void IntersectGenerator::next() -{ - generateValue(); -} - -void IntersectGenerator::generateValue() -{ - while (current_ != end_) { - double alpha = 0.0; - - if (axis_ == IntersectGenerator::XAxis) { - double x = mp_->tileXIntersectToPoint(zoomLevel_, current_).x(); - alpha = (x - first_) / denom_; - } else { - double y = mp_->tileYIntersectToPoint(zoomLevel_, current_).y(); - alpha = (y - first_) / denom_; - } - - if ((0.0 < alpha) && (alpha < 1.0)) { - value_ = QPair<double,int>(alpha, current_ + adjust_); - current_ += step_; - if (current_ == end_) - hasNext_ = false; - return; - } - current_ += step_; - } - hasNext_ = false; -} - -//------------------------------------------------------------// - QGeoMapPrivate::QGeoMapPrivate(QGeoMap *parent, QGeoTileCache *cache, int maxZoom, int tileSize) : map_(parent), cache_(cache), @@ -333,28 +219,18 @@ QGeoMapPrivate::QGeoMapPrivate(QGeoMap *parent, QGeoTileCache *cache, int maxZoo sideLength_ = pow(2.0, 1.0 * maxZoom_) * tileSize; projection_ = QSharedPointer<QGeoProjection>(new QGeoProjection2D(baseHeight_, sideLength_)); - screenPoly_.resize(4); - screenPoly_[0] = QPointF(0.0, 0.0); - screenPoly_[1] = QPointF(0.0, sideLength_); - screenPoly_[2] = QPointF(sideLength_, sideLength_); - screenPoly_[3] = QPointF(sideLength_, 0.0); - - screenPolyLeft_.resize(4); - screenPolyLeft_[0] = QPointF(0.0, 0.0); - screenPolyLeft_[1] = QPointF(0.0, sideLength_); - screenPolyLeft_[2] = QPointF(sideLength_ / 2.0, sideLength_); - screenPolyLeft_[3] = QPointF(sideLength_ / 2.0, 0.0); - - screenPolyRight_.resize(4); - screenPolyRight_[0] = QPointF(sideLength_ / 2.0, 0.0); - screenPolyRight_[1] = QPointF(sideLength_ / 2.0, sideLength_); - screenPolyRight_[2] = QPointF(sideLength_, sideLength_); - screenPolyRight_[3] = QPointF(sideLength_, 0.0); + + cameraTiles_ = new QGeoCameraTiles(projection_); + cameraTiles_->setTileSize(tileSize_); + cameraTiles_->setMaximumZoomLevel(maxZoom_); } QGeoMapPrivate::~QGeoMapPrivate() { // controller_ is a child of map_, don't need to delete it here + + delete cameraTiles_; + manager_->deregisterMap(map_); delete sphere_; delete glCamera_; @@ -384,6 +260,7 @@ void QGeoMapPrivate::setMappingManager(QGeoMappingManager *manager) if (manager) { manager->registerMap(map_); pluginString_ = manager->managerName() + QLatin1String("_") + QString::number(manager->managerVersion()); + cameraTiles_->setPluginString(pluginString_); sphere_->setMappingManager(manager); } else { manager->deregisterMap(map_); @@ -410,8 +287,11 @@ void QGeoMapPrivate::setCameraData(const QGeoCameraData &cameraData) cameraData_.setProjection(projection_.toWeakRef()); updateGlCamera(glCamera_); updateFrustum(frustum_); - visibleTiles_ = updateVisibleTiles(); - sphere_->update(visibleTiles_); + + cameraTiles_->setCamera(cameraData_); + visibleTiles_ = cameraTiles_->tiles(); + + sphere_->update(visibleTiles_.toList()); } QGeoCameraData QGeoMapPrivate::cameraData() const @@ -421,7 +301,7 @@ QGeoCameraData QGeoMapPrivate::cameraData() const void QGeoMapPrivate::update() { - sphere_->update(visibleTiles_); + sphere_->update(visibleTiles_.toList()); } void QGeoMapPrivate::resize(int width, int height) @@ -429,45 +309,10 @@ void QGeoMapPrivate::resize(int width, int height) width_ = width; height_ = height; aspectRatio_ = 1.0 * width_ / height_; + cameraTiles_->setScreenSize(QSize(width, height)); setCameraData(cameraData_); } -QVector2D QGeoMapPrivate::pointToTile(const QVector3D &point, int zoom, bool roundUp) const -{ - QVector2D p = projection_->pointToMercator(point); - - int z = 1 << zoom; - int x = 0; - int y = 0; - - if (p.y() == 1.0) - y = z - 1; - else - y = static_cast<int>(z * p.y()) % z; - - if ((qAbs(p.x()) < 1e-6) || (qAbs(p.x() - 1) < 1e-6)) - if (roundUp) - x = z - 1; - else - x = 0; - else - x = static_cast<int>(z * p.x()) % z; - - return QVector2D(x, y); -} - -QVector3D QGeoMapPrivate::tileXIntersectToPoint(int zoomLevel, int x) const -{ - int zpow2 = 1 << zoomLevel; - return projection_->mercatorToPoint(QVector2D(x * 1.0 / zpow2, zpow2 / 2.0)); -} - -QVector3D QGeoMapPrivate::tileYIntersectToPoint(int zoomLevel, int y) const -{ - int zpow2 = 1 << zoomLevel; - return projection_->mercatorToPoint(QVector2D(zpow2 / 2.0, y * 1.0 / zpow2)); -} - int QGeoMapPrivate::width() const { return width_; @@ -483,18 +328,11 @@ double QGeoMapPrivate::aspectRatio() const return aspectRatio_; } -void QGeoMapPrivate::setActiveMapType(const QGeoMapType type) +void QGeoMapPrivate::setActiveMapType(const QGeoMapType &type) { activeMapType_ = type; - //TODO: check if this shared - //make it more optimal - //rewrite current specs - QList<QGeoTileSpec> temp = visibleTiles_; - visibleTiles_.clear(); - foreach (QGeoTileSpec spec,temp) { - spec.setMapId(type.mapId()); - visibleTiles_ << spec; - } + cameraTiles_->setMapType(type); + visibleTiles_ = cameraTiles_->tiles(); map_->update(); } @@ -528,10 +366,10 @@ QRect QGeoMapPrivate::specToRect(const QGeoTileSpec &tileSpec) const double y1 = y * 1.0 / z; double y2 = (y + 1) * 1.0 / z; - QVector3D tl = projection_->mercatorToPoint(QVector2D(x1, y1)); - QVector3D tr = projection_->mercatorToPoint(QVector2D(x2, y1)); - QVector3D bl = projection_->mercatorToPoint(QVector2D(x1, y2)); - QVector3D br = projection_->mercatorToPoint(QVector2D(x2, y2)); + QDoubleVector3D tl = projection_->mercatorToPoint(QDoubleVector2D(x1, y1)); + QDoubleVector3D tr = projection_->mercatorToPoint(QDoubleVector2D(x2, y1)); + QDoubleVector3D bl = projection_->mercatorToPoint(QDoubleVector2D(x1, y2)); + QDoubleVector3D br = projection_->mercatorToPoint(QDoubleVector2D(x2, y2)); if (rightEdge) { tr.setX(sideLength_); @@ -563,10 +401,10 @@ QGLSceneNode* QGeoMapPrivate::createTileSpecNode(const QGeoTileSpec &tileSpec) double y1 = y * 1.0 / z; double y2 = (y + 1) * 1.0 / z; - QVector3D tl = projection_->mercatorToPoint(QVector2D(x1, y1)); - QVector3D tr = projection_->mercatorToPoint(QVector2D(x2, y1)); - QVector3D bl = projection_->mercatorToPoint(QVector2D(x1, y2)); - QVector3D br = projection_->mercatorToPoint(QVector2D(x2, y2)); + QDoubleVector3D tl = projection_->mercatorToPoint(QDoubleVector2D(x1, y1)); + QDoubleVector3D tr = projection_->mercatorToPoint(QDoubleVector2D(x2, y1)); + QDoubleVector3D bl = projection_->mercatorToPoint(QDoubleVector2D(x1, y2)); + QDoubleVector3D br = projection_->mercatorToPoint(QDoubleVector2D(x2, y2)); if (rightEdge) { tr.setX(sideLength_); @@ -592,23 +430,23 @@ QGLSceneNode* QGeoMapPrivate::createTileSpecNode(const QGeoTileSpec &tileSpec) QGeometryData g; - QVector3D n = QVector3D(0, 0, 1); + QDoubleVector3D n = QDoubleVector3D(0, 0, 1); g.appendVertex(tl); g.appendNormal(n); - g.appendTexCoord(QVector2D(tx1 * 1.0 / dz, ty1 * 1.0 / dz)); + g.appendTexCoord(QDoubleVector2D(tx1 * 1.0 / dz, ty1 * 1.0 / dz)); g.appendVertex(bl); g.appendNormal(n); - g.appendTexCoord(QVector2D(tx1 * 1.0 / dz, ty2 * 1.0 / dz)); + g.appendTexCoord(QDoubleVector2D(tx1 * 1.0 / dz, ty2 * 1.0 / dz)); g.appendVertex(br); g.appendNormal(n); - g.appendTexCoord(QVector2D(tx2 * 1.0 / dz, ty2 * 1.0 / dz)); + g.appendTexCoord(QDoubleVector2D(tx2 * 1.0 / dz, ty2 * 1.0 / dz)); g.appendVertex(tr); g.appendNormal(n); - g.appendTexCoord(QVector2D(tx2 * 1.0 / dz, ty1 * 1.0 / dz)); + g.appendTexCoord(QDoubleVector2D(tx2 * 1.0 / dz, ty1 * 1.0 / dz)); builder.addQuads(g); @@ -643,11 +481,11 @@ void QGeoMapPrivate::paintGL(QGLPainter *painter) glDisable(GL_DEPTH_TEST); - QVector3D c = camera->center(); + QDoubleVector3D c = QDoubleVector3D(camera->center()); c.setX(c.x() + sideLength_); camera->setCenter(c); - QVector3D e = camera->eye(); + QDoubleVector3D e = QDoubleVector3D(camera->eye()); e.setX(e.x() + sideLength_); camera->setEye(e); @@ -690,35 +528,37 @@ void QGeoMapPrivate::updateGlCamera(QGLCamera* glCamera) QGeoCoordinate coord = camera.center(); coord.setAltitude(0.0); - QVector3D center = projection_->coordToPoint(coord); + QDoubleVector3D center = projection_->coordToPoint(coord); coord.setAltitude(altitude); - QVector3D eye = projection_->coordToPoint(coord); + QDoubleVector3D eye = projection_->coordToPoint(coord); // if (pow(2.0, cameraData_.zoomFactor()) * tileSize_ < height_) { // center.setY(sideLength_ / 2.0); // eye.setY(sideLength_ / 2.0); // } - QVector3D view = eye - center; - QVector3D side = QVector3D::normal(view, QVector3D(0.0, 1.0, 0.0)); - QVector3D up = QVector3D::normal(side, view); + QDoubleVector3D view = eye - center; + QDoubleVector3D side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0)); + QDoubleVector3D up = QDoubleVector3D::normal(side, view); +/* QMatrix4x4 mBearing; mBearing.rotate(-1.0 * camera.bearing(), view); up = mBearing * up; - QVector3D side2 = QVector3D::normal(up, view); + QDoubleVector3D side2 = QDoubleVector3D::normal(up, view); QMatrix4x4 mTilt; mTilt.rotate(camera.tilt(), side2); eye = (mTilt * view) + center; view = eye - center; - side = QVector3D::normal(view, QVector3D(0.0, 1.0, 0.0)); - up = QVector3D::normal(view, side2); + side = QDoubleVector3D::normal(view, QDoubleVector3D(0.0, 1.0, 0.0)); + up = QDoubleVector3D::normal(view, side2); QMatrix4x4 mRoll; mRoll.rotate(camera.roll(), view); up = mRoll * up; +*/ double nearPlane = 1.0; double farPlane = 2.0 * altitude; @@ -776,25 +616,25 @@ QGeoCoordinate QGeoMapPrivate::screenPositionToCoordinate(const QPointF &pos) co x = (x + 1.0) / 2.0; y = (y + 1.0) / 2.0; - QVector3D tl = frustum_.topLeftFar(); - QVector3D tr = frustum_.topRightFar(); - QVector3D bl = frustum_.bottomLeftFar(); + QDoubleVector3D tl = frustum_.topLeftFar(); + QDoubleVector3D tr = frustum_.topRightFar(); + QDoubleVector3D bl = frustum_.bottomLeftFar(); - QVector3D n = (1 - x - y) * tl + x * tr + y * bl; + QDoubleVector3D n = (1 - x - y) * tl + x * tr + y * bl; if (eye_.z() == n.z()) return QGeoCoordinate(); double alpha = eye_.z() / (eye_.z() - n.z()); - QVector3D c = (1 - alpha) * eye_ + alpha * n; + QDoubleVector3D c = (1 - alpha) * eye_ + alpha * n; return projection_->pointToCoord(c); } QPointF QGeoMapPrivate::coordinateToScreenPosition(const QGeoCoordinate &coordinate) const { - QVector3D c = projection_->coordToPoint(coordinate); - QVector3D d = projectionMatrix_.map(c); + QDoubleVector3D c = projection_->coordToPoint(coordinate); + QDoubleVector3D d = QDoubleVector3D(projectionMatrix_.map(c)); QPointF point = QPointF((d.x() + 1.0) * width() / 2.0, (-d.y() + 1.0) * height() / 2.0); double side = pow(2.0, cameraData_.zoomFactor()) * tileSize_; @@ -836,526 +676,4 @@ void QGeoMapPrivate::updateFrustum(QGeoFrustum &frustum) frustum.update(glCamera(), cameraData().aspectRatio()); } -QList<QGeoTileSpec> QGeoMapPrivate::updateVisibleTiles() -{ - QList<QVector3D> points; - - points.append(pointsOnLineWithZ(frustum_.topLeftNear(), frustum_.topLeftFar(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.topRightNear(), frustum_.topRightFar(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.bottomLeftNear(), frustum_.bottomLeftFar(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.bottomRightNear(), frustum_.bottomRightFar(), baseHeight_)); - - points.append(pointsOnLineWithZ(frustum_.topLeftNear(), frustum_.bottomLeftNear(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.bottomLeftNear(), frustum_.bottomRightNear(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.bottomRightNear(), frustum_.topRightNear(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.topRightNear(), frustum_.topLeftNear(), baseHeight_)); - - points.append(pointsOnLineWithZ(frustum_.topLeftFar(), frustum_.bottomLeftFar(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.bottomLeftFar(), frustum_.bottomRightFar(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.bottomRightFar(), frustum_.topRightFar(), baseHeight_)); - points.append(pointsOnLineWithZ(frustum_.topRightFar(), frustum_.topLeftFar(), baseHeight_)); - - QList<QGeoTileSpec> tiles; - - if (points.isEmpty()) - return tiles; - - // sort points into a right handed polygon - - LengthSorter sorter; - - // - initial sort to remove duplicates - sorter.base = points.first(); - qSort(points.begin(), points.end(), sorter); - for (int i = points.size() - 1; i > 0; --i) { - if (points.at(i) == points.at(i - 1)) - points.removeAt(i); - } - - // - proper sort - // - start with the first point, put it in the sorted part of the list - // - add the nearest unsorted point to the last sorted point to the end - // of the sorted points - QList<QVector3D>::iterator i; - for (i = points.begin(); i != points.end(); ++i) { - sorter.base = *i; - if (i + 1 != points.end()) - qSort(i + 1, points.end(), sorter); - } - - // - determine if what we have is right handed - if (points.size() >= 3) { - QVector3D normal = QVector3D::normal(points.at(1) - points.at(0), - points.at(2) - points.at(1)); - // - if not, reverse the list - if (normal.z() < 0.0) { - int s = points.size(); - int s2 = s / 2; - for (int i = 0; i < s2; ++i) { - points.swap(i, s - 1 - i); - } - } - } - - // work out if the polygon needs clipping - // - if we go off the far right edge we need to clip into - // two regions - one which rounds down now and one which rounds up - // - otherwise if we cross an edge of the map we just need to clip - // to the map square - - bool round = false; - bool clip = false; - for (int i = 0; i < points.size(); ++i) { - QVector3D p = points.at(i); - if (p.x() >= sideLength_) { - round = true; - break; - } - if ((p.x() < 0) - || (sideLength_ < p.x()) - || (p.y() < 0) - || (sideLength_ < p.y())) { - clip = true; - } - } - - if (!round) { - if (!clip) { - tiles.append(tilesFromPoints(points.toVector(), false)); - } else { - QPair<QList<QVector3D>,QList<QVector3D> > pair = clipPolygonToMap(points); - if (!pair.first.isEmpty()) - tiles.append(tilesFromPoints(pair.first.toVector(), true)); - if (!pair.second.isEmpty()) - tiles.append(tilesFromPoints(pair.second.toVector(), false)); - } - } else { - QPair<QList<QVector3D>,QList<QVector3D> > pair = clipPolygonToMap(points); - if (!pair.first.isEmpty()) { - QPair<QList<QVector3D>, QList<QVector3D> > split = splitPolygonX(pair.first, sideLength_ / 2.0); - if (!split.first.isEmpty()) { - tiles.append(tilesFromPoints(split.first.toVector(), false)); - } - if (!split.second.isEmpty()) { - tiles.append(tilesFromPoints(split.second.toVector(), true)); - } - } - if (!pair.second.isEmpty()) { - QPair<QList<QVector3D>, QList<QVector3D> > split = splitPolygonX(pair.second, sideLength_ / 2.0); - if (!split.first.isEmpty()) { - tiles.append(tilesFromPoints(split.first.toVector(), false)); - } - if (!split.second.isEmpty()) { - tiles.append(tilesFromPoints(split.second.toVector(), true)); - } - } - } - - return tiles; -} - -QList<QGeoTileSpec> QGeoMapPrivate::tilesFromPoints(const QVector<QVector3D> &points, bool roundUp) const -{ - int numPoints = points.size(); - - if (numPoints == 0) - return QList<QGeoTileSpec>(); - - int zoomLevel = cameraData().zoomLevel(); - - int minY = -1; - int maxY = -1; - - QVector<QVector2D> tiles(points.size()); - for (int i = 0; i < numPoints; ++i) { - QVector2D t = pointToTile(points.at(i), zoomLevel, roundUp); - if (minY == -1) { - minY = t.y(); - maxY = t.y(); - } else { - minY = qMin(minY, static_cast<int>(t.y())); - maxY = qMax(maxY, static_cast<int>(t.y())); - } - tiles[i] = t; - } - - TileMap map(minY, maxY); - - for (int i1 = 0; i1 < numPoints; ++i1) { - int i2 = (i1 + 1) % numPoints; - tilesFromLine(points.at(i1), points.at(i2), tiles.at(i1), tiles.at(i2), zoomLevel, map); - } - - QList<QGeoTileSpec> results; - - results.reserve(map.size); - - int size = map.minX.size(); - for (int i = 0; i < size; ++i) { - int y = map.minY + i; - int minX = map.minX[i]; - int maxX = map.maxX[i]; - for (int x = minX; x <= maxX; ++x) - results << QGeoTileSpec(pluginString_, activeMapType().mapId(), zoomLevel, x, y); - } - - return results; -} - -void QGeoMapPrivate::tilesFromLine(const QVector3D &p1, - const QVector3D &p2, - const QVector2D &t1, - const QVector2D &t2, - int zoomLevel, - TileMap &map) const -{ - IntersectGenerator xGen = IntersectGenerator(this, p1.x(), p2.x(), t1.x(), t2.x(), - IntersectGenerator::XAxis, zoomLevel); - IntersectGenerator yGen = IntersectGenerator(this, p1.y(), p2.y(), t1.y(), t2.y(), - IntersectGenerator::YAxis, zoomLevel); - - int tileX = t1.x(); - int tileY = t1.y(); - - map.adjust(tileX, tileY); - - while (xGen.hasNext() && yGen.hasNext()) { - QPair<double, int> x = xGen.value(); - QPair<double, int> y = yGen.value(); - if (x.first < y.first) { - tileX = x.second; - map.adjust(tileX, tileY); - xGen.next(); - } else if (x.first > y.first) { - tileY = y.second; - map.adjust(tileX, tileY); - yGen.next(); - } else { - map.adjust(tileX, y.second); - map.adjust(x.second, tileY); - tileX = x.second; - tileY = y.second; - map.adjust(tileX, tileY); - xGen.next(); - yGen.next(); - } - } - - while (xGen.hasNext()) { - tileX = xGen.value().second; - map.adjust(tileX, tileY); - xGen.next(); - } - - while (yGen.hasNext()) { - tileY = yGen.value().second; - map.adjust(tileX, tileY); - yGen.next(); - } -} - -QPair<QList<QVector3D>,QList<QVector3D> > QGeoMapPrivate::clipPolygonToMap(const QList<QVector3D> &points) const -{ - bool clipX0 = false; - bool clipX1 = false; - bool clipY0 = false; - bool clipY1 = false; - int size = points.size(); - for (int i = 0; i < size; ++i) { - QVector3D p = points.at(i); - if (p.x() < 0.0) - clipX0 = true; - if (sideLength_ < p.x()) - clipX1 = true; - if (p.y() < 0.0) - clipY0 = true; - if (sideLength_ < p.y()) - clipY1 = true; - - } - - QList<QVector3D> results = points; - - if (clipY0) { - results = splitPolygonY(results, 0.0).second; - } - - if (clipY1) { - results = splitPolygonY(results, sideLength_).first; - } - - if (clipX0) { - if (clipX1) { - results = splitPolygonX(results, 0.0).second; - results = splitPolygonX(results, sideLength_).first; - return QPair<QList<QVector3D>,QList<QVector3D> >(results, QList<QVector3D>()); - } else { - QPair<QList<QVector3D>,QList<QVector3D> > pair = splitPolygonX(results, 0.0); - for (int i = 0; i < pair.first.size(); ++i) { - pair.first[i].setX(pair.first.at(i).x() + sideLength_); - } - return pair; - } - } else { - if (clipX1) { - QPair<QList<QVector3D>,QList<QVector3D> > pair = splitPolygonX(results, sideLength_); - for (int i = 0; i < pair.second.size(); ++i) { - pair.second[i].setX(pair.second.at(i).x() - sideLength_); - } - return pair; - } else { - return QPair<QList<QVector3D>,QList<QVector3D> >(results, QList<QVector3D>()); - } - } -} - -QPair<QList<QVector3D>,QList<QVector3D> > QGeoMapPrivate::splitPolygonY(const QList<QVector3D> &points, double y) const -{ - QList<QVector3D> pointsBelow; - QList<QVector3D> pointsAbove; - - int size = points.size(); - - if (size == 0) { - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); - } - - bool allAbove = true; - bool allBelow = true; - - for (int i = 0; i < size; ++i) { - double py = points.at(i).y(); - if (py < y) - allAbove = false; - if (y < py) - allBelow = false; - } - - if (allAbove) { - if (allBelow) { - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); - } else { - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, points); - } - } else { - if (allBelow) { - return QPair<QList<QVector3D>,QList<QVector3D> >(points, pointsAbove); - } - } - - - int intersect1 = -1; - int intersect2 = -1; - - // add intersects - - QList<QVector3D> tmpPoints = points; - - for (int i1 = 0; i1 < size; ++i1) { - int i2 = (i1 + 1) % size; - - QVector3D p1 = tmpPoints.at(i1); - QVector3D p2 = tmpPoints.at(i2); - - if (p1.y() == y) { - if (intersect1 == -1) - intersect1 = i1; - else if (intersect2 == -1) - intersect2 = i1; - else - qDebug() << __FUNCTION__ << " more than 2 intersections"; - } - - if (((p1.y() < y) && (y < p2.y())) - || ((p2.y() < y) && (y < p1.y()))) { - QList<QVector3D> newPoints = pointsOnLineWithY(p1, p2, y); - if (newPoints.size() == 1) { - tmpPoints.insert(i1 + 1, newPoints.at(0)); - ++size; - // will get added to intersect1 or intersect 2 in next iteration - } - } - } - - // split at intersects - if ((intersect1 != -1) && (intersect2 != -1)) { - - size = tmpPoints.size(); - - bool firstBelow = true; - - for (int i = intersect1; i <= intersect2; ++i) { - QVector3D p = tmpPoints.at(i); - if (y < p.y()) - firstBelow = false; - pointsBelow.append(p); - } - - for (int i = intersect2; i <= intersect1 + size; ++i) { - pointsAbove.append(tmpPoints.at(i % size)); - } - - if (firstBelow) - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); - else - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsAbove, pointsBelow); - - } else { - qDebug() << __FUNCTION__ << " less than 2 intersections"; - } - - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); -} - -QPair<QList<QVector3D>,QList<QVector3D> > QGeoMapPrivate::splitPolygonX(const QList<QVector3D> &points, double x) const -{ - QList<QVector3D> pointsBelow; - QList<QVector3D> pointsAbove; - - int size = points.size(); - - if (size == 0) { - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); - } - - bool allAbove = true; - bool allBelow = true; - - for (int i = 0; i < size; ++i) { - double px = points.at(i).x(); - if (px < x) - allAbove = false; - if (x < px) - allBelow = false; - } - - if (allAbove) { - if (allBelow) { - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); - } else { - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, points); - } - } else { - if (allBelow) { - return QPair<QList<QVector3D>,QList<QVector3D> >(points, pointsAbove); - } - } - - int intersect1 = -1; - int intersect2 = -1; - - // add intersects - - QList<QVector3D> tmpPoints = points; - - for (int i1 = 0; i1 < size; ++i1) { - int i2 = (i1 + 1) % size; - - QVector3D p1 = tmpPoints.at(i1); - QVector3D p2 = tmpPoints.at(i2); - - if (p1.x() == x) { - if (intersect1 == -1) - intersect1 = i1; - else if (intersect2 == -1) - intersect2 = i1; - else - qDebug() << __FUNCTION__ << " more than 2 intersections"; - } - - if (((p1.x() < x) && (x < p2.x())) - || ((p2.x() < x) && (x < p1.x()))) { - QList<QVector3D> newPoints = pointsOnLineWithX(p1, p2, x); - if (newPoints.size() == 1) { - tmpPoints.insert(i1 + 1, newPoints.at(0)); - ++size; - // will get added to intersect1 or intersect 2 in next iteration - } - } - } - - // split at intersects - if ((intersect1 != -1) && (intersect2 != -1)) { - - size = tmpPoints.size(); - - bool firstBelow = true; - - for (int i = intersect1; i <= intersect2; ++i) { - QVector3D p = tmpPoints.at(i); - if (x < p.x()) - firstBelow = false; - pointsBelow.append(p); - } - - for (int i = intersect2; i <= intersect1 + size; ++i) { - pointsAbove.append(tmpPoints.at(i % size)); - } - - if (firstBelow) - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); - else - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsAbove, pointsBelow); - - } else { - qDebug() << __FUNCTION__ << " less than 2 intersections"; - } - - return QPair<QList<QVector3D>,QList<QVector3D> >(pointsBelow, pointsAbove); -} - -QList<QVector3D> QGeoMapPrivate::pointsOnLineWithX(const QVector3D &p1, const QVector3D &p2, double x) const -{ - QList<QVector3D> results; - - if (p1.x() == p2.x()) { - if (p1.x() == x) { - results.append(p1); - results.append(p2); - } - } else { - double f = (p1.x() - x) / (p1.x() - p2.x()); - if ((0 <= f) && (f <= 1.0)) - results.append((1 - f) * p1 + f * p2); - } - - return results; -} - -QList<QVector3D> QGeoMapPrivate::pointsOnLineWithY(const QVector3D &p1, const QVector3D &p2, double y) const -{ - QList<QVector3D> results; - - if (p1.y() == p2.y()) { - if (p1.y() == y) { - results.append(p1); - results.append(p2); - } - } else { - double f = (p1.y() - y) / (p1.y() - p2.y()); - if ((0 <= f) && (f <= 1.0)) - results.append((1 - f) * p1 + f * p2); - } - - return results; -} - -QList<QVector3D> QGeoMapPrivate::pointsOnLineWithZ(const QVector3D &p1, const QVector3D &p2, double z) const -{ - QList<QVector3D> results; - - if (p1.z() == p2.z()) { - if (p1.z() == z) { - results.append(p1); - results.append(p2); - } - } else { - double f = (p1.z() - z) / (p1.z() - p2.z()); - if ((0 <= f) && (f <= 1.0)) - results.append((1 - f) * p1 + f * p2); - } - - return results; -} - QT_END_NAMESPACE diff --git a/src/location/maps/qgeomap_p_p.h b/src/location/maps/qgeomap_p_p.h index c686fb7e..300e7766 100644 --- a/src/location/maps/qgeomap_p_p.h +++ b/src/location/maps/qgeomap_p_p.h @@ -58,16 +58,15 @@ #include <QPair> #include <QPolygonF> #include <QSizeF> -#include <QVector3D> #include <QMatrix4x4> #include <QString> +#include <QSharedPointer> #include "qgeocameradata_p.h" #include "qgeofrustum_p.h" - #include "qgeomaptype.h" -#include <QSharedPointer> +#include "qdoublevector3d_p.h" QT_BEGIN_NAMESPACE @@ -81,64 +80,12 @@ class QGeoMapController; class QGeoMapSphere; class QGeoProjection; +class QGeoCameraTiles; + class QGLCamera; class QGLSceneNode; class QGLPainter; -class QGeoMapPrivate; - -struct TileMap -{ - TileMap(int minY, int maxY); - - int size; - int minY; - int maxY; - QVector<int> minX; - QVector<int> maxX; - - void adjust(int tileX, int tileY); -}; - -class IntersectGenerator -{ -public: - enum Axis { - XAxis, - YAxis - }; - IntersectGenerator(const QGeoMapPrivate *mp, - double p1, - double p2, - int t1, - int t2, - Axis axis, - int zoomLevel); - - bool hasNext() const; - QPair<double, int> value() const; - void next(); - -private: - void generateValue(); - -protected: - const QGeoMapPrivate *mp_; - Axis axis_; - int zoomLevel_; - - bool hasNext_; - QPair<double, int> value_; - - int current_; - int step_; - int end_; - - int adjust_; - double first_; - double denom_; -}; - class QGeoMapPrivate { public: @@ -170,21 +117,16 @@ public: void update(); const QGeoMapType activeMapType() const; - void setActiveMapType(const QGeoMapType mapType); + void setActiveMapType(const QGeoMapType &mapType); QGeoCoordinate screenPositionToCoordinate(const QPointF &pos) const; QPointF coordinateToScreenPosition(const QGeoCoordinate &coordinate) const; - QVector2D pointToTile(const QVector3D &point, int zoom, bool roundUp = false) const; - QVector3D tileXIntersectToPoint(int zoomLevel, int x) const; - QVector3D tileYIntersectToPoint(int zoomLevel, int y) const; - void tileFetched(const QGeoTileSpec &spec); private: void updateGlCamera(QGLCamera* glCamera); void updateFrustum(QGeoFrustum &frustum); - QList<QGeoTileSpec> updateVisibleTiles(); int width_; int height_; @@ -202,50 +144,23 @@ private: QGeoCameraData cameraData_; QGeoFrustum frustum_; - QList<QGeoTileSpec> visibleTiles_; + QSet<QGeoTileSpec> visibleTiles_; + + QGeoCameraTiles *cameraTiles_; QGeoMapSphere *sphere_; QGeoMapType activeMapType_; // from map2d_p.h - void tilesFromLine(const QVector3D &p1, - const QVector3D &p2, - const QVector2D &t1, - const QVector2D &t2, - int zoomLevel, - TileMap &map) const; - - QList<QGeoTileSpec> tilesFromPoints(const QVector<QVector3D> &points, bool roundUp) const; - - QPair<QList<QVector3D>,QList<QVector3D> > clipPolygonToMap(const QList<QVector3D> &points) const; - - class LengthSorter { - public: - QVector3D base; - bool operator()(const QVector3D &lhs, const QVector3D &rhs) { - return (lhs - base).lengthSquared() < (rhs - base).lengthSquared(); - } - }; - - QList<QVector3D> pointsOnLineWithX(const QVector3D &p1, const QVector3D &p2, double x) const; - QList<QVector3D> pointsOnLineWithY(const QVector3D &p1, const QVector3D &p2, double y) const; - QList<QVector3D> pointsOnLineWithZ(const QVector3D &p1, const QVector3D &p2, double z) const; - - QPair<QList<QVector3D>,QList<QVector3D> > splitPolygonX(const QList<QVector3D> &points, double x) const; - QPair<QList<QVector3D>,QList<QVector3D> > splitPolygonY(const QList<QVector3D> &points, double y) const; - int maxZoom_; int tileSize_; double baseHeight_; double sideLength_; - QPolygonF screenPoly_; - QPolygonF screenPolyLeft_; - QPolygonF screenPolyRight_; QSizeF viewSize_; - QVector3D eye_; + QDoubleVector3D eye_; QMatrix4x4 projectionMatrix_; }; diff --git a/src/location/maps/qgeoprojection.cpp b/src/location/maps/qgeoprojection.cpp index b751bcd4..ead0f61e 100644 --- a/src/location/maps/qgeoprojection.cpp +++ b/src/location/maps/qgeoprojection.cpp @@ -42,30 +42,31 @@ #include "qgeocoordinate.h" -#include <qvector2d.h> -#include <qvector3d.h> #include <QMatrix4x4> #include <qnumeric.h> #include <cmath> +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" + QT_BEGIN_NAMESPACE QGeoProjection::QGeoProjection() {} QGeoProjection::~QGeoProjection() {} -QVector3D QGeoProjection::mercatorToPoint(const QVector2D &mercator) const +QDoubleVector3D QGeoProjection::mercatorToPoint(const QDoubleVector2D &mercator) const { return this->coordToPoint(mercatorToCoord(mercator)); } -QVector2D QGeoProjection::pointToMercator(const QVector3D &point) const +QDoubleVector2D QGeoProjection::pointToMercator(const QDoubleVector3D &point) const { return coordToMercator(this->pointToCoord(point)); } -QVector2D QGeoProjection::coordToMercator(const QGeoCoordinate &coord) const +QDoubleVector2D QGeoProjection::coordToMercator(const QGeoCoordinate &coord) const { const double pi = M_PI; @@ -76,7 +77,7 @@ QVector2D QGeoProjection::coordToMercator(const QGeoCoordinate &coord) const lat = qMax(0.0, lat); lat = qMin(1.0, lat); - return QVector2D(lon, lat); + return QDoubleVector2D(lon, lat); } double QGeoProjection::realmod(const double a, const double b) @@ -85,7 +86,7 @@ double QGeoProjection::realmod(const double a, const double b) return a - static_cast<double>(div) * b; } -QGeoCoordinate QGeoProjection::mercatorToCoord(const QVector2D &mercator) const +QGeoCoordinate QGeoProjection::mercatorToCoord(const QDoubleVector2D &mercator) const { const double pi = M_PI; diff --git a/src/location/maps/qgeoprojection2d.cpp b/src/location/maps/qgeoprojection2d.cpp index b14c6a3f..a34c896a 100644 --- a/src/location/maps/qgeoprojection2d.cpp +++ b/src/location/maps/qgeoprojection2d.cpp @@ -42,8 +42,8 @@ #include "qgeocoordinate.h" -#include <QVector2D> -#include <QVector3D> +#include "qdoublevector2d_p.h" +#include "qdoublevector3d_p.h" #include <qnumeric.h> @@ -54,31 +54,31 @@ QGeoProjection2D::QGeoProjection2D(double baseHeight, double sideLength) QGeoProjection2D::~QGeoProjection2D() {} -QVector3D QGeoProjection2D::coordToPoint(const QGeoCoordinate &coord) const +QDoubleVector3D QGeoProjection2D::coordToPoint(const QGeoCoordinate &coord) const { - QVector2D m = coordToMercator(coord); + QDoubleVector2D m = coordToMercator(coord); double z = baseHeight_; if (!qIsNaN(coord.altitude())) z += coord.altitude(); - return QVector3D(m.x() * sideLength_, (1.0 - m.y()) * sideLength_, z); + return QDoubleVector3D(m.x() * sideLength_, (1.0 - m.y()) * sideLength_, z); } -QGeoCoordinate QGeoProjection2D::pointToCoord(const QVector3D &point) const +QGeoCoordinate QGeoProjection2D::pointToCoord(const QDoubleVector3D &point) const { - QVector2D m = QVector2D(point.x() / sideLength_, 1.0 - point.y() / sideLength_); + QDoubleVector2D m = QDoubleVector2D(point.x() / sideLength_, 1.0 - point.y() / sideLength_); QGeoCoordinate coord = mercatorToCoord(m); coord.setAltitude(point.z() - baseHeight_); return coord; } -QVector3D QGeoProjection2D::mercatorToPoint(const QVector2D &mercator) const +QDoubleVector3D QGeoProjection2D::mercatorToPoint(const QDoubleVector2D &mercator) const { - return QVector3D(mercator.x() * sideLength_, (1.0 - mercator.y()) * sideLength_, baseHeight_); + return QDoubleVector3D(mercator.x() * sideLength_, (1.0 - mercator.y()) * sideLength_, baseHeight_); } -QVector2D QGeoProjection2D::pointToMercator(const QVector3D &point) const +QDoubleVector2D QGeoProjection2D::pointToMercator(const QDoubleVector3D &point) const { - return QVector2D(point.x() / sideLength_, 1.0 - (point.y() / sideLength_)); + return QDoubleVector2D(point.x() / sideLength_, 1.0 - (point.y() / sideLength_)); } QGeoCoordinate QGeoProjection2D::interpolate(const QGeoCoordinate &start, const QGeoCoordinate &end, qreal progress) @@ -95,8 +95,8 @@ QGeoCoordinate QGeoProjection2D::interpolate(const QGeoCoordinate &start, const s2.setAltitude(0.0); QGeoCoordinate e2 = end; e2.setAltitude(0.0); - QVector3D s = coordToPoint(s2); - QVector3D e = coordToPoint(e2); + QDoubleVector3D s = coordToPoint(s2); + QDoubleVector3D e = coordToPoint(e2); double x = s.x(); @@ -108,7 +108,7 @@ QGeoCoordinate QGeoProjection2D::interpolate(const QGeoCoordinate &start, const double y = (1.0 - progress) * s.y() + progress * e.y(); - QGeoCoordinate result = pointToCoord(QVector3D(x, y, 0.0)); + QGeoCoordinate result = pointToCoord(QDoubleVector3D(x, y, 0.0)); result.setAltitude((1.0 - progress) * start.altitude() + progress * end.altitude()); return result; } diff --git a/src/location/maps/qgeoprojection2d_p.h b/src/location/maps/qgeoprojection2d_p.h index d749d05b..2ceab778 100644 --- a/src/location/maps/qgeoprojection2d_p.h +++ b/src/location/maps/qgeoprojection2d_p.h @@ -62,11 +62,11 @@ public: QGeoProjection2D(double baseHeight, double sideLength); virtual ~QGeoProjection2D(); - virtual QVector3D coordToPoint(const QGeoCoordinate &coord) const; - virtual QGeoCoordinate pointToCoord(const QVector3D &point) const; + virtual QDoubleVector3D coordToPoint(const QGeoCoordinate &coord) const; + virtual QGeoCoordinate pointToCoord(const QDoubleVector3D &point) const; - virtual QVector3D mercatorToPoint(const QVector2D &mercator) const; - virtual QVector2D pointToMercator(const QVector3D &point) const; + virtual QDoubleVector3D mercatorToPoint(const QDoubleVector2D &mercator) const; + virtual QDoubleVector2D pointToMercator(const QDoubleVector3D &point) const; virtual QGeoCoordinate interpolate(const QGeoCoordinate &start, const QGeoCoordinate &end, qreal progress); diff --git a/src/location/maps/qgeoprojection_p.h b/src/location/maps/qgeoprojection_p.h index fb83a896..ec27d9ff 100644 --- a/src/location/maps/qgeoprojection_p.h +++ b/src/location/maps/qgeoprojection_p.h @@ -57,8 +57,8 @@ QT_BEGIN_NAMESPACE class QGeoCoordinate; -class QVector2D; -class QVector3D; +class QDoubleVector2D; +class QDoubleVector3D; class Q_AUTOTEST_EXPORT QGeoProjection { @@ -66,14 +66,14 @@ public: QGeoProjection(); virtual ~QGeoProjection(); - virtual QVector3D coordToPoint(const QGeoCoordinate &coord) const = 0; - virtual QGeoCoordinate pointToCoord(const QVector3D &point) const = 0; + virtual QDoubleVector3D coordToPoint(const QGeoCoordinate &coord) const = 0; + virtual QGeoCoordinate pointToCoord(const QDoubleVector3D &point) const = 0; - QVector2D coordToMercator(const QGeoCoordinate &coord) const; - QGeoCoordinate mercatorToCoord(const QVector2D &mercator) const; + QDoubleVector2D coordToMercator(const QGeoCoordinate &coord) const; + QGeoCoordinate mercatorToCoord(const QDoubleVector2D &mercator) const; - virtual QVector3D mercatorToPoint(const QVector2D &mercator) const; - virtual QVector2D pointToMercator(const QVector3D &point) const; + virtual QDoubleVector3D mercatorToPoint(const QDoubleVector2D &mercator) const; + virtual QDoubleVector2D pointToMercator(const QDoubleVector3D &point) const; virtual QGeoCoordinate interpolate(const QGeoCoordinate &start, const QGeoCoordinate &end, qreal progress) = 0; private: |