summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2017-02-28 18:26:19 -0800
committerPaolo Angelelli <paolo.angelelli@qt.io>2017-08-30 13:49:36 +0000
commit6024168ef21dd4fe6c5ddd7e837d56076e886e01 (patch)
tree140e9d827a4045382dee6db2412268cc164cdfc5
parent8dae4824df50dfde8c4910bdf88cde78aeb1ce18 (diff)
downloadqtlocation-6024168ef21dd4fe6c5ddd7e837d56076e886e01.tar.gz
Mapbox GL native circle support
Circles crossing one pole are drawn inverted. Circles crossing 2 poles do not even have the correct geometry. Nevertheless, a first approximation. Task-number: QTBUG-58869 Change-Id: I5a508f5d6e27c4f08412a7ae327883866068a1e9 Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem.cpp10
-rw-r--r--src/location/declarativemaps/qdeclarativecirclemapitem_p.h8
-rw-r--r--src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp22
-rw-r--r--src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp48
-rw-r--r--src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h1
5 files changed, 75 insertions, 14 deletions
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
index 5f002bf9..91328dc7 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem.cpp
@@ -262,7 +262,7 @@ void QGeoMapCircleGeometry::updateScreenPointsInvert(const QList<QDoubleVector2D
sourceBounds_ = screenBounds_;
}
-static bool crossEarthPole(const QGeoCoordinate &center, qreal distance)
+bool QDeclarativeCircleMapItem::crossEarthPole(const QGeoCoordinate &center, qreal distance)
{
qreal poleLat = 90;
QGeoCoordinate northPole = QGeoCoordinate(poleLat, center.longitude());
@@ -275,7 +275,7 @@ static bool crossEarthPole(const QGeoCoordinate &center, qreal distance)
return false;
}
-static void calculatePeripheralPoints(QList<QGeoCoordinate> &path,
+void QDeclarativeCircleMapItem::calculatePeripheralPoints(QList<QGeoCoordinate> &path,
const QGeoCoordinate &center,
qreal distance,
int steps,
@@ -644,9 +644,9 @@ void QDeclarativeCircleMapItem::updateCirclePathForRendering(QList<QDoubleVector
const QGeoCoordinate &center,
qreal distance)
{
- qreal poleLat = 90;
- qreal distanceToNorthPole = center.distanceTo(QGeoCoordinate(poleLat, 0));
- qreal distanceToSouthPole = center.distanceTo(QGeoCoordinate(-poleLat, 0));
+ const qreal poleLat = 90;
+ const qreal distanceToNorthPole = center.distanceTo(QGeoCoordinate(poleLat, 0));
+ const qreal distanceToSouthPole = center.distanceTo(QGeoCoordinate(-poleLat, 0));
bool crossNorthPole = distanceToNorthPole < distance;
bool crossSouthPole = distanceToSouthPole < distance;
diff --git a/src/location/declarativemaps/qdeclarativecirclemapitem_p.h b/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
index 15774427..c117b444 100644
--- a/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
+++ b/src/location/declarativemaps/qdeclarativecirclemapitem_p.h
@@ -96,6 +96,12 @@ public:
const QGeoShape &geoShape() const Q_DECL_OVERRIDE;
QGeoMap::ItemType itemType() const Q_DECL_OVERRIDE;
+ static bool crossEarthPole(const QGeoCoordinate &center, qreal distance);
+ static void calculatePeripheralPoints(QList<QGeoCoordinate> &path, const QGeoCoordinate &center,
+ qreal distance, int steps, QGeoCoordinate &leftBound);
+ bool preserveCircleGeometry(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
+ qreal distance);
+
Q_SIGNALS:
void centerChanged(const QGeoCoordinate &center);
void radiusChanged(qreal radius);
@@ -111,8 +117,6 @@ protected Q_SLOTS:
private:
void updateCirclePath();
- bool preserveCircleGeometry(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
- qreal distance);
void updateCirclePathForRendering(QList<QDoubleVector2D> &path, const QGeoCoordinate &center,
qreal distance);
diff --git a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
index 1001ca31..2f506325 100644
--- a/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
+++ b/src/plugins/geoservices/mapboxgl/qgeomapmapboxgl.cpp
@@ -176,8 +176,7 @@ void QGeoMapMapboxGLPrivate::removeParameter(QGeoMapParameter *param)
QGeoMap::ItemTypes QGeoMapMapboxGLPrivate::supportedMapItemTypes() const
{
- // TODO https://bugreports.qt.io/browse/QTBUG-58869
- return QGeoMap::MapRectangle | QGeoMap::MapPolygon | QGeoMap::MapPolyline;
+ return QGeoMap::MapRectangle | QGeoMap::MapCircle | QGeoMap::MapPolygon | QGeoMap::MapPolyline;
}
void QGeoMapMapboxGLPrivate::addMapItem(QDeclarativeGeoMapItemBase *item)
@@ -188,25 +187,32 @@ void QGeoMapMapboxGLPrivate::addMapItem(QDeclarativeGeoMapItemBase *item)
case QGeoMap::NoItem:
case QGeoMap::MapQuickItem:
case QGeoMap::CustomMapItem:
- case QGeoMap::MapCircle:
return;
case QGeoMap::MapRectangle: {
- QDeclarativeRectangleMapItem *mapItem = qobject_cast<QDeclarativeRectangleMapItem *>(item);
+ QDeclarativeRectangleMapItem *mapItem = static_cast<QDeclarativeRectangleMapItem *>(item);
QObject::connect(mapItem, &QDeclarativeRectangleMapItem::bottomRightChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
QObject::connect(mapItem, &QDeclarativeRectangleMapItem::topLeftChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
QObject::connect(mapItem, &QDeclarativeRectangleMapItem::colorChanged, q, &QGeoMapMapboxGL::onMapItemPropertyChanged);
QObject::connect(mapItem->border(), &QDeclarativeMapLineProperties::colorChanged, q, &QGeoMapMapboxGL::onMapItemSubPropertyChanged);
QObject::connect(mapItem->border(), &QDeclarativeMapLineProperties::widthChanged, q, &QGeoMapMapboxGL::onMapItemUnsupportedPropertyChanged);
} break;
+ case QGeoMap::MapCircle: {
+ QDeclarativeCircleMapItem *mapItem = static_cast<QDeclarativeCircleMapItem *>(item);
+ QObject::connect(mapItem, &QDeclarativeCircleMapItem::centerChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
+ QObject::connect(mapItem, &QDeclarativeCircleMapItem::radiusChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
+ QObject::connect(mapItem, &QDeclarativeCircleMapItem::colorChanged, q, &QGeoMapMapboxGL::onMapItemPropertyChanged);
+ QObject::connect(mapItem->border(), &QDeclarativeMapLineProperties::colorChanged, q, &QGeoMapMapboxGL::onMapItemSubPropertyChanged);
+ QObject::connect(mapItem->border(), &QDeclarativeMapLineProperties::widthChanged, q, &QGeoMapMapboxGL::onMapItemUnsupportedPropertyChanged);
+ } break;
case QGeoMap::MapPolygon: {
- QDeclarativePolygonMapItem *mapItem = qobject_cast<QDeclarativePolygonMapItem *>(item);
+ QDeclarativePolygonMapItem *mapItem = static_cast<QDeclarativePolygonMapItem *>(item);
QObject::connect(mapItem, &QDeclarativePolygonMapItem::pathChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
QObject::connect(mapItem, &QDeclarativePolygonMapItem::colorChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
QObject::connect(mapItem->border(), &QDeclarativeMapLineProperties::colorChanged, q, &QGeoMapMapboxGL::onMapItemSubPropertyChanged);
QObject::connect(mapItem->border(), &QDeclarativeMapLineProperties::widthChanged, q, &QGeoMapMapboxGL::onMapItemUnsupportedPropertyChanged);
} break;
case QGeoMap::MapPolyline: {
- QDeclarativePolylineMapItem *mapItem = qobject_cast<QDeclarativePolylineMapItem *>(item);
+ QDeclarativePolylineMapItem *mapItem = static_cast<QDeclarativePolylineMapItem *>(item);
QObject::connect(mapItem, &QDeclarativePolylineMapItem::pathChanged, q, &QGeoMapMapboxGL::onMapItemGeometryChanged);
QObject::connect(mapItem->line(), &QDeclarativeMapLineProperties::colorChanged, q, &QGeoMapMapboxGL::onMapItemSubPropertyChanged);
QObject::connect(mapItem->line(), &QDeclarativeMapLineProperties::widthChanged, q, &QGeoMapMapboxGL::onMapItemSubPropertyChanged);
@@ -228,11 +234,13 @@ void QGeoMapMapboxGLPrivate::removeMapItem(QDeclarativeGeoMapItemBase *item)
case QGeoMap::NoItem:
case QGeoMap::MapQuickItem:
case QGeoMap::CustomMapItem:
- case QGeoMap::MapCircle:
return;
case QGeoMap::MapRectangle:
q->disconnect(static_cast<QDeclarativeRectangleMapItem *>(item)->border());
break;
+ case QGeoMap::MapCircle:
+ q->disconnect(static_cast<QDeclarativeCircleMapItem *>(item)->border());
+ break;
case QGeoMap::MapPolygon:
q->disconnect(static_cast<QDeclarativePolygonMapItem *>(item)->border());
break;
diff --git a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp
index f79f0a38..f8bd9b4d 100644
--- a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp
+++ b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange.cpp
@@ -86,6 +86,32 @@ QMapbox::Feature featureFromMapRectangle(QDeclarativeRectangleMapItem *mapItem)
return QMapbox::Feature(QMapbox::Feature::PolygonType, geometry, {}, getId(mapItem));
}
+QMapbox::Feature featureFromMapCircle(QDeclarativeCircleMapItem *mapItem)
+{
+ static const int circleSamples = 128;
+
+ QList<QGeoCoordinate> path;
+ QGeoCoordinate leftBound;
+ QDeclarativeCircleMapItem::calculatePeripheralPoints(path, mapItem->center(), mapItem->radius(), circleSamples, leftBound);
+ QList<QDoubleVector2D> pathProjected;
+ for (const QGeoCoordinate &c : qAsConst(path))
+ pathProjected << mapItem->map()->geoProjection().geoToMapProjection(c);
+ if (QDeclarativeCircleMapItem::crossEarthPole(mapItem->center(), mapItem->radius()))
+ mapItem->preserveCircleGeometry(pathProjected, mapItem->center(), mapItem->radius());
+ path.clear();
+ for (const QDoubleVector2D &c : qAsConst(pathProjected))
+ path << mapItem->map()->geoProjection().mapProjectionToGeo(c);
+
+
+ QMapbox::Coordinates coordinates;
+ for (const QGeoCoordinate &coordinate : path) {
+ coordinates << QMapbox::Coordinate { coordinate.latitude(), coordinate.longitude() };
+ }
+ coordinates.append(coordinates.first()); // closing the path
+ QMapbox::CoordinatesCollections geometry { { coordinates } };
+ return QMapbox::Feature(QMapbox::Feature::PolygonType, geometry, {}, getId(mapItem));
+}
+
QMapbox::Feature featureFromMapPolygon(QDeclarativePolygonMapItem *mapItem)
{
const QGeoPath *path = static_cast<const QGeoPath *>(&mapItem->geoShape());
@@ -126,6 +152,8 @@ QMapbox::Feature featureFromMapItem(QDeclarativeGeoMapItemBase *item)
switch (item->itemType()) {
case QGeoMap::MapRectangle:
return featureFromMapRectangle(static_cast<QDeclarativeRectangleMapItem *>(item));
+ case QGeoMap::MapCircle:
+ return featureFromMapCircle(static_cast<QDeclarativeCircleMapItem *>(item));
case QGeoMap::MapPolygon:
return featureFromMapPolygon(static_cast<QDeclarativePolygonMapItem *>(item));
case QGeoMap::MapPolyline:
@@ -182,6 +210,7 @@ QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleChange::addMapItem(QDe
switch (item->itemType()) {
case QGeoMap::MapRectangle:
+ case QGeoMap::MapCircle:
case QGeoMap::MapPolygon:
case QGeoMap::MapPolyline:
break;
@@ -325,6 +354,8 @@ QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleSetPaintProperty::from
switch (item->itemType()) {
case QGeoMap::MapRectangle:
return fromMapItem(static_cast<QDeclarativeRectangleMapItem *>(item));
+ case QGeoMap::MapCircle:
+ return fromMapItem(static_cast<QDeclarativeCircleMapItem *>(item));
case QGeoMap::MapPolygon:
return fromMapItem(static_cast<QDeclarativePolygonMapItem *>(item));
case QGeoMap::MapPolyline:
@@ -352,6 +383,23 @@ QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleSetPaintProperty::from
return changes;
}
+QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleSetPaintProperty::fromMapItem(QDeclarativeCircleMapItem *item)
+{
+ QList<QSharedPointer<QMapboxGLStyleChange>> changes;
+ changes.reserve(3);
+
+ const QString id = getId(item);
+
+ changes << QSharedPointer<QMapboxGLStyleChange>(
+ new QMapboxGLStyleSetPaintProperty(id, QStringLiteral("fill-opacity"), item->mapItemOpacity()));
+ changes << QSharedPointer<QMapboxGLStyleChange>(
+ new QMapboxGLStyleSetPaintProperty(id, QStringLiteral("fill-color"), item->color()));
+ changes << QSharedPointer<QMapboxGLStyleChange>(
+ new QMapboxGLStyleSetPaintProperty(id, QStringLiteral("fill-outline-color"), item->border()->color()));
+
+ return changes;
+}
+
QList<QSharedPointer<QMapboxGLStyleChange>> QMapboxGLStyleSetPaintProperty::fromMapItem(QDeclarativePolygonMapItem *item)
{
QList<QSharedPointer<QMapboxGLStyleChange>> changes;
diff --git a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h
index aa81d89f..33737c1d 100644
--- a/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h
+++ b/src/plugins/geoservices/mapboxgl/qmapboxglstylechange_p.h
@@ -93,6 +93,7 @@ public:
private:
static QList<QSharedPointer<QMapboxGLStyleChange>> fromMapItem(QDeclarativeRectangleMapItem *);
+ static QList<QSharedPointer<QMapboxGLStyleChange>> fromMapItem(QDeclarativeCircleMapItem *);
static QList<QSharedPointer<QMapboxGLStyleChange>> fromMapItem(QDeclarativePolygonMapItem *);
static QList<QSharedPointer<QMapboxGLStyleChange>> fromMapItem(QDeclarativePolylineMapItem *);