summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Klocek <michal.klocek@digia.com>2011-12-13 10:30:10 +0200
committerQt by Nokia <qt-info@nokia.com>2011-12-13 12:58:25 +0100
commit68e2fc8934756e299b04642682d1d8203e971399 (patch)
treee602d68bf4ddd87421e450be73bc8429108faeb2
parentfc576c395676bb766e4a14f8fb38df7e7498ccbf (diff)
downloadqtlocation-68e2fc8934756e299b04642682d1d8203e971399.tar.gz
Reimplement mapitems
* fixes performance issue on high zoomLevels * fixes "pop" effect when zooming * fixes flickering when zooming circle * remove qquickpainteditem * adds map mapitem graphical representation as geometry node * add basic vertex drawing support * removes updateContent, mapChanged, contentLeftPoint Change-Id: Ic76b24c7e47f83c2a45a680607c46595e5a9a790 Reviewed-by: Michal Klocek <michal.klocek@digia.com> Reviewed-by: Juha Vuolle <juha.vuolle@nokia.com>
-rw-r--r--src/imports/location/qdeclarativecirclemapitem.cpp380
-rw-r--r--src/imports/location/qdeclarativecirclemapitem_p.h81
-rw-r--r--src/imports/location/qdeclarativegeomapitembase.cpp30
-rw-r--r--src/imports/location/qdeclarativegeomapitembase_p.h17
-rw-r--r--src/imports/location/qdeclarativegeomapquickitem.cpp108
-rw-r--r--src/imports/location/qdeclarativegeomapquickitem_p.h12
-rw-r--r--src/imports/location/qdeclarativepolygonmapitem.cpp294
-rw-r--r--src/imports/location/qdeclarativepolygonmapitem_p.h76
-rw-r--r--src/imports/location/qdeclarativepolylinemapitem.cpp304
-rw-r--r--src/imports/location/qdeclarativepolylinemapitem_p.h77
-rw-r--r--src/imports/location/qdeclarativerectanglemapitem.cpp308
-rw-r--r--src/imports/location/qdeclarativerectanglemapitem_p.h75
-rw-r--r--src/imports/location/qdeclarativeroutemapitem.cpp88
-rw-r--r--src/imports/location/qdeclarativeroutemapitem_p.h16
14 files changed, 820 insertions, 1046 deletions
diff --git a/src/imports/location/qdeclarativecirclemapitem.cpp b/src/imports/location/qdeclarativecirclemapitem.cpp
index b6fdeada..a2e2a026 100644
--- a/src/imports/location/qdeclarativecirclemapitem.cpp
+++ b/src/imports/location/qdeclarativecirclemapitem.cpp
@@ -54,6 +54,11 @@ QT_BEGIN_NAMESPACE
#define M_PI 3.14159265358979323846
#endif
+struct Vertex
+{
+ QVector2D position;
+};
+
static const qreal qgeocoordinate_EARTH_MEAN_RADIUS = 6371.0072;
inline static qreal qgeocoordinate_degToRad(qreal deg)
@@ -65,9 +70,8 @@ inline static qreal qgeocoordinate_radToDeg(qreal rad)
return rad * 180 / M_PI;
}
-static QPolygonF createPolygon(const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h)
+static void updatePolygon(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h)
{
- QPolygonF points;
qreal minX, maxX, minY, maxY;
//TODO: dateline handling
@@ -99,23 +103,82 @@ static QPolygonF createPolygon(const Map& map, const QList<QGeoCoordinate> &path
w = maxX - minX;
h = maxY - minY;
+}
+
+static void calcualtePeripheralPoints(QList<QGeoCoordinate>& path, const QGeoCoordinate& center, qreal distance, int steps)
+{
+ // get angular distance in radians
+ distance = distance / (qgeocoordinate_EARTH_MEAN_RADIUS * 1000);
- return points;
+ // We are using horizontal system, we have radius (distance)
+ // projected onto Celestial sphere.
+ // This way we know the altitude in horizontal system => h = 90 - r;
+ // We can now "spin" around with azimuth as a step to get all the points from
+ // peripheral of the given circle.
+ // To get geographical position we need to change from horizontal system
+ // to equatorial system.
+
+ // get location
+ qreal lat = qgeocoordinate_degToRad(center.latitude());
+ qreal lon = qgeocoordinate_degToRad(center.longitude());
+
+ // precalculate
+ qreal cos_h = sin(distance);
+ qreal sin_h = cos(distance);
+ qreal cos_phi = cos(lat), sin_phi = sin(lat);
+ qreal sin_phi_x_sin_h = sin_phi * sin_h;
+ qreal cos_phi_x_cos_h = cos_phi * cos_h;
+ qreal sin_phi_x_cos_h = sin_phi * cos_h;
+ qreal cos_phi_x_sin_h = cos_phi * sin_h;
+
+ for (int i = 0; i < steps; ++i) {
+
+ qreal a = 2 * M_PI * i / steps;
+ qreal sin_delta = sin_phi_x_sin_h - cos_phi_x_cos_h * cos(a);
+ qreal cos_delta_x_cos_tau = cos_phi_x_sin_h + sin_phi_x_cos_h * cos(a);
+ qreal cos_delta_x_sin_tau = -sin(a) * cos_h;
+ // get the hour angle (use Cartesian to polar conversion)
+ qreal tau = atan2(cos_delta_x_sin_tau, cos_delta_x_cos_tau);
+ qreal cos_delta = sqrt(cos_delta_x_sin_tau
+ * cos_delta_x_sin_tau + cos_delta_x_cos_tau
+ * cos_delta_x_cos_tau);
+ // get declination ( use Cartesian to polar conversion )
+ qreal delta = atan2(sin_delta, cos_delta);
+ // get right ascension from tau , use a greenwich star time of 0
+ qreal alpha = lon - tau;
+ qreal lat2 = qgeocoordinate_radToDeg(delta);
+ qreal lon2 = qgeocoordinate_radToDeg(alpha);
+ if (lon2 < -180.0) {
+ lon2 += 360.0;
+ } else if (lon2 > 180.0) {
+ lon2 -= 360.0;
+ }
+ path << QGeoCoordinate(lat2, lon2, 0.0f);
+ }
}
QDeclarativeCircleMapItem::QDeclarativeCircleMapItem(QQuickItem *parent):
- QDeclarativeGeoMapItemBase(parent),
+ QDeclarativeGeoMapItemBase(parent),
center_(0),
- circleItem_(new CircleMapPaintedItem(this)),
+ mapCircleNode_(0),
+ radius_(0),
+ zoomLevel_(0.0),
dragActive_(false)
+
{
- circleItem_->setParentItem(this);
+ setFlag(ItemHasContents, true);
}
QDeclarativeCircleMapItem::~QDeclarativeCircleMapItem()
{
}
+void QDeclarativeCircleMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map)
+{
+ QDeclarativeGeoMapItemBase::setMap(quickMap,map);
+ if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
+}
+
void QDeclarativeCircleMapItem::setCenter(QDeclarativeCoordinate *center)
{
if (center_ == center)
@@ -123,10 +186,8 @@ void QDeclarativeCircleMapItem::setCenter(QDeclarativeCoordinate *center)
if (center_)
center_->disconnect(this);
center_ = center;
- if (!center_) {
- circleItem_->setCenter(QGeoCoordinate());
- } else {
- circleItem_->setCenter(center_->coordinate());
+
+ if (center_) {
connect(center_, SIGNAL(latitudeChanged(double)), this,
SLOT(updateMapItem()));
connect(center_, SIGNAL(longitudeChanged(double)), this,
@@ -134,8 +195,9 @@ void QDeclarativeCircleMapItem::setCenter(QDeclarativeCoordinate *center)
connect(center_, SIGNAL(altitudeChanged(double)), this,
SLOT(updateMapItem()));
}
+
+ updateMapItem(true);
emit centerChanged(center_);
- updateMapItem();
}
QDeclarativeCoordinate* QDeclarativeCircleMapItem::center()
@@ -143,66 +205,80 @@ QDeclarativeCoordinate* QDeclarativeCircleMapItem::center()
return center_;
}
-void QDeclarativeCircleMapItem::updateContent()
+void QDeclarativeCircleMapItem::setColor(const QColor &color)
{
- circleItem_->updateGeometry();
- setWidth(circleItem_->width());
- setHeight(circleItem_->height());
+ if (color_ == color)
+ return;
+ color_ = color;
+ updateMapItem(false);
+ emit colorChanged(color_);
}
-QPointF QDeclarativeCircleMapItem::contentTopLeftPoint()
+QColor QDeclarativeCircleMapItem::color() const
{
- return map_->coordinateToScreenPosition(center()->coordinate(), false) - QPointF(width(),height()) / 2;
+ return color_;
}
-void QDeclarativeCircleMapItem::mapChanged()
+void QDeclarativeCircleMapItem::setRadius(qreal radius)
{
- circleItem_->setMap(map_);
- if (map_) {
- connect(map_, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
- // initial update
- handleCameraDataChanged(map_->cameraData());
- }
-}
-void QDeclarativeCircleMapItem::handleCenterCoordinateChanged()
-{
- circleItem_->setCenter(center_->coordinate());
-}
+ if (radius_ == radius)
+ return;
-void QDeclarativeCircleMapItem::handleCameraDataChanged(const CameraData& cameraData)
-{
- circleItem_->setZoomLevel(cameraData.zoomFactor());
- updateMapItem();
+ radius_ = radius;
+ updateMapItem(true);
+ emit radiusChanged(radius);
}
-void QDeclarativeCircleMapItem::setColor(const QColor &color)
+qreal QDeclarativeCircleMapItem::radius() const
{
- if (color_ == color)
- return;
- color_ = color;
- QBrush m_brush(color);
- circleItem_->setBrush(m_brush);
- emit colorChanged(color_);
+ return radius_;
}
-QColor QDeclarativeCircleMapItem::color() const
+
+QSGNode* QDeclarativeCircleMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
- return color_;
+ Q_UNUSED(data);
+
+ MapCircleNode *node = static_cast<MapCircleNode*>(oldNode);
+
+ if (!node) {
+ mapCircleNode_ = new MapCircleNode();
+ updateMapItem(true);
+ }
+
+ mapCircleNode_->update();
+ return mapCircleNode_;
}
-void QDeclarativeCircleMapItem::setRadius(qreal radius)
+void QDeclarativeCircleMapItem::updateMapItem(bool dirtyGeometry)
{
- if (circleItem_->radius() == radius)
+ if (!map() || !center() || !center()->coordinate().isValid() || !mapCircleNode_)
return;
- circleItem_->setRadius(radius);
- updateMapItem();
- emit radiusChanged(radius);
+
+ mapCircleNode_->setBrushColor(color_);
+
+ if (dirtyGeometry) mapCircleNode_->setGeometry(*map(), radius(),center()->coordinate());
+
+ const QSizeF& size = mapCircleNode_->size();
+
+ setWidth(size.width());
+ setHeight(size.height());
+
+ setPositionOnMap(center()->coordinate(), QPointF(size.width(),size.height()) / 2);
+ update();
+
}
-qreal QDeclarativeCircleMapItem::radius() const
+void QDeclarativeCircleMapItem::handleCameraDataChanged(const CameraData& cameraData)
{
- return circleItem_->radius();
+ if (cameraData.zoomFactor() != zoomLevel_) {
+ zoomLevel_ = cameraData.zoomFactor();
+ updateMapItem(true);
+ }
+ else {
+ updateMapItem(false);
+ }
}
void QDeclarativeCircleMapItem::dragEnded()
@@ -211,7 +287,7 @@ void QDeclarativeCircleMapItem::dragEnded()
return;
dragActive_ = false;
QPointF newPoint = QPointF(x(),y()) + QPointF(width(), height()) / 2;
- QGeoCoordinate newCoordinate = map_->screenPositionToCoordinate(newPoint, false);
+ QGeoCoordinate newCoordinate = map()->screenPositionToCoordinate(newPoint, false);
if (newCoordinate.isValid()) {
internalCoordinate_.setCoordinate(newCoordinate);
setCenter(&internalCoordinate_);
@@ -225,204 +301,98 @@ void QDeclarativeCircleMapItem::dragStarted()
bool QDeclarativeCircleMapItem::contains(QPointF point)
{
- return circleItem_->contains(point);
+ return mapCircleNode_->contains(point);
}
-void QDeclarativeCircleMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- // TODO - if X and Y of the wrapper item are changed, currently
- // the item moves, but returns to old position when map camera changes
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
-}
//////////////////////////////////////////////////////////////////////
-CircleMapPaintedItem::CircleMapPaintedItem(QQuickItem *parent):
- QQuickPaintedItem(parent),
- map_(0),
- zoomLevel_(-1),
- initialized_(false),
- dirtyGeometry_(false)
+MapCircleNode::MapCircleNode():
+ fillColor_(Qt::black),
+ borderColor_(Qt::black),
+ geometry_(QSGGeometry::defaultAttributes_Point2D(),0)
{
- setAntialiasing(true);
- connect(this, SIGNAL(xChanged()), this, SLOT(update()));
- connect(this, SIGNAL(yChanged()), this, SLOT(update()));
+ geometry_.setDrawingMode(GL_TRIANGLE_FAN);
+ QSGGeometryNode::setMaterial(&fill_material_);
+ QSGGeometryNode::setGeometry(&geometry_);
}
-CircleMapPaintedItem::~CircleMapPaintedItem() {}
+MapCircleNode::~MapCircleNode() {}
-void CircleMapPaintedItem::setMap(Map* map)
+void MapCircleNode::update()
{
- if (map_ == map)
+ //TODO: optimize , perform calculation only if polygon has changed
+ if (polygon_.size()==0)
return;
- map_ = map;
-}
-Map* CircleMapPaintedItem::map()
-{
- return map_;
-}
+ QSGGeometry *fill = QSGGeometryNode::geometry();
-void CircleMapPaintedItem::setZoomLevel(qreal zoomLevel)
-{
- if (zoomLevel_ == zoomLevel)
- return;
- zoomLevel_ = zoomLevel;
- dirtyGeometry_ = true;
-}
+ Q_ASSERT(fill->sizeOfVertex() == sizeof(Vertex));
-qreal CircleMapPaintedItem::zoomLevel() const
-{
- return zoomLevel_;
-}
-
-void CircleMapPaintedItem::paint(QPainter *painter)
-{
- if (!initialized_)
- return;
-
- painter->setPen(pen_);
- painter->setBrush(brush_);
- painter->drawConvexPolygon(polygon_);
-}
+ int fillVertexCount = 0;
+ //note this will not allocate new buffer if the size has not changed
+ fill->allocate(polygon_.size() + 1 + 1); //one for center + one to close the circle
-void CircleMapPaintedItem::updateGeometry()
-{
- if (!dirtyGeometry_)
- return;
-
- initialized_ = false;
- if (!map_)
- return;
+ Vertex *vertices = (Vertex *)fill->vertexData();
- if (!centerCoord_.isValid() || radius_ <= 0)
- return;
+ //set center
+ vertices[fillVertexCount++].position = QVector2D(size_.width()/2,size_.height()/2);
- if (zoomLevel_ == -1)
- return;
-
- QPointF center = map_->coordinateToScreenPosition(centerCoord_, false);
-
- qreal w = 0;
- qreal h = 0;
- //TODO: execute only for radius or center changes
- path_.clear();
- calcualtePeripheralPoints(path_, centerCoord_, radius_, 125);
- //TODO: optimize essential part
- polygon_ = createPolygon(*map_, path_, w, h);
-
- setWidth(w);
- setHeight(h);
- setContentsSize(QSize(w, h));
-
- initialized_ = true;
- dirtyGeometry_ = false;
- update(); // qquickpainteditem
-}
-
-void CircleMapPaintedItem::calcualtePeripheralPoints(QList<QGeoCoordinate>& path, const QGeoCoordinate& center, qreal distance, int steps) const
-{
- // get angular distance in radians
- distance = distance / (qgeocoordinate_EARTH_MEAN_RADIUS * 1000);
-
- // We are using horizontal system, we have radius (distance)
- // projected onto Celestial sphere.
- // This way we know the altitude in horizontal system => h = 90 - r;
- // We can now "spin" around with azimuth as a step to get all the points from
- // peripheral of the given circle.
- // To get geographical position we need to change from horizontal system
- // to equatorial system.
-
- // get location
- qreal lat = qgeocoordinate_degToRad(center.latitude());
- qreal lon = qgeocoordinate_degToRad(center.longitude());
+ for (int i = 0; i < polygon_.size(); ++i) {
+ vertices[fillVertexCount++].position = QVector2D(polygon_.at(i));
+ }
+ //close circle
+ vertices[fillVertexCount++].position = QVector2D(polygon_.at(0));
- // precalculate
- qreal cos_h = sin(distance);
- qreal sin_h = cos(distance);
- qreal cos_phi = cos(lat), sin_phi = sin(lat);
- qreal sin_phi_x_sin_h = sin_phi * sin_h;
- qreal cos_phi_x_cos_h = cos_phi * cos_h;
- qreal sin_phi_x_cos_h = sin_phi * cos_h;
- qreal cos_phi_x_sin_h = cos_phi * sin_h;
+ Q_ASSERT(fillVertexCount == fill->vertexCount());
- for (int i = 0; i < steps; ++i) {
+ markDirty(DirtyGeometry);
- qreal a = 2 * M_PI * i / steps;
- qreal sin_delta = sin_phi_x_sin_h - cos_phi_x_cos_h * cos(a);
- qreal cos_delta_x_cos_tau = cos_phi_x_sin_h + sin_phi_x_cos_h * cos(a);
- qreal cos_delta_x_sin_tau = -sin(a) * cos_h;
- // get the hour angle (use Cartesian to polar conversion)
- qreal tau = atan2(cos_delta_x_sin_tau, cos_delta_x_cos_tau);
- qreal cos_delta = sqrt(cos_delta_x_sin_tau
- * cos_delta_x_sin_tau + cos_delta_x_cos_tau
- * cos_delta_x_cos_tau);
- // get declination ( use Cartesian to polar conversion )
- qreal delta = atan2(sin_delta, cos_delta);
- // get right ascension from tau , use a greenwich star time of 0
- qreal alpha = lon - tau;
- qreal lat2 = qgeocoordinate_radToDeg(delta);
- qreal lon2 = qgeocoordinate_radToDeg(alpha);
- if (lon2 < -180.0) {
- lon2 += 360.0;
- } else if (lon2 > 180.0) {
- lon2 -= 360.0;
- }
- path << QGeoCoordinate(lat2, lon2, 0.0f);
+ if (fillColor_ != fill_material_.color()) {
+ fill_material_.setColor(fillColor_);
+ setMaterial(&fill_material_);
}
-}
-
-
-void CircleMapPaintedItem::setBrush(const QBrush &brush)
-{
- brush_ = brush;
-}
-QBrush CircleMapPaintedItem::brush() const
-{
- return brush_;
+ //TODO: implement me : borders , gradient
}
-void CircleMapPaintedItem::setPen(const QPen &pen)
+void MapCircleNode::setBrushColor(const QColor &color)
{
- pen_ = pen;
+ fillColor_= color;
}
-QPen CircleMapPaintedItem::pen() const
+QColor MapCircleNode::brushColor() const
{
- return pen_;
+ return fillColor_;
}
-void CircleMapPaintedItem::setCenter(const QGeoCoordinate &center)
+void MapCircleNode::setPenColor(const QColor &color)
{
- if (centerCoord_ == center)
- return;
- centerCoord_ = center;
- dirtyGeometry_ = true;
+ borderColor_ = color;
}
-const QGeoCoordinate& CircleMapPaintedItem::center() const
+QColor MapCircleNode::penColor() const
{
- return centerCoord_;
+ return borderColor_;
}
-bool CircleMapPaintedItem::contains(QPointF point)
+bool MapCircleNode::contains(QPointF point)
{
return polygon_.containsPoint(point, Qt::OddEvenFill);
}
-void CircleMapPaintedItem::setRadius(qreal radius)
+
+void MapCircleNode::setGeometry(const Map& map, qreal radius,const QGeoCoordinate &center)
{
- if (radius_ == radius)
- return;
+ path_.clear();
+ calcualtePeripheralPoints(path_, center, radius, 125);
- radius_ = radius;
- dirtyGeometry_ = true;
-}
+ qreal w = 0;
+ qreal h = 0;
-qreal CircleMapPaintedItem::radius() const
-{
- return radius_;
+ polygon_.clear();
+ updatePolygon(polygon_, map, path_, w, h);
+ size_ = QSizeF(w, h);
}
QT_END_NAMESPACE
diff --git a/src/imports/location/qdeclarativecirclemapitem_p.h b/src/imports/location/qdeclarativecirclemapitem_p.h
index 012274d9..886c9fa0 100644
--- a/src/imports/location/qdeclarativecirclemapitem_p.h
+++ b/src/imports/location/qdeclarativecirclemapitem_p.h
@@ -43,12 +43,13 @@
#define QDECLARATIVECIRCLEMAPITEM_H
#include "qdeclarativegeomapitembase_p.h"
-#include <QPen>
-#include <QBrush>
+#include <QSGGeometryNode>
+#include <QSGFlatColorMaterial>
QT_BEGIN_NAMESPACE
-class CircleMapPaintedItem;
+class QDeclarativeGeoMapQuickItem;
+class MapCircleNode;
class QDeclarativeCircleMapItem : public QDeclarativeGeoMapItemBase
{
@@ -61,6 +62,10 @@ public:
QDeclarativeCircleMapItem(QQuickItem *parent = 0);
~QDeclarativeCircleMapItem();
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ //from QuickItem
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
QDeclarativeCoordinate* center();
void setCenter(QDeclarativeCoordinate* center);
@@ -70,6 +75,7 @@ public:
QColor color() const;
void setColor(const QColor &color);
+
void dragStarted();
void dragEnded();
bool contains(QPointF point);
@@ -79,71 +85,62 @@ Q_SIGNALS:
void radiusChanged(qreal radius);
void colorChanged(const QColor &color);
-protected:
- void updateContent();
- QPointF contentTopLeftPoint();
- void mapChanged();
- // from qquickitem
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+protected Q_SLOTS:
+ virtual void updateMapItem(bool dirtyGeomoetry=true);
private Q_SLOTS:
void handleCameraDataChanged(const CameraData& cameraData);
- void handleCenterCoordinateChanged();
private:
+ //TODO: pimpl
QDeclarativeCoordinate internalCoordinate_;
QDeclarativeCoordinate *center_;
- CircleMapPaintedItem *circleItem_;
+ MapCircleNode *mapCircleNode_;
QColor color_;
+ qreal radius_;
+ qreal zoomLevel_;
bool dragActive_;
};
//////////////////////////////////////////////////////////////////////
-class CircleMapPaintedItem: public QQuickPaintedItem
+class MapCircleNode: public QSGGeometryNode
{
public:
- CircleMapPaintedItem(QQuickItem *parent = 0);
- ~CircleMapPaintedItem();
+ MapCircleNode();
+ ~MapCircleNode();
- void setMap(Map* map);
- Map* map();
- void setZoomLevel(qreal zoomLevel);
- qreal zoomLevel() const;
-
- void setCenter(const QGeoCoordinate &center);
- const QGeoCoordinate& center() const;
-
- void setRadius(qreal radius);
- qreal radius() const;
+ void setSize(const QSize &size);
+ QSizeF size() const {
+ return size_;
+ }
- void paint(QPainter *painter);
+ QColor penColor() const;
+ void setPenColor(const QColor &pen);
- QPen pen() const;
- void setPen(const QPen &pen);
-
- QBrush brush() const;
- void setBrush(const QBrush &brush);
+ QColor brushColor() const;
+ void setBrushColor(const QColor &color);
+ void update();
bool contains(QPointF point);
- void updateGeometry();
+ void setGeometry(const Map &map, qreal radius,const QGeoCoordinate &center);
private:
- void calcualtePeripheralPoints(QList<QGeoCoordinate>& path, const QGeoCoordinate& center, qreal distance, int steps) const;
-
- Map *map_;
- qreal zoomLevel_;
- QGeoCoordinate centerCoord_;
- qreal radius_;
- QPen pen_;
- QBrush brush_;
- QPolygonF polygon_;
+ QSGFlatColorMaterial fill_material_;
+ //QSGFlatColorMaterial border_material_;
+ QColor fillColor_;
+ QColor borderColor_;
+ //keeps pixel geometry
+ QSGGeometry geometry_;
+ //keeps geographic geometry
QList<QGeoCoordinate> path_;
- bool initialized_;
- bool dirtyGeometry_;
+ QPolygonF polygon_;
+ QSizeF size_;
};
QT_END_NAMESPACE
+QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QDeclarativeCircleMapItem));
+
#endif /* QDECLARATIVECIRCLEMAPITEM_H */
diff --git a/src/imports/location/qdeclarativegeomapitembase.cpp b/src/imports/location/qdeclarativegeomapitembase.cpp
index 572b8258..4d48e37c 100644
--- a/src/imports/location/qdeclarativegeomapitembase.cpp
+++ b/src/imports/location/qdeclarativegeomapitembase.cpp
@@ -46,12 +46,8 @@ QT_BEGIN_NAMESPACE
QDeclarativeGeoMapItemBase::QDeclarativeGeoMapItemBase(QQuickItem *parent)
: QQuickItem(parent),
map_(0),
- quickMap_(0),
- inUpdate_(false)
+ quickMap_(0)
{
- setParentItem(parent);
- setFlag(ItemHasContents, true);
- setAcceptHoverEvents(false);
}
QDeclarativeGeoMapItemBase::~QDeclarativeGeoMapItemBase()
@@ -61,9 +57,6 @@ QDeclarativeGeoMapItemBase::~QDeclarativeGeoMapItemBase()
quickMap_->removeMapItem(this);
}
-void QDeclarativeGeoMapItemBase::mapChanged()
-{
-}
bool QDeclarativeGeoMapItemBase::contains(QPointF point)
{
@@ -79,10 +72,6 @@ void QDeclarativeGeoMapItemBase::dragEnded()
{
}
-void QDeclarativeGeoMapItemBase::updateContent()
-{
-}
-
void QDeclarativeGeoMapItemBase::setMap(QDeclarativeGeoMap *quickMap, Map *map) {
if (quickMap == quickMap_)
return;
@@ -94,18 +83,15 @@ void QDeclarativeGeoMapItemBase::setMap(QDeclarativeGeoMap *quickMap, Map *map)
map_->disconnect(this);
quickMap_ = quickMap;
map_ = map;
- mapChanged();
- updateMapItem();
}
-void QDeclarativeGeoMapItemBase::updateMapItem()
+void QDeclarativeGeoMapItemBase::setPositionOnMap(const QGeoCoordinate& coordinate, const QPointF& offset)
{
- if (inUpdate_ || !map_ || !quickMap_)
+ if (!map_ || !quickMap_)
return;
- inUpdate_ = true;
- updateContent();
- QPointF topLeft = contentTopLeftPoint();
+ QPointF topLeft = map_->coordinateToScreenPosition(coordinate, false) - offset;
+
if ((topLeft.x() > quickMap()->width())
|| (topLeft.x() + width() < 0)
|| (topLeft.y() + height() < 0)
@@ -115,12 +101,6 @@ void QDeclarativeGeoMapItemBase::updateMapItem()
setVisible(true);
setPos(topLeft);
}
- inUpdate_ = false;
-}
-
-QDeclarativeGeoMap* QDeclarativeGeoMapItemBase::quickMap()
-{
- return quickMap_;
}
#include "moc_qdeclarativegeomapitembase_p.cpp"
diff --git a/src/imports/location/qdeclarativegeomapitembase_p.h b/src/imports/location/qdeclarativegeomapitembase_p.h
index 3c303493..03adff7b 100644
--- a/src/imports/location/qdeclarativegeomapitembase_p.h
+++ b/src/imports/location/qdeclarativegeomapitembase_p.h
@@ -56,23 +56,22 @@ public:
QDeclarativeGeoMapItemBase(QQuickItem *parent = 0);
virtual ~QDeclarativeGeoMapItemBase();
- void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ virtual void setPositionOnMap(const QGeoCoordinate& coordinate, const QPointF& offset);
virtual bool contains(QPointF point);
virtual void dragStarted();
virtual void dragEnded();
- QDeclarativeGeoMap* quickMap();
- protected Q_SLOTS:
- virtual void updateMapItem();
+ QDeclarativeGeoMap* quickMap() {return quickMap_;}
+ Map* map() {return map_;}
-protected:
- virtual void mapChanged();
- virtual void updateContent();
- virtual QPointF contentTopLeftPoint() = 0;
+protected Q_SLOT:
+ virtual void updateMapItem(bool dirtyGeometry = true) = 0;
+
+private:
Map* map_;
QDeclarativeGeoMap* quickMap_;
- bool inUpdate_;
};
QT_END_NAMESPACE
diff --git a/src/imports/location/qdeclarativegeomapquickitem.cpp b/src/imports/location/qdeclarativegeomapquickitem.cpp
index 0f0f070f..1de6597c 100644
--- a/src/imports/location/qdeclarativegeomapquickitem.cpp
+++ b/src/imports/location/qdeclarativegeomapquickitem.cpp
@@ -61,7 +61,10 @@ QDeclarativeGeoMapQuickItem::QDeclarativeGeoMapQuickItem(QQuickItem *parent)
zoomLevel_(0.0),
inUpdate_(false),
mapAndSourceItemSet_(false),
- dragActive_(true) {}
+ dragActive_(true)
+{
+ setFlag(ItemHasContents, true);
+}
QDeclarativeGeoMapQuickItem::~QDeclarativeGeoMapQuickItem() {}
@@ -72,31 +75,46 @@ void QDeclarativeGeoMapQuickItem::setCoordinate(QDeclarativeCoordinate *coordina
if (coordinate_)
coordinate_->disconnect(this);
coordinate_ = coordinate;
- update();
+
if (coordinate_) {
connect(coordinate_,
SIGNAL(latitudeChanged(double)),
this,
- SLOT(coordinateCoordinateChanged(double)));
+ SLOT(updateMapItem()));
connect(coordinate_,
SIGNAL(longitudeChanged(double)),
this,
- SLOT(coordinateCoordinateChanged(double)));
+ SLOT(updateMapItem()));
connect(coordinate_,
SIGNAL(altitudeChanged(double)),
this,
- SLOT(coordinateCoordinateChanged(double)));
+ SLOT(updateMapItem()));
}
+
+ updateMapItem();
+
emit coordinateChanged();
}
+void QDeclarativeGeoMapQuickItem::setMap(QDeclarativeGeoMap* quickMap, Map *map)
+{
+ QDeclarativeGeoMapItemBase::setMap(quickMap,map);
+ if (map && quickMap) {
+ QObject::connect(quickMap, SIGNAL(heightChanged()), this, SLOT(updateMapItem()));
+ QObject::connect(quickMap, SIGNAL(widthChanged()), this, SLOT(updateMapItem()));
+ QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(updateMapItem()));
+ updateMapItem();
+ }
+}
+
+
void QDeclarativeGeoMapQuickItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
if (!dragActive_ && quickMap() && sourceItem() && newGeometry.isValid() && newGeometry != oldGeometry) {
QPointF point(newGeometry.x(), newGeometry.y());
// screenPositionToCoordinate seems to return nan values when
// it goes beyond viewport, hence sanity check (fixme todo):
- QGeoCoordinate newCoordinate = map_->screenPositionToCoordinate(point, false);
+ QGeoCoordinate newCoordinate = map()->screenPositionToCoordinate(point, false);
if (newCoordinate.isValid()) {
internalCoordinate_.setCoordinate(newCoordinate);
setCoordinate(&internalCoordinate_);
@@ -119,7 +137,7 @@ void QDeclarativeGeoMapQuickItem::dragEnded()
QPointF point(x(), y());
// screenPositionToCoordinate seems to return nan values when
// it goes beyond viewport, hence sanity check (fixme todo):
- QGeoCoordinate newCoordinate = map_->screenPositionToCoordinate(point, false);
+ QGeoCoordinate newCoordinate = map()->screenPositionToCoordinate(point, false);
if (newCoordinate.isValid()) {
internalCoordinate_.setCoordinate(newCoordinate);
setCoordinate(&internalCoordinate_);
@@ -127,11 +145,6 @@ void QDeclarativeGeoMapQuickItem::dragEnded()
}
}
-void QDeclarativeGeoMapQuickItem::coordinateCoordinateChanged(double)
-{
- updateMapItem();
- emit coordinateChanged();
-}
QDeclarativeCoordinate* QDeclarativeGeoMapQuickItem::coordinate()
{
@@ -143,42 +156,10 @@ void QDeclarativeGeoMapQuickItem::setSourceItem(QQuickItem* sourceItem)
if (sourceItem == sourceItem_)
return;
sourceItem_ = sourceItem;
- mapChanged();
- emit sourceItemChanged();
-}
-
-void QDeclarativeGeoMapQuickItem::updateMapItem()
-{
- if (!mapAndSourceItemSet_)
- return;
- QDeclarativeGeoMapItemBase::updateMapItem();
-}
-void QDeclarativeGeoMapQuickItem::mapChanged()
-{
- // currently this function checks for source item changes too
- if (!quickMap() && sourceItem_) {
- mapAndSourceItemSet_ = false;
- sourceItem_->setParentItem(0);
- return;
- }
- if (!quickMap() || !map_ || !sourceItem_) {
- mapAndSourceItemSet_ = false;
- return;
- }
- if (!mapAndSourceItemSet_ && quickMap() && map_ && sourceItem_) {
- mapAndSourceItemSet_ = true;
- sourceItem_->setParentItem(this);
- sourceItem_->setTransformOrigin(QQuickItem::TopLeft);
- connect(quickMap(), SIGNAL(heightChanged()), this, SLOT(updateMapItem()));
- connect(quickMap(), SIGNAL(widthChanged()), this, SLOT(updateMapItem()));
- connect(map_, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(updateMapItem()));
- connect(sourceItem_, SIGNAL(xChanged()), this, SLOT(updateMapItem()));
- connect(sourceItem_, SIGNAL(yChanged()), this, SLOT(updateMapItem()));
- connect(sourceItem_, SIGNAL(widthChanged()), this, SLOT(updateMapItem()));
- connect(sourceItem_, SIGNAL(heightChanged()), this, SLOT(updateMapItem()));
- }
updateMapItem();
+
+ emit sourceItemChanged();
}
QQuickItem* QDeclarativeGeoMapQuickItem::sourceItem()
@@ -214,26 +195,43 @@ qreal QDeclarativeGeoMapQuickItem::zoomLevel() const
return zoomLevel_;
}
-void QDeclarativeGeoMapQuickItem::updateContent()
+void QDeclarativeGeoMapQuickItem::updateMapItem(bool dirtyGeometry)
{
+ Q_UNUSED(dirtyGeometry);
+ if (!quickMap() && sourceItem_) {
+ mapAndSourceItemSet_ = false;
+ sourceItem_->setParentItem(0);
+ return;
+ }
+
+ if (!quickMap() || !map() || !sourceItem_) {
+ mapAndSourceItemSet_ = false;
+ return;
+ }
+
+ if (!mapAndSourceItemSet_ && quickMap() && map() && sourceItem_) {
+ mapAndSourceItemSet_ = true;
+ sourceItem_->setParentItem(this);
+ sourceItem_->setTransformOrigin(QQuickItem::TopLeft);
+ connect(sourceItem_, SIGNAL(xChanged()), this, SLOT(updateMapItem()));
+ connect(sourceItem_, SIGNAL(yChanged()), this, SLOT(updateMapItem()));
+ connect(sourceItem_, SIGNAL(widthChanged()), this, SLOT(updateMapItem()));
+ connect(sourceItem_, SIGNAL(heightChanged()), this, SLOT(updateMapItem()));
+ }
+
sourceItem_->setScale(scaleFactor());
sourceItem_->setPos(QPointF(0,0));
setWidth(sourceItem_->width());
setHeight(sourceItem_->height());
-}
-
-QPointF QDeclarativeGeoMapQuickItem::contentTopLeftPoint()
-{
- if (!map_)
- return QPointF(0,0);
- return map_->coordinateToScreenPosition(coordinate()->coordinate(), false) - scaleFactor() * anchorPoint_;
+ setPositionOnMap(coordinate()->coordinate() , scaleFactor() * anchorPoint_);
+ update();
}
qreal QDeclarativeGeoMapQuickItem::scaleFactor()
{
qreal scale = 1.0;
if (zoomLevel_ != 0.0)
- scale = pow(0.5, zoomLevel_ - map_->cameraData().zoomFactor());
+ scale = pow(0.5, zoomLevel_ - map()->cameraData().zoomFactor());
return scale;
}
diff --git a/src/imports/location/qdeclarativegeomapquickitem_p.h b/src/imports/location/qdeclarativegeomapquickitem_p.h
index b54d87f3..e359cecf 100644
--- a/src/imports/location/qdeclarativegeomapquickitem_p.h
+++ b/src/imports/location/qdeclarativegeomapquickitem_p.h
@@ -62,6 +62,8 @@ public:
QDeclarativeGeoMapQuickItem(QQuickItem *parent = 0);
~QDeclarativeGeoMapQuickItem();
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+
void setCoordinate(QDeclarativeCoordinate *coordinate);
QDeclarativeCoordinate* coordinate();
@@ -83,19 +85,11 @@ Q_SIGNALS:
void anchorPointChanged();
void zoomLevelChanged();
-protected:
- void updateContent();
- void mapChanged();
- QPointF contentTopLeftPoint();
-
protected Q_SLOTS:
- void updateMapItem();
+ virtual void updateMapItem(bool dirtyGeometry = true);
// from qquickitem
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-private Q_SLOTS:
- void coordinateCoordinateChanged(double);
-
private:
qreal scaleFactor();
QDeclarativeCoordinate* coordinate_;
diff --git a/src/imports/location/qdeclarativepolygonmapitem.cpp b/src/imports/location/qdeclarativepolygonmapitem.cpp
index 94ada8d4..2591eb22 100644
--- a/src/imports/location/qdeclarativepolygonmapitem.cpp
+++ b/src/imports/location/qdeclarativepolygonmapitem.cpp
@@ -43,10 +43,13 @@
#include <QDeclarativeInfo>
#include <QPainter>
-static QPolygonF createPolygon(const Map& map, const QList<QGeoCoordinate> &path, qreal& w,
- qreal& h)
+struct Vertex
+{
+ QVector2D position;
+};
+
+static void updatePolygon(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h)
{
- QPolygonF polygon;
qreal minX, maxX, minY, maxY;
//TODO: dateline handling
@@ -65,297 +68,252 @@ static QPolygonF createPolygon(const Map& map, const QList<QGeoCoordinate> &path
maxX = point.x();
minY = point.y();
maxY = point.y();
- polygon.append(point);
} else {
minX = qMin(point.x(), minX);
maxX = qMax(point.x(), maxX);
minY = qMin(point.y(), minY);
maxY = qMax(point.y(), maxY);
}
-
- polygon.append(point);
+ points.append(point);
}
- polygon.translate(-minX, -minY);
+ points.translate(-minX, -minY);
w = maxX - minX;
h = maxY - minY;
-
- return polygon;
}
QDeclarativePolygonMapItem::QDeclarativePolygonMapItem(QQuickItem *parent) :
QDeclarativeGeoMapItemBase(parent),
- polygonItem_(new PolygonMapPaintedItem(this)),
- initialized_(false)
+ mapPolygonNode_(0),
+ zoomLevel_(0.0)
{
- polygonItem_->setParentItem(this);
+ setFlag(ItemHasContents, true);
}
QDeclarativePolygonMapItem::~QDeclarativePolygonMapItem()
{
}
-void QDeclarativePolygonMapItem::componentComplete()
+void QDeclarativePolygonMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map)
{
- initialized_ = true;
+ QDeclarativeGeoMapItemBase::setMap(quickMap,map);
+ if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
}
QDeclarativeListProperty<QDeclarativeCoordinate> QDeclarativePolygonMapItem::declarativePath()
{
return QDeclarativeListProperty<QDeclarativeCoordinate>(this, 0, path_append, path_count,
- path_at, path_clear);
+ path_at, path_clear);
}
void QDeclarativePolygonMapItem::path_append(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property, QDeclarativeCoordinate *coordinate)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property, QDeclarativeCoordinate *coordinate)
{
- QDeclarativePolygonMapItem* item = qobject_cast<QDeclarativePolygonMapItem*>(
- property->object);
- item->path_.append(coordinate);
- QList<QGeoCoordinate> p = item->polygonItem_->path();
- p.append(coordinate->coordinate());
- item->polygonItem_->setPath(p);
- if (item->initialized_)
- emit item->pathChanged();
- item->updateMapItem();
+ QDeclarativePolygonMapItem* item = qobject_cast<QDeclarativePolygonMapItem*>(property->object);
+ item->coordPath_.append(coordinate);
+ item->path_.append(coordinate->coordinate());
+ item->updateMapItem(true);
+ emit item->pathChanged();
}
int QDeclarativePolygonMapItem::path_count(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property)
{
- return qobject_cast<QDeclarativePolygonMapItem*>(property->object)->path_.count();
+ return qobject_cast<QDeclarativePolygonMapItem*>(property->object)->coordPath_.count();
}
QDeclarativeCoordinate* QDeclarativePolygonMapItem::path_at(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property, int index)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property, int index)
{
- return qobject_cast<QDeclarativePolygonMapItem*>(property->object)->path_.at(index);
+ return qobject_cast<QDeclarativePolygonMapItem*>(property->object)->coordPath_.at(index);
}
void QDeclarativePolygonMapItem::path_clear(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property)
{
QDeclarativePolygonMapItem* item = qobject_cast<QDeclarativePolygonMapItem*>(
- property->object);
- qDeleteAll(item->path_);
+ property->object);
+ qDeleteAll(item->coordPath_);
+ item->coordPath_.clear();
item->path_.clear();
- item->polygonItem_->setPath(QList<QGeoCoordinate>());
- if (item->initialized_)
- emit item->pathChanged();
- item->updateMapItem();
+ item->updateMapItem(true);
+ emit item->pathChanged();
}
void QDeclarativePolygonMapItem::addCoordinate(QDeclarativeCoordinate* coordinate)
{
- path_.append(coordinate);
- QList<QGeoCoordinate> path = polygonItem_->path();
- path.append(coordinate->coordinate());
- polygonItem_->setPath(path);
- updateMapItem();
+ coordPath_.append(coordinate);
+ path_.append(coordinate->coordinate());
+ updateMapItem(true);
emit pathChanged();
}
void QDeclarativePolygonMapItem::removeCoordinate(QDeclarativeCoordinate* coordinate)
{
- int index = path_.lastIndexOf(coordinate);
+ int index = coordPath_.lastIndexOf(coordinate);
if (index == -1) {
qmlInfo(this) << tr("Coordinate does not belong to PolygonMapItem.");
return;
}
- QList<QGeoCoordinate> path = polygonItem_->path();
-
- if (path.count() < index + 1) {
+ if (path_.count() < index + 1) {
qmlInfo(this) << tr("Coordinate does not belong to PolygonMapItem.");
return;
}
- path.removeAt(index);
- polygonItem_->setPath(path);
+ coordPath_.removeAt(index);
path_.removeAt(index);
- updateMapItem();
+ updateMapItem(true);
emit pathChanged();
}
-void QDeclarativePolygonMapItem::updateContent()
+QColor QDeclarativePolygonMapItem::color() const
{
- polygonItem_->updateGeometry();
- setWidth(polygonItem_->width());
- setHeight(polygonItem_->height());
+ return color_;
}
-QPointF QDeclarativePolygonMapItem::contentTopLeftPoint()
+void QDeclarativePolygonMapItem::setColor(const QColor &color)
{
- return map_->coordinateToScreenPosition(
- polygonItem_->quickItemCoordinate(), false) - polygonItem_->quickItemAnchorPoint();
-}
+ if (color_ == color)
+ return;
-void QDeclarativePolygonMapItem::mapChanged()
+ color_ = color;
+ updateMapItem(false);
+ emit colorChanged(color_);
+}
+QSGNode* QDeclarativePolygonMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
- polygonItem_->setMap(map_);
- if (map_) {
- connect(map_, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
- // initial update
- handleCameraDataChanged(map_->cameraData());
+ Q_UNUSED(data);
+
+ MapPolygonNode *node = static_cast<MapPolygonNode*>(oldNode);
+
+ if (!node) {
+ mapPolygonNode_ = new MapPolygonNode();
+ updateMapItem(true);
}
-}
-void QDeclarativePolygonMapItem::dragStarted()
-{
- qmlInfo(this) << "warning: mouse dragging is not currently supported with polygon.";
+ mapPolygonNode_->update();
+ return mapPolygonNode_;
}
-bool QDeclarativePolygonMapItem::contains(QPointF point)
+void
+QDeclarativePolygonMapItem::updateMapItem(bool dirtyGeometry)
{
- return polygonItem_->contains(point);
+ if (!map() || path_.count() == 0 || !mapPolygonNode_)
+ return;
+
+ mapPolygonNode_->setBrushColor(color_);
+
+ if (dirtyGeometry)
+ mapPolygonNode_->setGeometry(*map(), path_);
+
+ const QSizeF& size = mapPolygonNode_->size();
+
+ setWidth(size.width());
+ setHeight(size.height());
+
+ setPositionOnMap(path_.at(0), mapPolygonNode_->geometry().at(0));
+ update();
}
void QDeclarativePolygonMapItem::handleCameraDataChanged(const CameraData& cameraData)
{
- polygonItem_->setZoomLevel(cameraData.zoomFactor());
- updateMapItem();
+ if (cameraData.zoomFactor() != zoomLevel_) {
+ zoomLevel_ = cameraData.zoomFactor();
+ updateMapItem(true);
+ } else {
+ updateMapItem(false);
+ }
}
-QColor QDeclarativePolygonMapItem::color() const
+void QDeclarativePolygonMapItem::dragStarted()
{
- return color_;
+ qmlInfo(this) << "warning: mouse dragging is not currently supported with polygon.";
}
-void QDeclarativePolygonMapItem::setColor(const QColor &color)
+bool QDeclarativePolygonMapItem::contains(QPointF point)
{
- if (color_ == color)
- return;
-
- color_ = color;
- polygonItem_->setBrush(color);
- emit colorChanged(color_);
+ return mapPolygonNode_->contains(point);
}
//////////////////////////////////////////////////////////////////////
-PolygonMapPaintedItem::PolygonMapPaintedItem(QQuickItem *parent) :
- QQuickPaintedItem(parent), map_(0), zoomLevel_(-1), initialized_(false)
+MapPolygonNode::MapPolygonNode() :
+ fillColor_(Qt::black),
+ borderColor_(Qt::black),
+ geometry_(QSGGeometry::defaultAttributes_Point2D(), 0)
{
- setAntialiasing(true);
- connect(this, SIGNAL(xChanged()), this, SLOT(update()));
- connect(this, SIGNAL(yChanged()), this, SLOT(update()));
+ geometry_.setDrawingMode(GL_POLYGON);
+ QSGGeometryNode::setMaterial(&fill_material_);
+ QSGGeometryNode::setGeometry(&geometry_);
}
-PolygonMapPaintedItem::~PolygonMapPaintedItem()
+MapPolygonNode::~MapPolygonNode()
{
}
-void PolygonMapPaintedItem::setMap(Map* map)
+void MapPolygonNode::update()
{
- map_ = map;
-}
+ //TODO: optimize , perform calculation only if polygon has changed
+ if (polygon_.size()==0) return;
-Map* PolygonMapPaintedItem::map()
-{
- return map_;
-}
+ QSGGeometry *fill = QSGGeometryNode::geometry();
-void PolygonMapPaintedItem::setZoomLevel(qreal zoomLevel)
-{
- if (zoomLevel_ == zoomLevel)
- return;
+ Q_ASSERT(fill->sizeOfVertex() == sizeof(Vertex));
- zoomLevel_ = zoomLevel;
- dirtyGeometry_ = true;
-}
+ int fillVertexCount = 0;
+ //note this will not allocate new buffer if the size has not changed
+ fill->allocate(polygon_.size());
-qreal PolygonMapPaintedItem::zoomLevel() const
-{
- return zoomLevel_;
-}
+ Vertex *vertices = (Vertex *)fill->vertexData();
-bool PolygonMapPaintedItem::contains(QPointF point)
-{
- return polygon_.containsPoint(point, Qt::OddEvenFill);
-}
+ for (int i = 0; i < polygon_.size(); ++i) {
+ vertices[fillVertexCount++].position = QVector2D(polygon_.at(i));
+ }
-void PolygonMapPaintedItem::setPath(const QList<QGeoCoordinate>& path)
-{
- coordPath_ = path;
- dirtyGeometry_ = true;
-}
+ Q_ASSERT(fillVertexCount == fill->vertexCount());
-QList<QGeoCoordinate> PolygonMapPaintedItem::path() const
-{
- return coordPath_;
-}
+ markDirty(DirtyGeometry);
-QGeoCoordinate PolygonMapPaintedItem::quickItemCoordinate() const
-{
- return quickItemCoordinate_;
-}
+ if (fillColor_ != fill_material_.color()) {
+ fill_material_.setColor(fillColor_);
+ setMaterial(&fill_material_);
+ }
-QPointF PolygonMapPaintedItem::quickItemAnchorPoint() const
-{
- return quickItemAnchorPoint_;
+ //TODO: implement me : borders , gradient
}
-void PolygonMapPaintedItem::setBrush(const QBrush &brush)
+void MapPolygonNode::setBrushColor(const QColor &color)
{
- brush_ = brush;
+ fillColor_= color;
}
-QBrush PolygonMapPaintedItem::brush() const
+QColor MapPolygonNode::brushColor() const
{
- return brush_;
+ return fillColor_;
}
-void PolygonMapPaintedItem::setPen(const QPen &pen)
+void MapPolygonNode::setPenColor(const QColor &color)
{
- pen_ = pen;
+ borderColor_ = color;
}
-QPen PolygonMapPaintedItem::pen() const
+QColor MapPolygonNode::penColor() const
{
- return pen_;
+ return borderColor_;
}
-void PolygonMapPaintedItem::paint(QPainter *painter)
+bool MapPolygonNode::contains(QPointF point)
{
- if (!initialized_)
- return;
- painter->setPen(pen_);
- painter->setBrush(brush_);
- painter->drawConvexPolygon(polygon_);
+ return polygon_.containsPoint(point, Qt::OddEvenFill);
}
-void PolygonMapPaintedItem::updateGeometry()
+void MapPolygonNode::setGeometry(const Map& map, const QList<QGeoCoordinate> &path)
{
- if (!dirtyGeometry_)
- return;
- initialized_ = false;
-
- if (!map_)
- return;
-
- if (coordPath_.size() == 0)
- return;
-
- if (zoomLevel_ == -1)
- return;
-
- QPointF point = map_->coordinateToScreenPosition(coordPath_.at(0), false);
-
- qreal w = 0;
qreal h = 0;
-
- //TODO: optimize essential part
- polygon_ = createPolygon(*map_, coordPath_, w, h);
-
- setWidth(w);
- setHeight(h);
- setContentsSize(QSize(w, h));
-
- quickItemCoordinate_ = coordPath_.at(0);
- quickItemAnchorPoint_ = polygon_.first();
- initialized_ = true;
-
- dirtyGeometry_ = false;
- update(); // qquickpainteditem
+ qreal w = 0;
+ polygon_.clear();
+ updatePolygon(polygon_, map, path, w, h);
+ size_ = QSizeF(w, h);
}
diff --git a/src/imports/location/qdeclarativepolygonmapitem_p.h b/src/imports/location/qdeclarativepolygonmapitem_p.h
index 8cd3342a..060ca0f7 100644
--- a/src/imports/location/qdeclarativepolygonmapitem_p.h
+++ b/src/imports/location/qdeclarativepolygonmapitem_p.h
@@ -43,14 +43,12 @@
#define QDECLARATIVEPOLYGONMAPITEM
#include "qdeclarativegeomapitembase_p.h"
-#include "qdeclarativecoordinate_p.h"
-#include "qdeclarativegeomap_p.h"
-#include <QPen>
-#include <QBrush>
+#include <QSGGeometryNode>
+#include <QSGFlatColorMaterial>
QT_BEGIN_NAMESPACE
-class PolygonMapPaintedItem;
+class MapPolygonNode;
class QDeclarativePolygonMapItem : public QDeclarativeGeoMapItemBase
{
@@ -63,7 +61,9 @@ public:
QDeclarativePolygonMapItem(QQuickItem *parent = 0);
~QDeclarativePolygonMapItem();
- virtual void componentComplete();
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ //from QuickItem
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
Q_INVOKABLE void addCoordinate(QDeclarativeCoordinate* coordinate);
Q_INVOKABLE void removeCoordinate(QDeclarativeCoordinate* coordinate);
@@ -80,10 +80,8 @@ Q_SIGNALS:
void pathChanged();
void colorChanged(const QColor &color);
-protected:
- void updateContent();
- QPointF contentTopLeftPoint();
- void mapChanged();
+protected Q_SLOTS:
+ virtual void updateMapItem(bool dirtyGeomoetry = true);
private Q_SLOTS:
// map size changed
@@ -97,57 +95,45 @@ private:
void pathPropertyChanged();
private:
- PolygonMapPaintedItem *polygonItem_;
- QList<QDeclarativeCoordinate*> path_;
+ MapPolygonNode *mapPolygonNode_;
+ QList<QDeclarativeCoordinate*> coordPath_;
+ QList<QGeoCoordinate> path_;
QColor color_;
- bool initialized_;
+ qreal zoomLevel_;
};
//////////////////////////////////////////////////////////////////////
-class PolygonMapPaintedItem : public QQuickPaintedItem
+class MapPolygonNode : public QSGGeometryNode
{
- Q_OBJECT
public:
- PolygonMapPaintedItem(QQuickItem *parent = 0);
- ~PolygonMapPaintedItem();
-
- void setMap(Map* map);
- Map* map();
-
- void setZoomLevel(qreal zoomLevel);
- qreal zoomLevel() const;
+ MapPolygonNode();
+ ~MapPolygonNode();
- QList<QGeoCoordinate> path() const;
- void setPath(const QList<QGeoCoordinate>& path);
+ void setSize(const QSize &size);
+ QSizeF size() const {
+ return size_;
+ }
- void paint(QPainter *painter);
+ QColor penColor() const;
+ void setPenColor(const QColor &pen);
- QPen pen() const;
- void setPen(const QPen &pen);
-
- QBrush brush() const;
- void setBrush(const QBrush &brush);
-
- QGeoCoordinate quickItemCoordinate() const;
- QPointF quickItemAnchorPoint() const;
+ QColor brushColor() const;
+ void setBrushColor(const QColor &color);
+ void update();
bool contains(QPointF point);
- void updateGeometry();
+ void setGeometry(const Map &map, const QList<QGeoCoordinate> &path);
+ const QPolygonF& geometry() { return polygon_; }
private:
-
- Map *map_;
- qreal zoomLevel_;
- QGeoCoordinate quickItemCoordinate_;
- QPointF quickItemAnchorPoint_;
- QPen pen_;
- QBrush brush_;
- QList<QGeoCoordinate> coordPath_;
+ QSGFlatColorMaterial fill_material_;
+ QColor fillColor_;
+ QColor borderColor_;
+ QSGGeometry geometry_;
QPolygonF polygon_;
- bool initialized_;
- bool dirtyGeometry_;
+ QSizeF size_;
};
diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp
index fcbbd52e..bb84256f 100644
--- a/src/imports/location/qdeclarativepolylinemapitem.cpp
+++ b/src/imports/location/qdeclarativepolylinemapitem.cpp
@@ -45,322 +45,272 @@
QT_BEGIN_NAMESPACE
-static QPainterPath createPath(const Map& map, const QList<QGeoCoordinate> &path, qreal& w,
- qreal& h)
+struct Vertex
+{
+ QVector2D position;
+};
+
+static void updatePolyline(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h)
{
- QPainterPath painter;
qreal minX, maxX, minY, maxY;
//TODO: dateline handling
for (int i = 0; i < path.size(); ++i) {
+
const QGeoCoordinate &coord = path.at(i);
if (!coord.isValid())
continue;
QPointF point = map.coordinateToScreenPosition(coord, false);
+
if (i == 0) {
minX = point.x();
maxX = point.x();
minY = point.y();
maxY = point.y();
- painter.moveTo(point);
} else {
minX = qMin(point.x(), minX);
maxX = qMax(point.x(), maxX);
minY = qMin(point.y(), minY);
maxY = qMax(point.y(), maxY);
- painter.lineTo(point);
}
-
+ points.append(point);
}
- painter.translate(-minX, -minY);
+ points.translate(-minX, -minY);
w = maxX - minX;
h = maxY - minY;
-
- return painter;
}
QDeclarativePolylineMapItem::QDeclarativePolylineMapItem(QQuickItem *parent) :
QDeclarativeGeoMapItemBase(parent),
- polylineItem_(new PolylineMapPaintedItem(this)),
- initialized_(false)
+ mapPolylineNode_(0),
+ zoomLevel_(0.0)
{
- polylineItem_->setParentItem(this);
+ setFlag(ItemHasContents, true);
}
QDeclarativePolylineMapItem::~QDeclarativePolylineMapItem()
{
}
+void QDeclarativePolylineMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map)
+{
+ QDeclarativeGeoMapItemBase::setMap(quickMap,map);
+ if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
+}
+
QDeclarativeListProperty<QDeclarativeCoordinate> QDeclarativePolylineMapItem::declarativePath()
{
return QDeclarativeListProperty<QDeclarativeCoordinate>(this, 0, path_append, path_count,
- path_at, path_clear);
+ path_at, path_clear);
}
-void QDeclarativePolylineMapItem::path_append(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property, QDeclarativeCoordinate *coordinate)
+void QDeclarativePolylineMapItem::path_append(QDeclarativeListProperty<QDeclarativeCoordinate> *property, QDeclarativeCoordinate *coordinate)
{
QDeclarativePolylineMapItem* item = qobject_cast<QDeclarativePolylineMapItem*>(
- property->object);
- item->path_.append(coordinate);
- QList<QGeoCoordinate> p = item->polylineItem_->path();
- p.append(coordinate->coordinate());
- item->polylineItem_->setPath(p);
- if (item->initialized_)
- emit item->pathChanged();
- item->updateMapItem();
+ property->object);
+ item->coordPath_.append(coordinate);
+ item->path_.append(coordinate->coordinate());
+ item->updateMapItem(true);
+ emit item->pathChanged();
}
int QDeclarativePolylineMapItem::path_count(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property)
{
- return qobject_cast<QDeclarativePolylineMapItem*>(property->object)->path_.count();
+ return qobject_cast<QDeclarativePolylineMapItem*>(property->object)->coordPath_.count();
}
QDeclarativeCoordinate* QDeclarativePolylineMapItem::path_at(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property, int index)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property, int index)
{
- return qobject_cast<QDeclarativePolylineMapItem*>(property->object)->path_.at(index);
+ return qobject_cast<QDeclarativePolylineMapItem*>(property->object)->coordPath_.at(index);
}
void QDeclarativePolylineMapItem::path_clear(
- QDeclarativeListProperty<QDeclarativeCoordinate> *property)
+ QDeclarativeListProperty<QDeclarativeCoordinate> *property)
{
QDeclarativePolylineMapItem* item = qobject_cast<QDeclarativePolylineMapItem*>(
- property->object);
- qDeleteAll(item->path_);
+ property->object);
+ qDeleteAll(item->coordPath_);
+ item->coordPath_.clear();
item->path_.clear();
- item->polylineItem_->setPath(QList<QGeoCoordinate>());
- if (item->initialized_)
- emit item->pathChanged();
- item->updateMapItem();
+ item->updateMapItem(true);
+ emit item->pathChanged();
}
void QDeclarativePolylineMapItem::addCoordinate(QDeclarativeCoordinate* coordinate)
{
- path_.append(coordinate);
- QList<QGeoCoordinate> path = polylineItem_->path();
- path.append(coordinate->coordinate());
- polylineItem_->setPath(path);
- updateMapItem();
+ coordPath_.append(coordinate);
+ path_.append(coordinate->coordinate());
+ updateMapItem(true);
emit pathChanged();
}
void QDeclarativePolylineMapItem::removeCoordinate(QDeclarativeCoordinate* coordinate)
{
- int index = path_.lastIndexOf(coordinate);
+ int index = coordPath_.lastIndexOf(coordinate);
if (index == -1) {
qmlInfo(this) << tr("Coordinate does not belong to PolylineMapItem.");
return;
}
- QList<QGeoCoordinate> path = polylineItem_->path();
-
- if (path.count() < index + 1) {
+ if (path_.count() < index + 1) {
qmlInfo(this) << tr("Coordinate does not belong to PolylineMapItem.");
return;
}
- path.removeAt(index);
- polylineItem_->setPath(path);
+ coordPath_.removeAt(index);
path_.removeAt(index);
- updateMapItem();
+ updateMapItem(true);
emit pathChanged();
}
-void QDeclarativePolylineMapItem::updateContent()
+QColor QDeclarativePolylineMapItem::color() const
{
- polylineItem_->updateGeometry();
- setWidth(polylineItem_->width());
- setHeight(polylineItem_->height());
+ return color_;
}
-QPointF QDeclarativePolylineMapItem::contentTopLeftPoint()
+void QDeclarativePolylineMapItem::setColor(const QColor &color)
{
- return map_->coordinateToScreenPosition(
- polylineItem_->quickItemCoordinate(), false) - polylineItem_->quickItemAnchorPoint();
+ if (color_ == color)
+ return;
+
+ color_ = color;
+ updateMapItem(false);
+ emit colorChanged(color_);
}
-void QDeclarativePolylineMapItem::mapChanged()
+QSGNode* QDeclarativePolylineMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
- polylineItem_->setMap(map_);
- if (map_) {
- connect(map_, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
- // initial update
- handleCameraDataChanged(map_->cameraData());
+ Q_UNUSED(data);
+
+ MapPolylineNode *node = static_cast<MapPolylineNode*>(oldNode);
+
+ if (!node) {
+ mapPolylineNode_ = new MapPolylineNode();
+ updateMapItem(true);
}
-}
-void QDeclarativePolylineMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
-{
- // TODO - if X and Y of the wrapper item are changed, currently
- // the item moves, but returns to old position when map camera changes
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
+ mapPolylineNode_->update();
+ return mapPolylineNode_;
}
-void QDeclarativePolylineMapItem::dragStarted()
-{
- qmlInfo(this) << "warning: mouse dragging is not currently supported with polylines/routes.";
-}
+void QDeclarativePolylineMapItem::updateMapItem(bool dirtyGeometry) {
-bool QDeclarativePolylineMapItem::contains(QPointF point)
-{
- // todo this currently returns all points _inside_ of the implicitly closed
- // painterpath whereas we are only interested in the outlines of it
- return polylineItem_->contains(point);
+ if (!map() || path_.count()==0 || !mapPolylineNode_)
+ return;
+
+ mapPolylineNode_->setPenColor(color_);
+
+ if (dirtyGeometry) mapPolylineNode_->setGeometry(*map(), path_);
+
+ const QSizeF& size = mapPolylineNode_->size();
+
+ setWidth(size.width());
+ setHeight(size.height());
+
+ setPositionOnMap(path_.at(0),mapPolylineNode_->geometry().at(0));
+ update();
}
void QDeclarativePolylineMapItem::handleCameraDataChanged(const CameraData& cameraData)
{
- polylineItem_->setZoomLevel(cameraData.zoomFactor());
- updateMapItem();
+ if (cameraData.zoomFactor() != zoomLevel_) {
+ zoomLevel_ = cameraData.zoomFactor();
+ updateMapItem(true);
+ } else {
+ updateMapItem(false);
+ }
}
-QColor QDeclarativePolylineMapItem::color() const
+bool QDeclarativePolylineMapItem::contains(QPointF point)
{
- return color_;
+ // TODO: this currently returns all points _inside_ of the implicitly closed
+ // painterpath whereas we are only interested in the outlines of it
+ return mapPolylineNode_->contains(point);
}
-void QDeclarativePolylineMapItem::setColor(const QColor &color)
+void QDeclarativePolylineMapItem::dragStarted()
{
- if (color_ == color)
- return;
-
- color_ = color;
- polylineItem_->setPen(color);
- emit colorChanged(color_);
+ qmlInfo(this) << "warning: mouse dragging is not currently supported with polylines/routes.";
}
//////////////////////////////////////////////////////////////////////
-PolylineMapPaintedItem::PolylineMapPaintedItem(QQuickItem *parent) :
- QQuickPaintedItem(parent), map_(0), zoomLevel_(-1), initialized_(false),
- dirtyGeometry_(false)
+MapPolylineNode::MapPolylineNode() :
+ fillColor_(Qt::black),
+ geometry_(QSGGeometry::defaultAttributes_Point2D(),0)
{
- setAntialiasing(true);
- connect(this, SIGNAL(xChanged()), this, SLOT(update()));
- connect(this, SIGNAL(yChanged()), this, SLOT(update()));
+ geometry_.setDrawingMode(GL_LINE_STRIP);
+ QSGGeometryNode::setMaterial(&fill_material_);
+ QSGGeometryNode::setGeometry(&geometry_);
}
-PolylineMapPaintedItem::~PolylineMapPaintedItem()
-{
-}
-void PolylineMapPaintedItem::setMap(Map* map)
+MapPolylineNode::~MapPolylineNode()
{
- map_ = map;
}
-Map* PolylineMapPaintedItem::map()
+void MapPolylineNode::update()
{
- return map_;
-}
-
-void PolylineMapPaintedItem::setZoomLevel(qreal zoomLevel)
-{
- if (zoomLevel_ == zoomLevel)
+ //TODO: optimize , perform calculation only if polygon has changed
+ if (polyline_.size() == 0)
return;
- zoomLevel_ = zoomLevel;
- dirtyGeometry_ = true;
-}
+ QSGGeometry *fill = QSGGeometryNode::geometry();
-qreal PolylineMapPaintedItem::zoomLevel() const
-{
- return zoomLevel_;
-}
+ Q_ASSERT(fill->sizeOfVertex() == sizeof(Vertex));
-bool PolylineMapPaintedItem::contains(QPointF point)
-{
- return path_.contains(point);
-}
+ int fillVertexCount = 0;
+ //note this will not allocate new buffer if the size has not changed
+ fill->allocate(polyline_.size());
-void PolylineMapPaintedItem::setPath(const QList<QGeoCoordinate>& path)
-{
- coordPath_ = path;
- dirtyGeometry_ = true;
-}
+ Vertex *vertices = (Vertex *)fill->vertexData();
-QList<QGeoCoordinate> PolylineMapPaintedItem::path() const
-{
- return coordPath_;
-}
+ for (int i = 0; i < polyline_.size(); ++i) {
+ vertices[fillVertexCount++].position = QVector2D(polyline_.at(i));
+ }
-QGeoCoordinate PolylineMapPaintedItem::quickItemCoordinate() const
-{
- return quickItemCoordinate_;
-}
+ Q_ASSERT(fillVertexCount == fill->vertexCount());
-QPointF PolylineMapPaintedItem::quickItemAnchorPoint() const
-{
- return quickItemAnchorPoint_;
-}
+ markDirty(DirtyGeometry);
-void PolylineMapPaintedItem::setBrush(const QBrush &brush)
-{
- brush_ = brush;
-}
+ if (fillColor_ != fill_material_.color()) {
+ fill_material_.setColor(fillColor_);
+ setMaterial(&fill_material_);
+ }
-QBrush PolylineMapPaintedItem::brush() const
-{
- return brush_;
+ //TODO: implement me : borders , gradient
}
-void PolylineMapPaintedItem::setPen(const QPen &pen)
+bool MapPolylineNode::contains(QPointF point)
{
- pen_ = pen;
+ //TODO: implement me
+ return polyline_.contains(point);
}
-QPen PolylineMapPaintedItem::pen() const
+void MapPolylineNode::setPenColor(const QColor &color)
{
- return pen_;
+ fillColor_ = color;
}
-void PolylineMapPaintedItem::paint(QPainter *painter)
+QColor MapPolylineNode::penColor() const
{
- if (!initialized_)
- return;
- painter->setPen(pen_);
- painter->setBrush(brush_);
- painter->drawPath(path_);
+ return fillColor_;
}
-void PolylineMapPaintedItem::updateGeometry()
+void MapPolylineNode::setGeometry(const Map& map, const QList<QGeoCoordinate> &path)
{
- if (!dirtyGeometry_)
- return;
- initialized_ = false;
-
- if (!map())
- return;
-
- if (coordPath_.size() == 0)
- return;
-
- if (zoomLevel_ == -1)
- return;
-
- qreal w = 0;
qreal h = 0;
-
- //TODO: optimize essential part
- path_ = createPath(*map_, coordPath_, w, h);
-
- setWidth(w);
- setHeight(h);
- setContentsSize(QSize(w, h));
-
- quickItemCoordinate_ = coordPath_.at(0);
- quickItemAnchorPoint_ = path_.pointAtPercent(0);
- initialized_ = true;
-
- dirtyGeometry_ = false;
- update();
+ qreal w = 0;
+ polyline_.clear();
+ updatePolyline(polyline_, map, path, w, h);
+ size_ = QSizeF(w, h);
}
QT_END_NAMESPACE
diff --git a/src/imports/location/qdeclarativepolylinemapitem_p.h b/src/imports/location/qdeclarativepolylinemapitem_p.h
index 60853a31..bcc5799d 100644
--- a/src/imports/location/qdeclarativepolylinemapitem_p.h
+++ b/src/imports/location/qdeclarativepolylinemapitem_p.h
@@ -43,14 +43,12 @@
#define QDECLARATIVEPOLYLINEMAPITEM
#include "qdeclarativegeomapitembase_p.h"
-#include "qdeclarativecoordinate_p.h"
-#include "qdeclarativegeomap_p.h"
-#include <QPen>
-#include <QBrush>
+#include <QSGGeometryNode>
+#include <QSGFlatColorMaterial>
QT_BEGIN_NAMESPACE
-class PolylineMapPaintedItem;
+class MapPolylineNode;
class QDeclarativePolylineMapItem : public QDeclarativeGeoMapItemBase
{
@@ -63,6 +61,10 @@ public:
QDeclarativePolylineMapItem(QQuickItem *parent = 0);
~QDeclarativePolylineMapItem();
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ //from QuickItem
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
Q_INVOKABLE void addCoordinate(QDeclarativeCoordinate* coordinate);
Q_INVOKABLE void removeCoordinate(QDeclarativeCoordinate* coordinate);
@@ -79,13 +81,7 @@ Q_SIGNALS:
void colorChanged(const QColor &color);
protected Q_SLOTS:
- // from qquickitem
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
-
-protected:
- void updateContent();
- QPointF contentTopLeftPoint();
- void mapChanged();
+ virtual void updateMapItem(bool dirtyGeomoetry = true);
private Q_SLOTS:
// map size changed
@@ -99,57 +95,42 @@ private:
void pathPropertyChanged();
private:
- PolylineMapPaintedItem *polylineItem_;
- QList<QDeclarativeCoordinate*> path_;
+ MapPolylineNode *mapPolylineNode_;
+ QList<QDeclarativeCoordinate*> coordPath_;
+ QList<QGeoCoordinate> path_;
QColor color_;
- bool initialized_;
+ qreal zoomLevel_;
};
//////////////////////////////////////////////////////////////////////
-class PolylineMapPaintedItem : public QQuickPaintedItem
+class MapPolylineNode : public QSGGeometryNode
{
- Q_OBJECT
public:
- PolylineMapPaintedItem(QQuickItem *parent = 0);
- ~PolylineMapPaintedItem();
-
- void setMap(Map* map);
- Map* map();
+ MapPolylineNode();
+ ~MapPolylineNode();
- void setZoomLevel(qreal zoomLevel);
- qreal zoomLevel() const;
+ void setSize(const QSize &size);
+ QSizeF size() const {
+ return size_;
+ }
- QList<QGeoCoordinate> path() const;
- void setPath(const QList<QGeoCoordinate>& path);
-
- void paint(QPainter *painter);
-
- QPen pen() const;
- void setPen(const QPen &pen);
-
- QBrush brush() const;
- void setBrush(const QBrush &brush);
+ QColor penColor() const;
+ void setPenColor(const QColor &pen);
+ void update();
bool contains(QPointF point);
- QGeoCoordinate quickItemCoordinate() const;
- QPointF quickItemAnchorPoint() const;
-
- void updateGeometry();
+ void setGeometry(const Map &map, const QList<QGeoCoordinate> &path);
+ const QPolygonF& geometry() { return polyline_; }
private:
- Map *map_;
- qreal zoomLevel_;
- QPen pen_;
- QBrush brush_;
- QGeoCoordinate quickItemCoordinate_;
- QPointF quickItemAnchorPoint_;
- QList<QGeoCoordinate> coordPath_;
- QPainterPath path_;
- bool initialized_;
- bool dirtyGeometry_;
+ QSGFlatColorMaterial fill_material_;
+ QColor fillColor_;
+ QSGGeometry geometry_;
+ QPolygonF polyline_;
+ QSizeF size_;
};
diff --git a/src/imports/location/qdeclarativerectanglemapitem.cpp b/src/imports/location/qdeclarativerectanglemapitem.cpp
index 9c31b662..24398983 100644
--- a/src/imports/location/qdeclarativerectanglemapitem.cpp
+++ b/src/imports/location/qdeclarativerectanglemapitem.cpp
@@ -44,20 +44,32 @@
QT_BEGIN_NAMESPACE
-QDeclarativeRectangleMapItem::QDeclarativeRectangleMapItem(QQuickItem *parent)
-: QDeclarativeGeoMapItemBase(parent),
- rectangleItem_(new RectangleMapPaintedItem(this)),
- topLeft_(0),
- bottomRight_(0),
- dragActive_(false)
+struct Vertex
{
- rectangleItem_->setParentItem(this);
+ QVector2D position;
+};
+
+QDeclarativeRectangleMapItem::QDeclarativeRectangleMapItem(QQuickItem *parent):
+ QDeclarativeGeoMapItemBase(parent),
+ mapRectangleNode_(0),
+ topLeft_(0),
+ bottomRight_(0),
+ zoomLevel_(0.0),
+ dragActive_(false)
+{
+ setFlag(ItemHasContents, true);
}
QDeclarativeRectangleMapItem::~QDeclarativeRectangleMapItem()
{
}
+void QDeclarativeRectangleMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map)
+{
+ QDeclarativeGeoMapItemBase::setMap(quickMap,map);
+ if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
+}
+
void QDeclarativeRectangleMapItem::setTopLeft(QDeclarativeCoordinate *topLeft)
{
if (topLeft_ == topLeft)
@@ -65,19 +77,18 @@ void QDeclarativeRectangleMapItem::setTopLeft(QDeclarativeCoordinate *topLeft)
if (topLeft_)
topLeft_->disconnect(this);
topLeft_ = topLeft;
- if (!topLeft_) {
- rectangleItem_->setTopLeft(QGeoCoordinate());
- } else {
- rectangleItem_->setTopLeft(topLeft_->coordinate());
+
+ if (topLeft_) {
connect(topLeft_, SIGNAL(latitudeChanged(double)), this,
- SLOT(handleTopLeftCoordinateChanged()));
+ SLOT(updateMapItem()));
connect(topLeft_, SIGNAL(longitudeChanged(double)), this,
- SLOT(handleTopLeftCoordinateChanged()));
+ SLOT(updateMapItem()));
connect(topLeft_, SIGNAL(altitudeChanged(double)), this,
- SLOT(handleTopLeftCoordinateChanged()));
+ SLOT(updateMapItem()));
}
+
+ updateMapItem(true);
emit topLeftChanged(topLeft_);
- updateMapItem();
}
QDeclarativeCoordinate* QDeclarativeRectangleMapItem::topLeft()
@@ -92,19 +103,16 @@ void QDeclarativeRectangleMapItem::setBottomRight(QDeclarativeCoordinate *bottom
if (bottomRight_)
bottomRight_->disconnect(this);
bottomRight_ = bottomRight;
- if (!bottomRight_) {
- rectangleItem_->setBottomRight(QGeoCoordinate());
- } else {
- rectangleItem_->setBottomRight(bottomRight_->coordinate());
+ if (bottomRight_) {
connect(bottomRight_, SIGNAL(latitudeChanged(double)), this,
- SLOT(handleBottomRightCoordinateChanged()));
+ SLOT(updateMapItem()));
connect(bottomRight_, SIGNAL(longitudeChanged(double)), this,
- SLOT(handleBottomRightCoordinateChanged()));
+ SLOT(updateMapItem()));
connect(bottomRight_, SIGNAL(altitudeChanged(double)), this,
- SLOT(handleBottomRightCoordinateChanged()));
+ SLOT(updateMapItem()));
}
- emit bottomRightChanged(bottomRight);
- updateMapItem();
+ updateMapItem(true);
+ emit bottomRightChanged(bottomRight_);
}
QDeclarativeCoordinate* QDeclarativeRectangleMapItem::bottomRight()
@@ -112,25 +120,68 @@ QDeclarativeCoordinate* QDeclarativeRectangleMapItem::bottomRight()
return bottomRight_;
}
-void QDeclarativeRectangleMapItem::updateContent()
+QColor QDeclarativeRectangleMapItem::color() const
{
- rectangleItem_->updateGeometry();
- setWidth(rectangleItem_->width());
- setHeight(rectangleItem_->height());
+ return color_;
}
-QPointF QDeclarativeRectangleMapItem::contentTopLeftPoint()
+void QDeclarativeRectangleMapItem::setColor(const QColor &color)
{
- return map_->coordinateToScreenPosition(rectangleItem_->topLeft(), false);
+ if (color_ == color)
+ return;
+ color_ = color;
+ updateMapItem(false);
+ emit colorChanged(color_);
}
-void QDeclarativeRectangleMapItem::mapChanged()
+QSGNode* QDeclarativeRectangleMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
- rectangleItem_->setMap(map_);
- if (map_) {
- connect(map_, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
- handleCameraDataChanged(map_->cameraData());
+ Q_UNUSED(data);
+
+ MapRectangleNode *node = static_cast<MapRectangleNode*>(oldNode);
+
+ if (!node) {
+ mapRectangleNode_ = new MapRectangleNode();
+ updateMapItem(true);
}
+
+ mapRectangleNode_->update();
+ return mapRectangleNode_;
+}
+
+void QDeclarativeRectangleMapItem::updateMapItem(bool dirtyGeometry)
+{
+ if (!map() || !topLeft() || !topLeft()->coordinate().isValid()
+ || !bottomRight() || !bottomRight()->coordinate().isValid()
+ || !mapRectangleNode_)
+ return;
+
+ mapRectangleNode_->setBrushColor(color_);
+
+ if (dirtyGeometry) mapRectangleNode_->setGeometry(*map(), topLeft()->coordinate(), bottomRight()->coordinate());
+
+ const QSizeF& size = mapRectangleNode_->size();
+
+ setWidth(size.width());
+ setHeight(size.height());
+
+ setPositionOnMap(topLeft()->coordinate(), QPointF(0, 0));
+ update();
+}
+
+void QDeclarativeRectangleMapItem::handleCameraDataChanged(const CameraData& cameraData)
+{
+ if (cameraData.zoomFactor() != zoomLevel_) {
+ zoomLevel_ = cameraData.zoomFactor();
+ updateMapItem(true);
+ } else {
+ updateMapItem(false);
+ }
+}
+
+bool QDeclarativeRectangleMapItem::contains(QPointF point)
+{
+ return mapRectangleNode_->contains(point);
}
void QDeclarativeRectangleMapItem::dragEnded()
@@ -140,9 +191,9 @@ void QDeclarativeRectangleMapItem::dragEnded()
dragActive_ = false;
QPointF newTopLeftPoint = QPointF(x(),y());
// does not preserve exact projection geometry but that should be acceptable
- QGeoCoordinate newTopLeft = map_->screenPositionToCoordinate(newTopLeftPoint, false);
+ QGeoCoordinate newTopLeft = map()->screenPositionToCoordinate(newTopLeftPoint, false);
QPointF newBottomRightPoint = QPointF(x() + width(), y() + height());
- QGeoCoordinate newBottomRight = map_->screenPositionToCoordinate(newBottomRightPoint, false);
+ QGeoCoordinate newBottomRight = map()->screenPositionToCoordinate(newBottomRightPoint, false);
if (newTopLeft.isValid() && newBottomRight.isValid()) {
internalTopLeft_.setCoordinate(newTopLeft);
internalBottomRight_.setCoordinate(newBottomRight);
@@ -155,146 +206,80 @@ void QDeclarativeRectangleMapItem::dragStarted()
{
dragActive_ = true;
}
+//////////////////////////////////////////////////////////////////////
-void QDeclarativeRectangleMapItem::handleCameraDataChanged(const CameraData& cameraData)
+MapRectangleNode::MapRectangleNode():
+ fillColor_(Qt::black),
+ borderColor_(Qt::black),
+ geometry_(QSGGeometry::defaultAttributes_Point2D(),0)
{
- rectangleItem_->setZoomLevel(cameraData.zoomFactor());
- updateMapItem();
+ geometry_.setDrawingMode(GL_QUADS);
+ QSGGeometryNode::setMaterial(&fill_material_);
+ QSGGeometryNode::setGeometry(&geometry_);
}
-bool QDeclarativeRectangleMapItem::contains(QPointF point)
+MapRectangleNode::~MapRectangleNode()
{
- return rectangleItem_->contains(point);
}
-void QDeclarativeRectangleMapItem::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
+void MapRectangleNode::update()
{
- // TODO - if X and Y of the wrapper item are changed, currently
- // the item moves, but returns to old position when map camera changes
- QQuickItem::geometryChanged(newGeometry, oldGeometry);
-}
+ QSGGeometry *fill = QSGGeometryNode::geometry();
-void QDeclarativeRectangleMapItem::handleTopLeftCoordinateChanged()
-{
- rectangleItem_->setTopLeft(topLeft_->coordinate());
- emit topLeftChanged(topLeft_);
-}
+ Q_ASSERT(fill->sizeOfVertex() == sizeof(Vertex));
-void QDeclarativeRectangleMapItem::handleBottomRightCoordinateChanged()
-{
- rectangleItem_->setBottomRight(bottomRight_->coordinate());
- emit bottomRightChanged(bottomRight_);
-}
+ int fillVertexCount = 0;
+ //note this will not allocate new buffer if the size has not changed
+ fill->allocate(4);
-QColor QDeclarativeRectangleMapItem::color() const
-{
- return color_;
-}
+ Vertex *vertices = (Vertex *)fill->vertexData();
-void QDeclarativeRectangleMapItem::setColor(const QColor &color)
-{
- if (color_ == color)
- return;
+ //set corners
+ vertices[fillVertexCount++].position = QVector2D(rect_.left(),rect_.top());
+ vertices[fillVertexCount++].position = QVector2D(rect_.right(),rect_.top());
+ vertices[fillVertexCount++].position = QVector2D(rect_.right(),rect_.bottom());
+ vertices[fillVertexCount++].position = QVector2D(rect_.left(),rect_.bottom());
- color_ = color;
- QBrush m_brush(color);
- rectangleItem_->setBrush(m_brush);
- emit colorChanged(color_);
-}
-
-//////////////////////////////////////////////////////////////////////
-
-RectangleMapPaintedItem::RectangleMapPaintedItem(QQuickItem *parent) :
- QQuickPaintedItem(parent), map_(0), zoomLevel_(-1), initialized_(false),
- dirtyGeometry_(false)
-{
- setAntialiasing(true);
- connect(this, SIGNAL(xChanged()), this, SLOT(update()));
- connect(this, SIGNAL(yChanged()), this, SLOT(update()));
-}
-
-RectangleMapPaintedItem::~RectangleMapPaintedItem()
-{
-}
-
-void RectangleMapPaintedItem::setMap(Map* map)
-{
- map_ = map;
-}
+ Q_ASSERT(fillVertexCount == fill->vertexCount());
-Map* RectangleMapPaintedItem::map()
-{
- return map_;
-}
-
-void RectangleMapPaintedItem::setZoomLevel(qreal zoomLevel)
-{
- if (zoomLevel_ == zoomLevel)
- return;
-
- zoomLevel_ = zoomLevel;
- dirtyGeometry_ = true;
-}
+ markDirty(DirtyGeometry);
-qreal RectangleMapPaintedItem::zoomLevel() const
-{
- return zoomLevel_;
+ if (fillColor_ != fill_material_.color()) {
+ fill_material_.setColor(fillColor_);
+ setMaterial(&fill_material_);
+ }
+ //TODO: implement me : borders , gradient
}
-void RectangleMapPaintedItem::setTopLeft(const QGeoCoordinate &topLeftCoord)
+void MapRectangleNode::setBrushColor(const QColor &color)
{
- if (topLeftCoord_ == topLeftCoord)
- return;
-
- topLeftCoord_ = topLeftCoord;
- dirtyGeometry_ = true;
+ fillColor_= color;
}
-QGeoCoordinate RectangleMapPaintedItem::topLeft() const
+QColor MapRectangleNode::brushColor() const
{
- return topLeftCoord_;
+ return fillColor_;
}
-void RectangleMapPaintedItem::setBottomRight(const QGeoCoordinate &bottomRightCoord)
+void MapRectangleNode::setPenColor(const QColor &color)
{
- if (bottomRightCoord_ == bottomRightCoord)
- return;
-
- bottomRightCoord_ = bottomRightCoord;
- dirtyGeometry_ = true;
+ borderColor_ = color;
}
-QGeoCoordinate RectangleMapPaintedItem::bottomRight() const
+QColor MapRectangleNode::penColor() const
{
- return bottomRightCoord_;
+ return borderColor_;
}
-void RectangleMapPaintedItem::paint(QPainter *painter)
+bool MapRectangleNode::contains(QPointF point)
{
- if (!initialized_)
- return;
- painter->setPen(pen_);
- painter->setBrush(brush_);
- painter->drawRect(rect_);
+ return rect_.contains(point);
}
-void RectangleMapPaintedItem::updateGeometry()
+void MapRectangleNode::setGeometry(const Map& map, const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight)
{
- if (!dirtyGeometry_)
- return;
- initialized_ = false;
-
- if (!map_)
- return;
-
- if (!topLeftCoord_.isValid() || !bottomRightCoord_.isValid())
- return;
-
- if (zoomLevel_ == -1)
- return;
-
- QPointF p1 = map_->coordinateToScreenPosition(topLeftCoord_, false);
- QPointF p2 = map_->coordinateToScreenPosition(bottomRightCoord_, false);
+ QPointF p1 = map.coordinateToScreenPosition(topLeft, false);
+ QPointF p2 = map.coordinateToScreenPosition(bottomRight, false);
qreal minX = qMin(p1.x(), p2.x());
qreal maxX = qMax(p1.x(), p2.x());
@@ -304,42 +289,9 @@ void RectangleMapPaintedItem::updateGeometry()
qreal w = maxX - minX;
qreal h = maxY - minY;
- setWidth(w);
- setHeight(h);
- setContentsSize(QSize(w, h));
-
+ size_ = QSizeF(w, h);
rect_.setTopLeft(QPointF(0, 0));
rect_.setBottomRight(QPointF(w, h));
-
- initialized_ = true;
- dirtyGeometry_ = false;
- update(); // qquickpainteditem
-}
-
-
-bool RectangleMapPaintedItem::contains(QPointF point)
-{
- return rect_.contains(point);
-}
-
-void RectangleMapPaintedItem::setBrush(const QBrush &brush)
-{
- brush_ = brush;
-}
-
-QBrush RectangleMapPaintedItem::brush() const
-{
- return brush_;
-}
-
-void RectangleMapPaintedItem::setPen(const QPen &pen)
-{
- pen_ = pen;
-}
-
-QPen RectangleMapPaintedItem::pen() const
-{
- return pen_;
}
QT_END_NAMESPACE
diff --git a/src/imports/location/qdeclarativerectanglemapitem_p.h b/src/imports/location/qdeclarativerectanglemapitem_p.h
index 7e3653c0..bea588de 100644
--- a/src/imports/location/qdeclarativerectanglemapitem_p.h
+++ b/src/imports/location/qdeclarativerectanglemapitem_p.h
@@ -43,14 +43,12 @@
#define QDECLARATIVERECTANGLEMAPITEM_H_
#include "qdeclarativegeomapitembase_p.h"
-#include "qdeclarativecoordinate_p.h"
-#include "qdeclarativegeomap_p.h"
-#include <QPen>
-#include <QBrush>
+#include <QSGGeometryNode>
+#include <QSGFlatColorMaterial>
QT_BEGIN_NAMESPACE
-class RectangleMapPaintedItem;
+class MapRectangleNode;
class QDeclarativeRectangleMapItem: public QDeclarativeGeoMapItemBase
{
@@ -64,6 +62,10 @@ public:
QDeclarativeRectangleMapItem(QQuickItem *parent = 0);
~QDeclarativeRectangleMapItem();
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ //from QuickItem
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
QDeclarativeCoordinate* topLeft();
void setTopLeft(QDeclarativeCoordinate *center);
@@ -83,73 +85,56 @@ Q_SIGNALS:
void colorChanged(const QColor &color);
protected Q_SLOTS:
- void updateContent();
- QPointF contentTopLeftPoint();
- void mapChanged();
- // from qquickitem
- void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
+ virtual void updateMapItem(bool dirtyGeometry = true);
+
private Q_SLOTS:
// map size changed
void handleCameraDataChanged(const CameraData& cameraData);
- void handleTopLeftCoordinateChanged();
- void handleBottomRightCoordinateChanged();
private:
- RectangleMapPaintedItem *rectangleItem_;
+ MapRectangleNode *mapRectangleNode_;
QDeclarativeCoordinate* topLeft_;
QDeclarativeCoordinate* bottomRight_;
QDeclarativeCoordinate internalTopLeft_;
QDeclarativeCoordinate internalBottomRight_;
QColor color_;
+ qreal zoomLevel_;
bool dragActive_;
};
//////////////////////////////////////////////////////////////////////
-class RectangleMapPaintedItem: public QQuickPaintedItem
+class MapRectangleNode: public QSGGeometryNode
{
- Q_OBJECT
public:
- RectangleMapPaintedItem(QQuickItem *parent = 0);
- ~RectangleMapPaintedItem();
-
- void setMap(Map* map);
- Map* map();
+ MapRectangleNode();
+ ~MapRectangleNode();
- void setZoomLevel(qreal zoomLevel);
- qreal zoomLevel() const;
+ void setSize(const QSize &size);
+ QSizeF size() const {
+ return size_;
+ }
- QGeoCoordinate topLeft() const;
- void setTopLeft(const QGeoCoordinate &topLeft);
+ QColor penColor() const;
+ void setPenColor(const QColor &pen);
- QGeoCoordinate bottomRight() const;
- void setBottomRight(const QGeoCoordinate &bottomRight);
-
- void paint(QPainter *painter);
-
- QPen pen() const;
- void setPen(const QPen &pen);
-
- QBrush brush() const;
- void setBrush(const QBrush &brush);
+ QColor brushColor() const;
+ void setBrushColor(const QColor &color);
+ void update();
bool contains(QPointF point);
- void updateGeometry();
+ void setGeometry(const Map& map, const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight);
private:
- Map *map_;
- qreal zoomLevel_;
- QGeoCoordinate topLeftCoord_;
- QGeoCoordinate bottomRightCoord_;
- QGeoCoordinate quickItemCoordinate_;
- QPointF quickItemAnchorPoint_;
- QPen pen_;
- QBrush brush_;
+ QSGFlatColorMaterial fill_material_;
+ QColor fillColor_;
+ QColor borderColor_;
+ QSGGeometry geometry_;
QRectF rect_;
- bool initialized_;
- bool dirtyGeometry_;
+ QSizeF size_;
+
};
QT_END_NAMESPACE
diff --git a/src/imports/location/qdeclarativeroutemapitem.cpp b/src/imports/location/qdeclarativeroutemapitem.cpp
index 7a904b87..c708473b 100644
--- a/src/imports/location/qdeclarativeroutemapitem.cpp
+++ b/src/imports/location/qdeclarativeroutemapitem.cpp
@@ -46,18 +46,25 @@
#include <QtDeclarative/QDeclarativeInfo>
#include <QtGui/QPainter>
-QDeclarativeRouteMapItem::QDeclarativeRouteMapItem(QQuickItem *parent)
- : QDeclarativeGeoMapItemBase(parent),
- polylineItem_(new PolylineMapPaintedItem(this)),
- route_(0)
+QDeclarativeRouteMapItem::QDeclarativeRouteMapItem(QQuickItem *parent):
+ QDeclarativeGeoMapItemBase(parent),
+ mapPolylineNode_(0),
+ route_(0),
+ zoomLevel_(0.0)
{
- polylineItem_->setParentItem(this);
+ setFlag(ItemHasContents, true);
}
QDeclarativeRouteMapItem::~QDeclarativeRouteMapItem()
{
}
+void QDeclarativeRouteMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map)
+{
+ QDeclarativeGeoMapItemBase::setMap(quickMap,map);
+ if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
+}
+
QColor QDeclarativeRouteMapItem::color() const
{
return color_;
@@ -69,9 +76,7 @@ void QDeclarativeRouteMapItem::setColor(const QColor &color)
return;
color_ = color;
- //QBrush m_brush(color);
- //polylineItem_->setBrush(m_brush);
- polylineItem_->setPen(color);
+ updateMapItem(false);
emit colorChanged(color_);
}
@@ -88,51 +93,66 @@ void QDeclarativeRouteMapItem::setRoute(QDeclarativeGeoRoute *route)
route_ = route;
if (route_) {
- polylineItem_->setPath(route_->routePath());
+ path_ = route_->routePath();
} else {
- polylineItem_->setPath(QList<QGeoCoordinate>());
+ path_ = QList<QGeoCoordinate>();
}
- updateMapItem();
+ updateMapItem(true);
emit routeChanged(route_);
}
-void QDeclarativeRouteMapItem::updateContent()
+QSGNode* QDeclarativeRouteMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
- polylineItem_->updateGeometry();
- setWidth(polylineItem_->width());
- setHeight(polylineItem_->height());
-}
+ Q_UNUSED(data);
-QPointF QDeclarativeRouteMapItem::contentTopLeftPoint()
-{
- return map_->coordinateToScreenPosition(
- polylineItem_->quickItemCoordinate(), false) - polylineItem_->quickItemAnchorPoint();
-}
+ MapPolylineNode *node = static_cast<MapPolylineNode*>(oldNode);
-void QDeclarativeRouteMapItem::mapChanged()
-{
- polylineItem_->setMap(map_);
- if (map_) {
- connect(map_, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData)));
- // initial update
- handleCameraDataChanged(map_->cameraData());
+ if (!node) {
+ mapPolylineNode_ = new MapPolylineNode();
+ updateMapItem(true);
}
+
+ mapPolylineNode_->update();
+ return mapPolylineNode_;
}
-void QDeclarativeRouteMapItem::dragStarted()
+
+void QDeclarativeRouteMapItem::updateMapItem(bool dirtyGeometry) {
+
+ if (!map() || path_.count() == 0 || !mapPolylineNode_)
+ return;
+
+ mapPolylineNode_->setPenColor(color_);
+
+ if (dirtyGeometry) mapPolylineNode_->setGeometry(*map(), path_);
+
+ const QSizeF& size = mapPolylineNode_->size();
+
+ setWidth(size.width());
+ setHeight(size.height());
+
+ setPositionOnMap(path_.at(0), mapPolylineNode_->geometry().at(0));
+ update();
+}
+
+void QDeclarativeRouteMapItem::handleCameraDataChanged(const CameraData& cameraData)
{
- qmlInfo(this) << "warning: mouse dragging is not currently supported with polylines/routes.";
+ if (cameraData.zoomFactor() != zoomLevel_) {
+ zoomLevel_ = cameraData.zoomFactor();
+ updateMapItem(true);
+ } else {
+ updateMapItem(false);
+ }
}
bool QDeclarativeRouteMapItem::contains(QPointF point)
{
- return polylineItem_->contains(point);
+ return mapPolylineNode_->contains(point);
}
-void QDeclarativeRouteMapItem::handleCameraDataChanged(const CameraData& cameraData)
+void QDeclarativeRouteMapItem::dragStarted()
{
- polylineItem_->setZoomLevel(cameraData.zoomFactor());
- updateMapItem();
+ qmlInfo(this) << "warning: mouse dragging is not currently supported with polylines/routes.";
}
diff --git a/src/imports/location/qdeclarativeroutemapitem_p.h b/src/imports/location/qdeclarativeroutemapitem_p.h
index b46795a6..157acc41 100644
--- a/src/imports/location/qdeclarativeroutemapitem_p.h
+++ b/src/imports/location/qdeclarativeroutemapitem_p.h
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
class QDeclarativeGeoRoute;
-class PolylineMapPaintedItem;
+class MapPolylineNode;
class QDeclarativeRouteMapItem : public QDeclarativeGeoMapItemBase
{
@@ -64,6 +64,10 @@ public:
QDeclarativeRouteMapItem(QQuickItem *parent = 0);
~QDeclarativeRouteMapItem();
+ virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map);
+ //from QuickItem
+ virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *);
+
QDeclarativeGeoRoute* route() const;
void setRoute(QDeclarativeGeoRoute *route);
@@ -77,19 +81,19 @@ Q_SIGNALS:
void routeChanged(const QDeclarativeGeoRoute *route);
void colorChanged(const QColor &color);
-protected:
- void updateContent();
- QPointF contentTopLeftPoint();
- void mapChanged();
+protected Q_SLOTS:
+ virtual void updateMapItem(bool dirtyGeomoetry = true);
private Q_SLOTS:
// map size changed
void handleCameraDataChanged(const CameraData& cameraData);
private:
- PolylineMapPaintedItem *polylineItem_;
+ MapPolylineNode *mapPolylineNode_;
QDeclarativeGeoRoute* route_;
QColor color_;
+ qreal zoomLevel_;
+ QList<QGeoCoordinate> path_;
bool dragActive_;
};