summaryrefslogtreecommitdiff
path: root/src/positioning/qgeopath_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/positioning/qgeopath_p.h')
-rw-r--r--src/positioning/qgeopath_p.h249
1 files changed, 196 insertions, 53 deletions
diff --git a/src/positioning/qgeopath_p.h b/src/positioning/qgeopath_p.h
index d39f0ab2..be73994f 100644
--- a/src/positioning/qgeopath_p.h
+++ b/src/positioning/qgeopath_p.h
@@ -51,73 +51,216 @@
// We mean it.
//
+#include <QtPositioning/private/qpositioningglobal_p.h>
#include "qgeoshape_p.h"
#include "qgeocoordinate.h"
#include "qlocationutils_p.h"
-#include <QtPositioning/private/qclipperutils_p.h>
-
+#include <QtPositioning/qgeopath.h>
#include <QtCore/QVector>
QT_BEGIN_NAMESPACE
-class QGeoPathPrivate : public QGeoShapePrivate
+inline static void computeBBox( const QList<QGeoCoordinate> &m_path,
+ QVector<double> &m_deltaXs,
+ double &m_minX,
+ double &m_maxX,
+ double &m_minLati,
+ double &m_maxLati,
+ QGeoRectangle &m_bbox)
+{
+ if (m_path.isEmpty()) {
+ m_deltaXs.clear();
+ m_minX = qInf();
+ m_maxX = -qInf();
+ m_minLati = qInf();
+ m_maxLati = -qInf();
+ m_bbox = QGeoRectangle();
+ return;
+ }
+
+ m_minLati = m_maxLati = m_path.at(0).latitude();
+ int minId = 0;
+ int maxId = 0;
+ m_deltaXs.resize(m_path.size());
+ m_deltaXs[0] = m_minX = m_maxX = 0.0;
+
+ for (int i = 1; i < m_path.size(); i++) {
+ const QGeoCoordinate &geoFrom = m_path.at(i-1);
+ const QGeoCoordinate &geoTo = m_path.at(i);
+ double longiFrom = geoFrom.longitude();
+ double longiTo = geoTo.longitude();
+ double deltaLongi = longiTo - longiFrom;
+ if (qAbs(deltaLongi) > 180.0) {
+ if (longiTo > 0.0)
+ longiTo -= 360.0;
+ else
+ longiTo += 360.0;
+ deltaLongi = longiTo - longiFrom;
+ }
+ m_deltaXs[i] = m_deltaXs[i-1] + deltaLongi;
+ if (m_deltaXs[i] < m_minX) {
+ m_minX = m_deltaXs[i];
+ minId = i;
+ }
+ if (m_deltaXs[i] > m_maxX) {
+ m_maxX = m_deltaXs[i];
+ maxId = i;
+ }
+ if (geoTo.latitude() > m_maxLati)
+ m_maxLati = geoTo.latitude();
+ if (geoTo.latitude() < m_minLati)
+ m_minLati = geoTo.latitude();
+ }
+
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(minId).longitude()),
+ QGeoCoordinate(m_minLati, m_path.at(maxId).longitude()));
+}
+
+inline static void updateBBox( const QList<QGeoCoordinate> &m_path,
+ QVector<double> &m_deltaXs,
+ double &m_minX,
+ double &m_maxX,
+ double &m_minLati,
+ double &m_maxLati,
+ QGeoRectangle &m_bbox)
+{
+ if (m_path.isEmpty()) {
+ m_deltaXs.clear();
+ m_minX = qInf();
+ m_maxX = -qInf();
+ m_minLati = qInf();
+ m_maxLati = -qInf();
+ m_bbox = QGeoRectangle();
+ return;
+ } else if (m_path.size() == 1) { // was 0 now is 1
+ m_deltaXs.resize(1);
+ m_deltaXs[0] = m_minX = m_maxX = 0.0;
+ m_minLati = m_maxLati = m_path.at(0).latitude();
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(0).longitude()),
+ QGeoCoordinate(m_minLati, m_path.at(0).longitude()));
+ return;
+ } else if ( m_path.size() != m_deltaXs.size() + 1 ) { // this case should not happen
+ computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox); // something went wrong
+ return;
+ }
+
+ const QGeoCoordinate &geoFrom = m_path.at(m_path.size()-2);
+ const QGeoCoordinate &geoTo = m_path.last();
+ double longiFrom = geoFrom.longitude();
+ double longiTo = geoTo.longitude();
+ double deltaLongi = longiTo - longiFrom;
+ if (qAbs(deltaLongi) > 180.0) {
+ if (longiTo > 0.0)
+ longiTo -= 360.0;
+ else
+ longiTo += 360.0;
+ deltaLongi = longiTo - longiFrom;
+ }
+
+ m_deltaXs.push_back(m_deltaXs.last() + deltaLongi);
+ double currentMinLongi = m_bbox.topLeft().longitude();
+ double currentMaxLongi = m_bbox.bottomRight().longitude();
+ if (m_deltaXs.last() < m_minX) {
+ m_minX = m_deltaXs.last();
+ currentMinLongi = geoTo.longitude();
+ }
+ if (m_deltaXs.last() > m_maxX) {
+ m_maxX = m_deltaXs.last();
+ currentMaxLongi = geoTo.longitude();
+ }
+ if (geoTo.latitude() > m_maxLati)
+ m_maxLati = geoTo.latitude();
+ if (geoTo.latitude() < m_minLati)
+ m_minLati = geoTo.latitude();
+ m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, currentMinLongi),
+ QGeoCoordinate(m_minLati, currentMaxLongi));
+}
+
+// Lazy by default. Eager, within the module, used only in MapItems/MapObjectsQSG
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPathPrivate : public QGeoShapePrivate
{
public:
- QGeoPathPrivate(QGeoShape::ShapeType type);
- QGeoPathPrivate(QGeoShape::ShapeType type, const QList<QGeoCoordinate> &path, const qreal width = 0.0);
- QGeoPathPrivate(const QGeoPathPrivate &other);
+ QGeoPathPrivate();
+ QGeoPathPrivate(const QList<QGeoCoordinate> &path, const qreal width = 0.0);
~QGeoPathPrivate();
- bool isValid() const override;
- bool isEmpty() const override;
- bool contains(const QGeoCoordinate &coordinate) const override;
- bool lineContains(const QGeoCoordinate &coordinate) const;
- bool polygonContains(const QGeoCoordinate &coordinate) const;
-
- QGeoCoordinate center() const override;
- QGeoRectangle boundingGeoRectangle() const override;
- void extendShape(const QGeoCoordinate &coordinate) override;
- void translate(double degreesLatitude, double degreesLongitude);
-
- QGeoShapePrivate *clone() const override;
-
- bool operator==(const QGeoShapePrivate &other) const override;
-
- const QList<QGeoCoordinate> &path() const;
- void setPath(const QList<QGeoCoordinate> &path);
- void clearPath();
-
- qreal width() const;
- void setWidth(const qreal &width);
- double length(int indexFrom, int indexTo) const;
- int size() const;
- void addCoordinate(const QGeoCoordinate &coordinate);
- void insertCoordinate(int index, const QGeoCoordinate &coordinate);
- void replaceCoordinate(int index, const QGeoCoordinate &coordinate);
- QGeoCoordinate coordinateAt(int index) const;
- bool containsCoordinate(const QGeoCoordinate &coordinate) const;
- void removeCoordinate(const QGeoCoordinate &coordinate);
- void removeCoordinate(int index);
- void computeBoundingBox();
- void updateBoundingBox();
- void updateClipperPath();
- void addHole(const QList<QGeoCoordinate> &holePath);
- const QList<QGeoCoordinate> holePath(int index) const;
- void removeHole(int index);
- int holesCount() const;
+// QGeoShape API
+ virtual QGeoShapePrivate *clone() const override;
+ virtual bool isValid() const override;
+ virtual bool isEmpty() const override;
+ virtual QGeoCoordinate center() const override;
+ virtual bool operator==(const QGeoShapePrivate &other) const override;
+ virtual bool contains(const QGeoCoordinate &coordinate) const override;
+ virtual QGeoRectangle boundingGeoRectangle() const override;
+ virtual void extendShape(const QGeoCoordinate &coordinate) override;
+// QGeoPathPrivate API
+ virtual const QList<QGeoCoordinate> &path() const;
+ virtual bool lineContains(const QGeoCoordinate &coordinate) const;
+ virtual qreal width() const;
+ virtual double length(int indexFrom, int indexTo) const;
+ virtual int size() const;
+ virtual QGeoCoordinate coordinateAt(int index) const;
+ virtual bool containsCoordinate(const QGeoCoordinate &coordinate) const;
+
+ virtual void setWidth(const qreal &width);
+ virtual void translate(double degreesLatitude, double degreesLongitude);
+ virtual void setPath(const QList<QGeoCoordinate> &path);
+ virtual void clearPath();
+ virtual void addCoordinate(const QGeoCoordinate &coordinate);
+ virtual void insertCoordinate(int index, const QGeoCoordinate &coordinate);
+ virtual void replaceCoordinate(int index, const QGeoCoordinate &coordinate);
+ virtual void removeCoordinate(const QGeoCoordinate &coordinate);
+ virtual void removeCoordinate(int index);
+ virtual void computeBoundingBox();
+ virtual void markDirty();
+
+// data members
QList<QGeoCoordinate> m_path;
- QList<QList<QGeoCoordinate>> m_holesList;
- QVector<double> m_deltaXs; // longitude deltas from m_path[0]
- double m_minX; // minimum value inside deltaXs
- double m_maxX; // maximum value inside deltaXs
- double m_minLati; // minimum latitude. paths do not wrap around through the poles
- double m_maxLati; // minimum latitude. paths do not wrap around through the poles
- QGeoRectangle m_bbox;
- qreal m_width;
- bool m_clipperDirty;
- QtClipperLib::Path m_clipperPath;
+ qreal m_width = 0;
+ QGeoRectangle m_bbox; // cached
+ bool m_bboxDirty = false;
+};
+
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPathPrivateEager : public QGeoPathPrivate
+{
+public:
+ QGeoPathPrivateEager();
+ QGeoPathPrivateEager(const QList<QGeoCoordinate> &path, const qreal width = 0.0);
+ ~QGeoPathPrivateEager();
+
+// QGeoShapePrivate API
+ virtual QGeoShapePrivate *clone() const override;
+ virtual void translate(double degreesLatitude, double degreesLongitude) override;
+
+// QGeoShapePrivate API
+ virtual void markDirty() override;
+ virtual void addCoordinate(const QGeoCoordinate &coordinate) override;
+ virtual void computeBoundingBox() override;
+
+// *Eager API
+ void updateBoundingBox();
+
+// data members
+ QVector<double> m_deltaXs; // longitude deltas from m_path[0]
+ double m_minX = 0; // minimum value inside deltaXs
+ double m_maxX = 0; // maximum value inside deltaXs
+ double m_minLati = 0; // minimum latitude. paths do not wrap around through the poles
+ double m_maxLati = 0; // minimum latitude. paths do not wrap around through the poles
+};
+
+// This is a mean of creating a QGeoPathPrivateEager and injecting it into QGeoPaths via operator=
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPathEager : public QGeoPath
+{
+ Q_GADGET
+public:
+
+ QGeoPathEager();
+ QGeoPathEager(const QList<QGeoCoordinate> &path, const qreal &width = 0.0);
+ QGeoPathEager(const QGeoPath &other);
+ QGeoPathEager(const QGeoShape &other);
+ ~QGeoPathEager();
};
QT_END_NAMESPACE