summaryrefslogtreecommitdiff
path: root/src/location/labs
diff options
context:
space:
mode:
Diffstat (limited to 'src/location/labs')
-rw-r--r--src/location/labs/qdeclarativenavigator.cpp349
-rw-r--r--src/location/labs/qdeclarativenavigator_p.h46
-rw-r--r--src/location/labs/qdeclarativenavigator_p_p.h65
-rw-r--r--src/location/labs/qgeojson.cpp1242
-rw-r--r--src/location/labs/qgeojson_p.h81
-rw-r--r--src/location/labs/qgeotiledmaplabs.cpp37
-rw-r--r--src/location/labs/qgeotiledmaplabs_p.h1
-rw-r--r--src/location/labs/qmapcircleobject.cpp26
-rw-r--r--src/location/labs/qmapcircleobject_p_p.h2
-rw-r--r--src/location/labs/qmapiconobject.cpp55
-rw-r--r--src/location/labs/qmapiconobject_p.h8
-rw-r--r--src/location/labs/qmapiconobject_p_p.h15
-rw-r--r--src/location/labs/qmapobjectview.cpp78
-rw-r--r--src/location/labs/qmapobjectview_p.h2
-rw-r--r--src/location/labs/qmapobjectview_p_p.h15
-rw-r--r--src/location/labs/qmappolygonobject.cpp43
-rw-r--r--src/location/labs/qmappolygonobject_p_p.h7
-rw-r--r--src/location/labs/qmappolylineobject.cpp18
-rw-r--r--src/location/labs/qmappolylineobject_p_p.h2
-rw-r--r--src/location/labs/qmaprouteobject.cpp14
-rw-r--r--src/location/labs/qmaprouteobject_p_p.h2
-rw-r--r--src/location/labs/qsg/qgeomapobjectqsgsupport.cpp6
-rw-r--r--src/location/labs/qsg/qmapcircleobjectqsg.cpp24
-rw-r--r--src/location/labs/qsg/qmapiconobjectqsg.cpp12
-rw-r--r--src/location/labs/qsg/qmapiconobjectqsg_p_p.h2
-rw-r--r--src/location/labs/qsg/qmappolygonobjectqsg.cpp66
-rw-r--r--src/location/labs/qsg/qmappolygonobjectqsg_p_p.h14
-rw-r--r--src/location/labs/qsg/qmappolylineobjectqsg.cpp36
-rw-r--r--src/location/labs/qsg/qmappolylineobjectqsg_p_p.h12
-rw-r--r--src/location/labs/qsg/qmaprouteobjectqsg.cpp5
-rw-r--r--src/location/labs/qsg/qmaprouteobjectqsg_p_p.h1
31 files changed, 2056 insertions, 230 deletions
diff --git a/src/location/labs/qdeclarativenavigator.cpp b/src/location/labs/qdeclarativenavigator.cpp
index 5b98f27f..eccfd082 100644
--- a/src/location/labs/qdeclarativenavigator.cpp
+++ b/src/location/labs/qdeclarativenavigator.cpp
@@ -37,6 +37,7 @@
#include <QtLocation/private/qdeclarativegeoroute_p.h>
#include <QtLocation/private/qdeclarativegeoroutemodel_p.h>
#include <QtLocation/private/qdeclarativegeoroutesegment_p.h>
+#include <QtLocation/qgeoserviceprovider.h>
#include <QtPositioningQuick/private/qdeclarativepositionsource_p.h>
#include <QtQml/qqmlinfo.h>
@@ -157,53 +158,27 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \qmlproperty Route Qt.labs.location::Navigator::currentRoute
+ \qmlproperty enumeration Qt.labs.location::Navigator::error
- This read-only property holds the current route the navigator 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
- off route, the navigation engine might recalculate and start following a
- new route.
+ This read-only property holds the latest error value of the geocoding request.
- \sa Route
-*/
-
-/*!
- \qmlproperty int Qt.labs.location::Navigator::currentSegment
-
- This read-only property holds the index of the current RouteSegment in the \l currentRoute.
-
- \sa RouteSegment
-*/
-
-/*!
- \qmlsignal Qt.labs.location::Navigator::waypointReached(Waypoint waypoint)
-
- This signal is emitted when the waypoint \e waypoint has been reached.
-
- \sa Waypoint
-*/
-
-/*!
- \qmlsignal Qt.labs.location::Navigator::destinationReached()
+ \list
+ \li Navigator.NoError - No error has occurred.
+ \li GeocodeModel.NotSupportedError - Navigation is not supported by the service provider.
+ \li GeocodeModel.ConnectionError - An error occurred while communicating with the service provider.
+ \li GeocodeModel.LoaderError - The geoservice provider library could not be loaded. Setting QT_DEBUG_PLUGINS environment variable may help diagnosing the reason.
+ \li GeocodeModel.UnknownParameterError - An unknown parameter was specified
+ \li GeocodeModel.MissingRequiredParameterError - required parameter was not specified.
+ \li GeocodeModel.UnknownError - An error occurred which does not fit into any of the other categories.
- This signal is emitted when the last waypoint of the route, the destination,
- has been reached.
+ \endlist
*/
QDeclarativeNavigatorPrivate::QDeclarativeNavigatorPrivate(QParameterizableObject *q_)
- : q(q_), m_params(new QDeclarativeNavigatorParams)
-{
-}
-
-void QDeclarativeNavigatorPrivate::updateReadyState()
+ : q(q_), m_params(new QDeclarativeNavigatorParams), m_basicDirections(static_cast<QDeclarativeNavigator *>(q_))
{
- qobject_cast<QDeclarativeNavigator *>(q)->updateReadyState();
}
-
-
QDeclarativeNavigator::QDeclarativeNavigator(QObject *parent)
: QParameterizableObject(parent), d_ptr(new QDeclarativeNavigatorPrivate(this))
{
@@ -238,11 +213,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();
@@ -288,11 +262,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();
@@ -327,18 +300,34 @@ void QDeclarativeNavigator::setTrackPositionSource(bool trackPositionSource)
emit trackPositionSourceChanged(trackPositionSource);
}
-QDeclarativeGeoRoute *QDeclarativeNavigator::currentRoute() const
+QDeclarativeNavigationBasicDirections *QDeclarativeNavigator::directions() const
{
- if (!d_ptr->m_ready || !d_ptr->m_navigator->active())
- return d_ptr->m_params->m_route.data();
- return d_ptr->m_currentRoute.data();
+ return &d_ptr->m_basicDirections;
}
-int QDeclarativeNavigator::currentSegment() const
+QDeclarativeNavigator::NavigationError QDeclarativeNavigator::error() const
{
- if (!d_ptr->m_ready || !d_ptr->m_navigator->active())
- return 0;
- return d_ptr->m_currentSegment;
+ return d_ptr->m_error;
+}
+
+QString QDeclarativeNavigator::errorString() const
+{
+ return d_ptr->m_errorString;
+}
+
+/* !NOT DOCUMENTED YET!
+ \qmlproperty QAbstractNavigator *Qt.labs.location::Navigator::engineHandle
+
+ This property returns a handle to the navigation object created by the engine.
+ This object can carry engine-specific properties, signals and methods, to expose
+ engine-specific features and data.
+
+ \note Using this property leads to writing code that won't work with different plugins.
+*/
+QAbstractNavigator *QDeclarativeNavigator::abstractNavigator() const
+{
+ return d_ptr->m_navigator.data();
+
}
bool QDeclarativeNavigator::active() const
@@ -397,6 +386,10 @@ void QDeclarativeNavigator::stop()
if (d_ptr->m_navigator->active())
d_ptr->m_active = d_ptr->m_navigator->stop();
+
+ // Cached data are cleared in response to signals emitted by m_navigator upon stop().
+ // For example, m_navigator emits currentRouteChanged with an empty route,
+ // and QDeclarativeNavigationBasicDirections reacts by clearing the declarative route.
}
void QDeclarativeNavigator::pluginReady()
@@ -417,26 +410,69 @@ bool QDeclarativeNavigator::ensureEngine()
if (!d_ptr->m_completed || !d_ptr->m_plugin->isAttached())
return false;
- auto manager = d_ptr->m_plugin->sharedGeoServiceProvider()->navigationManager();
- if (manager) {
- d_ptr->m_navigator.reset(manager->createNavigator(d_ptr->m_params));
- if (!d_ptr->m_navigator)
- return false;
- d_ptr->m_navigator->setLocale(manager->locale());
- d_ptr->m_navigator->setMeasurementSystem(manager->measurementSystem());
- 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::currentSegmentChanged, this, &QDeclarativeNavigator::onCurrentSegmentChanged);
- connect(d_ptr->m_navigator.get(), &QAbstractNavigator::activeChanged, this, [this](bool active){
- d_ptr->m_active = active;
- emit activeChanged(active);
- });
- connect(this, &QDeclarativeNavigator::trackPositionSourceChanged, d_ptr->m_navigator.get(), &QAbstractNavigator::setTrackPosition);
- emit navigatorReadyChanged(true);
- return true;
+ QGeoServiceProvider *serviceProvider = d_ptr->m_plugin->sharedGeoServiceProvider();
+ // if m_plugin->isAttached(), serviceProvider cannot be null
+ QNavigationManager *manager = serviceProvider->navigationManager();
+
+ if (serviceProvider->navigationError() != QGeoServiceProvider::NoError) {
+ QDeclarativeNavigator::NavigationError newError = UnknownError;
+ switch (serviceProvider->navigationError()) {
+ case QGeoServiceProvider::NotSupportedError:
+ newError = NotSupportedError; break;
+ case QGeoServiceProvider::UnknownParameterError:
+ newError = UnknownParameterError; break;
+ case QGeoServiceProvider::MissingRequiredParameterError:
+ newError = MissingRequiredParameterError; break;
+ case QGeoServiceProvider::ConnectionError:
+ newError = ConnectionError; break;
+ case QGeoServiceProvider::LoaderError:
+ newError = LoaderError; break;
+ default:
+ break;
+ }
+
+ setError(newError, serviceProvider->navigationErrorString());
+ return false;
}
- return false;
+
+ if (!manager) {
+ setError(NotSupportedError, tr("Plugin does not support navigation."));
+ return false;
+ }
+
+ d_ptr->m_navigator.reset(manager->createNavigator(d_ptr->m_params));
+ if (!d_ptr->m_navigator) {
+ setError(UnknownError, tr("Failed to create a navigator object."));
+ return false;
+ }
+
+ d_ptr->m_navigator->setLocale(manager->locale());
+ d_ptr->m_navigator->setMeasurementSystem(manager->measurementSystem());
+
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::activeChanged, this, [this](bool active){
+ d_ptr->m_active = active;
+ emit activeChanged(active);
+ });
+ connect(this, &QDeclarativeNavigator::trackPositionSourceChanged, d_ptr->m_navigator.get(), &QAbstractNavigator::setTrackPosition);
+
+ // read-only progress info updates
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::waypointReached,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::waypointReached);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::destinationReached,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::destinationReached);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteChanged,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onCurrentRouteChanged);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentRouteLegChanged,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::currentSegmentChanged,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::currentSegmentChanged);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::nextManeuverIconChanged,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::nextManeuverIconChanged);
+ connect(d_ptr->m_navigator.get(), &QAbstractNavigator::progressInformationChanged,
+ &d_ptr->m_basicDirections, &QDeclarativeNavigationBasicDirections::progressInformationChanged);
+
+ emit navigatorReadyChanged(true);
+ return true;
}
void QDeclarativeNavigator::updateReadyState() {
@@ -450,18 +486,175 @@ void QDeclarativeNavigator::updateReadyState() {
emit navigatorReadyChanged(d_ptr->m_ready);
}
-void QDeclarativeNavigator::onCurrentRouteChanged(const QGeoRoute &route)
+void QDeclarativeNavigator::setError(QDeclarativeNavigator::NavigationError error, const QString &errorString)
{
- if (d_ptr->m_currentRoute)
- d_ptr->m_currentRoute->deleteLater();
- d_ptr->m_currentRoute = new QDeclarativeGeoRoute(route, this);
+ d_ptr->m_error = error;
+ d_ptr->m_errorString = errorString;
+ emit errorChanged();
+}
+
+QDeclarativeNavigationBasicDirections::QDeclarativeNavigationBasicDirections(QDeclarativeNavigator *parent)
+: QObject(parent), m_navigator(parent)
+{
+ if (m_navigator)
+ m_navigatorPrivate = m_navigator->d_ptr.data();
+}
+
+/*!
+ \qmlpropertygroup Qt.labs.location::Navigator::directions
+ \qmlproperty Variant Qt.labs.location::Navigator::directions.nextManeuverIcon
+ \qmlproperty real Qt.labs.location::Navigator::directions.distanceToNextManeuver
+ \qmlproperty real Qt.labs.location::Navigator::directions.remainingTravelDistance
+ \qmlproperty real Qt.labs.location::Navigator::directions.remainingTravelDistanceToNextWaypoint
+ \qmlproperty real Qt.labs.location::Navigator::directions.traveledDistance
+ \qmlproperty int Qt.labs.location::Navigator::directions.timeToNextManeuver
+ \qmlproperty int Qt.labs.location::Navigator::directions.remainingTravelTime
+ \qmlproperty int Qt.labs.location::Navigator::directions.remainingTravelTimeToNextWaypoint
+ \qmlproperty int Qt.labs.location::Navigator::directions.traveledTime
+ \qmlproperty Route Qt.labs.location::Navigator::directions.currentRoute
+ \qmlproperty RouteLeg Qt.labs.location::Navigator::directions.currentRouteLeg
+ \qmlproperty int Qt.labs.location::Navigator::directions.currentSegment
+
+ \qmlsignal Qt.labs.location::Navigator::directions.waypointReached(Waypoint waypoint)
+ \qmlsignal Qt.labs.location::Navigator::directions.destinationReached()
+
+ These read-only properties are part of the directions property group.
+ The directions property group holds the navigation progress information
+ that can be used to access the route data and to extract directions.
+
+ \note specific backends might not provide (some of) these information.
+
+ \list
+ \li The \l nextManeuverIcon property holds the next turn icon.
+ \li The \l distanceToNextManeuver property holds the distance to the next maneuver, in meters.
+ \li The \l remainingTravelDistance property holds the remaining travel distance, in meters.
+ \li The \l remainingTravelDistanceToNextWaypoint property holds the remaining travel distance to the next waypoint, in meters.
+ \li The \l traveledDistance property holds the traveled distance, in meters.
+ \li The \l timeToNextManeuver property holds the time to the next maneuver, in milliseconds.
+ \li The \l remainingTravelTime property holds the remaining travel time, in milliseconds.
+ \li The \l remainingTravelTimeToNextWaypoint property holds the remaining travel time to the next waypoint, in milliseconds.
+ \li The \l traveledTime property holds the traveled time, in milliseconds.
+ \li The \l currentRoute property olds 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
+ off route, the navigation engine might recalculate and start following a
+ new route.
+ \li The \l currentRouteSegment 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.
+ \li The \l currentSegment property holds the index of the current RouteSegment in the \l currentRoute.
+ \li The \l waypointReached signal is emitted when the waypoint \e waypoint has been reached.
+ \li The \l destinationReached signal is emitted when the last waypoint of the route, the destination,
+ has been reached.
+ \endlist
+
+ \sa Route, RouteLeg, RouteSegment, Waypoint
+*/
+
+QVariant QDeclarativeNavigationBasicDirections::nextManeuverIcon() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->nextManeuverIcon();
+ return QVariant();
+}
+
+qreal QDeclarativeNavigationBasicDirections::distanceToNextManeuver() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->distanceToNextManeuver();
+ return qQNaN();
+}
+
+qreal QDeclarativeNavigationBasicDirections::remainingTravelDistance() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->remainingTravelDistance();
+ return qQNaN();
+}
+
+qreal QDeclarativeNavigationBasicDirections::remainingTravelDistanceToNextWaypoint() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->remainingTravelDistanceToNextWaypoint();
+ return qQNaN();
+}
+
+qreal QDeclarativeNavigationBasicDirections::traveledDistance() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->traveledDistance();
+ return 0;
+}
+
+int QDeclarativeNavigationBasicDirections::timeToNextManeuver() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->timeToNextManeuver();
+ return -1;
+}
+
+int QDeclarativeNavigationBasicDirections::remainingTravelTime() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->remainingTravelTime();
+ return -1;
+}
+
+int QDeclarativeNavigationBasicDirections::remainingTravelTimeToNextWaypoint() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->remainingTravelTimeToNextWaypoint();
+ return -1;
+}
+
+int QDeclarativeNavigationBasicDirections::traveledTime() const
+{
+ if (m_navigatorPrivate->m_navigator)
+ return m_navigatorPrivate->m_navigator->traveledTime();
+ return 0;
+}
+
+QDeclarativeGeoRoute *QDeclarativeNavigationBasicDirections::currentRoute() const
+{
+ if (!m_navigatorPrivate->m_ready
+ || !m_navigatorPrivate->m_navigator
+ || !m_navigatorPrivate->m_navigator->active())
+ return m_navigatorPrivate->m_params->m_route.data(); // the user-specified route, if any
+ return m_currentRoute;
+}
+
+QDeclarativeGeoRouteLeg *QDeclarativeNavigationBasicDirections::currentRouteLeg() const
+{
+ if (!m_navigatorPrivate->m_ready
+ || !m_navigatorPrivate->m_navigator
+ || !m_navigatorPrivate->m_navigator->active())
+ return nullptr;
+ return m_currentRouteLeg;
+}
+
+int QDeclarativeNavigationBasicDirections::currentSegment() const
+{
+ if (!m_navigatorPrivate->m_ready
+ || !m_navigatorPrivate->m_navigator
+ || !m_navigatorPrivate->m_navigator->active())
+ return 0;
+ return m_navigatorPrivate->m_navigator->currentSegment();
+}
+
+void QDeclarativeNavigationBasicDirections::onCurrentRouteChanged()
+{
+ if (m_currentRoute)
+ m_currentRoute->deleteLater();
+ m_currentRoute = new QDeclarativeGeoRoute(m_navigatorPrivate->m_navigator->currentRoute(), this);
emit currentRouteChanged();
}
-void QDeclarativeNavigator::onCurrentSegmentChanged(int segment)
+void QDeclarativeNavigationBasicDirections::onCurrentRouteLegChanged()
{
- d_ptr->m_currentSegment = segment;
- emit currentSegmentChanged();
+ if (m_currentRouteLeg)
+ m_currentRouteLeg->deleteLater();
+ m_currentRouteLeg = new QDeclarativeGeoRouteLeg(m_navigatorPrivate->m_navigator->currentRouteLeg(), this);
+ emit currentRouteLegChanged();
}
QT_END_NAMESPACE
+
diff --git a/src/location/labs/qdeclarativenavigator_p.h b/src/location/labs/qdeclarativenavigator_p.h
index 13884c41..e12d6ba4 100644
--- a/src/location/labs/qdeclarativenavigator_p.h
+++ b/src/location/labs/qdeclarativenavigator_p.h
@@ -52,6 +52,7 @@
#include <QtQml/qqml.h>
#include <QSharedPointer>
#include <QtLocation/private/qparameterizableobject_p.h>
+#include <QtLocation/qgeoserviceprovider.h>
QT_BEGIN_NAMESPACE
@@ -59,12 +60,16 @@ class QDeclarativeGeoServiceProvider;
class QDeclarativeGeoMap;
class QNavigationManager;
class QDeclarativeGeoRoute;
+class QDeclarativeGeoRouteLeg;
class QDeclarativePositionSource;
class QDeclarativeGeoWaypoint;
class QGeoRoute;
+class QGeoRouteLeg;
class QGeoRouteSegment;
class QDeclarativeNavigatorPrivate;
class QDeclarativeGeoRouteSegment;
+class QDeclarativeNavigationBasicDirections;
+class QAbstractNavigator;
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigator : public QParameterizableObject, public QQmlParserStatus
{
@@ -76,11 +81,28 @@ class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigator : public QParameterizableO
Q_PROPERTY(bool active READ active WRITE setActive NOTIFY activeChanged)
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(int currentSegment READ currentSegment NOTIFY currentSegmentChanged)
+ Q_PROPERTY(QDeclarativeNavigationBasicDirections *directions READ directions CONSTANT)
+ Q_PROPERTY(NavigationError error READ error NOTIFY errorChanged)
+ Q_PROPERTY(QString errorString READ errorString NOTIFY errorChanged)
+ Q_PROPERTY(QAbstractNavigator *engineHandle READ abstractNavigator CONSTANT)
+
Q_INTERFACES(QQmlParserStatus)
public:
+ enum NavigationError {
+ //QGeoServiceProvider related errors start here
+ NoError = QGeoServiceProvider::NoError,
+ NotSupportedError = QGeoServiceProvider::NotSupportedError, //TODO Qt6 consider merge with NotSupportedError
+ ConnectionError = QGeoServiceProvider::ConnectionError, //TODO Qt6 merge with Map's ConnectionError
+ LoaderError = QGeoServiceProvider::LoaderError,
+ UnknownParameterError = QGeoServiceProvider::UnknownParameterError, //TODO Qt6 consider rename UnsupportedOperationError
+ MissingRequiredParameterError = QGeoServiceProvider::MissingRequiredParameterError,
+ //we leave gap for future QGeoCodeReply errors
+
+ // Navigation-specific error should start at 100
+ UnknownError = 100
+ };
+
explicit QDeclarativeNavigator(QObject *parent = nullptr);
~QDeclarativeNavigator();
@@ -112,36 +134,34 @@ public:
void setTrackPositionSource(bool trackPositionSource);
bool trackPositionSource() const;
- QDeclarativeGeoRoute *currentRoute() const;
- int currentSegment() const;
+ QDeclarativeNavigationBasicDirections *directions() const;
+ QAbstractNavigator *abstractNavigator() const;
+
+ NavigationError error() const;
+ QString errorString() const;
signals:
void navigatorReadyChanged(bool ready);
void trackPositionSourceChanged(bool trackPositionSource);
void activeChanged(bool active);
- void waypointReached(const QDeclarativeGeoWaypoint *pos);
- void destinationReached();
void pluginChanged();
void mapChanged();
void routeChanged();
void positionSourceChanged();
- void currentRouteChanged();
- void currentSegmentChanged();
+ void errorChanged();
-private:
+protected:
void pluginReady();
bool ensureEngine();
void updateReadyState();
-
-private slots:
- void onCurrentRouteChanged(const QGeoRoute &route);
- void onCurrentSegmentChanged(int segment);
+ void setError(NavigationError error, const QString &errorString);
private:
QScopedPointer<QDeclarativeNavigatorPrivate> d_ptr;
friend class QDeclarativeNavigatorPrivate;
+ friend class QDeclarativeNavigationBasicDirections;
};
QT_END_NAMESPACE
diff --git a/src/location/labs/qdeclarativenavigator_p_p.h b/src/location/labs/qdeclarativenavigator_p_p.h
index 229ead1e..77fe2ff2 100644
--- a/src/location/labs/qdeclarativenavigator_p_p.h
+++ b/src/location/labs/qdeclarativenavigator_p_p.h
@@ -52,6 +52,7 @@
#include <QtLocation/private/qlocationglobal_p.h>
#include <QtCore/qpointer.h>
#include <QtLocation/qgeoroute.h>
+#include <QtLocation/private/qdeclarativenavigator_p.h>
QT_BEGIN_NAMESPACE
@@ -59,12 +60,69 @@ class QDeclarativeGeoServiceProvider;
class QDeclarativeGeoMap;
class QNavigationManager;
class QDeclarativeGeoRoute;
+class QDeclarativeGeoRouteLeg;
class QDeclarativePositionSource;
class QGeoMapParameter;
class QDeclarativeGeoRouteSegment;
class QParameterizableObject;
class QAbstractNavigator;
+class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigationBasicDirections : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QVariant nextManeuverIcon READ nextManeuverIcon NOTIFY nextManeuverIconChanged)
+ Q_PROPERTY(qreal distanceToNextManeuver READ distanceToNextManeuver NOTIFY progressInformationChanged)
+ Q_PROPERTY(qreal remainingTravelDistance READ remainingTravelDistance NOTIFY progressInformationChanged)
+ Q_PROPERTY(qreal remainingTravelDistanceToNextWaypoint READ remainingTravelDistanceToNextWaypoint NOTIFY progressInformationChanged)
+ Q_PROPERTY(qreal traveledDistance READ traveledDistance NOTIFY progressInformationChanged)
+ Q_PROPERTY(int timeToNextManeuver READ timeToNextManeuver NOTIFY progressInformationChanged)
+ Q_PROPERTY(int remainingTravelTime READ remainingTravelTime NOTIFY progressInformationChanged)
+ Q_PROPERTY(int remainingTravelTimeToNextWaypoint READ remainingTravelTimeToNextWaypoint NOTIFY progressInformationChanged)
+ Q_PROPERTY(int traveledTime READ traveledTime NOTIFY progressInformationChanged)
+ Q_PROPERTY(QDeclarativeGeoRoute *currentRoute READ currentRoute NOTIFY currentRouteChanged)
+ Q_PROPERTY(QDeclarativeGeoRouteLeg *currentRouteLeg READ currentRouteLeg NOTIFY currentRouteChanged)
+ Q_PROPERTY(int currentSegment READ currentSegment NOTIFY currentSegmentChanged)
+
+public:
+ explicit QDeclarativeNavigationBasicDirections(QDeclarativeNavigator *parent);
+
+ QVariant nextManeuverIcon() const;
+ qreal distanceToNextManeuver() const;
+ qreal remainingTravelDistance() const;
+ qreal remainingTravelDistanceToNextWaypoint() const;
+ qreal traveledDistance() const;
+ int timeToNextManeuver() const;
+ int remainingTravelTime() const;
+ int remainingTravelTimeToNextWaypoint() const;
+ int traveledTime() const;
+
+ QDeclarativeGeoRoute *currentRoute() const;
+ QDeclarativeGeoRouteLeg *currentRouteLeg() const;
+ int currentSegment() const;
+
+Q_SIGNALS:
+ void progressInformationChanged();
+ void nextManeuverIconChanged();
+ void currentRouteChanged();
+ void currentRouteLegChanged();
+ void currentSegmentChanged();
+ void waypointReached(const QDeclarativeGeoWaypoint *pos);
+ void destinationReached();
+
+protected slots:
+ void onCurrentRouteChanged();
+ void onCurrentRouteLegChanged();
+
+protected:
+ QDeclarativeNavigator *m_navigator;
+ QDeclarativeNavigatorPrivate *m_navigatorPrivate;
+ QPointer<QDeclarativeGeoRoute> m_currentRoute;
+ QPointer<QDeclarativeGeoRouteLeg> m_currentRouteLeg;
+
+ friend class QDeclarativeNavigator;
+};
+
class Q_LOCATION_PRIVATE_EXPORT QDeclarativeNavigatorParams
{
public:
@@ -81,16 +139,17 @@ class QDeclarativeNavigatorPrivate
public:
QDeclarativeNavigatorPrivate(QParameterizableObject *q_);
- void updateReadyState();
QParameterizableObject *q = nullptr;
QSharedPointer<QDeclarativeNavigatorParams> m_params;
QScopedPointer<QAbstractNavigator> m_navigator;
QDeclarativeGeoServiceProvider *m_plugin = nullptr;
- QPointer<QDeclarativeGeoRoute> m_currentRoute;
- int m_currentSegment = 0;
+ QDeclarativeNavigationBasicDirections m_basicDirections;
+
bool m_active = false;
bool m_completed = false;
bool m_ready = false;
+ QDeclarativeNavigator::NavigationError m_error = QDeclarativeNavigator::NoError;
+ QString m_errorString;
};
QT_END_NAMESPACE
diff --git a/src/location/labs/qgeojson.cpp b/src/location/labs/qgeojson.cpp
new file mode 100644
index 00000000..f7f37661
--- /dev/null
+++ b/src/location/labs/qgeojson.cpp
@@ -0,0 +1,1242 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Julian Sherollari <jdotsh@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore 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$
+**
+****************************************************************************/
+
+#include "qgeojson_p.h"
+#include <qjsonobject.h>
+#include <qjsonvalue.h>
+#include <qjsonarray.h>
+#include <qgeocoordinate.h>
+#include <qgeocircle.h>
+#include <qgeopath.h>
+#include <qgeopolygon.h>
+#include <qtextstream.h>
+
+QT_BEGIN_NAMESPACE
+
+/*! \class QGeoJson
+ \inmodule QtLocation
+ \since 5.13
+
+ QGeoJson class can be used to convert between a GeoJSON document (see the
+ \l {https://en.wikipedia.org/wiki/GeoJSON} {Wikipedia page}, \l
+ {https://tools.ietf.org/html/rfc7946} {RFC}) and a \l
+ {http://doc.qt.io/qt-5/qvariant.html#QVariantList-typedef} {QVariantList}
+ of \l QVariantMap elements ready to be used as Model in a \l MapItemView.
+ WARNING! This private class is part of Qt labs, thus not stable API, it is
+ part of the experimental components of QtLocation. Until it is promoted to
+ public API, it may be subject to source and binary-breaking changes.
+
+ \section2 Importing GeoJSON
+
+ The method \l importGeoJson accepts a \l
+ {http://doc.qt.io/qt-5/qjsondocument.html} {QJsonDocument} from which it
+ extracts a single \l {https://tools.ietf.org/html/rfc7159} {JSON} object,
+ since the GeoJSON RFC expects that a valid GeoJSON Document has in its root
+ a single JSON object. This method doesn't perform any validation on the
+ input. The importer returns a QVariantList containing a single QVariantMap.
+ This map has always at least 2 (key, value) pairs. The first one has \c
+ type as key, and the corresponding value is a string identifying the
+ GeoJSON type. This value can be one of the GeoJSON object types: \c Point,
+ \c MultiPoint, \c LineString, \c MultiLineString, \c Polygon, \c
+ MultiPolygon, \c GeometryCollection, \c FeatureCollection. The second pair
+ has \c data as key, and the corresponding value can be either a QGeoShape
+ or a list, depending on the GeoJSON type. The next section provides details
+ about this node. The \c Feature type is converted into the type of the
+ geometry contained within, with an additional (key, value) pair, where the
+ key is \c properties and the value is a \l QVariantMap. Thus, a feature Map
+ is distinguishable from the corresponding geometry, by looking for a \c
+ properties member.
+
+ \section3 Structure of the data node
+
+ For the single type geometry objects (\c Point, \c LineString, and \c
+ Polygon), the value corresponding to the \c data key is a QGeoShape:
+
+ \list
+ \li When the type is \c Point, the data is a QGeoCircle with the point
+ coordinates stored in the center property.
+
+ For example, the following GeoJSON document contains a \c Point
+ geometry:
+
+ \code
+ {
+ "type" : "Point",
+ "data" : [60.0, 11.0]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : Point
+ data : QGeoCircle({60.000, 11.000}, -1)
+ }
+ \endcode
+
+ \li When the type is \c LineString the data ia a QGeoPath.
+
+ For example, the following GeoJSON document contains a \c LineString
+ geometry:
+
+ \code
+ {
+ "type" : "LineString",
+ "coordinates" : [[13.5, 43],[10.73, 59.92]]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : LineString,
+ data : QGeoPath([{43.000, 13.500}, {59.920, 10.730}])
+ }
+ \endcode
+
+ \li When the type is \c Polygon, the data is a QGeoPolygon (holes are
+ supported).
+
+ For example, the following GeoJSON document contains a \c Polygon
+ geometry:
+
+ \code
+ {
+ "type" : "Polygon",
+ "coordinates" : [
+ [[17.13, 51.11],
+ [30.54, 50.42],
+ [26.70, 58.36],
+ [17.13, 51.11]]
+ ],
+ "bbox" : [60, 60, -60, -60]
+
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : Polygon
+ data : QGeoPolygon([{51.110, 17.130}, {50.420,30.540}, {58.360, 26.700}, {51.110, 17.130}])
+ }
+ \endcode
+
+ \endlist
+
+ For the homogeneously typed multipart geometry objects (\c MultiPoint, \c
+ MultiLineString, \c MultiPolygon) the value corresponding to the \c data
+ key is a QVariantList. Each element of the list is a QVariantMap of one of
+ the above listed types. The elements in this list will be all of the same
+ GeoJSON type:
+
+ \list
+ \li When the type is \c MultiPoint, the data is a List of Points.
+
+ For example, the following GeoJSON document contains a \c MultiPoint
+ geometry:
+
+ \code
+ {
+ "type" : "MultiPoint",
+ "coordinates" : [
+ [11,60],
+ [5.5,60.3],
+ [5.7,58.90]
+ ]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : MultiPoint
+ data : [
+ {
+ type : Point
+ data : QGeoCircle({60.000, 11.000}, -1)
+ },
+ {
+ type : Point
+ data : QGeoCircle({60.300, 5.500}, -1)
+ },
+ {
+ type : Point
+ data : QGeoCircle({58.900, 5.700}, -1)
+ }
+ ]
+ }
+ \endcode
+
+ \li When the type is \c MultiLineString, the data is a List of LineStrings.
+
+ For example, the following GeoJSON document contains a \c MultiLineString
+ geometry:
+
+ \code
+ {
+ "type" : "MultiLineString",
+ "coordinates" : [
+ [[13.5, 43], [10.73, 59.92]],
+ [[9.15, 45], [-3.15, 58.90]]
+ ]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : MultiLineString
+ data : [
+ {
+ type : LineString
+ data : QGeoPath([{45.000, 9.150}, {58.900, -3.150}])
+ },
+ {
+ type : LineString
+ data : QGeoPath([{43.000, 13.500}, {59.920, 10.730}])
+ }
+ ]
+ }
+ \endcode
+
+ \li When the type is \c MultiPolygon, the data is a List of Polygons.
+
+ For example, the following GeoJSON document contains a \c MultiPolygon
+ geometry:
+
+ \code
+ {
+ "type" : "MultiPoint",
+ "coordinates" : [
+ [11,60],
+ [5.5,60.3],
+ [5.7,58.90]
+ ]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : MultiPoint
+ data : [
+ {
+ type : Point
+ data : QGeoCircle({60.000, 11.000}, -1)
+ },
+ {
+ type : Point
+ data : QGeoCircle({60.300, 5.500}, -1)
+ },
+ {
+ type : Point
+ data : QGeoCircle({58.900, 5.700}, -1)
+ }
+ ]
+ }
+ \endcode
+
+ \endlist
+
+ The \c GeometryCollection is a heterogeneous composition of other geometry
+ types. In the resulting QVariantMap, the value of the \c data member is a
+ QVariantList populated by QVariantMaps of various geometries, including the
+ GeometryCollection itself.
+
+ For example, the following \c GeometryCollection:
+
+ \code
+ {
+ "type" : "GeometryCollection",
+ "geometries" : [
+ {
+ "type" : "MultiPoint",
+ "coordinates" : [
+ [11,60], [5.5,60.3], [5.7,58.90]
+ ]
+ },
+ {
+ "type" : "MultiLineString",
+ "coordinates" : [
+ [[13.5, 43], [10.73, 59.92]],
+ [[9.15, 45], [-3.15, 58.90]]
+ ]
+ },
+ {
+ "type" : "MultiPolygon",
+ "coordinates" : [
+ [
+ [[17.13, 51.11],
+ [30.54, 50.42],
+ [26.74, 58.36],
+ [17.13, 51.11]]
+ ],
+ [
+ [[19.84, 41.33],
+ [30.45, 49.26],
+ [17.07, 50.10],
+ [19.84, 41.33]]
+ ]
+ ]
+ }
+ ]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : GeometryCollection
+ data : [
+ {
+ type : MultiPolygon
+ data : [
+ {
+ type : Polygon
+ data : QGeoPolygon([{41.330, 19.840}, {49.260, 30.450}, {50.100, 17.070}, {41.330, 19.840}])
+ }
+ {
+ type : Polygon
+ data : QGeoPolygon([{51.110, 17.130}, {50.420, 30.540}, {58.360, 26.740}, {51.110, 17.130}])
+ }
+ ]
+ }
+ {
+ type : MultiLineString
+ data : [
+ {
+ type : LineString
+ data : QGeoPath([{45.000, 9.150}, {58.900, -3.150}])
+ }
+ {
+ type : LineString
+ data : QGeoPath([{43.000, 13.500}, {59.920, 10.730}])
+ }
+ ]
+ }
+ {
+ type : MultiPoint
+ data : [
+ {
+ type : Point
+ data : QGeoCircle({58.900, 5.700}, -1)
+ },
+ {
+ type : Point
+ data : QGeoCircle({60.300, 5.500}, -1)
+ },
+ {
+ type : Point
+ data : QGeoCircle({60.000, 11.000}, -1)
+ }
+ ]
+ }
+ ]
+ }
+ \endcode
+
+ The \c Feature object, which consists of one of the previous geometries
+ together with related attributes, is structured like one of the 7 above
+ mentioned geometry types, plus a \c properties member. The value of this
+ member is a QVariantMap. The only way to distinguish a Feature from the
+ included geometry is to check if a \c properties node is present in the
+ QVariantMap.
+
+ For example, the following \c Feature:
+
+ \code
+ {
+ "type" : "Feature",
+ "id" : "Poly",
+ "properties" : {
+ "text" : "This is a Feature with a Polygon"
+ },
+ "geometry" : {
+ "type" : "Polygon",
+ "coordinates" : [
+ [[17.13, 51.11],
+ [30.54, 50.42],
+ [26.70, 58.36],
+ [17.13, 51.11]],
+ [[23.46, 54.36],
+ [20.52, 51.91],
+ [28.25, 51.50],
+ [26.80, 54.36],
+ [23.46, 54.36]]
+ ]
+ }
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : Polygon
+ data : QGeoPolygon([{51.110, 17.130}, {50.420,30.540}, {58.360, 26.700}, {51.110, 17.130}])
+ properties : {text : This is a Feature with a Polygon}
+ }
+ \endcode
+
+ The \c FeatureCollection is a composition of Feature objects. The value of
+ the \c data member in a FeatureCollection is a QVariantList populated by
+ Feature type QVariantMaps.
+
+ For example, the following \c FeatureCollection:
+
+ \code
+ {
+ "type" : "FeatureCollection",
+ "features" : [
+ {
+ "type" : "Feature",
+ "id" : "Poly",
+ "properties" : {
+ "text" : "This is a Feature with a Polygon"
+ },
+ "geometry" : {
+ "type" : "Polygon",
+ "coordinates" : [
+ [[17.13, 51.11],
+ [30.54, 50.42],
+ [26.70, 58.36],
+ [17.13, 51.11]],
+ [[23.46, 54.36],
+ [20.52, 51.91],
+ [28.25, 51.50],
+ [26.80, 54.36],
+ [23.46, 54.36]]
+ ]
+ }
+ },
+ {
+ "type" : "Feature",
+ "id" : "MultiLine",
+ "properties" : {
+ "text" : "This is a Feature with a MultiLineString"
+ },
+ "geometry" : {
+ "type" : "MultiLineString",
+ "coordinates" : [
+ [[13.5, 43], [10.73, 59.92]],
+ [[9.15, 45], [-3.15, 58.90]]
+ ]
+ }
+ }
+ ]
+ }
+ \endcode
+
+ it is converted to a QVariantMap with the following structure:
+
+ \code
+ {
+ type : FeatureCollection
+ data : [
+ {
+ type : MultiLineString
+ data : [
+ {
+ type : LineString
+ data : QGeoPath([{45.000, 9.150}, {58.900, -3.150}])
+ }
+ {
+ type : LineString
+ data : QGeoPath([{43.000, 13.500}, {59.920, 10.730}])
+ }
+ ]
+ properties : {text : This is a Feature with a MultiLineString}
+ },
+ {
+ type : Polygon
+ data : QGeoPolygon({51.110, 17.130}, {50.420, 30.540}, {58.360, 26.700}, {51.110, 17.130})
+ properties : {text : This is a Feature with a Polygon}
+ }
+ ]
+ }
+ \endcode
+
+ \section2 Exporting GeoJSON
+
+ The exporter accepts the QVariantList returned by \l {The importer}, and
+ returns a JSON document. The exporter is complementary to the importer
+ because it executes the inverse action.
+
+ \section2 The toString function
+
+ The \l toString outputs, for debugging purposes, the content of a
+ QVariantList structured like \l importGeoJson does, to a QString using a
+ prettyfied format.
+*/
+
+static QGeoCoordinate importPosition(const QVariant &position)
+{
+ QGeoCoordinate returnedCoordinates;
+ const QVariantList positionList = position.value<QVariantList>();
+ for (int i = 0; i < positionList.size(); ++i) { // Iterating Point coordinates arrays
+ switch (i) {
+ case 0:
+ returnedCoordinates.setLongitude(positionList.at(i).toDouble());
+ break;
+ case 1:
+ returnedCoordinates.setLatitude(positionList.at(i).toDouble());
+ break;
+ case 2:
+ returnedCoordinates.setAltitude(positionList.at(i).toDouble());
+ break;
+ default:
+ break;
+ }
+ }
+ return returnedCoordinates;
+}
+
+static QList<QGeoCoordinate> importArrayOfPositions(const QVariant &arrayOfPositions)
+{
+ QList <QGeoCoordinate> returnedCoordinates;
+ const QVariantList positionsList = arrayOfPositions.value<QVariantList>();
+ QGeoCoordinate singlePosition;
+ for (int i = 0; i < positionsList.size(); ++i) { // Iterating the LineString coordinates nested arrays
+ singlePosition = importPosition((positionsList.at(i)));
+ returnedCoordinates.append(singlePosition); // Populating the QList of coordinates
+ }
+ return returnedCoordinates;
+}
+
+static QList<QList<QGeoCoordinate>> importArrayOfArrayOfPositions(const QVariant &arrayOfArrayofPositions)
+{
+ QList<QList<QGeoCoordinate>> returnedCoordinates;
+ const QVariantList positionsList = arrayOfArrayofPositions.value<QVariantList>();
+ QList<QGeoCoordinate> arrayOfPositions;
+ for (int i = 0; i < positionsList.size(); ++i) { // Iterating the Polygon coordinates nested arrays
+ arrayOfPositions = importArrayOfPositions((positionsList.at(i)));
+ returnedCoordinates << arrayOfPositions;
+ }
+ return returnedCoordinates;
+}
+
+static QGeoCircle importPoint(const QVariantMap &inputMap)
+{
+ QGeoCircle returnedObject;
+ QGeoCoordinate center;
+ QVariant valueCoords = inputMap.value(QStringLiteral("coordinates"));
+ center = importPosition(valueCoords);
+ returnedObject.setCenter(center);
+ return returnedObject;
+}
+
+static QGeoPath importLineString(const QVariantMap &inputMap)
+{
+ QGeoPath returnedObject;
+ QList <QGeoCoordinate> coordinatesList;
+ const QVariant valueCoordinates = inputMap.value(QStringLiteral("coordinates"));
+ coordinatesList = importArrayOfPositions(valueCoordinates);
+ returnedObject.setPath(coordinatesList);
+ return returnedObject;
+}
+
+static QGeoPolygon importPolygon(const QVariantMap &inputMap)
+{
+ QGeoPolygon returnedObject;
+ const QVariant valueCoordinates = inputMap.value(QStringLiteral("coordinates"));
+ QList<QList<QGeoCoordinate>> perimeters = importArrayOfArrayOfPositions(valueCoordinates);
+ for (int i = 0; i < perimeters.size(); ++i) { // Import an array of QList<QGeocoordinates>
+ if (i == 0)
+ returnedObject.setPath(perimeters.at(i)); // External perimeter
+ else
+ returnedObject.addHole(perimeters.at(i)); // Inner perimeters
+ }
+ return returnedObject;
+}
+
+static QVariantList importMultiPoint(const QVariantMap &inputMap)
+{
+ QVariantList returnedObject;
+ const QVariantList coordinatesList = inputMap.value(QStringLiteral("coordinates")).value<QVariantList>();
+ QVariantMap singlePointMap;
+ QGeoCircle parsedPoint;
+ for (int i = 0; i < coordinatesList.size(); ++i) { // Iterating MultiPoint coordinates nasted arrays
+ parsedPoint.setCenter(importPosition(coordinatesList.at(i)));
+ singlePointMap.insert(QStringLiteral("type"), QStringLiteral("Point"));
+ singlePointMap.insert(QStringLiteral("data"), QVariant::fromValue(parsedPoint));
+ returnedObject.append(QVariant::fromValue(singlePointMap));
+ }
+ return returnedObject;
+}
+
+static QVariantList importMultiLineString(const QVariantMap &inputMap)
+{
+ QVariantList returnedObject;
+ QGeoPath parsedLineString;
+ const QVariant listCoords = inputMap.value(QStringLiteral("coordinates"));
+ const QVariantList list = listCoords.value<QVariantList>();
+ QVariantMap singleLinestringMap;
+ for (int i = 0; i < list.size(); ++i) { // Iterating the MultiLineString coordinates nasted arrays using importArrayOfPositions
+ singleLinestringMap.clear();
+ const QList <QGeoCoordinate> coordinatesList = importArrayOfPositions(list.at(i));
+ singleLinestringMap.insert(QStringLiteral("type"), QStringLiteral("LineString"));
+ parsedLineString.setPath(coordinatesList);
+ singleLinestringMap.insert(QStringLiteral("data"), QVariant::fromValue(parsedLineString));
+ returnedObject.append(QVariant::fromValue(singleLinestringMap));
+ }
+ return returnedObject;
+}
+
+static QVariantList importMultiPolygon(const QVariantMap &inputMap)
+{
+ QVariantList returnedObject;
+ QGeoPolygon singlePoly;
+ QVariantMap singlePolygonMap;
+ const QVariant valueCoordinates = inputMap.value(QStringLiteral("coordinates"));
+ const QVariantList list = valueCoordinates.value<QVariantList>();
+ for (int i = 0; i < list.size(); ++i) { // Iterating the MultiPolygon coordinates nasted arrays
+ singlePolygonMap.clear();
+ const QList<QList<QGeoCoordinate>> coordinatesList = importArrayOfArrayOfPositions(list.at(i));
+
+ for (int j = 0; j < coordinatesList.size(); ++j) {
+ if (j == 0)
+ singlePoly.setPath(coordinatesList.at(j));
+ else
+ singlePoly.addHole(coordinatesList.at(j));
+ }
+ singlePolygonMap.insert(QStringLiteral("type"), QStringLiteral("Polygon"));
+ singlePolygonMap.insert(QStringLiteral("data"), QVariant::fromValue(singlePoly));
+ returnedObject.append(QVariant::fromValue(singlePolygonMap));
+ }
+ return returnedObject;
+}
+
+static QVariantMap importGeometry(const QVariantMap &inputMap); // Function prototype for a tail recursion
+
+static QVariantList importGeometryCollection(const QVariantMap &inputMap)
+{
+ QVariantList returnedObject;
+ const QVariant listGeometries = inputMap.value(QStringLiteral("geometries"));
+ const QVariantList list = listGeometries.value<QVariantList>(); // QVariantList of heterogeneous composition of the other geometry types
+ for (int i = 0; i < list.size(); ++i) {
+ QVariantMap geometryMap = list.at(i).value<QVariantMap>();
+ QVariantMap geoMap = importGeometry(geometryMap);
+ returnedObject.append(geoMap);
+ }
+ return returnedObject;
+}
+
+static QVariantMap importGeometry(const QVariantMap &inputMap)
+{
+ QVariantMap returnedObject;
+ QString geometryTypes[] = {
+ QStringLiteral("Point"),
+ QStringLiteral("MultiPoint"),
+ QStringLiteral("LineString"),
+ QStringLiteral("MultiLineString"),
+ QStringLiteral("Polygon"),
+ QStringLiteral("MultiPolygon"),
+ QStringLiteral("GeometryCollection")
+ };
+ enum geoTypeSwitch {
+ Point,
+ MultiPoint,
+ LineString,
+ MultiLineString,
+ Polygon,
+ MultiPolygon,
+ GeometryCollection
+ };
+ for (int i = 0; i<7; ++i) {
+ if (inputMap.value(QStringLiteral("type")).value<QString>() == geometryTypes[i]) {
+ switch (i) {
+ case Point: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("Point"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importPoint(inputMap)));
+ break;
+ }
+ case MultiPoint: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("MultiPoint"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importMultiPoint(inputMap)));
+ break;
+ }
+ case LineString: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("LineString"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importLineString(inputMap)));
+ break;
+ }
+ case MultiLineString: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("MultiLineString"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importMultiLineString(inputMap)));
+ break;
+ }
+ case Polygon: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("Polygon"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importPolygon(inputMap)));
+ break;
+ }
+ case MultiPolygon: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("MultiPolygon"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importMultiPolygon(inputMap)));
+ break;
+ }
+ case GeometryCollection: {
+ returnedObject.insert(QStringLiteral("type"), QStringLiteral("GeometryCollection"));
+ returnedObject.insert(QStringLiteral("data"), QVariant::fromValue(importGeometryCollection(inputMap)));
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return returnedObject;
+}
+
+static QVariantList importFeatureCollection(const QVariantMap &inputMap)
+{
+ QVariantList returnedObject;
+ const QVariantList featuresList = inputMap.value(QStringLiteral("features")).value<QVariantList>();
+ for (int i = 0; i < featuresList.size(); ++i) {
+ QVariantMap inputFeatureMap = featuresList.at(i).value<QVariantMap>();
+ QVariantMap singleFeatureMap = importGeometry(inputFeatureMap.value(QStringLiteral("geometry")).value<QVariantMap>());
+ const QVariantMap importedProperties = inputFeatureMap.value(QStringLiteral("properties")).value<QVariantMap>();
+ singleFeatureMap.insert(QStringLiteral("properties"), importedProperties);
+ if (inputFeatureMap.contains(QStringLiteral("id"))) {
+ QVariant importedId = inputFeatureMap.value(QStringLiteral("id")).value<QVariant>();
+ singleFeatureMap.insert(QStringLiteral("id"), importedId);
+ }
+ returnedObject.append(singleFeatureMap);
+ }
+ return returnedObject;
+}
+
+static QJsonValue exportPosition(const QGeoCoordinate &obtainedCoordinates)
+{
+ QJsonValue geoLat = obtainedCoordinates.latitude();
+ QJsonValue geoLong = obtainedCoordinates.longitude();
+ QJsonArray array = {geoLong, geoLat};
+ QJsonValue geoAlt;
+ if (!qIsNaN(obtainedCoordinates.altitude())) {
+ geoAlt = obtainedCoordinates.altitude();
+ array.append(geoAlt);
+ }
+ QJsonValue geoArray = array;
+ return geoArray;
+}
+
+static QJsonValue exportArrayOfPositions(const QList<QGeoCoordinate> &obtainedCoordinatesList)
+{
+ QJsonValue lineCoordinates;
+ QJsonValue multiPosition;
+ QJsonArray arrayPosition;
+ for (int i = 0; i < obtainedCoordinatesList.size(); ++i) {
+ multiPosition = exportPosition(obtainedCoordinatesList.at(i));
+ arrayPosition.append(multiPosition);
+ }
+ lineCoordinates = arrayPosition;
+ return lineCoordinates;
+}
+
+static QJsonValue exportArrayOfArrayOfPositions(const QList<QList<QGeoCoordinate>> &obtainedCoordinates)
+{
+ QJsonValue lineCoordinates;
+ QJsonValue polyCoordinates;
+ QJsonArray arrayPath;
+ for (int i = 0; i < obtainedCoordinates.size(); ++i) {
+ lineCoordinates = exportArrayOfPositions(obtainedCoordinates.at(i));
+ arrayPath.append(lineCoordinates);
+ }
+ polyCoordinates = arrayPath;
+ return polyCoordinates;
+}
+
+static QJsonObject exportPoint(const QVariantMap &pointMap)
+{
+ QJsonObject parsedPoint;
+ QGeoCircle circle = pointMap.value(QStringLiteral("data")).value<QGeoCircle>();
+ parsedPoint.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("Point")));
+ parsedPoint.insert(QStringLiteral("coordinates"), exportPosition(circle.center()));
+ return parsedPoint;
+}
+
+static QJsonObject exportLineString(const QVariantMap &lineStringMap)
+{
+ QJsonObject parsedLineString;
+ QList <QGeoCoordinate> linestringPath = lineStringMap.value(QStringLiteral("data")).value<QGeoPath>().path();
+ parsedLineString.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("LineString")));
+ parsedLineString.insert(QStringLiteral("coordinates"), exportArrayOfPositions(linestringPath));
+ return parsedLineString;
+}
+
+static QJsonObject exportPolygon(const QVariantMap &polygonMap)
+{
+ QVariant polygonVariant = polygonMap.value(QStringLiteral("data"));
+ QJsonObject parsedPolygon;
+ QJsonValue polyCoordinates;
+ QList<QList<QGeoCoordinate>> obtainedCoordinatesPoly;
+ QGeoPolygon parsedPoly = polygonVariant.value<QGeoPolygon>();
+ obtainedCoordinatesPoly << parsedPoly.path();
+ if (parsedPoly.holesCount()!=0)
+ for (int i = 0; i < parsedPoly.holesCount(); ++i) {
+ obtainedCoordinatesPoly << parsedPoly.holePath(i);
+ }
+ polyCoordinates = exportArrayOfArrayOfPositions(obtainedCoordinatesPoly);
+ parsedPolygon.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("Polygon")));
+ parsedPolygon.insert(QStringLiteral("coordinates"), polyCoordinates);
+ return parsedPolygon;
+}
+
+static QJsonObject exportMultiPoint(const QVariantMap &multiPointMap)
+{
+ QJsonObject parsedMultiPoint;
+ QList <QGeoCoordinate> obtainedCoordinatesMP;
+ QVariantList multiCircleVariantList = multiPointMap.value(QStringLiteral("data")).value<QVariantList>();
+ for (const QVariant &exCircleVariantMap: multiCircleVariantList) {
+ obtainedCoordinatesMP << exCircleVariantMap.value<QVariantMap>().value(QStringLiteral("data")).value<QGeoCircle>().center();
+ }
+ QJsonValue multiPosition = exportArrayOfPositions(obtainedCoordinatesMP);
+ parsedMultiPoint.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("MultiPoint")));
+ parsedMultiPoint.insert(QStringLiteral("coordinates"), multiPosition);
+ return parsedMultiPoint;
+}
+
+static QJsonObject exportMultiLineString(const QVariantMap &multiLineStringMap)
+{
+ QJsonObject parsedMultiLineString;
+ QList<QList<QGeoCoordinate>> extractedCoordinatesValue;
+ QVariant multiPathVariant = multiLineStringMap.value(QStringLiteral("data"));
+ QVariantList multiPathList = multiPathVariant.value<QVariantList>();
+ for (int i = 0; i < multiPathList.size(); ++i) {
+ extractedCoordinatesValue << multiPathList.at(i).value<QVariantMap>().value(QStringLiteral("data")).value<QGeoPath>().path();
+ }
+ QJsonValue exportedCoordinatesValue = exportArrayOfArrayOfPositions(extractedCoordinatesValue);
+ parsedMultiLineString.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("MultiLineString")));
+ parsedMultiLineString.insert(QStringLiteral("coordinates"), exportedCoordinatesValue);
+ return parsedMultiLineString;
+}
+
+static QJsonObject exportMultiPolygon(const QVariantMap &multiPolygonMap)
+{
+ QJsonObject parsedMultiPolygon;
+ QJsonValue polyCoordinates;
+ QJsonArray parsedArrayPolygon;
+ QList<QList<QGeoCoordinate>> extractedCoordinatesValue;
+ QVariant multiPolygonVariant = multiPolygonMap.value(QStringLiteral("data"));
+ QVariantList multiPolygonList = multiPolygonVariant.value<QVariantList>();
+ int polyHoles = 0;
+ int currentHole;
+ for (int i = 0; i < multiPolygonList.size(); ++i) { // Start parsing Polygon list
+ extractedCoordinatesValue << multiPolygonList.at(i).value<QVariantMap>().value(QStringLiteral("data")).value<QGeoPolygon>().path(); // Extract external polygon path
+ polyHoles = multiPolygonList.at(i).value<QVariantMap>().value(QStringLiteral("data")).value<QGeoPolygon>().holesCount();
+ if (polyHoles) // Check if the polygon has holes
+ for (currentHole = 0 ; currentHole < polyHoles; currentHole++)
+ extractedCoordinatesValue << multiPolygonList.at(i).value<QVariantMap>().value(QStringLiteral("data")).value<QGeoPolygon>().holePath(currentHole);
+ polyCoordinates = exportArrayOfArrayOfPositions(extractedCoordinatesValue); // Generates QJsonDocument compatible value
+ parsedArrayPolygon.append(polyCoordinates); // Adds one level of nesting in coordinates
+ extractedCoordinatesValue.clear(); // Clears the temporary polygon linear ring storage
+ }
+ QJsonValue exportedCoordinatesNodeValue = parsedArrayPolygon;
+ parsedMultiPolygon.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("MultiPolygon")));
+ parsedMultiPolygon.insert(QStringLiteral("coordinates"), exportedCoordinatesNodeValue);
+ return parsedMultiPolygon;
+}
+
+static QJsonObject exportGeometry(const QVariantMap &geometryMap); // Function prototype
+
+static QJsonObject exportGeometryCollection(const QVariantMap &geometryCollection)
+{
+ QJsonObject parsed;
+ QJsonObject parsedGeometry;
+ QJsonValue valueGeometries;
+ QJsonArray parsedGeometries;
+ QVariantList geometriesList = geometryCollection.value(QStringLiteral("data")).value<QVariantList>();
+ for (int i = 0; i < geometriesList.size(); ++i) {
+ parsedGeometry = exportGeometry(geometriesList.at(i).value<QVariantMap>());
+ valueGeometries = parsedGeometry;
+ parsedGeometries.append(valueGeometries);
+ }
+ QJsonValue exportedGeometriesValue = parsedGeometries;
+ parsed.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("GeometryCollection")));
+ parsed.insert(QStringLiteral("geometries"), exportedGeometriesValue);
+ return parsed;
+}
+
+static QJsonObject exportGeometry(const QVariantMap &geometryMap)
+{
+ QJsonObject exportedGeometry;
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("Point"))
+ exportedGeometry = exportPoint(geometryMap);
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("MultiPoint"))
+ exportedGeometry = exportMultiPoint(geometryMap);
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("LineString"))
+ exportedGeometry = exportLineString(geometryMap);
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("MultiLineString"))
+ exportedGeometry = exportMultiLineString(geometryMap);
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("Polygon"))
+ exportedGeometry = exportPolygon(geometryMap);
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("MultiPolygon"))
+ exportedGeometry = exportMultiPolygon(geometryMap);
+ if (geometryMap.value(QStringLiteral("type")) == QStringLiteral("GeometryCollection"))
+ exportedGeometry = exportGeometryCollection(geometryMap);
+ return exportedGeometry;
+}
+
+static QJsonObject exportFeature(const QVariantMap &featureMap)
+{
+ QJsonObject exportedFeature;
+ QJsonValue geometryNodeValue = QJsonValue(exportGeometry(featureMap));
+ QJsonValue propertiesNodeValue = featureMap.value(QStringLiteral("properties")).value<QVariant>().toJsonValue();
+ QJsonValue idNodeValue = featureMap.value(QStringLiteral("id")).value<QVariant>().toJsonValue();
+ exportedFeature.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("Feature")));
+ exportedFeature.insert(QStringLiteral("geometry"), geometryNodeValue);
+ exportedFeature.insert(QStringLiteral("properties"), propertiesNodeValue);
+ exportedFeature.insert(QStringLiteral("id"), idNodeValue);
+ return exportedFeature;
+}
+
+static QJsonObject exportFeatureCollection(const QVariantMap &featureCollection)
+{
+ QJsonObject exportedFeatureCollection;
+ QJsonArray featureArray;
+ QVariantList featureList = featureCollection.value(QStringLiteral("data")).value<QVariantList>();
+ for (int i = 0; i < featureList.size(); ++i) {
+ featureArray.append(QJsonValue(exportFeature(featureList.at(i).value<QVariantMap>())));
+ }
+ exportedFeatureCollection.insert(QStringLiteral("type"), QJsonValue(QStringLiteral("FeatureCollection")));
+ exportedFeatureCollection.insert(QStringLiteral("features"), QJsonValue(featureArray) );
+ return exportedFeatureCollection;
+}
+
+/*!
+This method imports the \a geoJson document, expected to contain valid GeoJSON
+data, into a QVariantList structured like described in the section \l
+{Importing GeoJSON}.
+
+\note This method performs no validation on the input.
+
+\sa exportGeoJson
+*/
+QVariantList QGeoJson::importGeoJson(const QJsonDocument &geoJson)
+{
+ QVariantList returnedList;
+ QJsonObject object = geoJson.object(); // Read json object from imported doc
+ QVariantMap rootGeoJsonObject = object.toVariantMap(); // Extraced map using Qt's API
+ QString geoType[] = {
+ QStringLiteral("Point"),
+ QStringLiteral("MultiPoint"),
+ QStringLiteral("LineString"),
+ QStringLiteral("MultiLineString"),
+ QStringLiteral("Polygon"),
+ QStringLiteral("MultiPolygon"),
+ QStringLiteral("GeometryCollection"),
+ QStringLiteral("Feature"),
+ QStringLiteral("FeatureCollection")
+ };
+ enum geoTypeSwitch {
+ Point,
+ MultiPoint,
+ LineString,
+ MultiLineString,
+ Polygon,
+ MultiPolygon,
+ GeometryCollection,
+ Feature,
+ FeatureCollection
+ };
+ QVariantMap parsedGeoJsonMap;
+
+ // Checking whether the JSON object has a "type" member
+ const QVariant keyVariant = rootGeoJsonObject.value(QStringLiteral("type"));
+ if (keyVariant == QVariant::Invalid) {
+ // Type check failed
+ }
+ QString valueType = keyVariant.value<QString>();
+
+ // Checking whether the "type" member has a GeoJSON admitted value
+ for (int i = 0; i < 9; ++i) {
+ if (valueType == geoType[i]) {
+ switch (i) {
+ case Point: {
+ QGeoCircle circle = importPoint(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(circle);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("Point"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ case MultiPoint: {
+ QVariantList multiCircle = importMultiPoint(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(multiCircle);
+ QList <QGeoCircle> testlist;
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("MultiPoint"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ case LineString: {
+ QGeoPath lineString = importLineString(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(lineString);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("LineString"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ case MultiLineString: {
+ QVariantList multiLineString = importMultiLineString(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(multiLineString);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("MultiLineString"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ case Polygon: {
+ QGeoPolygon poly = importPolygon(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(poly);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("Polygon"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ case MultiPolygon: {
+ QVariantList multiPoly = importMultiPolygon(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(multiPoly);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("MultiPolygon"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ // List of GeoJson geometry objects
+ case GeometryCollection: {
+ QVariantList multiGeo = importGeometryCollection(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(multiGeo);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("GeometryCollection"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ // Single GeoJson geometry object with properties
+ case Feature: {
+ parsedGeoJsonMap = importGeometry(rootGeoJsonObject.value(QStringLiteral("geometry")).value<QVariantMap>());
+ QVariantMap importedProperties = rootGeoJsonObject.value(QStringLiteral("properties")).value<QVariantMap>();
+ parsedGeoJsonMap.insert(QStringLiteral("properties"), importedProperties);
+ if (rootGeoJsonObject.contains(QStringLiteral("id"))){
+ QVariant importedId = rootGeoJsonObject.value(QStringLiteral("id")).value<QVariant>();
+ parsedGeoJsonMap.insert(QStringLiteral("id"), importedId);
+ }
+ break;
+ }
+ // Heterogeneous list of GeoJSON geometries with properties
+ case FeatureCollection: {
+ QVariantList featCollection = importFeatureCollection(rootGeoJsonObject);
+ QVariant dataNodeValue = QVariant::fromValue(featCollection);
+ parsedGeoJsonMap.insert(QStringLiteral("type"), QStringLiteral("FeatureCollection"));
+ parsedGeoJsonMap.insert(QStringLiteral("data"), dataNodeValue);
+ break;
+ }
+ default:
+ break;
+ }
+ QVariant bboxNodeValue = rootGeoJsonObject.value(QStringLiteral("bbox"));
+ if (bboxNodeValue != QVariant::Invalid) {
+ parsedGeoJsonMap.insert(QStringLiteral("bbox"), bboxNodeValue);
+ }
+ returnedList.append(parsedGeoJsonMap);
+ } else if (i >= 9) {
+ // Error
+ break;
+ }
+ }
+ return returnedList;
+}
+
+/*!
+This method exports the QVariantList \a geoData, expected to be structured like
+described in the section \l {Importing GeoJSON}, to a QJsonDocument containing
+the data converted to GeoJSON.
+
+\note This method performs no validation on the input.
+
+\sa importGeoJson
+*/
+QJsonDocument QGeoJson::exportGeoJson(const QVariantList &geoData)
+{
+ QVariantMap exportMap = geoData.at(0).value<QVariantMap>(); // Extracting the QVMap
+ QJsonObject newObject;
+ QJsonDocument newDocument;
+ if (exportMap.contains(QStringLiteral("properties"))) {
+ newObject = exportFeature(exportMap);
+ } else {
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("Point")) // Check the value corresponding to the key "Point"
+ newObject = exportPoint(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("MultiPoint"))
+ newObject = exportMultiPoint(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("LineString"))
+ newObject = exportLineString(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("MultiLineString"))
+ newObject = exportMultiLineString(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("Polygon"))
+ newObject = exportPolygon(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("MultiPolygon"))
+ newObject = exportMultiPolygon(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("GeometryCollection"))
+ newObject = exportGeometryCollection(exportMap);
+ if (exportMap.value(QStringLiteral("type")) == QStringLiteral("FeatureCollection"))
+ newObject = exportFeatureCollection(exportMap);
+ }
+ if (exportMap.contains((QStringLiteral("bbox")))) {
+ QJsonArray bboxArray;
+ QVariantList bboxList = exportMap.value(QStringLiteral("bbox")).value<QVariantList>();
+ for (int i = 0; i < bboxList.size(); ++i) {
+ bboxArray.append(QJsonValue(bboxList.at(i).value<double>()));
+ }
+ newObject.insert(QStringLiteral("bbox"), QJsonValue(bboxArray));
+ }
+ newDocument.setObject(newObject);
+ return newDocument;
+}
+
+// Functions for toString
+QTextStream &operator << (QTextStream &stream, const QGeoCoordinate &crd)
+{
+ stream << "{ " << QString::number(crd.latitude(), 'f', 3) << ", "
+ << QString::number(crd.longitude(), 'f', 3) << ", "
+ << QString::number(crd.altitude(), 'f', 3) << " }";
+ return stream;
+}
+
+QTextStream &operator << (QTextStream &stream, const QGeoShape &shape)
+{
+ switch (shape.type()) {
+ case QGeoShape::CircleType: {
+ QGeoCircle circle(shape);
+ stream << "QGeoCircle(" <<circle.center() << ", "<< QString::number(circle.radius()) << ")";
+ break;
+ }
+ case QGeoShape::PathType: {
+ QGeoPath path(shape);
+ stream << "QGeoPath(";
+ for (auto c: path.path())
+ stream << c << ", ";
+ stream << ")";
+ break;
+ }
+ case QGeoShape::PolygonType: {
+ QGeoPolygon poly(shape);
+ stream << "QGeoPolygon(";
+ for (auto c: poly.path())
+ stream << c << ", ";
+ stream << ")";
+ break;
+ }
+ default:
+ stream << "QGeoShape(Unknown)";
+ break;
+ }
+ return stream;
+}
+
+static const QString sTab = QStringLiteral(" ");
+
+QString printQvariant(const QVariant v, int tabs = 0) {
+ QString sTabs;
+ QString res;
+ QTextStream stream(&res);
+ for (int i = 0; i< tabs; i++) {
+ sTabs += sTab;
+ }
+ if (v.type() == QVariant::List) {
+ stream << sTabs << "[\n";
+ const QVariantList &l = v.toList();
+ for (int i = 0; i < l.size(); ++i)
+ stream << printQvariant(l.at(i), tabs + 1);
+ stream << sTabs << "]\n";
+ } else if (v.type() == QVariant::Map) {
+ stream << sTabs << "{\n";
+ const QVariantList &l = v.toList();
+ const QVariantMap &map = v.toMap();
+
+ // Either one or the other are valid
+ if (!map.keys().isEmpty()) {
+ // Handle type first, to easy reading
+ if (map.contains(QStringLiteral("type"))) {
+ stream << sTabs << sTab << QStringLiteral("type") << " : "
+ << printQvariant(map[QStringLiteral("type")], tabs + 1).remove(QRegExp(QStringLiteral("^[ ]*")));;
+ }
+ for (QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter) {
+ if (iter.key() == QStringLiteral("type"))
+ continue;
+ stream << sTabs << sTab << iter.key() << " : " << printQvariant(iter.value(), tabs + 1).remove(QRegExp(QStringLiteral("^[ ]*")));;
+ }
+ }
+ for (int i = 0; i < l.size(); ++i)
+ stream << printQvariant(l.at(i), tabs + 1);
+ stream << sTabs << "}\n";
+ } else {
+ stream << sTabs;
+ QGeoShape workigGeometry;
+ if ( v.canConvert<QGeoShape>()) {
+ workigGeometry = v.value<QGeoShape>();
+ if (workigGeometry.type() == QGeoShape::CircleType) {
+ QGeoCircle circle = v.value<QGeoCircle>();
+ stream << circle<< "\n";
+ } else if (workigGeometry.type() == QGeoShape::PathType) {
+ QGeoPath path = v.value<QGeoPath>();
+ stream << path<< "\n";
+ } else if (workigGeometry.type() == QGeoShape::PolygonType) {
+ QGeoPolygon polygon = v.value<QGeoPolygon>();
+ stream << polygon<< "\n";
+ }
+ } else {
+ if (v.isNull())
+ stream << "null\n";
+ else
+ stream << v.toString() << "\n";
+ }
+ }
+ return res;
+}
+
+/*!
+This method accepts the QVariantLists structured like described in section \l
+{Importing GeoJSON}, and returns a string containing the same data in a
+readable form.
+*/
+QString QGeoJson::toString(const QVariantList &geoData) {
+ return printQvariant(geoData.first(), 0);
+}
+
+QT_END_NAMESPACE
diff --git a/src/location/labs/qgeojson_p.h b/src/location/labs/qgeojson_p.h
new file mode 100644
index 00000000..064dfcf6
--- /dev/null
+++ b/src/location/labs/qgeojson_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2018 Julian Sherollari <jdotsh@gmail.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtCore 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 QGEOJSON_H
+#define QGEOJSON_H
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qjsondocument.h>
+#include <QtLocation/private/qlocationglobal_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.
+//
+
+
+QT_BEGIN_NAMESPACE
+
+class Q_LOCATION_PRIVATE_EXPORT QGeoJson
+{
+public:
+
+ // This method imports a GeoJSON file to a QVariantList
+ static QVariantList importGeoJson(const QJsonDocument &doc);
+
+ // This method exports a GeoJSON file from a QVariantList
+ static QJsonDocument exportGeoJson(const QVariantList &list);
+
+ // This method exports the content of the imported QVariantList in a
+ // readable format
+ static QString toString(const QVariantList
+ &importedGeoJson);
+
+};
+
+QT_END_NAMESPACE
+
+#endif // QGEOJSON_H
diff --git a/src/location/labs/qgeotiledmaplabs.cpp b/src/location/labs/qgeotiledmaplabs.cpp
index 22d582c0..7d8d7108 100644
--- a/src/location/labs/qgeotiledmaplabs.cpp
+++ b/src/location/labs/qgeotiledmaplabs.cpp
@@ -44,6 +44,8 @@
#include <QtLocation/private/qmapiconobjectqsg_p_p.h>
#include <QtLocation/private/qdeclarativepolylinemapitem_p.h>
#include <QtLocation/private/qgeomapobjectqsgsupport_p.h>
+#include <QtPositioning/private/qlocationutils_p.h>
+#include <math.h>
QT_BEGIN_NAMESPACE
@@ -57,6 +59,7 @@ public:
QGeoMapObjectPrivate *createMapObjectImplementation(QGeoMapObject *obj) override;
virtual QList<QGeoMapObject *> mapObjects() const override;
void removeMapObject(QGeoMapObject *obj);
+ QList<QObject *>mapObjectsAt(const QGeoCoordinate &coordinate) const;
void updateMapObjects(QSGNode *root, QQuickWindow *window);
void updateObjectsGeometry();
@@ -95,6 +98,34 @@ void QGeoTiledMapLabsPrivate::removeMapObject(QGeoMapObject *obj)
m_qsgSupport.removeMapObject(obj);
}
+QList<QObject *> QGeoTiledMapLabsPrivate::mapObjectsAt(const QGeoCoordinate &coordinate) const
+{
+ // ToDo: use a space partitioning strategy
+ QList<QObject *> res;
+ for (const auto o: mapObjects()) {
+ // explicitly handle lines
+ bool contains = false;
+ if (o->type() == QGeoMapObject::PolylineType ) {
+ QMapPolylineObject *mpo = static_cast<QMapPolylineObject *>(o);
+ qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate);
+ QGeoPath path = o->geoShape();
+ path.setWidth(mpp * mpo->border()->width());
+ contains = path.contains(coordinate);
+ } else if (o->type() == QGeoMapObject::RouteType) {
+ qreal mpp = QLocationUtils::metersPerPixel(m_cameraData.zoomLevel(), coordinate);
+ QGeoPath path = o->geoShape();
+ path.setWidth(mpp * 4); // MapRouteObjectQSG has a hardcoded 4 pixels width;
+ contains = path.contains(coordinate);
+ } else {
+ contains = o->geoShape().contains(coordinate);
+ }
+
+ if (contains)
+ res.append(o);
+ }
+ return res;
+}
+
void QGeoTiledMapLabsPrivate::updateMapObjects(QSGNode *root, QQuickWindow *window)
{
m_qsgSupport.updateMapObjects(root, window);
@@ -161,6 +192,12 @@ void QGeoTiledMapLabs::removeMapObject(QGeoMapObject *obj)
d->removeMapObject(obj);
}
+QList<QObject *> QGeoTiledMapLabs::mapObjectsAt(const QGeoCoordinate &coordinate) const
+{
+ Q_D(const QGeoTiledMapLabs);
+ return d->mapObjectsAt(coordinate);
+}
+
QGeoTiledMapLabs::QGeoTiledMapLabs(QGeoTiledMapLabsPrivate &dd, QGeoTiledMappingManagerEngine *engine, QObject *parent)
: QGeoTiledMap(dd, engine, parent)
{
diff --git a/src/location/labs/qgeotiledmaplabs_p.h b/src/location/labs/qgeotiledmaplabs_p.h
index 4f179028..d10ec633 100644
--- a/src/location/labs/qgeotiledmaplabs_p.h
+++ b/src/location/labs/qgeotiledmaplabs_p.h
@@ -72,6 +72,7 @@ public:
bool createMapObjectImplementation(QGeoMapObject *obj) override;
void removeMapObject(QGeoMapObject *obj) override;
+ QList<QObject *> mapObjectsAt(const QGeoCoordinate &coordinate) const override;
protected:
QSGNode *updateSceneGraph(QSGNode *node, QQuickWindow *window) override;
diff --git a/src/location/labs/qmapcircleobject.cpp b/src/location/labs/qmapcircleobject.cpp
index d7f1d58f..5f0db29d 100644
--- a/src/location/labs/qmapcircleobject.cpp
+++ b/src/location/labs/qmapcircleobject.cpp
@@ -37,6 +37,7 @@
#include "qmapcircleobject_p.h"
#include "qmapcircleobject_p_p.h"
#include <QExplicitlySharedDataPointer>
+#include <QtPositioning/qgeocircle.h>
QT_BEGIN_NAMESPACE
@@ -68,7 +69,30 @@ QGeoMapObject::Type QMapCircleObjectPrivate::type() const
return QGeoMapObject::CircleType;
}
+QGeoShape QMapCircleObjectPrivate::geoShape() const
+{
+ return QGeoCircle(center(), radius());
+}
+
+void QMapCircleObjectPrivate::setGeoShape(const QGeoShape &shape)
+{
+ if (shape == geoShape())
+ return;
+ const QGeoCircle circle(shape); // if shape isn't a circle, circle will be created as a default-constructed circle
+ const bool centerHasChanged = circle.center() != center();
+ const bool radiusHasChanged = circle.radius() != radius();
+
+ if (centerHasChanged)
+ setCenter(circle.center()); // to handle overrides
+ if (radiusHasChanged)
+ setRadius(circle.radius()); // to handle overrides
+
+ if (centerHasChanged)
+ emit static_cast<QMapCircleObject *>(q)->centerChanged();
+ if (radiusHasChanged)
+ emit static_cast<QMapCircleObject *>(q)->radiusChanged();
+}
//
// QMapCircleObjectPrivate default implementation
@@ -162,8 +186,6 @@ QGeoMapObjectPrivate *QMapCircleObjectPrivateDefault::clone()
return new QMapCircleObjectPrivateDefault(static_cast<QMapCircleObjectPrivate &>(*this));
}
-
-
QMapCircleObject::QMapCircleObject(QObject *parent)
: QGeoMapObject(QExplicitlySharedDataPointer<QGeoMapObjectPrivate>(new QMapCircleObjectPrivateDefault(this)), parent)
diff --git a/src/location/labs/qmapcircleobject_p_p.h b/src/location/labs/qmapcircleobject_p_p.h
index b3353b62..4bf212c7 100644
--- a/src/location/labs/qmapcircleobject_p_p.h
+++ b/src/location/labs/qmapcircleobject_p_p.h
@@ -76,6 +76,8 @@ public:
// QGeoMapObjectPrivate interface
bool equals(const QGeoMapObjectPrivate &other) const override;
+ virtual QGeoShape geoShape() const override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
};
diff --git a/src/location/labs/qmapiconobject.cpp b/src/location/labs/qmapiconobject.cpp
index be82ebbf..a0cd4d46 100644
--- a/src/location/labs/qmapiconobject.cpp
+++ b/src/location/labs/qmapiconobject.cpp
@@ -37,6 +37,7 @@
#include "qmapiconobject_p.h"
#include "qmapiconobject_p_p.h"
#include <QExplicitlySharedDataPointer>
+#include <QtPositioning/QGeoCircle>
QT_BEGIN_NAMESPACE
@@ -91,7 +92,9 @@ QMapIconObjectPrivateDefault::QMapIconObjectPrivateDefault(const QMapIconObjectP
{
m_coordinate = other.coordinate();
m_content = other.content();
- m_size = other.size();
+ m_iconSize = other.iconSize();
+ qreal radius = QGeoCircle(other.geoShape()).radius();
+ m_radius = (qIsFinite(radius)) ? radius : 100.0;
}
QMapIconObjectPrivateDefault::~QMapIconObjectPrivateDefault()
@@ -104,9 +107,9 @@ QGeoCoordinate QMapIconObjectPrivateDefault::coordinate() const
return m_coordinate;
}
-void QMapIconObjectPrivateDefault::setCoordinate(const QGeoCoordinate &center)
+void QMapIconObjectPrivateDefault::setCoordinate(const QGeoCoordinate &coordinate)
{
- m_coordinate = center;
+ m_coordinate = coordinate;
}
QVariant QMapIconObjectPrivateDefault::content() const
@@ -119,14 +122,14 @@ void QMapIconObjectPrivateDefault::setContent(const QVariant &content)
m_content = content;
}
-QSizeF QMapIconObjectPrivateDefault::size() const
+QSizeF QMapIconObjectPrivateDefault::iconSize() const
{
- return m_size;
+ return m_iconSize;
}
-void QMapIconObjectPrivateDefault::setSize(const QSizeF &size)
+void QMapIconObjectPrivateDefault::setIconSize(const QSizeF &size)
{
- m_size = size;
+ m_iconSize = size;
}
QGeoMapObjectPrivate *QMapIconObjectPrivateDefault::clone()
@@ -134,6 +137,30 @@ QGeoMapObjectPrivate *QMapIconObjectPrivateDefault::clone()
return new QMapIconObjectPrivateDefault(static_cast<QMapIconObjectPrivate &>(*this));
}
+QGeoShape QMapIconObjectPrivateDefault::geoShape() const
+{
+ return QGeoCircle(coordinate(), m_radius); // fixing the radius to 100 meters, as a meaningful size for
+ // fitting the viewport to this icon without losing context completely
+}
+
+void QMapIconObjectPrivateDefault::setGeoShape(const QGeoShape &shape)
+{
+ QGeoCoordinate crd;
+ const QGeoCircle circle(shape); // if shape isn't a circle, circle will be created as a default-constructed circle
+ if (circle.isValid()) {
+ crd = circle.center();
+ m_radius = circle.radius();
+ } else {
+ crd = shape.boundingGeoRectangle().center();
+ }
+
+ if (crd == coordinate())
+ return;
+
+ setCoordinate(crd);
+ emit static_cast<QMapIconObject *>(q)->coordinateChanged(crd);
+}
+
/*
@@ -206,25 +233,25 @@ void QMapIconObject::setCoordinate(const QGeoCoordinate &center)
}
/*!
- \qmlproperty Variant Qt.labs.location::MapIconObject::size
+ \qmlproperty Variant Qt.labs.location::MapIconObject::iconSize
The size of the icon as it will be shown on the map.
*/
-QSizeF QMapIconObject::size() const
+QSizeF QMapIconObject::iconSize() const
{
const QMapIconObjectPrivate *d = static_cast<const QMapIconObjectPrivate *>(d_ptr.data());
- return d->size();
+ return d->iconSize();
}
-void QMapIconObject::setSize(const QSizeF &size)
+void QMapIconObject::setIconSize(const QSizeF &size)
{
QMapIconObjectPrivate *d = static_cast<QMapIconObjectPrivate*>(d_ptr.data());
- if (d->size() == size)
+ if (d->iconSize() == size)
return;
- d->setSize(size);
- emit sizeChanged();
+ d->setIconSize(size);
+ emit iconSizeChanged();
}
void QMapIconObject::setMap(QGeoMap *map)
diff --git a/src/location/labs/qmapiconobject_p.h b/src/location/labs/qmapiconobject_p.h
index 16b00d04..6ba2f83e 100644
--- a/src/location/labs/qmapiconobject_p.h
+++ b/src/location/labs/qmapiconobject_p.h
@@ -61,7 +61,7 @@ class Q_LOCATION_PRIVATE_EXPORT QMapIconObject : public QGeoMapObject
Q_OBJECT
Q_PROPERTY(QGeoCoordinate coordinate READ coordinate WRITE setCoordinate NOTIFY coordinateChanged)
Q_PROPERTY(QVariant content READ content WRITE setContent NOTIFY contentChanged)
- Q_PROPERTY(QSizeF size READ size WRITE setSize NOTIFY sizeChanged)
+ Q_PROPERTY(QSizeF iconSize READ iconSize WRITE setIconSize NOTIFY iconSizeChanged)
public:
QMapIconObject(QObject *parent = nullptr);
@@ -69,18 +69,18 @@ public:
QVariant content() const;
QGeoCoordinate coordinate() const;
- QSizeF size() const;
+ QSizeF iconSize() const;
void setContent(QVariant content);
void setCoordinate(const QGeoCoordinate &coordinate);
- void setSize(const QSizeF &size);
+ void setIconSize(const QSizeF &size);
void setMap(QGeoMap *map) override;
signals:
void contentChanged(QVariant content);
void coordinateChanged(QGeoCoordinate coordinate);
- void sizeChanged();
+ void iconSizeChanged();
};
QT_END_NAMESPACE
diff --git a/src/location/labs/qmapiconobject_p_p.h b/src/location/labs/qmapiconobject_p_p.h
index 08a1a893..01ed5b4a 100644
--- a/src/location/labs/qmapiconobject_p_p.h
+++ b/src/location/labs/qmapiconobject_p_p.h
@@ -66,8 +66,8 @@ public:
virtual void setCoordinate(const QGeoCoordinate &coordinate) = 0;
virtual QVariant content() const = 0;
virtual void setContent(const QVariant &content) = 0;
- virtual QSizeF size() const = 0;
- virtual void setSize(const QSizeF &size) = 0;
+ virtual QSizeF iconSize() const = 0;
+ virtual void setIconSize(const QSizeF &size) = 0;
// QGeoMapObjectPrivate interface
bool equals(const QGeoMapObjectPrivate &other) const override;
@@ -85,16 +85,19 @@ public:
void setCoordinate(const QGeoCoordinate &coordinate) override;
QVariant content() const override;
void setContent(const QVariant &content) override;
- virtual QSizeF size() const override;
- virtual void setSize(const QSizeF &size) override;
+ virtual QSizeF iconSize() const override;
+ virtual void setIconSize(const QSizeF &size) override;
- // QMapIconObjectPrivate interface
+ // QGeoMapObjectPrivate interface
QGeoMapObjectPrivate *clone() override;
+ QGeoShape geoShape() const override;
+ void setGeoShape(const QGeoShape &shape) override;
public:
QVariant m_content;
QGeoCoordinate m_coordinate;
- QSizeF m_size;
+ QSizeF m_iconSize;
+ qreal m_radius = 100.0; // can be set only via setGeoShape, will be used only by
private:
QMapIconObjectPrivateDefault(const QMapIconObjectPrivateDefault &other) = delete;
diff --git a/src/location/labs/qmapobjectview.cpp b/src/location/labs/qmapobjectview.cpp
index fc583415..90234ea6 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,36 @@ 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());
+}
+
+QGeoShape QMapObjectViewPrivateDefault::geoShape() const
+{
+ const QMapObjectView *qq = static_cast<const QMapObjectView *>(q);
+ QGeoRectangle rect;
+ const QList<QGeoMapObject *> kids = qq->geoMapObjectChildren();
+ for (const auto &kid: kids) {
+ if (!rect.isValid())
+ rect = kid->geoShape().boundingGeoRectangle();
+ else
+ rect = rect.united(kid->geoShape().boundingGeoRectangle());
+ }
+ return rect;
+}
+
+void QMapObjectViewPrivateDefault::setGeoShape(const QGeoShape &/*shape*/)
+{
+ // MOV doesn't support setting the geoshape.
+}
+
/*
QMapObjectView
@@ -160,10 +211,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 +227,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 +240,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 +259,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 76affced..be5801d3 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; // for items instantiated before the map is set
diff --git a/src/location/labs/qmapobjectview_p_p.h b/src/location/labs/qmapobjectview_p_p.h
index 7550e209..55f45f67 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,20 @@ 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;
+ virtual QGeoShape geoShape() const override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
+
+ QVariant m_model;
+ QQmlComponent *m_delegate = nullptr;
};
QT_END_NAMESPACE
diff --git a/src/location/labs/qmappolygonobject.cpp b/src/location/labs/qmappolygonobject.cpp
index 1d495899..6ccba748 100644
--- a/src/location/labs/qmappolygonobject.cpp
+++ b/src/location/labs/qmappolygonobject.cpp
@@ -70,7 +70,10 @@ QMapPolygonObjectPrivateDefault::QMapPolygonObjectPrivateDefault(QGeoMapObject *
QMapPolygonObjectPrivateDefault::QMapPolygonObjectPrivateDefault(const QMapPolygonObjectPrivate &other) : QMapPolygonObjectPrivate(other.q)
{
- m_path = other.path();
+ m_path.setPath(other.path()); // to stay on the safe side
+ QGeoPolygon poly(other.geoShape()); // to handle holes
+ for (int i = 0; i < poly.holesCount(); i++)
+ m_path.addHole(poly.holePath(i));
m_borderColor = other.borderColor();
m_fillColor = other.fillColor();
m_borderWidth = other.borderWidth();
@@ -88,12 +91,12 @@ QGeoMapObject::Type QMapPolygonObjectPrivate::type() const
QList<QGeoCoordinate> QMapPolygonObjectPrivateDefault::path() const
{
- return m_path;
+ return m_path.path();
}
void QMapPolygonObjectPrivateDefault::setPath(const QList<QGeoCoordinate> &path)
{
- m_path = path;
+ m_path.setPath(path);
}
QColor QMapPolygonObjectPrivateDefault::fillColor() const
@@ -131,6 +134,23 @@ QGeoMapObjectPrivate *QMapPolygonObjectPrivateDefault::clone()
return new QMapPolygonObjectPrivateDefault(static_cast<QMapPolygonObjectPrivate &>(*this));
}
+QGeoShape QMapPolygonObjectPrivateDefault::geoShape() const
+{
+ return m_path;
+}
+
+void QMapPolygonObjectPrivateDefault::setGeoShape(const QGeoShape &shape)
+{
+ if (shape == m_path)
+ return;
+
+ const QGeoPolygon poly(shape);
+ setPath(poly.path()); // to handle overrides
+ for (int i = 0; i < poly.holesCount(); i++)
+ m_path.addHole(poly.holePath(i));
+ emit static_cast<QMapPolygonObject *>(q)->pathChanged();
+}
+
bool QMapPolygonObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
{
if (other.type() != type()) // This check might be unnecessary, depending on how equals gets used
@@ -138,12 +158,27 @@ bool QMapPolygonObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
const QMapPolygonObjectPrivate &o = static_cast<const QMapPolygonObjectPrivate &>(other);
return (QGeoMapObjectPrivate::equals(o)
- && path() == o.path()
+ && geoShape() == o.geoShape()
&& borderColor() == o.borderColor()
&& fillColor() == o.fillColor()
&& borderWidth() == o.borderWidth());
}
+QGeoShape QMapPolygonObjectPrivate::geoShape() const
+{
+ return QGeoPolygon(path());
+}
+
+void QMapPolygonObjectPrivate::setGeoShape(const QGeoShape &shape)
+{
+ if (shape == geoShape())
+ return;
+
+ const QGeoPolygon poly(shape);
+ setPath(poly.path()); // to handle overrides
+ emit static_cast<QMapPolygonObject *>(q)->pathChanged();
+}
+
diff --git a/src/location/labs/qmappolygonobject_p_p.h b/src/location/labs/qmappolygonobject_p_p.h
index d7e95d49..767765df 100644
--- a/src/location/labs/qmappolygonobject_p_p.h
+++ b/src/location/labs/qmappolygonobject_p_p.h
@@ -52,6 +52,7 @@
#include <QtLocation/private/qgeomapobject_p_p.h>
#include <QGeoCoordinate>
#include <QColor>
+#include <QGeoPolygon>
QT_BEGIN_NAMESPACE
@@ -74,6 +75,8 @@ public:
// QGeoMapObjectPrivate interface
bool equals(const QGeoMapObjectPrivate &other) const override;
+ virtual QGeoShape geoShape() const override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
};
class Q_LOCATION_PRIVATE_EXPORT QMapPolygonObjectPrivateDefault : public QMapPolygonObjectPrivate
@@ -95,9 +98,11 @@ public:
// QGeoMapObjectPrivate interface
QGeoMapObjectPrivate *clone() override;
+ virtual QGeoShape geoShape() const override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
public:
- QList<QGeoCoordinate> m_path;
+ QGeoPolygon m_path; // small overhead compared to plain QList<QGeoCoordinate>
QColor m_borderColor;
QColor m_fillColor = Qt::transparent;
qreal m_borderWidth = 0;
diff --git a/src/location/labs/qmappolylineobject.cpp b/src/location/labs/qmappolylineobject.cpp
index 1c351962..c6d3cdaf 100644
--- a/src/location/labs/qmappolylineobject.cpp
+++ b/src/location/labs/qmappolylineobject.cpp
@@ -37,6 +37,7 @@
#include "qmappolylineobject_p.h"
#include "qmappolylineobject_p_p.h"
#include <QtLocation/private/locationvaluetypehelper_p.h>
+#include <QtPositioning/QGeoPath>
QT_BEGIN_NAMESPACE
@@ -127,6 +128,23 @@ bool QMapPolylineObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
&& width() == o.width());
}
+QGeoShape QMapPolylineObjectPrivate::geoShape() const
+{
+ return QGeoPath(path());
+}
+
+void QMapPolylineObjectPrivate::setGeoShape(const QGeoShape &shape)
+{
+ const QGeoPath p(shape);
+ if (p == path())
+ return;
+
+ setPath(p.path()); // to handle overrides
+ emit static_cast<QMapPolylineObject *>(q)->pathChanged();
+}
+
+
+
QGeoMapObjectPrivate *QMapPolylineObjectPrivateDefault::clone()
{
return new QMapPolylineObjectPrivateDefault(static_cast<QMapPolylineObjectPrivate &>(*this));
diff --git a/src/location/labs/qmappolylineobject_p_p.h b/src/location/labs/qmappolylineobject_p_p.h
index 1d5919d2..a0eb3711 100644
--- a/src/location/labs/qmappolylineobject_p_p.h
+++ b/src/location/labs/qmappolylineobject_p_p.h
@@ -72,6 +72,8 @@ public:
// QGeoMapObjectPrivate interface
bool equals(const QGeoMapObjectPrivate &other) const override;
+ virtual QGeoShape geoShape() const override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
};
class Q_LOCATION_PRIVATE_EXPORT QMapPolylineObjectPrivateDefault : public QMapPolylineObjectPrivate
diff --git a/src/location/labs/qmaprouteobject.cpp b/src/location/labs/qmaprouteobject.cpp
index c3365d30..fd29954b 100644
--- a/src/location/labs/qmaprouteobject.cpp
+++ b/src/location/labs/qmaprouteobject.cpp
@@ -100,7 +100,7 @@ QGeoRoute QMapRouteObjectPrivate::route() const
void QMapRouteObjectPrivate::setRoute(const QDeclarativeGeoRoute *route)
{
- Q_UNUSED(route)
+ Q_UNUSED(route);
}
bool QMapRouteObjectPrivate::equals(const QGeoMapObjectPrivate &other) const
@@ -118,6 +118,16 @@ QGeoMapObjectPrivate *QMapRouteObjectPrivate::clone()
return new QMapRouteObjectPrivate(*this);
}
+QGeoShape QMapRouteObjectPrivate::geoShape() const
+{
+ return route().bounds();
+}
+
+void QMapRouteObjectPrivate::setGeoShape(const QGeoShape &/*shape*/)
+{
+ // Not supported for MapRouteObject
+}
+
/*
@@ -172,7 +182,7 @@ void QMapRouteObject::setMap(QGeoMap *map)
if (!map) {
// Map was set, now it has ben re-set to NULL, but not inside d_ptr.
// so m_map inside d_ptr can still be used to remove itself, inside the destructor.
- d_ptr = new QMapRouteObjectPrivate(*d);
+ d_ptr = new QMapRouteObjectPrivate(*d); // This is not losing data: check MapRouteObjectPrivate::declarativeGeoRoute()
// Old pimpl deleted implicitly by QExplicitlySharedDataPointer
}
}
diff --git a/src/location/labs/qmaprouteobject_p_p.h b/src/location/labs/qmaprouteobject_p_p.h
index e01b1cc6..f12f9b33 100644
--- a/src/location/labs/qmaprouteobject_p_p.h
+++ b/src/location/labs/qmaprouteobject_p_p.h
@@ -72,6 +72,8 @@ public:
// QGeoMapObjectPrivate interface
bool equals(const QGeoMapObjectPrivate &other) const override;
QGeoMapObjectPrivate *clone() override;
+ virtual QGeoShape geoShape() const override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
};
QT_END_NAMESPACE
diff --git a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
index e0e3a6d7..1a1b102b 100644
--- a/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
+++ b/src/location/labs/qsg/qgeomapobjectqsgsupport.cpp
@@ -126,7 +126,11 @@ QGeoMapObjectPrivate *QGeoMapObjectQSGSupport::createMapObjectImplementationPriv
QList<QGeoMapObject *> QGeoMapObjectQSGSupport::mapObjects() const
{
- return QList<QGeoMapObject *>();
+ QList<QGeoMapObject *> res;
+ for (int i = 0; i < m_mapObjects.size(); ++i) {
+ res.append(m_mapObjects.at(i).object.data());
+ }
+ return res;
}
void QGeoMapObjectQSGSupport::removeMapObject(QGeoMapObject *obj)
diff --git a/src/location/labs/qsg/qmapcircleobjectqsg.cpp b/src/location/labs/qsg/qmapcircleobjectqsg.cpp
index 775016b9..32f3030b 100644
--- a/src/location/labs/qsg/qmapcircleobjectqsg.cpp
+++ b/src/location/labs/qsg/qmapcircleobjectqsg.cpp
@@ -50,12 +50,10 @@ QMapCircleObjectPrivateQSG::QMapCircleObjectPrivateQSG(const QMapCircleObjectPri
: QMapCircleObjectPrivateDefault(other)
{
// Data already cloned by the *Default copy constructor, but necessary
- // update operations triggered by setters overrides
- setCenter(center());
- setRadius(radius());
- setColor(color());
- setBorderColor(borderColor());
- setBorderWidth(borderWidth());
+ // update operations triggered only by setters overrides
+ updateGeometry();
+ if (m_map)
+ emit m_map->sgNodeChanged();
}
QMapCircleObjectPrivateQSG::~QMapCircleObjectPrivateQSG()
@@ -77,7 +75,7 @@ void QMapCircleObjectPrivateQSG::updateCirclePath()
void QMapCircleObjectPrivateQSG::updateGeometry()
{
if (!m_map || m_map->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator
- || !qIsFinite(m_radius) || !m_center.isValid())
+ || !qIsFinite(radius()) || !center().isValid())
return;
const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
@@ -153,7 +151,7 @@ QSGNode *QMapCircleObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
QSGNode *root,
QQuickWindow * /*window*/)
{
-// Q_UNUSED(visibleNode) // coz of -Werror=unused-but-set-parameter
+// Q_UNUSED(visibleNode); // coz of -Werror=unused-but-set-parameter
MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode);
bool created = false;
@@ -182,7 +180,7 @@ QSGNode *QMapCircleObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
void QMapCircleObjectPrivateQSG::setCenter(const QGeoCoordinate &center)
{
- m_center = center;
+ QMapCircleObjectPrivateDefault::setCenter(center);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
@@ -190,7 +188,7 @@ void QMapCircleObjectPrivateQSG::setCenter(const QGeoCoordinate &center)
void QMapCircleObjectPrivateQSG::setRadius(qreal radius)
{
- m_radius = radius;
+ QMapCircleObjectPrivateDefault::setRadius(radius);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
@@ -198,7 +196,7 @@ void QMapCircleObjectPrivateQSG::setRadius(qreal radius)
void QMapCircleObjectPrivateQSG::setColor(const QColor &color)
{
- m_fillColor = color;
+ QMapCircleObjectPrivateDefault::setColor(color);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
@@ -206,7 +204,7 @@ void QMapCircleObjectPrivateQSG::setColor(const QColor &color)
void QMapCircleObjectPrivateQSG::setBorderColor(const QColor &color)
{
- m_borderColor = color;
+ QMapCircleObjectPrivateDefault::setBorderColor(color);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
@@ -214,7 +212,7 @@ void QMapCircleObjectPrivateQSG::setBorderColor(const QColor &color)
void QMapCircleObjectPrivateQSG::setBorderWidth(qreal width)
{
- m_borderWidth = width;
+ QMapCircleObjectPrivateDefault::setBorderWidth(width);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
diff --git a/src/location/labs/qsg/qmapiconobjectqsg.cpp b/src/location/labs/qsg/qmapiconobjectqsg.cpp
index 47c39695..d9a80c91 100644
--- a/src/location/labs/qsg/qmapiconobjectqsg.cpp
+++ b/src/location/labs/qsg/qmapiconobjectqsg.cpp
@@ -67,8 +67,10 @@ QMapIconObjectPrivateQSG::QMapIconObjectPrivateQSG(QGeoMapObject *q)
QMapIconObjectPrivateQSG::QMapIconObjectPrivateQSG(const QMapIconObjectPrivate &other)
: QMapIconObjectPrivateDefault(other)
{
+ // Data already cloned by the *Default copy constructor, but necessary
+ // update operations triggered only by setters overrides
setContent(content());
- setCoordinate(coordinate());
+// setCoordinate(coordinate());
}
QMapIconObjectPrivateQSG::~QMapIconObjectPrivateQSG()
@@ -99,7 +101,7 @@ QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
QSGNode *root,
QQuickWindow *window)
{
- Q_UNUSED(visibleNode)
+ Q_UNUSED(visibleNode);
bool created = false;
RootNode *node = static_cast<RootNode *>(oldNode);
if (!node) {
@@ -116,7 +118,7 @@ QSGNode *QMapIconObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
m_imageNode->setTexture(window->createTextureFromImage(m_image));
QRect rect = m_image.rect();
m_imageNode->setSourceRect(rect);
- m_imageNode->setRect(QRectF(QPointF(0,0), m_size));
+ m_imageNode->setRect(QRectF(QPointF(0,0), iconSize()));
}
if (m_geometryDirty) {
@@ -211,9 +213,9 @@ void QMapIconObjectPrivateQSG::setContent(const QVariant &content)
emit m_map->sgNodeChanged();
}
-void QMapIconObjectPrivateQSG::setSize(const QSizeF &size)
+void QMapIconObjectPrivateQSG::setIconSize(const QSizeF &size)
{
- QMapIconObjectPrivateDefault::setSize(size);
+ QMapIconObjectPrivateDefault::setIconSize(size);
updateGeometry();
}
diff --git a/src/location/labs/qsg/qmapiconobjectqsg_p_p.h b/src/location/labs/qsg/qmapiconobjectqsg_p_p.h
index c57828af..abc2fe9b 100644
--- a/src/location/labs/qsg/qmapiconobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmapiconobjectqsg_p_p.h
@@ -77,7 +77,7 @@ public:
// QGeoMapIconPrivate interface
void setCoordinate(const QGeoCoordinate &coordinate) override;
void setContent(const QVariant &content) override;
- void setSize(const QSizeF &size) override;
+ void setIconSize(const QSizeF &size) override;
// QGeoMapObjectPrivate
QGeoMapObjectPrivate *clone() override;
diff --git a/src/location/labs/qsg/qmappolygonobjectqsg.cpp b/src/location/labs/qsg/qmappolygonobjectqsg.cpp
index 99a84ec5..9963cac9 100644
--- a/src/location/labs/qsg/qmappolygonobjectqsg.cpp
+++ b/src/location/labs/qsg/qmappolygonobjectqsg.cpp
@@ -37,22 +37,24 @@
#include "qmappolygonobjectqsg_p_p.h"
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgsimplerectnode.h>
+#include <QtPositioning/private/qgeopolygon_p.h>
QT_BEGIN_NAMESPACE
QMapPolygonObjectPrivateQSG::QMapPolygonObjectPrivateQSG(QGeoMapObject *q)
- : QMapPolygonObjectPrivate(q)
+ : QMapPolygonObjectPrivateDefault(q)
{
}
QMapPolygonObjectPrivateQSG::QMapPolygonObjectPrivateQSG(const QMapPolygonObjectPrivate &other)
- : QMapPolygonObjectPrivate(other.q)
+ : QMapPolygonObjectPrivateDefault(other)
{
- setPath(other.path());
- setFillColor(other.fillColor());
- setBorderColor(other.borderColor());
- setBorderWidth(other.borderWidth());
+ // Data already cloned by the *Default copy constructor, but necessary
+ // update operations triggered only by setters overrides
+ updateGeometry();
+ if (m_map)
+ emit m_map->sgNodeChanged();
}
QMapPolygonObjectPrivateQSG::~QMapPolygonObjectPrivateQSG()
@@ -69,8 +71,8 @@ QList<QDoubleVector2D> QMapPolygonObjectPrivateQSG::projectPath()
const QGeoProjectionWebMercator &p =
static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
- geopathProjected_.reserve(m_geoPath.path().size());
- for (const QGeoCoordinate &c : m_geoPath.path())
+ geopathProjected_.reserve(m_path.path().size());
+ for (const QGeoCoordinate &c : m_path.path())
geopathProjected_ << p.geoToMapProjection(c);
return geopathProjected_;
}
@@ -80,7 +82,7 @@ QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
QSGNode *root,
QQuickWindow * /*window*/)
{
- Q_UNUSED(visibleNode)
+ Q_UNUSED(visibleNode);
MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode);
bool created = false;
@@ -107,29 +109,9 @@ QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
return node;
}
-QList<QGeoCoordinate> QMapPolygonObjectPrivateQSG::path() const
-{
- return m_geoPath.path();
-}
-
-QColor QMapPolygonObjectPrivateQSG::fillColor() const
-{
- return m_fillColor;
-}
-
-QColor QMapPolygonObjectPrivateQSG::borderColor() const
-{
- return m_borderColor;
-}
-
-qreal QMapPolygonObjectPrivateQSG::borderWidth() const
-{
- return m_borderWidth;
-}
-
void QMapPolygonObjectPrivateQSG::setPath(const QList<QGeoCoordinate> &path)
{
- m_geoPath.setPath(path);
+ QMapPolygonObjectPrivateDefault::setPath(path);
updateGeometry();
if (m_map)
@@ -138,7 +120,7 @@ void QMapPolygonObjectPrivateQSG::setPath(const QList<QGeoCoordinate> &path)
void QMapPolygonObjectPrivateQSG::setFillColor(const QColor &color)
{
- m_fillColor = color;
+ QMapPolygonObjectPrivateDefault::setFillColor(color);
updateGeometry();
if (m_map)
@@ -147,7 +129,7 @@ void QMapPolygonObjectPrivateQSG::setFillColor(const QColor &color)
void QMapPolygonObjectPrivateQSG::setBorderColor(const QColor &color)
{
- m_borderColor = color;
+ QMapPolygonObjectPrivateDefault::setBorderColor(color);
updateGeometry();
if (m_map)
@@ -156,7 +138,7 @@ void QMapPolygonObjectPrivateQSG::setBorderColor(const QColor &color)
void QMapPolygonObjectPrivateQSG::setBorderWidth(qreal width)
{
- m_borderWidth = width;
+ QMapPolygonObjectPrivateDefault::setBorderWidth(width);
updateGeometry();
if (m_map)
@@ -168,9 +150,21 @@ QGeoMapObjectPrivate *QMapPolygonObjectPrivateQSG::clone()
return new QMapPolygonObjectPrivateQSG(static_cast<QMapPolygonObjectPrivate &>(*this));
}
+void QMapPolygonObjectPrivateQSG::setGeoShape(const QGeoShape &shape)
+{
+ if (shape == m_path)
+ return;
+
+ m_path = QGeoPathEager(shape);
+ updateGeometry();
+ if (m_map)
+ emit m_map->sgNodeChanged();
+ emit static_cast<QMapPolygonObject *>(q)->pathChanged();
+}
+
void QMapPolygonObjectPrivateQSG::updateGeometry()
{
- if (!m_map || m_geoPath.path().length() == 0
+ if (!m_map || m_path.path().length() == 0
|| m_map->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
@@ -180,7 +174,7 @@ void QMapPolygonObjectPrivateQSG::updateGeometry()
const QList<QDoubleVector2D> &geopathProjected = projectPath();
m_geometry.markSourceDirty();
- m_geometry.setPreserveGeometry(true, m_geoPath.boundingGeoRectangle().topLeft());
+ m_geometry.setPreserveGeometry(true, m_path.boundingGeoRectangle().topLeft());
m_geometry.updateSourcePoints(*m_map, geopathProjected);
m_geometry.updateScreenPoints(*m_map);
@@ -193,7 +187,7 @@ void QMapPolygonObjectPrivateQSG::updateGeometry()
closedPath << closedPath.first();
m_borderGeometry.markSourceDirty();
- m_borderGeometry.setPreserveGeometry(true, m_geoPath.boundingGeoRectangle().topLeft());
+ m_borderGeometry.setPreserveGeometry(true, m_path.boundingGeoRectangle().topLeft());
const QGeoCoordinate &geometryOrigin = m_geometry.origin();
diff --git a/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h b/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h
index b288528a..0f42a92e 100644
--- a/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmappolygonobjectqsg_p_p.h
@@ -57,7 +57,7 @@
QT_BEGIN_NAMESPACE
-class Q_LOCATION_PRIVATE_EXPORT QMapPolygonObjectPrivateQSG : public QMapPolygonObjectPrivate, public QQSGMapObject
+class Q_LOCATION_PRIVATE_EXPORT QMapPolygonObjectPrivateQSG : public QMapPolygonObjectPrivateDefault, public QQSGMapObject
{
public:
QMapPolygonObjectPrivateQSG(QGeoMapObject *q);
@@ -73,12 +73,7 @@ public:
QSGNode *root,
QQuickWindow *window) override;
- // QGeoMapPolylinePrivate interface
- QList<QGeoCoordinate> path() const override;
- QColor fillColor() const override;
- QColor borderColor() const override;
- qreal borderWidth() const override;
-
+ // QGeoMapPolygonPrivate interface
void setPath(const QList<QGeoCoordinate> &path) override;
void setFillColor(const QColor &color) override;
void setBorderColor(const QColor &color) override;
@@ -86,15 +81,12 @@ public:
// QGeoMapObjectPrivate
QGeoMapObjectPrivate *clone() override;
+ virtual void setGeoShape(const QGeoShape &shape) override;
// Data Members
QGeoMapPolygonGeometry m_geometry;
QGeoMapPolylineGeometry m_borderGeometry;
- QGeoPath m_geoPath;
- QColor m_fillColor;
- QColor m_borderColor;
- qreal m_borderWidth = 0;
bool m_updatingGeometry = false;
};
diff --git a/src/location/labs/qsg/qmappolylineobjectqsg.cpp b/src/location/labs/qsg/qmappolylineobjectqsg.cpp
index 5b184326..2bf5b287 100644
--- a/src/location/labs/qsg/qmappolylineobjectqsg.cpp
+++ b/src/location/labs/qsg/qmappolylineobjectqsg.cpp
@@ -45,18 +45,20 @@ QT_BEGIN_NAMESPACE
*/
QMapPolylineObjectPrivateQSG::QMapPolylineObjectPrivateQSG(QGeoMapObject *q)
- : QMapPolylineObjectPrivate(q)
+ : QMapPolylineObjectPrivateDefault(q)
{
}
QMapPolylineObjectPrivateQSG::QMapPolylineObjectPrivateQSG(const QMapPolylineObjectPrivate &other)
- : QMapPolylineObjectPrivate(other.q)
+ : QMapPolylineObjectPrivateDefault(other)
{
- // do the appropriate internal update and trigger map repaint
- setPath(other.path());
- setColor(other.color());
- setWidth(other.width());
+ m_geoPath.setPath(m_path);
+ // rest of the data already cloned by the *Default copy constructor, but necessary
+ // update operations triggered only by setters overrides
+ updateGeometry();
+ if (m_map)
+ emit m_map->sgNodeChanged();
}
QMapPolylineObjectPrivateQSG::~QMapPolylineObjectPrivateQSG()
@@ -102,7 +104,7 @@ QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
QSGNode *root,
QQuickWindow * /*window*/)
{
- Q_UNUSED(visibleNode)
+ Q_UNUSED(visibleNode);
MapPolylineNode *node = static_cast<MapPolylineNode *>(oldNode);
bool created = false;
@@ -127,24 +129,23 @@ QSGNode *QMapPolylineObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
return node;
}
-QList<QGeoCoordinate> QMapPolylineObjectPrivateQSG::path() const { return m_geoPath.path(); }
-
-QColor QMapPolylineObjectPrivateQSG::color() const { return m_color; }
-
-qreal QMapPolylineObjectPrivateQSG::width() const { return m_width; }
+QList<QGeoCoordinate> QMapPolylineObjectPrivateQSG::path() const
+{
+ return m_geoPath.path();
+}
void QMapPolylineObjectPrivateQSG::setPath(const QList<QGeoCoordinate> &path)
{
+ m_path = path;
m_geoPath.setPath(path);
updateGeometry();
-
if (m_map)
emit m_map->sgNodeChanged();
}
void QMapPolylineObjectPrivateQSG::setColor(const QColor &color)
{
- m_color = color;
+ QMapPolylineObjectPrivateDefault::setColor(color);
updateGeometry();
if (m_map)
@@ -153,7 +154,7 @@ void QMapPolylineObjectPrivateQSG::setColor(const QColor &color)
void QMapPolylineObjectPrivateQSG::setWidth(qreal width)
{
- m_width = width;
+ QMapPolylineObjectPrivateDefault::setWidth(width);
updateGeometry();
if (m_map)
@@ -165,4 +166,9 @@ QGeoMapObjectPrivate *QMapPolylineObjectPrivateQSG::clone()
return new QMapPolylineObjectPrivateQSG(static_cast<QMapPolylineObjectPrivate &>(*this));
}
+QGeoShape QMapPolylineObjectPrivateQSG::geoShape() const
+{
+ return m_geoPath;
+}
+
QT_END_NAMESPACE
diff --git a/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h b/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h
index 792413e5..e8eb5839 100644
--- a/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmappolylineobjectqsg_p_p.h
@@ -54,10 +54,11 @@
#include <QtLocation/private/qmappolylineobject_p.h>
#include <QtLocation/private/qqsgmapobject_p.h>
#include <QtCore/qscopedvaluerollback.h>
+#include <QtPositioning/private/qgeopath_p.h>
QT_BEGIN_NAMESPACE
-class Q_LOCATION_PRIVATE_EXPORT QMapPolylineObjectPrivateQSG : public QMapPolylineObjectPrivate, public QQSGMapObject
+class Q_LOCATION_PRIVATE_EXPORT QMapPolylineObjectPrivateQSG : public QMapPolylineObjectPrivateDefault, public QQSGMapObject
{
public:
QMapPolylineObjectPrivateQSG(QGeoMapObject *q);
@@ -75,22 +76,17 @@ public:
// QGeoMapPolylinePrivate interface
QList<QGeoCoordinate> path() const override;
- QColor color() const override;
- qreal width() const override;
-
void setPath(const QList<QGeoCoordinate> &path) override;
void setColor(const QColor &color) override;
void setWidth(qreal width) override;
// QGeoMapObjectPrivate
QGeoMapObjectPrivate *clone() override;
+ virtual QGeoShape geoShape() const override;
// Data Members
+ QGeoPathEager m_geoPath;
QGeoMapPolylineGeometry m_geometry;
- QGeoPath m_geoPath;
-
- QColor m_color;
- qreal m_width = 0;
bool m_updatingGeometry = false;
};
diff --git a/src/location/labs/qsg/qmaprouteobjectqsg.cpp b/src/location/labs/qsg/qmaprouteobjectqsg.cpp
index eaea64f3..8f347f88 100644
--- a/src/location/labs/qsg/qmaprouteobjectqsg.cpp
+++ b/src/location/labs/qsg/qmaprouteobjectqsg.cpp
@@ -100,4 +100,9 @@ void QMapRouteObjectPrivateQSG::setVisible(bool visible)
m_polyline->setVisible(visible);
}
+QGeoShape QMapRouteObjectPrivateQSG::geoShape() const
+{
+ return m_polyline->geoShape();
+}
+
QT_END_NAMESPACE
diff --git a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h
index 0c946259..2ade5d53 100644
--- a/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h
+++ b/src/location/labs/qsg/qmaprouteobjectqsg_p_p.h
@@ -80,6 +80,7 @@ public:
QGeoMapObjectPrivate *clone() override;
void setMap(QGeoMap *map) override;
void setVisible(bool visible) override;
+ virtual QGeoShape geoShape() const override;
// Data Members
QScopedPointer<QMapPolylineObjectPrivateQSG> m_polyline;