summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/imports/location/location.cpp4
-rw-r--r--src/imports/locationlabs/locationlabs.cpp4
-rw-r--r--src/imports/positioning/locationsingleton.cpp8
-rw-r--r--src/imports/positioning/positioning.cpp8
-rw-r--r--src/location/declarativemaps/qdeclarativegeocodemodel.cpp2
-rw-r--r--src/location/declarativemaps/qdeclarativegeocodemodel_p.h4
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap.cpp95
-rw-r--r--src/location/declarativemaps/qdeclarativegeomap_p.h3
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroute.cpp29
-rw-r--r--src/location/declarativemaps/qdeclarativegeoroute_p.h4
-rw-r--r--src/location/declarativemaps/qdeclarativepolygonmapitem.cpp4
-rw-r--r--src/location/declarativemaps/qdeclarativepolylinemapitem.cpp16
-rw-r--r--src/location/declarativeplaces/qdeclarativeplace_p.h2
-rw-r--r--src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp26
-rw-r--r--src/location/doc/src/plugins/osm.qdoc5
-rw-r--r--src/location/labs/qdeclarativenavigator.cpp67
-rw-r--r--src/location/labs/qdeclarativenavigator_p.h6
-rw-r--r--src/location/labs/qdeclarativenavigator_p_p.h5
-rw-r--r--src/location/labs/qmapobjectview.cpp59
-rw-r--r--src/location/labs/qmapobjectview_p.h2
-rw-r--r--src/location/labs/qmapobjectview_p_p.h13
-rw-r--r--src/location/location.pro2
-rw-r--r--src/location/maps/qgeocodereply.cpp22
-rw-r--r--src/location/maps/qgeocodereply.h2
-rw-r--r--src/location/maps/qgeocodereply_p.h10
-rw-r--r--src/location/maps/qgeomap.cpp3
-rw-r--r--src/location/maps/qgeomap_p.h2
-rw-r--r--src/location/maps/qgeoroute.cpp48
-rw-r--r--src/location/maps/qgeoroute.h3
-rw-r--r--src/location/maps/qgeoroute_p.h8
-rw-r--r--src/location/maps/qgeotilerequestmanager.cpp4
-rw-r--r--src/location/maps/qnavigationmanagerengine_p.h8
-rw-r--r--src/location/places/qplacesearchrequest_p.h2
-rw-r--r--src/plugins/geoservices/osm/qgeocodereplyosm.cpp46
-rw-r--r--src/plugins/geoservices/osm/qgeocodereplyosm.h16
-rw-r--r--src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp22
-rw-r--r--src/plugins/geoservices/osm/qgeocodingmanagerengineosm.h2
-rw-r--r--src/plugins/position/corelocation/qgeopositioninfosource_cl.mm4
-rw-r--r--src/positioning/positioning.pro5
-rw-r--r--src/positioning/qgeolocation.cpp27
-rw-r--r--src/positioning/qgeolocation.h4
-rw-r--r--src/positioning/qgeolocation_p.h2
-rw-r--r--src/positioning/qgeopath.cpp462
-rw-r--r--src/positioning/qgeopath_p.h248
-rw-r--r--src/positioning/qgeopolygon.cpp259
-rw-r--r--src/positioning/qgeopolygon.h3
-rw-r--r--src/positioning/qgeopolygon_p.h135
-rw-r--r--src/positioning/qgeorectangle.cpp3
-rw-r--r--src/positioning/qgeoshape.cpp4
-rw-r--r--src/positioningquick/qdeclarativegeoaddress.cpp (renamed from src/positioning/qdeclarativegeoaddress.cpp)0
-rw-r--r--src/positioningquick/qdeclarativegeoaddress_p.h (renamed from src/positioning/qdeclarativegeoaddress_p.h)3
-rw-r--r--src/positioningquick/qdeclarativegeolocation.cpp (renamed from src/positioning/qdeclarativegeolocation.cpp)15
-rw-r--r--src/positioningquick/qdeclarativegeolocation_p.h (renamed from src/positioning/qdeclarativegeolocation_p.h)11
-rw-r--r--tests/auto/declarative_core/tst_geocoding.qml24
-rw-r--r--tests/auto/geotestplugin/qgeocodingmanagerengine_test.h53
-rw-r--r--tests/auto/qgeolocation/tst_qgeolocation.cpp32
-rw-r--r--tests/auto/qgeolocation/tst_qgeolocation.h2
-rw-r--r--tests/plugins/declarativetestplugin/locationtest.cpp3
59 files changed, 1405 insertions, 462 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 0815e3b5..d4a60528 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,7 +1,7 @@
load(qt_build_config)
CONFIG += warning_clean
-MODULE_VERSION = 5.12.0
+MODULE_VERSION = 5.13.0
# Adds a way to debug location. The define is needed for multiple subprojects as they
# include the essential headers.
diff --git a/src/imports/location/location.cpp b/src/imports/location/location.cpp
index 2c2331bf..dbedd1de 100644
--- a/src/imports/location/location.cpp
+++ b/src/imports/location/location.cpp
@@ -212,6 +212,6 @@ public:
}
};
-#include "location.moc"
-
QT_END_NAMESPACE
+
+#include "location.moc"
diff --git a/src/imports/locationlabs/locationlabs.cpp b/src/imports/locationlabs/locationlabs.cpp
index cebdf0e4..21c63622 100644
--- a/src/imports/locationlabs/locationlabs.cpp
+++ b/src/imports/locationlabs/locationlabs.cpp
@@ -80,6 +80,6 @@ public:
}
};
-#include "locationlabs.moc"
-
QT_END_NAMESPACE
+
+#include "locationlabs.moc"
diff --git a/src/imports/positioning/locationsingleton.cpp b/src/imports/positioning/locationsingleton.cpp
index e355851e..8f810d94 100644
--- a/src/imports/positioning/locationsingleton.cpp
+++ b/src/imports/positioning/locationsingleton.cpp
@@ -214,6 +214,14 @@ QGeoPath LocationSingleton::path() const
return QGeoPath();
}
+/*!
+ \qmlmethod geopath QtPositioning::path(list<coordinate> coordinates, real width) const
+
+ Constructs a geopath from coordinates and width.
+
+ \sa {geopath}
+ \since 5.9
+*/
QGeoPath LocationSingleton::path(const QJSValue &value, qreal width) const
{
QList<QGeoCoordinate> pathList;
diff --git a/src/imports/positioning/positioning.cpp b/src/imports/positioning/positioning.cpp
index a3cb98fa..215fa61a 100644
--- a/src/imports/positioning/positioning.cpp
+++ b/src/imports/positioning/positioning.cpp
@@ -38,8 +38,8 @@
****************************************************************************/
-#include <QtPositioning/private/qdeclarativegeoaddress_p.h>
-#include <QtPositioning/private/qdeclarativegeolocation_p.h>
+#include <QtPositioningQuick/private/qdeclarativegeoaddress_p.h>
+#include <QtPositioningQuick/private/qdeclarativegeolocation_p.h>
#include <QtPositioning/private/qwebmercator_p.h>
#include <QtPositioningQuick/private/qdeclarativepositionsource_p.h>
@@ -621,6 +621,6 @@ public:
}
};
-#include "positioning.moc"
-
QT_END_NAMESPACE
+
+#include "positioning.moc"
diff --git a/src/location/declarativemaps/qdeclarativegeocodemodel.cpp b/src/location/declarativemaps/qdeclarativegeocodemodel.cpp
index 43ce95a9..a73f9341 100644
--- a/src/location/declarativemaps/qdeclarativegeocodemodel.cpp
+++ b/src/location/declarativemaps/qdeclarativegeocodemodel.cpp
@@ -42,6 +42,7 @@
#include <QtPositioning/QGeoCircle>
#include <QtLocation/QGeoServiceProvider>
#include <QtLocation/QGeoCodingManager>
+#include <QtLocation/private/qgeocodereply_p.h>
#include <QtPositioning/QGeoPolygon>
QT_BEGIN_NAMESPACE
@@ -389,6 +390,7 @@ void QDeclarativeGeocodeModel::geocodeFinished(QGeoCodeReply *reply)
reply->deleteLater();
reply_ = 0;
int oldCount = declarativeLocations_.count();
+ // const QVariantMap &extraData = QGeoCodeReplyPrivate::get(*reply)->extraData();
setLocations(reply->locations());
setError(NoError, QString());
setStatus(QDeclarativeGeocodeModel::Ready);
diff --git a/src/location/declarativemaps/qdeclarativegeocodemodel_p.h b/src/location/declarativemaps/qdeclarativegeocodemodel_p.h
index 6c8f533b..e2361045 100644
--- a/src/location/declarativemaps/qdeclarativegeocodemodel_p.h
+++ b/src/location/declarativemaps/qdeclarativegeocodemodel_p.h
@@ -52,8 +52,8 @@
#include <QtLocation/private/qdeclarativegeoserviceprovider_p.h>
#include <QtLocation/qgeocodereply.h>
-#include <QtPositioning/private/qdeclarativegeoaddress_p.h>
-#include <QtPositioning/private/qdeclarativegeolocation_p.h>
+#include <QtPositioningQuick/private/qdeclarativegeoaddress_p.h>
+#include <QtPositioningQuick/private/qdeclarativegeolocation_p.h>
#include <QtQml/qqml.h>
#include <QtQml/QQmlParserStatus>
diff --git a/src/location/declarativemaps/qdeclarativegeomap.cpp b/src/location/declarativemaps/qdeclarativegeomap.cpp
index 63587efe..3c73ca12 100644
--- a/src/location/declarativemaps/qdeclarativegeomap.cpp
+++ b/src/location/declarativemaps/qdeclarativegeomap.cpp
@@ -1305,7 +1305,7 @@ void QDeclarativeGeoMap::setVisibleRegion(const QGeoShape &shape)
return;
}
- fitViewportToGeoShape();
+ fitViewportToGeoShape(m_visibleRegion);
}
QGeoShape QDeclarativeGeoMap::visibleRegion() const
@@ -1445,39 +1445,6 @@ QMargins QDeclarativeGeoMap::mapMargins() const
, height() - va.height() - va.y());
}
-// TODO: offer the possibility to specify the margins.
-void QDeclarativeGeoMap::fitViewportToGeoShape()
-{
- if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
- // This case remains handled here, and not inside QGeoMap*::fitViewportToGeoRectangle,
- // in order to honor animations on center and zoomLevel
- const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
- const int borderSize = 10;
- const QMargins borders(borderSize, borderSize, borderSize, borderSize);
-
- if (!m_map || !m_visibleRegion.isValid())
- return;
-
- const QMargins margins = borders + mapMargins();
- const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(m_visibleRegion,
- margins);
- if (!fitData.first.isValid())
- return;
-
- // position camera to the center of bounding box
- setProperty("center", QVariant::fromValue(fitData.first)); // not using setCenter(centerCoordinate) to honor a possible animation set on the center property
-
- if (!qIsFinite(fitData.second))
- return;
- double newZoom = qMax<double>(minimumZoomLevel(), fitData.second);
- setProperty("zoomLevel", QVariant::fromValue(newZoom)); // not using setZoomLevel(newZoom) to honor a possible animation set on the zoomLevel property
- } else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) {
- // Animations cannot be honored in this case, as m_map acts as a black box
- m_map->fitViewportToGeoRectangle(m_visibleRegion);
- }
-}
-
-
/*!
\qmlproperty list<MapType> QtLocation::Map::supportedMapTypes
@@ -1604,6 +1571,64 @@ void QDeclarativeGeoMap::clearData()
}
/*!
+ \qmlmethod void QtLocation::Map::fitViewportToGeoShape(geoShape, margins)
+
+ Fits the viewport to a specific geo shape.
+ The margins are in screen pixels.
+
+ \note If the projection used by the plugin is not WebMercator, and the plugin does not have fitting to
+ shape capability, this method will do nothing.
+
+ \sa visibleRegion
+ \since 5.13
+*/
+void QDeclarativeGeoMap::fitViewportToGeoShape(const QGeoShape &shape, QVariant margins)
+{
+ QMargins m(10, 10, 10, 10); // lets defaults to 10 if margins is invalid
+ switch (margins.type()) {
+ case QMetaType::Int:
+ case QMetaType::Double: {
+ const int value = int(margins.toDouble());
+ m = QMargins(value, value, value, value);
+ }
+ break;
+ // ToDo: Support distinct margins in some QML form. Perhaps QRect?
+ default:
+ break;
+ }
+ fitViewportToGeoShape(shape, m);
+}
+
+void QDeclarativeGeoMap::fitViewportToGeoShape(const QGeoShape &shape, const QMargins &borders)
+{
+ if (!m_map || !shape.isValid())
+ return;
+
+ if (m_map->geoProjection().projectionType() == QGeoProjection::ProjectionWebMercator) {
+ // This case remains handled here, and not inside QGeoMap*::fitViewportToGeoRectangle,
+ // in order to honor animations on center and zoomLevel
+ const QMargins margins = borders + mapMargins();
+ const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
+ const QPair<QGeoCoordinate, qreal> fitData = p.fitViewportToGeoRectangle(shape.boundingGeoRectangle(),
+ margins);
+ if (!fitData.first.isValid())
+ return;
+
+ // position camera to the center of bounding box
+ setProperty("center", QVariant::fromValue(fitData.first)); // not using setCenter(centerCoordinate) to honor a possible animation set on the center property
+
+ if (!qIsFinite(fitData.second))
+ return;
+ double newZoom = qMax<double>(minimumZoomLevel(), fitData.second);
+ setProperty("zoomLevel", QVariant::fromValue(newZoom)); // not using setZoomLevel(newZoom) to honor a possible animation set on the zoomLevel property
+ } else if (m_map->capabilities() & QGeoMap::SupportsFittingViewportToGeoRectangle) {
+ // Animations cannot be honored in this case, as m_map acts as a black box
+ m_map->fitViewportToGeoRectangle(m_visibleRegion, borders);
+ }
+ // else out of luck
+}
+
+/*!
\qmlproperty string QtLocation::Map::errorString
This read-only property holds the textual presentation of the latest mapping provider error.
@@ -2205,7 +2230,7 @@ void QDeclarativeGeoMap::geometryChanged(const QRectF &newGeometry, const QRectF
Multiple fitViewportTo*() calls replace each other.
*/
if (m_pendingFitViewport && width() && height()) {
- fitViewportToGeoShape();
+ fitViewportToGeoShape(m_visibleRegion);
m_pendingFitViewport = false;
}
diff --git a/src/location/declarativemaps/qdeclarativegeomap_p.h b/src/location/declarativemaps/qdeclarativegeomap_p.h
index f59f6f54..3cbefe79 100644
--- a/src/location/declarativemaps/qdeclarativegeomap_p.h
+++ b/src/location/declarativemaps/qdeclarativegeomap_p.h
@@ -198,6 +198,8 @@ public:
Q_INVOKABLE void pan(int dx, int dy);
Q_INVOKABLE void prefetchData(); // optional hint for prefetch
Q_INVOKABLE void clearData();
+ Q_INVOKABLE void fitViewportToGeoShape(const QGeoShape &shape, QVariant margins);
+ void fitViewportToGeoShape(const QGeoShape &shape, const QMargins &borders = QMargins(10, 10, 10, 10));
QString errorString() const;
QGeoServiceProvider::Error error() const;
@@ -278,7 +280,6 @@ private:
void populateMap();
void populateParameters();
void fitViewportToMapItemsRefine(bool refine, bool onlyVisible);
- void fitViewportToGeoShape();
bool isInteractive();
void attachCopyrightNotice(bool initialVisibility);
void detachCopyrightNotice(bool currentVisibility);
diff --git a/src/location/declarativemaps/qdeclarativegeoroute.cpp b/src/location/declarativemaps/qdeclarativegeoroute.cpp
index 09ed46ab..64aeb656 100644
--- a/src/location/declarativemaps/qdeclarativegeoroute.cpp
+++ b/src/location/declarativemaps/qdeclarativegeoroute.cpp
@@ -352,6 +352,35 @@ QList<QObject *> QDeclarativeGeoRoute::legs()
}
/*!
+ \qmlproperty Object Route::extendedAttributes
+
+ This property holds the extended attributes of the route and is a map.
+ These attributes are plugin specific, and can be empty.
+
+ Consult the \l {Qt Location#Plugin References and Parameters}{plugin documentation}
+ for what attributes are supported and how they should be used.
+
+ Note, due to limitations of the QQmlPropertyMap, it is not possible
+ to declaratively specify the attributes in QML, assignment of attributes keys
+ and values can only be accomplished by JavaScript.
+
+ \since QtLocation 5.13
+*/
+QQmlPropertyMap *QDeclarativeGeoRoute::extendedAttributes() const
+{
+ if (!m_extendedAttributes) {
+ QDeclarativeGeoRoute *self = const_cast<QDeclarativeGeoRoute *>(this);
+ self->m_extendedAttributes = new QQmlPropertyMap(self);
+ // Fill it
+ const QVariantMap &xAttrs = route_.extendedAttributes();
+ const QStringList &keys = xAttrs.keys();
+ for (const QString &key: keys)
+ self->m_extendedAttributes->insert(key, xAttrs.value(key));
+ }
+ return m_extendedAttributes;
+}
+
+/*!
\qmlmethod bool QtLocation::Route::equals(Route other)
This method performs deep comparison.
diff --git a/src/location/declarativemaps/qdeclarativegeoroute_p.h b/src/location/declarativemaps/qdeclarativegeoroute_p.h
index 98d08e98..767e21ea 100644
--- a/src/location/declarativemaps/qdeclarativegeoroute_p.h
+++ b/src/location/declarativemaps/qdeclarativegeoroute_p.h
@@ -69,6 +69,7 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeGeoRoute : public QObject
Q_PROPERTY(QQmlListProperty<QDeclarativeGeoRouteSegment> segments READ segments CONSTANT)
Q_PROPERTY(QDeclarativeGeoRouteQuery *routeQuery READ routeQuery REVISION 11)
Q_PROPERTY(QList<QObject *> legs READ legs CONSTANT REVISION 12)
+ Q_PROPERTY(QObject *extendedAttributes READ extendedAttributes CONSTANT REVISION 12)
public:
explicit QDeclarativeGeoRoute(QObject *parent = 0);
@@ -91,6 +92,7 @@ public:
const QGeoRoute &route() const;
QDeclarativeGeoRouteQuery *routeQuery();
QList<QObject *> legs();
+ QQmlPropertyMap *extendedAttributes() const;
Q_INVOKABLE bool equals(QDeclarativeGeoRoute *other) const;
@@ -111,6 +113,8 @@ private:
QList<QDeclarativeGeoRouteSegment *> segments_;
QList<QObject *> legs_;
bool segmentsDirty_ = true;
+ QQmlPropertyMap *m_extendedAttributes = nullptr;
+
friend class QDeclarativeRouteMapItem;
};
diff --git a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
index f4cdc6bf..23ea5666 100644
--- a/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolygonmapitem.cpp
@@ -50,6 +50,7 @@
#include <QtPositioning/private/qdoublevector2d_p.h>
#include <QtPositioning/private/qclipperutils_p.h>
+#include <QtPositioning/private/qgeopolygon_p.h>
/* poly2tri triangulator includes */
#include <clip2tri.h>
@@ -318,6 +319,7 @@ QDeclarativePolygonMapItem::QDeclarativePolygonMapItem(QQuickItem *parent)
: QDeclarativeGeoMapItemBase(parent), border_(this), color_(Qt::transparent), dirtyMaterial_(true),
updatingGeometry_(false)
{
+ geopath_ = QGeoPolygonEager();
setFlag(ItemHasContents, true);
QObject::connect(&border_, SIGNAL(colorChanged(QColor)),
this, SLOT(markSourceDirtyAndUpdate()));
@@ -611,7 +613,7 @@ void QDeclarativePolygonMapItem::setGeoShape(const QGeoShape &shape)
if (shape == geopath_)
return;
- geopath_ = shape;
+ geopath_ = QGeoPathEager(shape);
regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
borderGeometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
diff --git a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
index 2fb3098d..2bed0896 100644
--- a/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativepolylinemapitem.cpp
@@ -54,6 +54,7 @@
#include <QtGui/private/qtriangulator_p.h>
#include <QtPositioning/private/qclipperutils_p.h>
+#include <QtPositioning/private/qgeopath_p.h>
#include <array>
QT_BEGIN_NAMESPACE
@@ -738,6 +739,7 @@ bool QGeoMapPolylineGeometry::contains(const QPointF &point) const
QDeclarativePolylineMapItem::QDeclarativePolylineMapItem(QQuickItem *parent)
: QDeclarativeGeoMapItemBase(parent), line_(this), dirtyMaterial_(true), updatingGeometry_(false)
{
+ geopath_ = QGeoPathEager();
setFlag(ItemHasContents, true);
QObject::connect(&line_, SIGNAL(colorChanged(QColor)),
this, SLOT(updateAfterLinePropertiesChanged()));
@@ -806,7 +808,7 @@ void QDeclarativePolylineMapItem::setPath(const QGeoPath &path)
if (geopath_.path() == path.path())
return;
- geopath_ = path;
+ geopath_ = QGeoPathEager(path);
regenerateCache();
geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
markSourceDirtyAndUpdate();
@@ -1135,18 +1137,8 @@ const QGeoShape &QDeclarativePolylineMapItem::geoShape() const
void QDeclarativePolylineMapItem::setGeoShape(const QGeoShape &shape)
{
- if (shape == geopath_)
- return;
-
const QGeoPath geopath(shape); // if shape isn't a path, path will be created as a default-constructed path
- const bool pathHasChanged = geopath.path() != geopath_.path();
- geopath_ = geopath;
-
- regenerateCache();
- geometry_.setPreserveGeometry(true, geopath_.boundingGeoRectangle().topLeft());
- markSourceDirtyAndUpdate();
- if (pathHasChanged)
- emit pathChanged();
+ setPath(geopath);
}
QGeoMap::ItemType QDeclarativePolylineMapItem::itemType() const
diff --git a/src/location/declarativeplaces/qdeclarativeplace_p.h b/src/location/declarativeplaces/qdeclarativeplace_p.h
index 67d2c8df..309bd64c 100644
--- a/src/location/declarativeplaces/qdeclarativeplace_p.h
+++ b/src/location/declarativeplaces/qdeclarativeplace_p.h
@@ -55,7 +55,7 @@
#include <QtQml/QQmlPropertyMap>
#include <QtLocation/QPlace>
-#include <QtPositioning/private/qdeclarativegeolocation_p.h>
+#include <QtPositioningQuick/private/qdeclarativegeolocation_p.h>
#include <QtLocation/private/qdeclarativecategory_p.h>
#include <QtLocation/private/qdeclarativecontactdetail_p.h>
#include <QtLocation/private/qdeclarativesupplier_p.h>
diff --git a/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp b/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
index b9f782cf..8bbe7f64 100644
--- a/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
+++ b/src/location/declarativeplaces/qdeclarativesearchmodelbase.cpp
@@ -46,6 +46,8 @@
#include <QtLocation/QPlaceSearchReply>
#include <QtPositioning/QGeoCircle>
#include <QtPositioning/QGeoPolygon>
+#include <QtLocation/private/qdeclarativegeoroute_p.h>
+#include <QtLocation/private/qplacesearchrequest_p.h>
QT_BEGIN_NAMESPACE
@@ -102,18 +104,36 @@ QVariant QDeclarativeSearchModelBase::searchArea() const
void QDeclarativeSearchModelBase::setSearchArea(const QVariant &searchArea)
{
QGeoShape s;
-
+ QDeclarativeGeoRoute *route = nullptr;
+ bool routeSearchArea = false;
if (searchArea.userType() == qMetaTypeId<QGeoRectangle>())
s = searchArea.value<QGeoRectangle>();
else if (searchArea.userType() == qMetaTypeId<QGeoCircle>())
s = searchArea.value<QGeoCircle>();
else if (searchArea.userType() == qMetaTypeId<QGeoShape>())
s = searchArea.value<QGeoShape>();
+ else if (searchArea.type() == qMetaTypeId<QObject *>()) {
+ route = searchArea.value<QDeclarativeGeoRoute *>();
+ if (!route)
+ return;
+ routeSearchArea = true;
+ }
- if (m_request.searchArea() == s)
+ QPlaceSearchRequestPrivate *rp = QPlaceSearchRequestPrivate::get(m_request);
+ // Invalidating the other thing
+ if (routeSearchArea)
+ m_request.setSearchArea(QGeoShape());
+ else
+ rp->routeSearchArea = QGeoRoute();
+
+ if (m_request.searchArea() == s
+ && (!route || rp->routeSearchArea == route->route()))
return;
- m_request.setSearchArea(s);
+ if (routeSearchArea)
+ rp->routeSearchArea = route->route();
+ else
+ m_request.setSearchArea(s);
emit searchAreaChanged();
}
diff --git a/src/location/doc/src/plugins/osm.qdoc b/src/location/doc/src/plugins/osm.qdoc
index 649d3bed..1fbb7d3e 100644
--- a/src/location/doc/src/plugins/osm.qdoc
+++ b/src/location/doc/src/plugins/osm.qdoc
@@ -69,6 +69,11 @@ a prefix.
\li Url string set when making network requests to the geocoding server. This parameter should be set to a
valid server url with the correct osm API. If not specified the default \l {http://nominatim.openstreetmap.org/}{url} will be used.
\note The API documentation is available at \l {https://wiki.openstreetmap.org/wiki/Nominatim}{Project OSM Nominatim}.
+ \li osm.geocoding.debug_query
+ \li Instructs the plugin to inject the query url to nominatim into the geocode reply, for debugging purposes.
+ \li osm.geocoding.include_extended_data
+ \li Instructs the plugin to include Nominatim-specific information (such as geometry and class) into the returned Location
+ objects, exposed as extendedAttributes.
\row
\li osm.mapping.cache.directory
\li Absolute path to map tile cache directory used as network disk cache.
diff --git a/src/location/labs/qdeclarativenavigator.cpp b/src/location/labs/qdeclarativenavigator.cpp
index 0bf5035f..86c2b85a 100644
--- a/src/location/labs/qdeclarativenavigator.cpp
+++ b/src/location/labs/qdeclarativenavigator.cpp
@@ -141,7 +141,7 @@ QT_BEGIN_NAMESPACE
/*!
\qmlproperty Route Qt.labs.location::Navigator::currentRoute
- This read-only property holds the current route the navigator following.
+ This read-only property holds the current route the navigator is following.
This can be the same as \l route, or can be different, if the navigator
cannot follow the user-specified route.
For example if the position coming from \l positionSource is considerably
@@ -152,6 +152,18 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \qmlproperty RouteLeg Qt.labs.location::Navigator::currentRouteLeg
+
+ This read-only property holds the current route leg the navigator is following.
+ This is always a part of \l currentRoute, and so the property \l RouteLeg::overallRoute
+ of currentRouteLeg will hold the same route as \l currentRoute.
+
+ \sa RouteLeg
+
+ \since 5.13
+*/
+
+/*!
\qmlproperty int Qt.labs.location::Navigator::currentSegment
This read-only property holds the index of the current RouteSegment in the \l currentRoute.
@@ -179,9 +191,29 @@ QDeclarativeNavigatorPrivate::QDeclarativeNavigatorPrivate(QParameterizableObjec
{
}
-void QDeclarativeNavigatorPrivate::updateReadyState()
+void QDeclarativeNavigatorPrivate::clearCachedData()
{
- qobject_cast<QDeclarativeNavigator *>(q)->updateReadyState();
+ const bool routeChanged = !m_currentRoute.isNull();
+ const bool routeLegChanged = !m_currentRouteLeg.isNull();
+ const bool segmentChanged = m_currentSegment != 0;
+
+ if (m_currentRoute)
+ m_currentRoute->deleteLater();
+ m_currentRoute = nullptr;
+
+ if (m_currentRouteLeg)
+ m_currentRouteLeg->deleteLater();
+ m_currentRouteLeg = nullptr;
+
+ m_currentSegment = 0;
+
+ QDeclarativeNavigator *qq = qobject_cast<QDeclarativeNavigator *>(q);
+ if (routeChanged)
+ qq->currentRouteChanged();
+ if (routeLegChanged)
+ qq->currentRouteLegChanged();
+ if (segmentChanged)
+ qq->currentSegmentChanged();
}
@@ -220,11 +252,10 @@ void QDeclarativeNavigator::setMap(QDeclarativeGeoMap *map)
return;
d_ptr->m_params->m_map = map;
- QDeclarativeNavigatorPrivate *dptr = d_ptr.data();
connect(map, &QObject::destroyed, this,
- [this, dptr]() {
+ [this]() {
this->mapChanged();
- dptr->updateReadyState();
+ this->updateReadyState();
});
emit mapChanged();
updateReadyState();
@@ -270,11 +301,10 @@ void QDeclarativeNavigator::setPositionSource(QDeclarativePositionSource *positi
return;
d_ptr->m_params->m_positionSource = positionSource;
- QDeclarativeNavigatorPrivate *dptr = d_ptr.data();
QObject::connect(positionSource, &QObject::destroyed,
- [this, dptr]() {
+ [this]() {
this->positionSourceChanged();
- dptr->updateReadyState();
+ this->updateReadyState();
}
);
emit positionSourceChanged();
@@ -316,6 +346,13 @@ QDeclarativeGeoRoute *QDeclarativeNavigator::currentRoute() const
return d_ptr->m_currentRoute.data();
}
+QDeclarativeGeoRouteLeg *QDeclarativeNavigator::currentRouteLeg() const
+{
+ if (!d_ptr->m_ready || !d_ptr->m_navigator->active())
+ return nullptr;
+ return d_ptr->m_currentRouteLeg.data();
+}
+
int QDeclarativeNavigator::currentSegment() const
{
if (!d_ptr->m_ready || !d_ptr->m_navigator->active())
@@ -379,6 +416,9 @@ void QDeclarativeNavigator::stop()
if (d_ptr->m_navigator->active())
d_ptr->m_active = d_ptr->m_navigator->stop();
+
+ // clear cached data
+ d_ptr->clearCachedData();
}
void QDeclarativeNavigator::pluginReady()
@@ -409,6 +449,7 @@ bool QDeclarativeNavigator::ensureEngine()
connect(d_ptr->m_navigator.get(), &QAbstractNavigator::waypointReached, this, &QDeclarativeNavigator::waypointReached);
connect(d_ptr->m_navigator.get(), &QAbstractNavigator::destinationReached, this, &QDeclarativeNavigator::destinationReached);
connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteChanged, this, &QDeclarativeNavigator::onCurrentRouteChanged);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteLegChanged, this, &QDeclarativeNavigator::onCurrentRouteLegChanged);
connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentSegmentChanged, this, &QDeclarativeNavigator::onCurrentSegmentChanged);
connect(d_ptr->m_navigator.get(), &QAbstractNavigator::activeChanged, this, [this](bool active){
d_ptr->m_active = active;
@@ -440,6 +481,14 @@ void QDeclarativeNavigator::onCurrentRouteChanged(const QGeoRoute &route)
emit currentRouteChanged();
}
+void QDeclarativeNavigator::onCurrentRouteLegChanged(const QGeoRouteLeg &routeLeg)
+{
+ if (d_ptr->m_currentRoute)
+ d_ptr->m_currentRouteLeg->deleteLater();
+ d_ptr->m_currentRouteLeg = new QDeclarativeGeoRouteLeg(routeLeg, this);
+ emit currentRouteLegChanged();
+}
+
void QDeclarativeNavigator::onCurrentSegmentChanged(int segment)
{
d_ptr->m_currentSegment = segment;
diff --git a/src/location/labs/qdeclarativenavigator_p.h b/src/location/labs/qdeclarativenavigator_p.h
index 13884c41..2a425e70 100644
--- a/src/location/labs/qdeclarativenavigator_p.h
+++ b/src/location/labs/qdeclarativenavigator_p.h
@@ -59,9 +59,11 @@ class QDeclarativeGeoServiceProvider;
class QDeclarativeGeoMap;
class QNavigationManager;
class QDeclarativeGeoRoute;
+class QDeclarativeGeoRouteLeg;
class QDeclarativePositionSource;
class QDeclarativeGeoWaypoint;
class QGeoRoute;
+class QGeoRouteLeg;
class QGeoRouteSegment;
class QDeclarativeNavigatorPrivate;
class QDeclarativeGeoRouteSegment;
@@ -77,6 +79,7 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigator : public QParameterizableO
Q_PROPERTY(bool navigatorReady READ navigatorReady NOTIFY navigatorReadyChanged)
Q_PROPERTY(bool trackPositionSource READ trackPositionSource WRITE setTrackPositionSource NOTIFY trackPositionSourceChanged)
Q_PROPERTY(QDeclarativeGeoRoute *currentRoute READ currentRoute NOTIFY currentRouteChanged)
+ Q_PROPERTY(QDeclarativeGeoRouteLeg *currentRouteLeg READ currentRouteLeg NOTIFY currentRouteChanged)
Q_PROPERTY(int currentSegment READ currentSegment NOTIFY currentSegmentChanged)
Q_INTERFACES(QQmlParserStatus)
@@ -113,6 +116,7 @@ public:
bool trackPositionSource() const;
QDeclarativeGeoRoute *currentRoute() const;
+ QDeclarativeGeoRouteLeg *currentRouteLeg() const;
int currentSegment() const;
signals:
@@ -127,6 +131,7 @@ signals:
void routeChanged();
void positionSourceChanged();
void currentRouteChanged();
+ void currentRouteLegChanged();
void currentSegmentChanged();
private:
@@ -136,6 +141,7 @@ private:
private slots:
void onCurrentRouteChanged(const QGeoRoute &route);
+ void onCurrentRouteLegChanged(const QGeoRouteLeg &routeLeg);
void onCurrentSegmentChanged(int segment);
private:
diff --git a/src/location/labs/qdeclarativenavigator_p_p.h b/src/location/labs/qdeclarativenavigator_p_p.h
index 229ead1e..8849ec7a 100644
--- a/src/location/labs/qdeclarativenavigator_p_p.h
+++ b/src/location/labs/qdeclarativenavigator_p_p.h
@@ -59,6 +59,7 @@ class QDeclarativeGeoServiceProvider;
class QDeclarativeGeoMap;
class QNavigationManager;
class QDeclarativeGeoRoute;
+class QDeclarativeGeoRouteLeg;
class QDeclarativePositionSource;
class QGeoMapParameter;
class QDeclarativeGeoRouteSegment;
@@ -81,12 +82,14 @@ class QDeclarativeNavigatorPrivate
public:
QDeclarativeNavigatorPrivate(QParameterizableObject *q_);
- void updateReadyState();
+ void clearCachedData();
+
QParameterizableObject *q = nullptr;
QSharedPointer<QDeclarativeNavigatorParams> m_params;
QScopedPointer<QAbstractNavigator> m_navigator;
QDeclarativeGeoServiceProvider *m_plugin = nullptr;
QPointer<QDeclarativeGeoRoute> m_currentRoute;
+ QPointer<QDeclarativeGeoRouteLeg> m_currentRouteLeg;
int m_currentSegment = 0;
bool m_active = false;
bool m_completed = false;
diff --git a/src/location/labs/qmapobjectview.cpp b/src/location/labs/qmapobjectview.cpp
index 2ffc27bc..7a7d7d3d 100644
--- a/src/location/labs/qmapobjectview.cpp
+++ b/src/location/labs/qmapobjectview.cpp
@@ -89,7 +89,8 @@ QGeoMapObject::Type QMapObjectViewPrivate::type() const
*/
-QMapObjectViewPrivateDefault::QMapObjectViewPrivateDefault(const QMapObjectViewPrivate &other) : QMapObjectViewPrivate(other.q)
+QMapObjectViewPrivateDefault::QMapObjectViewPrivateDefault(const QMapObjectViewPrivate &other)
+: QMapObjectViewPrivate(other.q), m_model(other.model()), m_delegate(other.delegate())
{
}
@@ -98,6 +99,26 @@ QMapObjectViewPrivateDefault::~QMapObjectViewPrivateDefault()
}
+QVariant QMapObjectViewPrivateDefault::model() const
+{
+ return m_model;
+}
+
+void QMapObjectViewPrivateDefault::setModel(const QVariant &model)
+{
+ m_model = model;
+}
+
+QQmlComponent *QMapObjectViewPrivateDefault::delegate() const
+{
+ return m_delegate;
+}
+
+void QMapObjectViewPrivateDefault::setDelegate(QQmlComponent *delegate)
+{
+ m_delegate = delegate;
+}
+
QMapObjectViewPrivateDefault::QMapObjectViewPrivateDefault(QGeoMapObject *q) : QMapObjectViewPrivate(q)
{
@@ -108,6 +129,17 @@ QGeoMapObjectPrivate *QMapObjectViewPrivateDefault::clone()
return new QMapObjectViewPrivateDefault(*this);
}
+bool QMapObjectViewPrivateDefault::equals(const QGeoMapObjectPrivate &other) const
+{
+ if (other.type() != type())
+ return false;
+
+ const QMapObjectViewPrivate &o = static_cast<const QMapObjectViewPrivate &>(other);
+ return (QGeoMapObjectPrivate::equals(o)
+ && model() == o.model()
+ && delegate() == o.delegate());
+}
+
/*
QMapObjectView
@@ -160,10 +192,11 @@ void QMapObjectView::classBegin()
void QMapObjectView::componentComplete()
{
QGeoMapObject::componentComplete();
- if (m_delegate)
- m_delegateModel->setDelegate(m_delegate);
- if (m_model.isValid())
- m_delegateModel->setModel(m_model);
+ QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data());
+ if (d->delegate())
+ m_delegateModel->setDelegate(d->delegate());
+ if (d->model().isValid())
+ m_delegateModel->setModel(d->model());
m_delegateModel->componentComplete();
}
@@ -175,7 +208,8 @@ void QMapObjectView::componentComplete()
*/
QVariant QMapObjectView::model() const
{
- return m_model;
+ const QMapObjectViewPrivate *d = static_cast<const QMapObjectViewPrivate *>(d_ptr.data());
+ return d->model();
}
/*!
@@ -187,14 +221,16 @@ QVariant QMapObjectView::model() const
*/
QQmlComponent *QMapObjectView::delegate() const
{
- return m_delegate;
+ const QMapObjectViewPrivate *d = static_cast<const QMapObjectViewPrivate *>(d_ptr.data());
+ return d->delegate();
}
void QMapObjectView::setModel(QVariant model)
{
- if (m_model == model)
+ QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data());
+ if (d->model() == model)
return;
- m_model = model;
+ d->setModel(model);
if (d_ptr->m_componentCompleted)
m_delegateModel->setModel(model);
@@ -204,9 +240,10 @@ void QMapObjectView::setModel(QVariant model)
void QMapObjectView::setDelegate(QQmlComponent *delegate)
{
- if (m_delegate == delegate)
+ QMapObjectViewPrivate *d = static_cast<QMapObjectViewPrivate *>(d_ptr.data());
+ if (d->delegate() == delegate)
return;
- m_delegate = delegate;
+ d->setDelegate(delegate);
if (d_ptr->m_componentCompleted)
m_delegateModel->setDelegate(delegate);
diff --git a/src/location/labs/qmapobjectview_p.h b/src/location/labs/qmapobjectview_p.h
index 49b80883..5e85aa7a 100644
--- a/src/location/labs/qmapobjectview_p.h
+++ b/src/location/labs/qmapobjectview_p.h
@@ -103,8 +103,6 @@ protected:
void flushDelegateModel();
void flushUserAddedMapObjects();
- QVariant m_model;
- QQmlComponent *m_delegate = nullptr;
QQmlDelegateModel *m_delegateModel = nullptr;
QVector<QPointer<QGeoMapObject>> m_instantiatedMapObjects;
QVector<QPointer<QGeoMapObject>> m_pendingMapObjects;
diff --git a/src/location/labs/qmapobjectview_p_p.h b/src/location/labs/qmapobjectview_p_p.h
index 7550e209..e283f1b0 100644
--- a/src/location/labs/qmapobjectview_p_p.h
+++ b/src/location/labs/qmapobjectview_p_p.h
@@ -65,6 +65,11 @@ public:
QMapObjectViewPrivate(QGeoMapObject *q);
~QMapObjectViewPrivate() override;
+ virtual QVariant model() const = 0;
+ virtual void setModel(const QVariant &model) = 0;
+ virtual QQmlComponent *delegate() const = 0;
+ virtual void setDelegate(QQmlComponent *delegate) = 0;
+
virtual QGeoMapObject::Type type() const override final;
};
@@ -75,10 +80,18 @@ public:
QMapObjectViewPrivateDefault(const QMapObjectViewPrivate &other);
~QMapObjectViewPrivateDefault() override;
+ virtual QVariant model() const override;
+ virtual void setModel(const QVariant &model) override;
+ virtual QQmlComponent *delegate() const override;
+ virtual void setDelegate(QQmlComponent *delegate) override;
// QGeoMapObjectPrivate interface
public:
QGeoMapObjectPrivate *clone() override;
+ bool equals(const QGeoMapObjectPrivate &other) const override;
+
+ QVariant m_model;
+ QQmlComponent *m_delegate = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/location/location.pro b/src/location/location.pro
index 1535a85e..1b541b9e 100644
--- a/src/location/location.pro
+++ b/src/location/location.pro
@@ -1,5 +1,5 @@
TARGET = QtLocation
-QT = core-private positioning-private
+QT = core-private positioning-private positioningquick-private
android {
# adding qtconcurrent dependency here for the osm plugin
QT += concurrent
diff --git a/src/location/maps/qgeocodereply.cpp b/src/location/maps/qgeocodereply.cpp
index 5fefb6fe..9fbede9c 100644
--- a/src/location/maps/qgeocodereply.cpp
+++ b/src/location/maps/qgeocodereply.cpp
@@ -97,6 +97,13 @@ QGeoCodeReply::QGeoCodeReply(QObject *parent)
: QObject(parent),
d_ptr(new QGeoCodeReplyPrivate()) {}
+QGeoCodeReply::QGeoCodeReply(QGeoCodeReplyPrivate &dd, QObject *parent)
+ : QObject(parent),
+ d_ptr(&dd)
+{
+
+}
+
/*!
Constructs a geocode reply with a given \a error and \a errorString and the specified \a parent.
*/
@@ -335,4 +342,19 @@ QGeoCodeReplyPrivate::QGeoCodeReplyPrivate(QGeoCodeReply::Error error, const QSt
QGeoCodeReplyPrivate::~QGeoCodeReplyPrivate() {}
+QVariantMap QGeoCodeReplyPrivate::extraData() const
+{
+ return QVariantMap();
+}
+
+const QGeoCodeReplyPrivate *QGeoCodeReplyPrivate::get(const QGeoCodeReply &reply)
+{
+ return reply.d_ptr;
+}
+
+QGeoCodeReplyPrivate *QGeoCodeReplyPrivate::get(QGeoCodeReply &reply)
+{
+ return reply.d_ptr;
+}
+
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeocodereply.h b/src/location/maps/qgeocodereply.h
index c41e740d..c2395f10 100644
--- a/src/location/maps/qgeocodereply.h
+++ b/src/location/maps/qgeocodereply.h
@@ -85,6 +85,7 @@ Q_SIGNALS:
protected:
explicit QGeoCodeReply(QObject *parent = nullptr);
+ explicit QGeoCodeReply(QGeoCodeReplyPrivate &dd, QObject *parent = nullptr);
void setError(Error error, const QString &errorString);
void setFinished(bool finished);
@@ -99,6 +100,7 @@ protected:
private:
QGeoCodeReplyPrivate *d_ptr;
Q_DISABLE_COPY(QGeoCodeReply)
+ friend class QGeoCodeReplyPrivate;
};
QT_END_NAMESPACE
diff --git a/src/location/maps/qgeocodereply_p.h b/src/location/maps/qgeocodereply_p.h
index fefe7883..3f77497b 100644
--- a/src/location/maps/qgeocodereply_p.h
+++ b/src/location/maps/qgeocodereply_p.h
@@ -48,22 +48,28 @@
// We mean it.
//
+#include <QtLocation/private/qlocationglobal_p.h>
#include "qgeocodereply.h"
#include "qgeoshape.h"
#include <QList>
+#include <QVariantMap>
QT_BEGIN_NAMESPACE
class QGeoLocation;
-class QGeoCodeReplyPrivate
+class Q_LOCATION_PRIVATE_EXPORT QGeoCodeReplyPrivate
{
public:
QGeoCodeReplyPrivate();
QGeoCodeReplyPrivate(QGeoCodeReply::Error error, const QString &errorString);
- ~QGeoCodeReplyPrivate();
+ virtual ~QGeoCodeReplyPrivate();
+
+ virtual QVariantMap extraData() const;
+ static const QGeoCodeReplyPrivate *get(const QGeoCodeReply &reply);
+ static QGeoCodeReplyPrivate *get(QGeoCodeReply &reply);
QGeoCodeReply::Error error;
QString errorString;
diff --git a/src/location/maps/qgeomap.cpp b/src/location/maps/qgeomap.cpp
index 963ef6bd..bf5e557d 100644
--- a/src/location/maps/qgeomap.cpp
+++ b/src/location/maps/qgeomap.cpp
@@ -135,9 +135,10 @@ bool QGeoMap::anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QP
return false;
}
-bool QGeoMap::fitViewportToGeoRectangle(const QGeoRectangle &rectangle)
+bool QGeoMap::fitViewportToGeoRectangle(const QGeoRectangle &rectangle, const QMargins &borders)
{
Q_UNUSED(rectangle)
+ Q_UNUSED(borders)
return false;
}
diff --git a/src/location/maps/qgeomap_p.h b/src/location/maps/qgeomap_p.h
index 874b300f..c0af9e10 100644
--- a/src/location/maps/qgeomap_p.h
+++ b/src/location/maps/qgeomap_p.h
@@ -150,7 +150,7 @@ public:
virtual bool setBearing(qreal bearing, const QGeoCoordinate &coordinate);
virtual QGeoShape visibleRegion() const;
virtual bool anchorCoordinateToPoint(const QGeoCoordinate &coordinate, const QPointF &anchorPoint);
- virtual bool fitViewportToGeoRectangle(const QGeoRectangle &rectangle);
+ virtual bool fitViewportToGeoRectangle(const QGeoRectangle &rectangle, const QMargins &borders);
virtual void setCopyrightVisible(bool visible);
virtual void removeMapObject(QGeoMapObject *obj);
diff --git a/src/location/maps/qgeoroute.cpp b/src/location/maps/qgeoroute.cpp
index 799fe7f1..ef54e4aa 100644
--- a/src/location/maps/qgeoroute.cpp
+++ b/src/location/maps/qgeoroute.cpp
@@ -321,6 +321,26 @@ QList<QGeoRouteLeg> QGeoRoute::routeLegs() const
return d_ptr->routeLegs();
}
+/*!
+ Sets the extended attributes \a extendedAttributes associated with this route.
+
+ \since 5.13
+*/
+void QGeoRoute::setExtendedAttributes(const QVariantMap &extendedAttributes)
+{
+ d_ptr->setExtendedAttributes(extendedAttributes);
+}
+
+/*!
+ Returns the extended attributes associated with this route.
+
+ \since 5.13
+*/
+QVariantMap QGeoRoute::extendedAttributes() const
+{
+ return d_ptr->extendedAttributes();
+}
+
/*******************************************************************************
*******************************************************************************/
@@ -361,7 +381,7 @@ bool QGeoRoutePrivate::equals(const QGeoRoutePrivate &other) const
s2 = s2.nextRouteSegment();
}
- return ((id() == other.id())
+ return ( (id() == other.id())
&& (request() == other.request())
&& (bounds() == other.bounds())
&& (travelTime() == other.travelTime())
@@ -369,7 +389,8 @@ bool QGeoRoutePrivate::equals(const QGeoRoutePrivate &other) const
&& (travelMode() == other.travelMode())
&& (path() == other.path())
&& (metadata() == other.metadata())
- && (routeLegs() == other.routeLegs()));
+ && (routeLegs() == other.routeLegs())
+ && (extendedAttributes() == other.extendedAttributes()) );
}
void QGeoRoutePrivate::setId(const QString &id)
@@ -472,6 +493,16 @@ QList<QGeoRouteLeg> QGeoRoutePrivate::routeLegs() const
return QList<QGeoRouteLeg>();
}
+void QGeoRoutePrivate::setExtendedAttributes(const QVariantMap &/*extendedAttributes*/)
+{
+
+}
+
+QVariantMap QGeoRoutePrivate::extendedAttributes() const
+{
+ return QVariantMap();
+}
+
void QGeoRoutePrivate::setLegIndex(int /*idx*/)
{
@@ -514,7 +545,8 @@ QGeoRoutePrivateDefault::QGeoRoutePrivateDefault(const QGeoRoutePrivateDefault &
m_path(other.m_path),
m_legs(other.m_legs),
m_firstSegment(other.m_firstSegment),
- m_numSegments(other.m_numSegments){}
+ m_numSegments(other.m_numSegments),
+ m_extendedAttributes(other.m_extendedAttributes) {} // Purposedly ignoring legIndex and parentRoute
QGeoRoutePrivateDefault::~QGeoRoutePrivateDefault() {}
@@ -636,6 +668,16 @@ QList<QGeoRouteLeg> QGeoRoutePrivateDefault::routeLegs() const
return m_legs;
}
+void QGeoRoutePrivateDefault::setExtendedAttributes(const QVariantMap &extendedAttributes)
+{
+ m_extendedAttributes = extendedAttributes;
+}
+
+QVariantMap QGeoRoutePrivateDefault::extendedAttributes() const
+{
+ return m_extendedAttributes;
+}
+
void QGeoRoutePrivateDefault::setLegIndex(int idx)
{
if (idx >= 0)
diff --git a/src/location/maps/qgeoroute.h b/src/location/maps/qgeoroute.h
index 381152e3..363ca61b 100644
--- a/src/location/maps/qgeoroute.h
+++ b/src/location/maps/qgeoroute.h
@@ -90,6 +90,9 @@ public:
void setRouteLegs(const QList<QGeoRouteLeg> &legs);
QList<QGeoRouteLeg> routeLegs() const;
+ void setExtendedAttributes(const QVariantMap &extendedAttributes);
+ QVariantMap extendedAttributes() const;
+
protected:
QGeoRoute(const QExplicitlySharedDataPointer<QGeoRoutePrivate> &dd);
QExplicitlySharedDataPointer<QGeoRoutePrivate> &d();
diff --git a/src/location/maps/qgeoroute_p.h b/src/location/maps/qgeoroute_p.h
index 39f96c48..721d00b9 100644
--- a/src/location/maps/qgeoroute_p.h
+++ b/src/location/maps/qgeoroute_p.h
@@ -55,6 +55,7 @@
#include "qgeoroutesegment.h"
#include <QSharedData>
+#include <QVariantMap>
#include <QScopedPointer>
QT_BEGIN_NAMESPACE
@@ -100,6 +101,9 @@ public:
virtual void setRouteLegs(const QList<QGeoRouteLeg> &legs);
virtual QList<QGeoRouteLeg> routeLegs() const;
+ virtual void setExtendedAttributes(const QVariantMap &extendedAttributes);
+ virtual QVariantMap extendedAttributes() const;
+
virtual QString engineName() const = 0;
virtual int segmentsCount() const = 0;
@@ -153,6 +157,9 @@ public:
virtual void setRouteLegs(const QList<QGeoRouteLeg> &legs) override;
virtual QList<QGeoRouteLeg> routeLegs() const override;
+ void setExtendedAttributes(const QVariantMap &extendedAttributes) override;
+ QVariantMap extendedAttributes() const override;
+
// QGeoRouteLeg API
virtual void setLegIndex(int idx) override;
virtual int legIndex() const override;
@@ -175,6 +182,7 @@ public:
QGeoRouteSegment m_firstSegment;
mutable int m_numSegments;
QScopedPointer<QGeoRoute> m_containingRoute;
+ QVariantMap m_extendedAttributes;
int m_legIndex = 0;
};
diff --git a/src/location/maps/qgeotilerequestmanager.cpp b/src/location/maps/qgeotilerequestmanager.cpp
index d4d94ad0..aa6de94d 100644
--- a/src/location/maps/qgeotilerequestmanager.cpp
+++ b/src/location/maps/qgeotilerequestmanager.cpp
@@ -240,6 +240,6 @@ void QGeoTileRequestManagerPrivate::tileError(const QGeoTileSpec &tile, const QS
}
}
-#include "qgeotilerequestmanager.moc"
-
QT_END_NAMESPACE
+
+#include "qgeotilerequestmanager.moc"
diff --git a/src/location/maps/qnavigationmanagerengine_p.h b/src/location/maps/qnavigationmanagerengine_p.h
index 0852b3ea..e7b3876c 100644
--- a/src/location/maps/qnavigationmanagerengine_p.h
+++ b/src/location/maps/qnavigationmanagerengine_p.h
@@ -60,11 +60,18 @@ class QGeoMap;
class QGeoMapParameter;
class QMapRouteObject;
class QGeoRoute;
+class QGeoRouteLeg;
class QNavigationManager;
class QNavigationManagerEnginePrivate;
class QDeclarativeNavigatorParams;
class QDeclarativeGeoWaypoint;
+/*
+ This class is not supposed to react on QDeclarativeNavigator properties changes.
+ This class is meant to react only on start, stop and setTrackPosition.
+ Upon start(), it is supposed to fetch all info from the QDeclarativeNavigatorParams that the engine is supposed
+ to inject.
+*/
class Q_LOCATION_PRIVATE_EXPORT QAbstractNavigator: public QObject
{
Q_OBJECT
@@ -89,6 +96,7 @@ signals:
void waypointReached(const QDeclarativeGeoWaypoint *pos);
void destinationReached();
void currentRouteChanged(const QGeoRoute &route);
+ void currentRouteLegChanged(const QGeoRouteLeg &route);
void currentSegmentChanged(int segment);
private:
diff --git a/src/location/places/qplacesearchrequest_p.h b/src/location/places/qplacesearchrequest_p.h
index fdff89b8..73360926 100644
--- a/src/location/places/qplacesearchrequest_p.h
+++ b/src/location/places/qplacesearchrequest_p.h
@@ -56,6 +56,7 @@
#include <QtCore/QList>
#include <QtLocation/private/qlocationglobal_p.h>
#include <QtCore/QVariant>
+#include <QtLocation/QGeoRoute>
QT_BEGIN_NAMESPACE
@@ -79,6 +80,7 @@ public:
QString recommendationId;
QLocation::VisibilityScope visibilityScope;
QPlaceSearchRequest::RelevanceHint relevanceHint;
+ QGeoRoute routeSearchArea;
int limit;
QVariant searchContext;
bool related = false;
diff --git a/src/plugins/geoservices/osm/qgeocodereplyosm.cpp b/src/plugins/geoservices/osm/qgeocodereplyosm.cpp
index a30601d0..e6a487ba 100644
--- a/src/plugins/geoservices/osm/qgeocodereplyosm.cpp
+++ b/src/plugins/geoservices/osm/qgeocodereplyosm.cpp
@@ -49,8 +49,8 @@
QT_BEGIN_NAMESPACE
-QGeoCodeReplyOsm::QGeoCodeReplyOsm(QNetworkReply *reply, QObject *parent)
-: QGeoCodeReply(parent)
+QGeoCodeReplyOsm::QGeoCodeReplyOsm(QNetworkReply *reply, bool includeExtraData, QObject *parent)
+: QGeoCodeReply(*new QGeoCodeReplyOsmPrivate, parent), m_includeExtraData(includeExtraData)
{
if (!reply) {
setError(UnknownError, QStringLiteral("Null reply"));
@@ -98,6 +98,27 @@ static QGeoAddress parseAddressObject(const QJsonObject &object)
return address;
}
+static void injectExtra(QGeoLocation &location, const QJsonObject &object)
+{
+ QVariantMap extra;
+ static const QList<QString> extraKeys = { QStringLiteral("geojson"),
+ QStringLiteral("icon"),
+ QStringLiteral("importance"),
+ QStringLiteral("type"),
+ QStringLiteral("osm_id"),
+ QStringLiteral("osm_type"),
+ QStringLiteral("licence"),
+ QStringLiteral("place_id"),
+ QStringLiteral("class") };
+
+ for (const auto k: extraKeys) {
+ if (object.contains(k))
+ extra[k] = object.value(k).toVariant();
+ }
+
+ location.setExtendedAttributes(extra);
+}
+
void QGeoCodeReplyOsm::networkReplyFinished()
{
QNetworkReply *reply = static_cast<QNetworkReply *>(sender());
@@ -121,6 +142,8 @@ void QGeoCodeReplyOsm::networkReplyFinished()
location.setCoordinate(coordinate);
location.setAddress(parseAddressObject(object));
+ if (m_includeExtraData)
+ injectExtra(location, object);
locations.append(location);
setLocations(locations);
@@ -154,6 +177,8 @@ void QGeoCodeReplyOsm::networkReplyFinished()
location.setCoordinate(coordinate);
location.setBoundingBox(rectangle);
location.setAddress(parseAddressObject(object));
+ if (m_includeExtraData)
+ injectExtra(location, object);
locations.append(location);
}
@@ -171,4 +196,21 @@ void QGeoCodeReplyOsm::networkReplyError(QNetworkReply::NetworkError error)
setError(QGeoCodeReply::CommunicationError, reply->errorString());
}
+QGeoCodeReplyOsmPrivate::QGeoCodeReplyOsmPrivate()
+{
+
+}
+
+QGeoCodeReplyOsmPrivate::~QGeoCodeReplyOsmPrivate()
+{
+
+}
+
+QVariantMap QGeoCodeReplyOsmPrivate::extraData() const
+{
+ return m_extraData;
+}
+
QT_END_NAMESPACE
+
+
diff --git a/src/plugins/geoservices/osm/qgeocodereplyosm.h b/src/plugins/geoservices/osm/qgeocodereplyosm.h
index 0847f58c..f00a8bb2 100644
--- a/src/plugins/geoservices/osm/qgeocodereplyosm.h
+++ b/src/plugins/geoservices/osm/qgeocodereplyosm.h
@@ -42,6 +42,7 @@
#include <QtNetwork/QNetworkReply>
#include <QtLocation/QGeoCodeReply>
+#include <QtLocation/private/qgeocodereply_p.h>
QT_BEGIN_NAMESPACE
@@ -50,12 +51,25 @@ class QGeoCodeReplyOsm : public QGeoCodeReply
Q_OBJECT
public:
- explicit QGeoCodeReplyOsm(QNetworkReply *reply, QObject *parent = 0);
+ explicit QGeoCodeReplyOsm(QNetworkReply *reply, bool includeExtraData = false, QObject *parent = 0);
~QGeoCodeReplyOsm();
private Q_SLOTS:
void networkReplyFinished();
void networkReplyError(QNetworkReply::NetworkError error);
+
+private:
+ bool m_includeExtraData = false;
+};
+
+class QGeoCodeReplyOsmPrivate : public QGeoCodeReplyPrivate
+{
+public:
+ QGeoCodeReplyOsmPrivate();
+ ~QGeoCodeReplyOsmPrivate();
+ QVariantMap extraData() const override;
+
+ QVariantMap m_extraData;
};
QT_END_NAMESPACE
diff --git a/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp b/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp
index d7751287..b2744551 100644
--- a/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp
+++ b/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.cpp
@@ -38,7 +38,6 @@
****************************************************************************/
#include "qgeocodingmanagerengineosm.h"
-#include "qgeocodereplyosm.h"
#include <QtCore/QVariantMap>
#include <QtCore/QUrl>
@@ -50,6 +49,8 @@
#include <QtPositioning/QGeoAddress>
#include <QtPositioning/QGeoShape>
#include <QtPositioning/QGeoRectangle>
+#include "qgeocodereplyosm.h"
+
QT_BEGIN_NAMESPACE
@@ -85,6 +86,11 @@ QGeoCodingManagerEngineOsm::QGeoCodingManagerEngineOsm(const QVariantMap &parame
else
m_urlPrefix = QStringLiteral("https://nominatim.openstreetmap.org");
+ if (parameters.contains(QStringLiteral("osm.geocoding.debug_query")))
+ m_debugQuery = parameters.value(QStringLiteral("osm.geocoding.debug_query")).toBool();
+ if (parameters.contains(QStringLiteral("osm.geocoding.include_extended_data")))
+ m_includeExtraData = parameters.value(QStringLiteral("osm.geocoding.include_extended_data")).toBool();
+
*error = QGeoServiceProvider::NoError;
errorString->clear();
}
@@ -125,7 +131,12 @@ QGeoCodeReply *QGeoCodingManagerEngineOsm::geocode(const QString &address, int l
QNetworkReply *reply = m_networkManager->get(request);
- QGeoCodeReplyOsm *geocodeReply = new QGeoCodeReplyOsm(reply, this);
+ QGeoCodeReplyOsm *geocodeReply = new QGeoCodeReplyOsm(reply, m_includeExtraData, this);
+ if (m_debugQuery) {
+ QGeoCodeReplyOsmPrivate *replyPrivate
+ = static_cast<QGeoCodeReplyOsmPrivate *>(QGeoCodeReplyPrivate::get(*geocodeReply));
+ replyPrivate->m_extraData["request_url"] = url;
+ }
connect(geocodeReply, SIGNAL(finished()), this, SLOT(replyFinished()));
connect(geocodeReply, SIGNAL(error(QGeoCodeReply::Error,QString)),
@@ -156,7 +167,12 @@ QGeoCodeReply *QGeoCodingManagerEngineOsm::reverseGeocode(const QGeoCoordinate &
QNetworkReply *reply = m_networkManager->get(request);
- QGeoCodeReplyOsm *geocodeReply = new QGeoCodeReplyOsm(reply, this);
+ QGeoCodeReplyOsm *geocodeReply = new QGeoCodeReplyOsm(reply, m_includeExtraData, this);
+ if (m_debugQuery) {
+ QGeoCodeReplyOsmPrivate *replyPrivate
+ = static_cast<QGeoCodeReplyOsmPrivate *>(QGeoCodeReplyPrivate::get(*geocodeReply));
+ replyPrivate->m_extraData["request_url"] = url;
+ }
connect(geocodeReply, SIGNAL(finished()), this, SLOT(replyFinished()));
connect(geocodeReply, SIGNAL(error(QGeoCodeReply::Error,QString)),
diff --git a/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.h b/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.h
index 0fec49de..7a54fa43 100644
--- a/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.h
+++ b/src/plugins/geoservices/osm/qgeocodingmanagerengineosm.h
@@ -71,6 +71,8 @@ private:
QNetworkAccessManager *m_networkManager;
QByteArray m_userAgent;
QString m_urlPrefix;
+ bool m_debugQuery = false;
+ bool m_includeExtraData = false;
};
QT_END_NAMESPACE
diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
index 6435963b..421f7743 100644
--- a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
+++ b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
@@ -325,6 +325,6 @@ void QGeoPositionInfoSourceCL::setError(QGeoPositionInfoSource::Error positionEr
emit QGeoPositionInfoSource::error(positionError);
}
-#include "moc_qgeopositioninfosource_cl_p.cpp"
-
QT_END_NAMESPACE
+
+#include "moc_qgeopositioninfosource_cl_p.cpp"
diff --git a/src/positioning/positioning.pro b/src/positioning/positioning.pro
index 44de23ea..35e8e9e1 100644
--- a/src/positioning/positioning.pro
+++ b/src/positioning/positioning.pro
@@ -49,8 +49,6 @@ PRIVATE_HEADERS += \
qnmeapositioninfosource_p.h \
qgeocoordinate_p.h \
qgeopositioninfosource_p.h \
- qdeclarativegeoaddress_p.h \
- qdeclarativegeolocation_p.h \
qdoublevector2d_p.h \
qdoublevector3d_p.h \
qwebmercator_p.h \
@@ -58,6 +56,7 @@ PRIVATE_HEADERS += \
qlocationdata_simulator_p.h \
qdoublematrix4x4_p.h \
qgeopath_p.h \
+ qgeopolygon_p.h \
qgeocoordinateobject_p.h \
qgeopositioninfo_p.h \
qclipperutils_p.h
@@ -78,8 +77,6 @@ SOURCES += \
qlocationutils.cpp \
qnmeapositioninfosource.cpp \
qgeopositioninfosourcefactory.cpp \
- qdeclarativegeoaddress.cpp \
- qdeclarativegeolocation.cpp \
qdoublevector2d.cpp \
qdoublevector3d.cpp \
qgeopath.cpp \
diff --git a/src/positioning/qgeolocation.cpp b/src/positioning/qgeolocation.cpp
index 62e1a6a3..dd34112f 100644
--- a/src/positioning/qgeolocation.cpp
+++ b/src/positioning/qgeolocation.cpp
@@ -53,6 +53,7 @@ QGeoLocationPrivate::QGeoLocationPrivate(const QGeoLocationPrivate &other)
this->address = other.address;
this->coordinate = other.coordinate;
this->viewport = other.viewport;
+ this->extendedAttributes = other.extendedAttributes;
}
QGeoLocationPrivate::~QGeoLocationPrivate()
@@ -63,7 +64,8 @@ bool QGeoLocationPrivate::operator==(const QGeoLocationPrivate &other) const
{
return (this->address == other.address
&& this->coordinate == other.coordinate
- && this->viewport == other.viewport);
+ && this->viewport == other.viewport
+ && this->extendedAttributes == other.extendedAttributes);
}
@@ -72,7 +74,7 @@ bool QGeoLocationPrivate::isEmpty() const
return (address.isEmpty()
&& !coordinate.isValid()
&& viewport.isEmpty()
- );
+ && extendedAttributes.isEmpty());
}
/*!
@@ -193,6 +195,27 @@ void QGeoLocation::setBoundingBox(const QGeoRectangle &boundingBox)
}
/*!
+ Returns the extended attributes associated to this location.
+ Extended attributes are backend-dependent and can be location-dependent.
+
+ \since 5.13
+*/
+QVariantMap QGeoLocation::extendedAttributes() const
+{
+ return d->extendedAttributes;
+}
+
+/*!
+ Sets the extended attributes of the location.
+
+ \since 5.13
+*/
+void QGeoLocation::setExtendedAttributes(const QVariantMap &data)
+{
+ d->extendedAttributes = data;
+}
+
+/*!
Returns true if all fields of the location are 0; otherwise returns false.
*/
bool QGeoLocation::isEmpty() const
diff --git a/src/positioning/qgeolocation.h b/src/positioning/qgeolocation.h
index 580b2fb3..ff1dbcd9 100644
--- a/src/positioning/qgeolocation.h
+++ b/src/positioning/qgeolocation.h
@@ -70,8 +70,10 @@ public:
void setAddress(const QGeoAddress &address);
QGeoCoordinate coordinate() const;
void setCoordinate(const QGeoCoordinate &position);
- QGeoRectangle boundingBox() const;
+ QGeoRectangle boundingBox() const; // ### Qt6: change this into QGeoShape geometry
void setBoundingBox(const QGeoRectangle &box);
+ QVariantMap extendedAttributes() const;
+ void setExtendedAttributes(const QVariantMap &data);
bool isEmpty() const;
diff --git a/src/positioning/qgeolocation_p.h b/src/positioning/qgeolocation_p.h
index a12e4cb4..a9ce639d 100644
--- a/src/positioning/qgeolocation_p.h
+++ b/src/positioning/qgeolocation_p.h
@@ -55,6 +55,7 @@
#include <QtPositioning/QGeoAddress>
#include <QtPositioning/QGeoCoordinate>
#include <QtPositioning/QGeoRectangle>
+#include <QVariantMap>
QT_BEGIN_NAMESPACE
@@ -73,6 +74,7 @@ public:
QGeoAddress address;
QGeoCoordinate coordinate;
QGeoRectangle viewport;
+ QVariantMap extendedAttributes;
};
QT_END_NAMESPACE
diff --git a/src/positioning/qgeopath.cpp b/src/positioning/qgeopath.cpp
index 0c3d0c1c..843b3f1b 100644
--- a/src/positioning/qgeopath.cpp
+++ b/src/positioning/qgeopath.cpp
@@ -114,7 +114,7 @@ Q_GLOBAL_STATIC(PathVariantConversions, initPathConversions)
Constructs a new, empty geo path.
*/
QGeoPath::QGeoPath()
-: QGeoShape(new QGeoPathPrivate(QGeoShape::PathType))
+: QGeoShape(new QGeoPathPrivate())
{
initPathConversions();
}
@@ -124,7 +124,7 @@ QGeoPath::QGeoPath()
(\a path and \a width).
*/
QGeoPath::QGeoPath(const QList<QGeoCoordinate> &path, const qreal &width)
-: QGeoShape(new QGeoPathPrivate(QGeoShape::PathType, path, width))
+: QGeoShape(new QGeoPathPrivate(path, width))
{
initPathConversions();
}
@@ -146,7 +146,7 @@ QGeoPath::QGeoPath(const QGeoShape &other)
{
initPathConversions();
if (type() != QGeoShape::PathType)
- d_ptr = new QGeoPathPrivate(QGeoShape::PathType);
+ d_ptr = new QGeoPathPrivate();
}
/*!
@@ -391,128 +391,70 @@ QString QGeoPath::toString() const
}
/*******************************************************************************
- * QGeoPathPrivate
+ *
+ * QGeoPathPrivate & friends
+ *
*******************************************************************************/
-QGeoPathPrivate::QGeoPathPrivate(QGeoShape::ShapeType type)
-: QGeoShapePrivate(type), m_width(0), m_clipperDirty(true)
+QGeoPathPrivate::QGeoPathPrivate()
+: QGeoShapePrivate(QGeoShape::PathType)
{
+
}
-QGeoPathPrivate::QGeoPathPrivate(QGeoShape::ShapeType type, const QList<QGeoCoordinate> &path, const qreal width)
-: QGeoShapePrivate(type), m_width(0), m_clipperDirty(true)
+QGeoPathPrivate::QGeoPathPrivate(const QList<QGeoCoordinate> &path, const qreal width)
+: QGeoShapePrivate(QGeoShape::PathType)
{
setPath(path);
setWidth(width);
}
-QGeoPathPrivate::QGeoPathPrivate(const QGeoPathPrivate &other)
-: QGeoShapePrivate(other.type), m_path(other.m_path),
- m_deltaXs(other.m_deltaXs), m_minX(other.m_minX), m_maxX(other.m_maxX), m_minLati(other.m_minLati),
- m_maxLati(other.m_maxLati), m_bbox(other.m_bbox), m_width(other.m_width), m_clipperDirty(true)
+QGeoPathPrivate::~QGeoPathPrivate()
{
-}
-QGeoPathPrivate::~QGeoPathPrivate() {}
+}
QGeoShapePrivate *QGeoPathPrivate::clone() const
{
return new QGeoPathPrivate(*this);
}
-bool QGeoPathPrivate::operator==(const QGeoShapePrivate &other) const
-{
- if (!QGeoShapePrivate::operator==(other))
- return false;
-
- const QGeoPathPrivate &otherPath = static_cast<const QGeoPathPrivate &>(other);
- if (m_path.size() != otherPath.m_path.size())
- return false;
-
- if (type == QGeoShape::PathType)
- return m_width == otherPath.m_width && m_path == otherPath.m_path;
- else
- return m_path == otherPath.m_path;
-}
-
bool QGeoPathPrivate::isValid() const
{
- if (type == QGeoShape::PathType)
- return !isEmpty();
- else
- return m_path.size() > 2;
-
+ return !isEmpty();
}
bool QGeoPathPrivate::isEmpty() const
{
- return m_path.isEmpty(); // this should perhaps return geometric emptiness, less than 2 points for line, or empty polygon for polygons
-}
-
-const QList<QGeoCoordinate> &QGeoPathPrivate::path() const
-{
- return m_path;
-}
-
-void QGeoPathPrivate::setPath(const QList<QGeoCoordinate> &path)
-{
- for (const QGeoCoordinate &c: path)
- if (!c.isValid())
- return;
- m_path = path;
- computeBoundingBox();
-}
-
-void QGeoPathPrivate::clearPath()
-{
- m_path.clear();
- computeBoundingBox();
+ return path().isEmpty(); // this should perhaps return geometric emptiness, less than 2 points for line, or empty polygon for polygons
}
-qreal QGeoPathPrivate::width() const
+QGeoCoordinate QGeoPathPrivate::center() const
{
- return m_width;
+ return boundingGeoRectangle().center();
}
-void QGeoPathPrivate::setWidth(const qreal &width)
+void QGeoPathPrivate::extendShape(const QGeoCoordinate &coordinate)
{
- if (qIsNaN(width) || width < 0.0)
+ if (!coordinate.isValid() || contains(coordinate))
return;
- m_width = width;
+ addCoordinate(coordinate);
}
-double QGeoPathPrivate::length(int indexFrom, int indexTo) const
+bool QGeoPathPrivate::operator==(const QGeoShapePrivate &other) const
{
- if (path().isEmpty())
- return 0.0;
-
- bool wrap = indexTo == -1;
- if (indexTo < 0 || indexTo >= path().size())
- indexTo = path().size() - 1;
- double len = 0.0;
- // TODO: consider calculating the length of the actual rhumb line segments
- // instead of the shortest path from A to B.
- for (int i = indexFrom; i < indexTo; i++)
- len += m_path[i].distanceTo(m_path[i+1]);
- if (wrap)
- len += m_path.last().distanceTo(m_path.first());
- return len;
-}
+ if (!QGeoShapePrivate::operator==(other))
+ return false;
-int QGeoPathPrivate::size() const
-{
- return m_path.size();
+ const QGeoPathPrivate &otherPath = static_cast<const QGeoPathPrivate &>(other);
+ if (m_path.size() != otherPath.m_path.size())
+ return false;
+ return m_width == otherPath.m_width && m_path == otherPath.m_path;
}
-/*!
- Returns true if coordinate is present in m_path.
-*/
-bool QGeoPathPrivate::contains(const QGeoCoordinate &coordinate) const
+const QList<QGeoCoordinate> &QGeoPathPrivate::path() const
{
- if (type == QGeoShape::PathType)
- return lineContains(coordinate);
- else
- return polygonContains(coordinate);
+ return m_path;
}
bool QGeoPathPrivate::lineContains(const QGeoCoordinate &coordinate) const
@@ -584,54 +526,67 @@ bool QGeoPathPrivate::lineContains(const QGeoCoordinate &coordinate) const
return (m_path[0].distanceTo(coordinate) <= lineRadius);
}
-/*!
- modified version of polygonContains with holes support.
-*/
-bool QGeoPathPrivate::polygonContains(const QGeoCoordinate &coordinate) const
+bool QGeoPathPrivate::contains(const QGeoCoordinate &coordinate) const
{
- if (m_clipperDirty)
- const_cast<QGeoPathPrivate *>(this)->updateClipperPath();
-
- // iterates the holes List checking whether the point is contained inside the holes
- for (const QList<QGeoCoordinate> &holePath : qAsConst(m_holesList)) {
+ return lineContains(coordinate);
+}
- QGeoPolygon holePolygon;
- holePolygon.setPath(holePath);
- QGeoPath holeBoundary;
- holeBoundary.setPath(holePath);
+qreal QGeoPathPrivate::width() const
+{
+ return m_width;
+}
- if (holePolygon.contains(coordinate) && !(holeBoundary.contains(coordinate)))
- return false;
- }
+void QGeoPathPrivate::setWidth(const qreal &width)
+{
+ if (qIsNaN(width) || width < 0.0)
+ return;
+ m_width = width;
+}
- QDoubleVector2D coord = QWebMercator::coordToMercator(coordinate);
- double tlx = QWebMercator::coordToMercator(m_bbox.topLeft()).x();
- if (coord.x() < tlx)
- coord.setX(coord.x() + 1.0);
+double QGeoPathPrivate::length(int indexFrom, int indexTo) const
+{
+ if (path().isEmpty())
+ return 0.0;
- IntPoint intCoord = QClipperUtils::toIntPoint(coord);
- return c2t::clip2tri::pointInPolygon(intCoord, m_clipperPath) != 0;
+ bool wrap = indexTo == -1;
+ if (indexTo < 0 || indexTo >= path().size())
+ indexTo = path().size() - 1;
+ double len = 0.0;
+ // TODO: consider calculating the length of the actual rhumb line segments
+ // instead of the shortest path from A to B.
+ for (int i = indexFrom; i < indexTo; i++)
+ len += m_path[i].distanceTo(m_path[i+1]);
+ if (wrap)
+ len += m_path.last().distanceTo(m_path.first());
+ return len;
}
-QGeoCoordinate QGeoPathPrivate::center() const
+int QGeoPathPrivate::size() const
{
- return boundingGeoRectangle().center();
+ return m_path.size();
}
-QGeoRectangle QGeoPathPrivate::boundingGeoRectangle() const
+QGeoCoordinate QGeoPathPrivate::coordinateAt(int index) const
{
- return m_bbox;
+ if (index < 0 || index >= m_path.size())
+ return QGeoCoordinate();
+
+ return m_path.at(index);
}
-void QGeoPathPrivate::extendShape(const QGeoCoordinate &coordinate)
+bool QGeoPathPrivate::containsCoordinate(const QGeoCoordinate &coordinate) const
{
- if (!coordinate.isValid() || contains(coordinate))
- return;
- addCoordinate(coordinate);
+ return m_path.indexOf(coordinate) > -1;
}
void QGeoPathPrivate::translate(double degreesLatitude, double degreesLongitude)
{
+ // Need min/maxLati, so update bbox
+ QVector<double> m_deltaXs;
+ double m_minX, m_maxX, m_minLati, m_maxLati;
+ m_bboxDirty = false;
+ computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
+
if (degreesLatitude > 0.0)
degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati);
else
@@ -640,17 +595,29 @@ void QGeoPathPrivate::translate(double degreesLatitude, double degreesLongitude)
p.setLatitude(p.latitude() + degreesLatitude);
p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
}
- if (!m_holesList.isEmpty()){
- for (QList<QGeoCoordinate> &hole: m_holesList){
- for (QGeoCoordinate &holeVertex: hole){
- holeVertex.setLatitude(holeVertex.latitude() + degreesLatitude);
- holeVertex.setLongitude(QLocationUtils::wrapLong(holeVertex.longitude() + degreesLongitude));
- }
- }
- }
m_bbox.translate(degreesLatitude, degreesLongitude);
- m_minLati += degreesLatitude;
- m_maxLati += degreesLatitude;
+}
+
+QGeoRectangle QGeoPathPrivate::boundingGeoRectangle() const
+{
+ if (m_bboxDirty)
+ const_cast<QGeoPathPrivate &>(*this).computeBoundingBox();
+ return m_bbox;
+}
+
+void QGeoPathPrivate::setPath(const QList<QGeoCoordinate> &path)
+{
+ for (const QGeoCoordinate &c: path)
+ if (!c.isValid())
+ return;
+ m_path = path;
+ markDirty();
+}
+
+void QGeoPathPrivate::clearPath()
+{
+ m_path.clear();
+ markDirty();
}
void QGeoPathPrivate::addCoordinate(const QGeoCoordinate &coordinate)
@@ -658,38 +625,23 @@ void QGeoPathPrivate::addCoordinate(const QGeoCoordinate &coordinate)
if (!coordinate.isValid())
return;
m_path.append(coordinate);
- updateBoundingBox();
+ markDirty();
}
void QGeoPathPrivate::insertCoordinate(int index, const QGeoCoordinate &coordinate)
{
if (index < 0 || index > m_path.size() || !coordinate.isValid())
return;
-
m_path.insert(index, coordinate);
- computeBoundingBox();
+ markDirty();
}
void QGeoPathPrivate::replaceCoordinate(int index, const QGeoCoordinate &coordinate)
{
if (index < 0 || index >= m_path.size() || !coordinate.isValid())
return;
-
m_path[index] = coordinate;
- computeBoundingBox();
-}
-
-QGeoCoordinate QGeoPathPrivate::coordinateAt(int index) const
-{
- if (index < 0 || index >= m_path.size())
- return QGeoCoordinate();
-
- return m_path.at(index);
-}
-
-bool QGeoPathPrivate::containsCoordinate(const QGeoCoordinate &coordinate) const
-{
- return m_path.indexOf(coordinate) > -1;
+ markDirty();
}
void QGeoPathPrivate::removeCoordinate(const QGeoCoordinate &coordinate)
@@ -702,171 +654,121 @@ void QGeoPathPrivate::removeCoordinate(int index)
{
if (index < 0 || index >= m_path.size())
return;
-
m_path.removeAt(index);
- computeBoundingBox();
+ markDirty();
+}
+
+void QGeoPathPrivate::markDirty()
+{
+ m_bboxDirty = true;
}
void QGeoPathPrivate::computeBoundingBox()
{
- m_clipperDirty = true;
- if (m_path.isEmpty()) {
- m_deltaXs.clear();
- m_minX = qInf();
- m_maxX = -qInf();
- m_minLati = qInf();
- m_maxLati = -qInf();
- m_bbox = QGeoRectangle();
- return;
- }
+ QVector<double> m_deltaXs;
+ double m_minX, m_maxX, m_minLati, m_maxLati;
+ m_bboxDirty = false;
+ computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
+}
- 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;
+QGeoPathPrivateEager::QGeoPathPrivateEager()
+: QGeoPathPrivate()
+{
+ m_bboxDirty = false; // never dirty on the eager version
+}
- 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();
- }
+QGeoPathPrivateEager::QGeoPathPrivateEager(const QList<QGeoCoordinate> &path, const qreal width)
+: QGeoPathPrivate(path, width)
+{
+ m_bboxDirty = false; // never dirty on the eager version
+}
+
+QGeoPathPrivateEager::~QGeoPathPrivateEager()
+{
- m_bbox = QGeoRectangle(QGeoCoordinate(m_maxLati, m_path.at(minId).longitude()),
- QGeoCoordinate(m_minLati, m_path.at(maxId).longitude()));
}
-void QGeoPathPrivate::updateBoundingBox()
+QGeoShapePrivate *QGeoPathPrivateEager::clone() const
{
- m_clipperDirty = true;
- 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
- computeBoundingBox(); // something went wrong
- return;
- }
+ return new QGeoPathPrivateEager(*this);
+}
- 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;
- }
+void QGeoPathPrivateEager::markDirty()
+{
+ computeBoundingBox();
+}
- 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));
-}
-
-void QGeoPathPrivate::updateClipperPath()
-{
- m_clipperDirty = false;
- double tlx = QWebMercator::coordToMercator(m_bbox.topLeft()).x();
- QList<QDoubleVector2D> preservedPath;
- for (const QGeoCoordinate &c : m_path) {
- QDoubleVector2D crd = QWebMercator::coordToMercator(c);
- if (crd.x() < tlx)
- crd.setX(crd.x() + 1.0);
- preservedPath << crd;
+void QGeoPathPrivateEager::translate(double degreesLatitude, double degreesLongitude)
+{
+ if (degreesLatitude > 0.0)
+ degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati);
+ else
+ degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati);
+ for (QGeoCoordinate &p: m_path) {
+ p.setLatitude(p.latitude() + degreesLatitude);
+ p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
}
- m_clipperPath = QClipperUtils::qListToPath(preservedPath);
+ m_bbox.translate(degreesLatitude, degreesLongitude);
+ m_minLati += degreesLatitude;
+ m_maxLati += degreesLatitude;
}
-
-/*!
- Sets the \a path for an Hole inside the polygon.The hole has QList<QGeoCoordinate> type
-*/
-void QGeoPathPrivate::addHole(const QList<QGeoCoordinate> &holePath)
+void QGeoPathPrivateEager::addCoordinate(const QGeoCoordinate &coordinate)
{
- for (const QGeoCoordinate &holeVertex: holePath)
- if (!holeVertex.isValid())
- return;
+ if (!coordinate.isValid())
+ return;
+ m_path.append(coordinate);
+ //m_clipperDirty = true; // clipper not used in polylines
+ updateBoundingBox();
+}
- m_holesList << holePath;
+void QGeoPathPrivateEager::QGeoPathPrivateEager::computeBoundingBox()
+{
+ computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
}
-/*!
- Returns a QVariant containing a QList<QGeoCoordinate> representing the hole at index
-*/
-const QList<QGeoCoordinate> QGeoPathPrivate::holePath(int index) const
+void QGeoPathPrivateEager::QGeoPathPrivateEager::updateBoundingBox()
{
- return m_holesList.at(index);
+ updateBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
}
+QGeoPathEager::QGeoPathEager() : QGeoPath()
+{
+ initPathConversions();
+ d_ptr = new QGeoPathPrivateEager;
+}
-/*!
- Removes element at position \a index from the holes QList.
-*/
-void QGeoPathPrivate::removeHole(int index)
+QGeoPathEager::QGeoPathEager(const QList<QGeoCoordinate> &path, const qreal &width) : QGeoPath()
{
- if (index < 0 || index >= m_holesList.size())
- return;
+ initPathConversions();
+ d_ptr = new QGeoPathPrivateEager(path, width);
+}
- m_holesList.removeAt(index);
+QGeoPathEager::QGeoPathEager(const QGeoPath &other) : QGeoPath()
+{
+ initPathConversions();
+ d_ptr = new QGeoPathPrivateEager;
+ setPath(other.path());
+ setWidth(other.width());
}
-/*!
- Returns the number of holes.
-*/
-int QGeoPathPrivate::holesCount() const
+QGeoPathEager::QGeoPathEager(const QGeoShape &other) : QGeoPath()
{
- return m_holesList.size();
+ initPathConversions();
+ if (other.type() == QGeoShape::PathType)
+ *this = QGeoPathEager(QGeoPath(other));
+ else
+ d_ptr = new QGeoPathPrivateEager;
}
+QGeoPathEager::~QGeoPathEager() {}
+
QT_END_NAMESPACE
+
+
+
+
+
+
+
diff --git a/src/positioning/qgeopath_p.h b/src/positioning/qgeopath_p.h
index d39f0ab2..4fffe61d 100644
--- a/src/positioning/qgeopath_p.h
+++ b/src/positioning/qgeopath_p.h
@@ -51,73 +51,217 @@
// 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
diff --git a/src/positioning/qgeopolygon.cpp b/src/positioning/qgeopolygon.cpp
index 66659d4b..4e902be5 100644
--- a/src/positioning/qgeopolygon.cpp
+++ b/src/positioning/qgeopolygon.cpp
@@ -38,7 +38,7 @@
****************************************************************************/
#include "qgeopolygon.h"
-#include "qgeopath_p.h"
+#include "qgeopolygon_p.h"
#include "qgeocoordinate.h"
#include "qnumeric.h"
@@ -111,7 +111,7 @@ Q_GLOBAL_STATIC(PolygonVariantConversions, initPolygonConversions)
Constructs a new, empty geo polygon.
*/
QGeoPolygon::QGeoPolygon()
-: QGeoShape(new QGeoPolygonPrivate(QGeoShape::PolygonType))
+: QGeoShape(new QGeoPolygonPrivate())
{
initPolygonConversions();
}
@@ -120,7 +120,7 @@ QGeoPolygon::QGeoPolygon()
Constructs a new geo \a polygon from a list of coordinates.
*/
QGeoPolygon::QGeoPolygon(const QList<QGeoCoordinate> &path)
-: QGeoShape(new QGeoPolygonPrivate(QGeoShape::PolygonType, path))
+: QGeoShape(new QGeoPolygonPrivate(path))
{
initPolygonConversions();
}
@@ -142,7 +142,7 @@ QGeoPolygon::QGeoPolygon(const QGeoShape &other)
{
initPolygonConversions();
if (type() != QGeoShape::PolygonType)
- d_ptr = new QGeoPolygonPrivate(QGeoShape::PolygonType);
+ d_ptr = new QGeoPolygonPrivate();
}
/*!
@@ -432,4 +432,255 @@ int QGeoPolygon::holesCount() const
return d->holesCount();
}
+/*******************************************************************************
+ *
+ * QGeoPathPrivate & friends
+ *
+*******************************************************************************/
+
+QGeoPolygonPrivate::QGeoPolygonPrivate()
+: QGeoPathPrivate()
+{
+ type = QGeoShape::PolygonType;
+}
+
+QGeoPolygonPrivate::QGeoPolygonPrivate(const QList<QGeoCoordinate> &path)
+: QGeoPathPrivate(path)
+{
+ type = QGeoShape::PolygonType;
+}
+
+QGeoPolygonPrivate::~QGeoPolygonPrivate() {}
+
+QGeoShapePrivate *QGeoPolygonPrivate::clone() const
+{
+ return new QGeoPolygonPrivate(*this);
+}
+
+bool QGeoPolygonPrivate::isValid() const
+{
+ return path().size() > 2;
+}
+
+bool QGeoPolygonPrivate::contains(const QGeoCoordinate &coordinate) const
+{
+ return polygonContains(coordinate);
+}
+
+inline static void translatePoly( QList<QGeoCoordinate> &m_path,
+ QList<QList<QGeoCoordinate>> &m_holesList,
+ QGeoRectangle &m_bbox,
+ double degreesLatitude,
+ double degreesLongitude,
+ double m_maxLati,
+ double m_minLati)
+{
+ if (degreesLatitude > 0.0)
+ degreesLatitude = qMin(degreesLatitude, 90.0 - m_maxLati);
+ else
+ degreesLatitude = qMax(degreesLatitude, -90.0 - m_minLati);
+ for (QGeoCoordinate &p: m_path) {
+ p.setLatitude(p.latitude() + degreesLatitude);
+ p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
+ }
+ if (!m_holesList.isEmpty()){
+ for (QList<QGeoCoordinate> &hole: m_holesList){
+ for (QGeoCoordinate &holeVertex: hole){
+ holeVertex.setLatitude(holeVertex.latitude() + degreesLatitude);
+ holeVertex.setLongitude(QLocationUtils::wrapLong(holeVertex.longitude() + degreesLongitude));
+ }
+ }
+ }
+ m_bbox.translate(degreesLatitude, degreesLongitude);
+}
+
+void QGeoPolygonPrivate::translate(double degreesLatitude, double degreesLongitude)
+{
+ // Need min/maxLati, so update bbox
+ QVector<double> m_deltaXs;
+ double m_minX, m_maxX, m_minLati, m_maxLati;
+ m_bboxDirty = false;
+ computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
+
+ translatePoly(m_path, m_holesList, m_bbox, degreesLatitude, degreesLongitude, m_maxLati, m_minLati);
+}
+
+bool QGeoPolygonPrivate::operator==(const QGeoShapePrivate &other) const
+{
+ if (!QGeoShapePrivate::operator==(other)) // checks type
+ return false;
+
+ const QGeoPolygonPrivate &otherPath = static_cast<const QGeoPolygonPrivate &>(other);
+ if (m_path.size() != otherPath.m_path.size()
+ || m_holesList.size() != otherPath.m_holesList.size())
+ return false;
+ return m_path == otherPath.m_path && m_holesList == otherPath.m_holesList;
+}
+
+void QGeoPolygonPrivate::addHole(const QList<QGeoCoordinate> &holePath)
+{
+ for (const QGeoCoordinate &holeVertex: holePath)
+ if (!holeVertex.isValid())
+ return;
+
+ m_holesList << holePath;
+ // ToDo: mark clipper dirty when hole caching gets added
+}
+
+const QList<QGeoCoordinate> QGeoPolygonPrivate::holePath(int index) const
+{
+ return m_holesList.at(index);
+}
+
+void QGeoPolygonPrivate::removeHole(int index)
+{
+ if (index < 0 || index >= m_holesList.size())
+ return;
+
+ m_holesList.removeAt(index);
+ // ToDo: mark clipper dirty when hole caching gets added
+}
+
+int QGeoPolygonPrivate::holesCount() const
+{
+ return m_holesList.size();
+}
+
+bool QGeoPolygonPrivate::polygonContains(const QGeoCoordinate &coordinate) const
+{
+ if (m_clipperDirty)
+ const_cast<QGeoPolygonPrivate *>(this)->updateClipperPath(); // this one updates bbox too if needed
+
+ QDoubleVector2D coord = QWebMercator::coordToMercator(coordinate);
+ double tlx = QWebMercator::coordToMercator(m_bbox.topLeft()).x();
+ if (coord.x() < tlx)
+ coord.setX(coord.x() + 1.0);
+
+ IntPoint intCoord = QClipperUtils::toIntPoint(coord);
+ if (!c2t::clip2tri::pointInPolygon(intCoord, m_clipperPath))
+ return false;
+
+ // else iterates the holes List checking whether the point is contained inside the holes
+ for (const QList<QGeoCoordinate> &holePath : qAsConst(m_holesList)) {
+ // ToDo: cache these
+ QGeoPolygon holePolygon;
+ holePolygon.setPath(holePath);
+ // QGeoPath holeBoundary;
+ // holeBoundary.setPath(holePath);
+
+ if (holePolygon.contains(coordinate)
+ // && !(holeBoundary.contains(coordinate))
+ )
+ return false;
+ }
+ return true;
+}
+
+void QGeoPolygonPrivate::markDirty()
+{
+ m_bboxDirty = m_clipperDirty = true;
+}
+
+void QGeoPolygonPrivate::updateClipperPath()
+{
+ if (m_bboxDirty)
+ computeBoundingBox();
+ m_clipperDirty = false;
+ double tlx = QWebMercator::coordToMercator(m_bbox.topLeft()).x();
+ QList<QDoubleVector2D> preservedPath;
+ for (const QGeoCoordinate &c : m_path) {
+ QDoubleVector2D crd = QWebMercator::coordToMercator(c);
+ if (crd.x() < tlx)
+ crd.setX(crd.x() + 1.0);
+ preservedPath << crd;
+ }
+ m_clipperPath = QClipperUtils::qListToPath(preservedPath);
+}
+
+QGeoPolygonPrivateEager::QGeoPolygonPrivateEager() : QGeoPolygonPrivate()
+{
+ m_bboxDirty = false; // never dirty on the eager version
+}
+
+QGeoPolygonPrivateEager::QGeoPolygonPrivateEager(const QList<QGeoCoordinate> &path) : QGeoPolygonPrivate(path)
+{
+ m_bboxDirty = false; // never dirty on the eager version
+}
+
+QGeoPolygonPrivateEager::~QGeoPolygonPrivateEager()
+{
+
+}
+
+QGeoShapePrivate *QGeoPolygonPrivateEager::clone() const
+{
+ return new QGeoPolygonPrivate(*this);
+}
+
+void QGeoPolygonPrivateEager::translate(double degreesLatitude, double degreesLongitude)
+{
+ translatePoly(m_path, m_holesList, m_bbox, degreesLatitude, degreesLongitude, m_maxLati, m_minLati);
+}
+
+void QGeoPolygonPrivateEager::markDirty()
+{
+ m_clipperDirty = true;
+ computeBoundingBox();
+}
+
+void QGeoPolygonPrivateEager::addCoordinate(const QGeoCoordinate &coordinate)
+{
+ if (!coordinate.isValid())
+ return;
+ m_path.append(coordinate);
+ m_clipperDirty = true;
+ updateBoundingBox(); // do not markDirty as it uses computeBoundingBox instead
+}
+
+void QGeoPolygonPrivateEager::computeBoundingBox()
+{
+ computeBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
+}
+
+void QGeoPolygonPrivateEager::updateBoundingBox()
+{
+ updateBBox(m_path, m_deltaXs, m_minX, m_maxX, m_minLati, m_maxLati, m_bbox);
+}
+
+QGeoPolygonEager::QGeoPolygonEager() : QGeoPolygon()
+{
+ initPolygonConversions();
+ d_ptr = new QGeoPolygonPrivateEager;
+}
+
+QGeoPolygonEager::QGeoPolygonEager(const QList<QGeoCoordinate> &path) : QGeoPolygon()
+{
+ initPolygonConversions();
+ d_ptr = new QGeoPolygonPrivateEager(path);
+}
+
+QGeoPolygonEager::QGeoPolygonEager(const QGeoPolygon &other) : QGeoPolygon()
+{
+ initPolygonConversions();
+ // without being able to dynamic_cast the d_ptr, only way to be sure is to reconstruct a new QGeoPolygonPrivateEager
+ d_ptr = new QGeoPolygonPrivateEager;
+ setPath(other.path());
+ for (int i = 0; i < other.holesCount(); i++)
+ addHole(other.holePath(i));
+}
+
+QGeoPolygonEager::QGeoPolygonEager(const QGeoShape &other) : QGeoPolygon()
+{
+ initPolygonConversions();
+ if (other.type() == QGeoShape::PolygonType)
+ *this = QGeoPolygonEager(QGeoPolygon(other));
+ else
+ d_ptr = new QGeoPolygonPrivateEager;
+}
+
+QGeoPolygonEager::~QGeoPolygonEager()
+{
+
+}
+
QT_END_NAMESPACE
diff --git a/src/positioning/qgeopolygon.h b/src/positioning/qgeopolygon.h
index ccc4b98b..8becda8f 100644
--- a/src/positioning/qgeopolygon.h
+++ b/src/positioning/qgeopolygon.h
@@ -46,8 +46,7 @@
QT_BEGIN_NAMESPACE
class QGeoCoordinate;
-class QGeoPathPrivate;
-typedef QGeoPathPrivate QGeoPolygonPrivate;
+class QGeoPolygonPrivate;
class Q_POSITIONING_EXPORT QGeoPolygon : public QGeoShape
{
diff --git a/src/positioning/qgeopolygon_p.h b/src/positioning/qgeopolygon_p.h
new file mode 100644
index 00000000..d28fcc6e
--- /dev/null
+++ b/src/positioning/qgeopolygon_p.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtPositioning module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QGEOPOLYGON_P_H
+#define QGEOPOLYGON_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 <QtPositioning/private/qgeopath_p.h>
+#include <QtPositioning/qgeopolygon.h>
+
+QT_BEGIN_NAMESPACE
+
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPolygonPrivate : public QGeoPathPrivate
+{
+public:
+ QGeoPolygonPrivate();
+ QGeoPolygonPrivate(const QList<QGeoCoordinate> &path);
+ ~QGeoPolygonPrivate();
+
+// QGeoShape API
+ virtual QGeoShapePrivate *clone() const override;
+ virtual bool isValid() const override;
+ virtual bool contains(const QGeoCoordinate &coordinate) const override;
+ virtual void translate(double degreesLatitude, double degreesLongitude) override;
+ virtual bool operator==(const QGeoShapePrivate &other) const override;
+
+// QGeoPath API
+ virtual void markDirty() override;
+
+// QGeoPolygonPrivate API
+ int holesCount() const;
+ bool polygonContains(const QGeoCoordinate &coordinate) const;
+ const QList<QGeoCoordinate> holePath(int index) const;
+
+ virtual void addHole(const QList<QGeoCoordinate> &holePath);
+ virtual void removeHole(int index);
+ virtual void updateClipperPath();
+
+// data members
+ bool m_clipperDirty = true;
+ QList<QList<QGeoCoordinate>> m_holesList;
+ QtClipperLib::Path m_clipperPath;
+};
+
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPolygonPrivateEager : public QGeoPolygonPrivate
+{
+public:
+ QGeoPolygonPrivateEager();
+ QGeoPolygonPrivateEager(const QList<QGeoCoordinate> &path);
+ ~QGeoPolygonPrivateEager();
+
+// QGeoShape API
+ virtual QGeoShapePrivate *clone() const override;
+ virtual void translate(double degreesLatitude, double degreesLongitude) override;
+
+// QGeoPath API
+ virtual void markDirty() override;
+ virtual void addCoordinate(const QGeoCoordinate &coordinate) override;
+ virtual void computeBoundingBox() override;
+
+// QGeoPolygonPrivate API
+
+// *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 QGeoPolygonPrivateEager and injecting it into QGeoPolygons via operator=
+class Q_POSITIONING_PRIVATE_EXPORT QGeoPolygonEager : public QGeoPolygon
+{
+ Q_GADGET
+public:
+
+ QGeoPolygonEager();
+ QGeoPolygonEager(const QList<QGeoCoordinate> &path);
+ QGeoPolygonEager(const QGeoPolygon &other);
+ QGeoPolygonEager(const QGeoShape &other);
+ ~QGeoPolygonEager();
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOPOLYGON_P_H
diff --git a/src/positioning/qgeorectangle.cpp b/src/positioning/qgeorectangle.cpp
index 337b4c76..bb2debcf 100644
--- a/src/positioning/qgeorectangle.cpp
+++ b/src/positioning/qgeorectangle.cpp
@@ -804,7 +804,8 @@ void QGeoRectangle::extendRectangle(const QGeoCoordinate &coordinate)
QGeoRectangle QGeoRectangle::united(const QGeoRectangle &rectangle) const
{
QGeoRectangle result(*this);
- result |= rectangle;
+ if (rectangle.isValid())
+ result |= rectangle;
return result;
}
diff --git a/src/positioning/qgeoshape.cpp b/src/positioning/qgeoshape.cpp
index d17f9eea..b1d310af 100644
--- a/src/positioning/qgeoshape.cpp
+++ b/src/positioning/qgeoshape.cpp
@@ -449,6 +449,6 @@ QDataStream &operator>>(QDataStream &stream, QGeoShape &shape)
}
#endif
-#include "moc_qgeoshape.cpp"
-
QT_END_NAMESPACE
+
+#include "moc_qgeoshape.cpp"
diff --git a/src/positioning/qdeclarativegeoaddress.cpp b/src/positioningquick/qdeclarativegeoaddress.cpp
index 470a4c12..470a4c12 100644
--- a/src/positioning/qdeclarativegeoaddress.cpp
+++ b/src/positioningquick/qdeclarativegeoaddress.cpp
diff --git a/src/positioning/qdeclarativegeoaddress_p.h b/src/positioningquick/qdeclarativegeoaddress_p.h
index 3285cea9..dd814978 100644
--- a/src/positioning/qdeclarativegeoaddress_p.h
+++ b/src/positioningquick/qdeclarativegeoaddress_p.h
@@ -53,10 +53,11 @@
#include <QtCore/QObject>
#include <QtPositioning/QGeoAddress>
+#include <QtPositioningQuick/private/qpositioningquickglobal_p.h>
QT_BEGIN_NAMESPACE
-class Q_POSITIONING_EXPORT QDeclarativeGeoAddress : public QObject
+class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativeGeoAddress : public QObject
{
Q_OBJECT
diff --git a/src/positioning/qdeclarativegeolocation.cpp b/src/positioningquick/qdeclarativegeolocation.cpp
index 9e3b71e5..c06fcff2 100644
--- a/src/positioning/qdeclarativegeolocation.cpp
+++ b/src/positioningquick/qdeclarativegeolocation.cpp
@@ -75,15 +75,24 @@ QT_USE_NAMESPACE
\endcode
*/
+/*!
+ \qmlproperty VariantMap QDeclarativeGeoLocation::extendedAttributes
+
+ This property holds the extended attributes for this Location.
+ Extended attributes are backend-dependent and can be location-dependent.
+
+ \since 5.13
+*/
+
QDeclarativeGeoLocation::QDeclarativeGeoLocation(QObject *parent)
-: QObject(parent), m_address(0)
+: QObject(parent)
{
setLocation(QGeoLocation());
}
QDeclarativeGeoLocation::QDeclarativeGeoLocation(const QGeoLocation &src, QObject *parent)
-: QObject(parent), m_address(0)
+: QObject(parent)
{
setLocation(src);
}
@@ -109,6 +118,7 @@ void QDeclarativeGeoLocation::setLocation(const QGeoLocation &src)
setCoordinate(src.coordinate());
setBoundingBox(src.boundingBox());
+ setProperty("extendedAttributes", src.extendedAttributes());
}
QGeoLocation QDeclarativeGeoLocation::location() const
@@ -117,6 +127,7 @@ QGeoLocation QDeclarativeGeoLocation::location() const
retValue.setAddress(m_address ? m_address->address() : QGeoAddress());
retValue.setCoordinate(m_coordinate);
retValue.setBoundingBox(m_boundingBox);
+ retValue.setExtendedAttributes(m_extendedAttributes);
return retValue;
}
diff --git a/src/positioning/qdeclarativegeolocation_p.h b/src/positioningquick/qdeclarativegeolocation_p.h
index a02d7b45..2d604ea5 100644
--- a/src/positioning/qdeclarativegeolocation_p.h
+++ b/src/positioningquick/qdeclarativegeolocation_p.h
@@ -52,13 +52,15 @@
//
#include <QtCore/QObject>
+#include <QtCore/QVariantMap>
#include <QtPositioning/QGeoLocation>
#include <QtPositioning/qgeorectangle.h>
-#include <QtPositioning/private/qdeclarativegeoaddress_p.h>
+#include <QtPositioningQuick/private/qdeclarativegeoaddress_p.h>
+#include <QtPositioningQuick/private/qpositioningquickglobal_p.h>
QT_BEGIN_NAMESPACE
-class Q_POSITIONING_EXPORT QDeclarativeGeoLocation : public QObject
+class Q_POSITIONINGQUICK_PRIVATE_EXPORT QDeclarativeGeoLocation : public QObject
{
Q_OBJECT
@@ -66,6 +68,7 @@ class Q_POSITIONING_EXPORT QDeclarativeGeoLocation : public QObject
Q_PROPERTY(QDeclarativeGeoAddress *address READ address WRITE setAddress NOTIFY addressChanged)
Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged)
Q_PROPERTY(QGeoRectangle boundingBox READ boundingBox WRITE setBoundingBox NOTIFY boundingBoxChanged)
+ Q_PROPERTY(QVariantMap extendedAttributes MEMBER m_extendedAttributes NOTIFY extendedAttributesChanged REVISION 13)
public:
explicit QDeclarativeGeoLocation(QObject *parent = 0);
@@ -87,11 +90,13 @@ Q_SIGNALS:
void addressChanged();
void coordinateChanged();
void boundingBoxChanged();
+ void extendedAttributesChanged();
private:
- QDeclarativeGeoAddress *m_address;
+ QDeclarativeGeoAddress *m_address = nullptr;
QGeoRectangle m_boundingBox;
QGeoCoordinate m_coordinate;
+ QVariantMap m_extendedAttributes;
};
QT_END_NAMESPACE
diff --git a/tests/auto/declarative_core/tst_geocoding.qml b/tests/auto/declarative_core/tst_geocoding.qml
index 1eadf870..16843528 100644
--- a/tests/auto/declarative_core/tst_geocoding.qml
+++ b/tests/auto/declarative_core/tst_geocoding.qml
@@ -272,6 +272,14 @@ Item {
]
}
+ Plugin {
+ id: extendedPlugin;
+ name: "qmlgeo.test.plugin";
+ allowExperimental: true
+ PluginParameter { name: "finishRequestImmediately"; value: false}
+ PluginParameter { name: "includeExtendedData"; value: true }
+ }
+
GeocodeModel {id: testModel; plugin: testPlugin2}
SignalSpy {id: locationsSpy; target: testModel; signalName: "locationsChanged"}
SignalSpy {id: countSpy; target: testModel; signalName: "countChanged"}
@@ -297,6 +305,9 @@ Item {
GeocodeModel {id: automaticModel; plugin: autoPlugin; query: automaticAddress1; autoUpdate: true}
SignalSpy {id: automaticLocationsSpy; target: automaticModel; signalName: "locationsChanged"}
+ GeocodeModel {id: extendedModel; plugin: extendedPlugin; query: automaticAddress1; autoUpdate: true}
+ SignalSpy {id: extendedLocationsSpy; target: extendedModel; signalName: "locationsChanged"}
+
TestCase {
name: "GeocodeModelGeocoding"
function clear_slack_model() {
@@ -546,6 +557,19 @@ Item {
compare (automaticModel.count, 3)
}
+ function test_geocode_extended_attributes() {
+ compare (extendedModel.count, 6) // should be something already
+ compare (extendedLocationsSpy.count, 3)
+ compare(extendedModel.get(0).extendedAttributes
+ ["QGeoCodingManagerEngineTest_locationExtendedAttribute"], 42)
+ // change query and its contents and verify that autoupdate occurs
+ extendedModel.query = automaticCoordinate1
+ tryCompare(extendedLocationsSpy, "count", 4)
+ compare (extendedModel.count, 3)
+ compare(extendedModel.get(0).extendedAttributes
+ ["QGeoCodingManagerEngineTest_locationExtendedAttribute"], 42)
+ }
+
function test_delayed_geocode() {
// basic delayed response
slackModel.reset()
diff --git a/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h b/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h
index ecbb60d1..5a8ff451 100644
--- a/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h
+++ b/tests/auto/geotestplugin/qgeocodingmanagerengine_test.h
@@ -35,20 +35,39 @@
#include <QtPositioning/qgeoaddress.h>
#include <QtPositioning/qgeolocation.h>
#include <qgeocodereply.h>
+#include <QtLocation/private/qgeocodereply_p.h>
#include <QtPositioning/QGeoShape>
#include <QTimer>
#include <QDebug>
#include <QTimerEvent>
+#include <QVariantMap>
QT_USE_NAMESPACE
+class GeocodeReplyTestPrivate : public QGeoCodeReplyPrivate
+{
+public:
+ GeocodeReplyTestPrivate()
+ {
+ }
+ ~GeocodeReplyTestPrivate()
+ {
+ }
+ QVariantMap extraData() const override
+ {
+ return m_extraData;
+ }
+
+ QVariantMap m_extraData;
+};
+
class GeocodeReplyTest :public QGeoCodeReply
{
Q_OBJECT
public:
- GeocodeReplyTest(QObject *parent = 0) : QGeoCodeReply (parent) {}
+ GeocodeReplyTest(QObject *parent = 0) : QGeoCodeReply (*new GeocodeReplyTestPrivate, parent) {}
void callAddLocation ( const QGeoLocation & location ) {addLocation(location);}
void callSetError ( Error error, const QString & errorString ) {setError(error, errorString);}
@@ -82,6 +101,11 @@ public:
finishRequestImmediately_ = qvariant_cast<bool>(parameters.value("finishRequestImmediately"));
if (parameters.contains("validateWellKnownValues"))
validateWellKnownValues_ = qvariant_cast<bool>(parameters.value("validateWellKnownValues"));
+ if (parameters.contains("includeExtendedData")) {
+ includeExtendedData_ = qvariant_cast<bool>(parameters.value("includeExtendedData"));
+ extendedLocationData_["QGeoCodingManagerEngineTest_locationExtendedAttribute"] = 42;
+ extendedReplyData_["QGeoCodingManagerEngineTest_extraData"] = 43;
+ }
setLocale(QLocale (QLocale::German, QLocale::Germany));
}
@@ -105,6 +129,8 @@ public:
if (errorCode_ == QGeoCodeReply::NoError)
setLocations(geocodeReply_, searchString, limit, offset);
+ if (includeExtendedData_)
+ injectExtra(geocodeReply_, extendedReplyData_);
if (finishRequestImmediately_) {
// check if we should finish with error
@@ -126,6 +152,8 @@ public:
geocodeReply_ = new GeocodeReplyTest();
connect(geocodeReply_, SIGNAL(aborted()), this, SLOT(requestAborted()));
geocodeReply_->callSetViewport(bounds);
+ if (includeExtendedData_)
+ injectExtra(geocodeReply_, extendedReplyData_);
if (address.street().startsWith("error")) {
errorString_ = address.street();
@@ -184,6 +212,8 @@ public:
address.setStreet(searchString);
address.setCounty(QString::number(offset));
location.setAddress(address);
+ if (includeExtendedData_)
+ injectExtra(location, extendedLocationData_);
reply->callAddLocation(location);
}
}
@@ -195,6 +225,8 @@ public:
for (int i = 0; i < count; ++i) {
QGeoLocation location;
location.setAddress(address);
+ if (includeExtendedData_)
+ injectExtra(location, extendedLocationData_);
reply->callAddLocation(location);
}
}
@@ -204,6 +236,8 @@ public:
for (int i = 0; i < coordinate.longitude(); ++i) {
QGeoLocation location;
location.setCoordinate(coordinate);
+ if (includeExtendedData_)
+ injectExtra(location, extendedLocationData_);
reply->callAddLocation(location);
}
}
@@ -215,6 +249,8 @@ public:
setLocations(geocodeReply_, coordinate);
geocodeReply_->callSetViewport(bounds);
+ if (includeExtendedData_)
+ injectExtra(geocodeReply_, extendedReplyData_);
if (coordinate.latitude() > 70) {
errorString_ = "error";
@@ -256,7 +292,20 @@ protected:
emit finished(geocodeReply_);
}
+ static void injectExtra(QGeoCodeReply *reply, const QVariantMap &extra)
+ {
+ GeocodeReplyTestPrivate *replyPrivate
+ = static_cast<GeocodeReplyTestPrivate *>(QGeoCodeReplyPrivate::get(*reply));
+ replyPrivate->m_extraData = extra;
+ }
+
+ static void injectExtra(QGeoLocation &location, const QVariantMap &extra)
+ {
+ location.setExtendedAttributes(extra);
+ }
+
private:
+ bool includeExtendedData_ = false;
bool validateWellKnownValues_;
bool finishRequestImmediately_;
bool supported_;
@@ -264,6 +313,8 @@ private:
int timerId_;
QGeoCodeReply::Error errorCode_;
QString errorString_;
+ QVariantMap extendedLocationData_;
+ QVariantMap extendedReplyData_;
};
#endif
diff --git a/tests/auto/qgeolocation/tst_qgeolocation.cpp b/tests/auto/qgeolocation/tst_qgeolocation.cpp
index 9e40b0b0..bb1f47f9 100644
--- a/tests/auto/qgeolocation/tst_qgeolocation.cpp
+++ b/tests/auto/qgeolocation/tst_qgeolocation.cpp
@@ -57,6 +57,7 @@ void tst_QGeoLocation::constructor()
QCOMPARE(m_location.address(), m_address);
QCOMPARE(m_location.coordinate(), m_coordinate);
QCOMPARE(m_location.boundingBox(), m_viewport);
+ QCOMPARE(m_location.extendedAttributes(), m_extendedAttributes);
}
void tst_QGeoLocation::copy_constructor()
@@ -123,6 +124,16 @@ void tst_QGeoLocation::viewport()
QVERIFY(m_location.boundingBox() != qgeoboundingboxcopy);
}
+void tst_QGeoLocation::extendedAttributes()
+{
+ m_extendedAttributes = QVariantMap({{ "foo" , 42 }});
+ m_location.setExtendedAttributes(m_extendedAttributes);
+ QCOMPARE(m_location.extendedAttributes(), m_extendedAttributes);
+
+ m_extendedAttributes["foo"] = 41;
+ QVERIFY(m_location.extendedAttributes() != m_extendedAttributes);
+}
+
void tst_QGeoLocation::operators()
{
QGeoAddress qgeoaddresscopy;
@@ -131,6 +142,7 @@ void tst_QGeoLocation::operators()
qgeoaddresscopy.setCountryCode("DEU");
QGeoCoordinate qgeocoordinatecopy (32.324 , 41.324 , 24.55);
+ QVariantMap extendedAttributesCopy {{ "foo" , 42 }};
m_address.setCity("Madrid");
m_address.setCountry("Spain");
@@ -140,8 +152,11 @@ void tst_QGeoLocation::operators()
m_coordinate.setLongitude(38.43443);
m_coordinate.setAltitude(634.21);
+ m_extendedAttributes["foo"] = 43;
+
m_location.setAddress(m_address);
m_location.setCoordinate(m_coordinate);
+ m_location.setExtendedAttributes(m_extendedAttributes);
//Create a copy and see that they are the same
QGeoLocation qgeolocationcopy(m_location);
@@ -152,9 +167,15 @@ void tst_QGeoLocation::operators()
qgeolocationcopy.setAddress(qgeoaddresscopy);
QVERIFY(!(m_location == qgeolocationcopy));
QVERIFY(m_location != qgeolocationcopy);
+ qgeolocationcopy.setAddress(m_address);
qgeolocationcopy.setCoordinate(qgeocoordinatecopy);
QVERIFY(!(m_location == qgeolocationcopy));
QVERIFY(m_location != qgeolocationcopy);
+ qgeolocationcopy.setCoordinate(m_coordinate);
+ qgeolocationcopy.setExtendedAttributes(extendedAttributesCopy);
+ QVERIFY(!(m_location == qgeolocationcopy));
+ QVERIFY(m_location != qgeolocationcopy);
+
//delete qgeolocationcopy;
//Asign and test that they are the same
@@ -195,6 +216,8 @@ void tst_QGeoLocation::comparison()
otherLocation.setCoordinate(QGeoCoordinate(12,13));
} else if (dataField == "viewport"){
otherLocation.setBoundingBox(QGeoRectangle(QGeoCoordinate(1,2), 0.5,0.5));
+ } else if (dataField == "extendedAttributes"){
+ otherLocation.setExtendedAttributes(QVariantMap({{"foo", 44}}));
} else {
qFatal("Unknown data field to test");
}
@@ -209,6 +232,7 @@ void tst_QGeoLocation::comparison_data()
QTest::newRow("no change") << "no change";
QTest::newRow("address") << "address";
QTest::newRow("coordinate") << "coordinate";
+ QTest::newRow("extendedAttributes") << "extendedAttributes";
}
void tst_QGeoLocation::isEmpty()
@@ -222,6 +246,8 @@ void tst_QGeoLocation::isEmpty()
boundingBox.setBottomRight(QGeoCoordinate(-1, 1));
QVERIFY(!boundingBox.isEmpty());
+ QVariantMap extendedAttributes({{"foo", 11}});
+
QGeoLocation location;
QVERIFY(location.isEmpty());
@@ -243,6 +269,12 @@ void tst_QGeoLocation::isEmpty()
QVERIFY(!location.isEmpty());
location.setBoundingBox(QGeoRectangle());
QVERIFY(location.isEmpty());
+
+ // extended attributes
+ location.setExtendedAttributes(extendedAttributes);
+ QVERIFY(!location.isEmpty());
+ location.setExtendedAttributes(QVariantMap());
+ QVERIFY(location.isEmpty());
}
QTEST_APPLESS_MAIN(tst_QGeoLocation);
diff --git a/tests/auto/qgeolocation/tst_qgeolocation.h b/tests/auto/qgeolocation/tst_qgeolocation.h
index 182cad27..a2bf6649 100644
--- a/tests/auto/qgeolocation/tst_qgeolocation.h
+++ b/tests/auto/qgeolocation/tst_qgeolocation.h
@@ -62,6 +62,7 @@ private Q_SLOTS:
void address();
void coordinate();
void viewport();
+ void extendedAttributes();
void operators();
void comparison();
void comparison_data();
@@ -74,6 +75,7 @@ private:
QGeoAddress m_address;
QGeoCoordinate m_coordinate;
QGeoRectangle m_viewport;
+ QVariantMap m_extendedAttributes;
};
Q_DECLARE_METATYPE( QGeoCoordinate::CoordinateFormat);
diff --git a/tests/plugins/declarativetestplugin/locationtest.cpp b/tests/plugins/declarativetestplugin/locationtest.cpp
index 44e74e86..f5efd423 100644
--- a/tests/plugins/declarativetestplugin/locationtest.cpp
+++ b/tests/plugins/declarativetestplugin/locationtest.cpp
@@ -62,7 +62,6 @@ public:
}
};
-#include "locationtest.moc"
-
QT_END_NAMESPACE
+#include "locationtest.moc"