summaryrefslogtreecommitdiff
path: root/src/location/maps
diff options
context:
space:
mode:
Diffstat (limited to 'src/location/maps')
-rw-r--r--src/location/maps/maps.pri6
-rw-r--r--src/location/maps/qdoublevector2d.cpp132
-rw-r--r--src/location/maps/qdoublevector2d_p.h240
-rw-r--r--src/location/maps/qdoublevector3d.cpp187
-rw-r--r--src/location/maps/qdoublevector3d_p.h294
-rw-r--r--src/location/maps/qgeocameratiles.cpp746
-rw-r--r--src/location/maps/qgeocameratiles_p.h92
-rw-r--r--src/location/maps/qgeofrustum.cpp11
-rw-r--r--src/location/maps/qgeofrustum_p.h41
-rw-r--r--src/location/maps/qgeomap.cpp790
-rw-r--r--src/location/maps/qgeomap_p_p.h103
-rw-r--r--src/location/maps/qgeoprojection.cpp15
-rw-r--r--src/location/maps/qgeoprojection2d.cpp28
-rw-r--r--src/location/maps/qgeoprojection2d_p.h8
-rw-r--r--src/location/maps/qgeoprojection_p.h16
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 &center, double radius) const
+bool QGeoFrustum::contains(const QDoubleVector3D &center, 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 &center, double radius) const;
+ bool contains(const QDoubleVector3D &center, 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: