diff options
author | Michal Klocek <michal.klocek@digia.com> | 2011-12-14 11:29:15 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-18 16:08:47 +0100 |
commit | 24a7188845f36eebab208ab626803663d8168ac2 (patch) | |
tree | c7e7d5ad80b412daf7ec875863d11271687a774b | |
parent | bdc72e694036547417d6c5925584113721366c81 (diff) | |
download | qtlocation-24a7188845f36eebab208ab626803663d8168ac2.tar.gz |
Fix threading issue for map item
* restrict node access only to updatePaintNode
* add dirty flags
* move gemoetry calcualtion to declaratvie class
* fix missing first update call
Change-Id: Ie1a6e5e6fcde9d336d72783dfdf22e39bf53c285
Reviewed-by: Juha Vuolle <juha.vuolle@nokia.com>
-rw-r--r-- | src/imports/location/qdeclarativecirclemapitem.cpp | 177 | ||||
-rw-r--r-- | src/imports/location/qdeclarativecirclemapitem_p.h | 38 | ||||
-rw-r--r-- | src/imports/location/qdeclarativegeomapitembase_p.h | 3 | ||||
-rw-r--r-- | src/imports/location/qdeclarativegeomapquickitem.cpp | 3 | ||||
-rw-r--r-- | src/imports/location/qdeclarativegeomapquickitem_p.h | 2 | ||||
-rw-r--r-- | src/imports/location/qdeclarativepolygonmapitem.cpp | 166 | ||||
-rw-r--r-- | src/imports/location/qdeclarativepolygonmapitem_p.h | 35 | ||||
-rw-r--r-- | src/imports/location/qdeclarativepolylinemapitem.cpp | 129 | ||||
-rw-r--r-- | src/imports/location/qdeclarativepolylinemapitem_p.h | 30 | ||||
-rw-r--r-- | src/imports/location/qdeclarativerectanglemapitem.cpp | 129 | ||||
-rw-r--r-- | src/imports/location/qdeclarativerectanglemapitem_p.h | 29 | ||||
-rw-r--r-- | src/imports/location/qdeclarativeroutemapitem.cpp | 101 | ||||
-rw-r--r-- | src/imports/location/qdeclarativeroutemapitem_p.h | 7 | ||||
-rw-r--r-- | tests/applications/declarative_map/map3d.qml | 18 |
14 files changed, 349 insertions, 518 deletions
diff --git a/src/imports/location/qdeclarativecirclemapitem.cpp b/src/imports/location/qdeclarativecirclemapitem.cpp index b921e459..8c6a423f 100644 --- a/src/imports/location/qdeclarativecirclemapitem.cpp +++ b/src/imports/location/qdeclarativecirclemapitem.cpp @@ -48,8 +48,6 @@ QT_BEGIN_NAMESPACE -//TODO: make export ?? - #ifndef M_PI #define M_PI 3.14159265358979323846 #endif @@ -105,7 +103,7 @@ static void updatePolygon(QPolygonF& points,const Map& map, const QList<QGeoCoor h = maxY - minY; } -static void calcualtePeripheralPoints(QList<QGeoCoordinate>& path, const QGeoCoordinate& center, qreal distance, int steps) +static void calculatePeripheralPoints(QList<QGeoCoordinate>& path, const QGeoCoordinate& center, qreal distance, int steps) { // get angular distance in radians distance = distance / (qgeocoordinate_EARTH_MEAN_RADIUS * 1000); @@ -160,13 +158,16 @@ static void calcualtePeripheralPoints(QList<QGeoCoordinate>& path, const QGeoCoo QDeclarativeCircleMapItem::QDeclarativeCircleMapItem(QQuickItem *parent): QDeclarativeGeoMapItemBase(parent), center_(0), - mapCircleNode_(0), radius_(0), zoomLevel_(0.0), + dirtyPixelGeometry_(true), + dirtyGeoGeometry_(true), + dirtyMaterial_(true), dragActive_(false) { setFlag(ItemHasContents, true); + border_.setWidth(3.0); QObject::connect(&border_, SIGNAL(colorChanged(QColor)), this, SLOT(handleBorderUpdated())); QObject::connect(&border_, SIGNAL(widthChanged(qreal)), @@ -184,15 +185,18 @@ QDeclarativeMapLineProperties *QDeclarativeCircleMapItem::border() void QDeclarativeCircleMapItem::handleBorderUpdated() { - updateMapItem(true); + dirtyGeoGeometry_ = true; + updateMapItem(); } void QDeclarativeCircleMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map) { - QDeclarativeGeoMapItemBase::setMap(quickMap, map); - if (map) - QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), - this, SLOT(handleCameraDataChanged(CameraData))); + QDeclarativeGeoMapItemBase::setMap(quickMap,map); + if (map) { + QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + dirtyGeoGeometry_ = true; + updateMapItem(); + } } void QDeclarativeCircleMapItem::setCenter(QDeclarativeCoordinate *center) @@ -212,7 +216,8 @@ void QDeclarativeCircleMapItem::setCenter(QDeclarativeCoordinate *center) SLOT(updateMapItem())); } - updateMapItem(true); + dirtyGeoGeometry_ = true; + updateMapItem(); emit centerChanged(center_); } @@ -226,7 +231,8 @@ void QDeclarativeCircleMapItem::setColor(const QColor &color) if (color_ == color) return; color_ = color; - updateMapItem(false); + dirtyMaterial_ = true; + updateMapItem(); emit colorChanged(color_); } @@ -237,12 +243,12 @@ QColor QDeclarativeCircleMapItem::color() const void QDeclarativeCircleMapItem::setRadius(qreal radius) { - if (radius_ == radius) return; radius_ = radius; - updateMapItem(true); + dirtyGeoGeometry_ = true; + updateMapItem(); emit radiusChanged(radius); } @@ -258,33 +264,45 @@ QSGNode* QDeclarativeCircleMapItem::updatePaintNode(QSGNode* oldNode, UpdatePain MapCircleNode *node = static_cast<MapCircleNode*>(oldNode); - if (!node) { - mapCircleNode_ = new MapCircleNode(); - updateMapItem(true); - } + if (!node) + node = new MapCircleNode(); - mapCircleNode_->update(); - return mapCircleNode_; + //TODO: update only material + if (dirtyPixelGeometry_ || dirtyMaterial_) { + node->update(color_,circlePolygon_,QPointF(width()/2,height()/2), + borderPolygon_, border_.color(), border_.width()); + dirtyPixelGeometry_ = false; + dirtyMaterial_ = false; + } + return node; } -void QDeclarativeCircleMapItem::updateMapItem(bool dirtyGeometry) +void QDeclarativeCircleMapItem::updateMapItem() { - if (!map() || !center() || !center()->coordinate().isValid() || !mapCircleNode_) + if (!map() || !center() || !center()->coordinate().isValid()) return; - mapCircleNode_->setBrushColor(color_); - mapCircleNode_->setPenColor(border_.color()); - mapCircleNode_->setLineWidth(border_.width()); - - if (dirtyGeometry) - mapCircleNode_->setGeometry(*map(), radius(),center()->coordinate()); - - const QSizeF& size = mapCircleNode_->size(); + if (dirtyGeoGeometry_) { + circlePath_.clear(); + calculatePeripheralPoints(circlePath_, center_->coordinate(), radius_, 125); + dirtyGeoGeometry_ = false; + dirtyPixelGeometry_ = true; + } - setWidth(size.width()); - setHeight(size.height()); + if (dirtyPixelGeometry_) { + qreal w = 0; + qreal h = 0; + circlePolygon_.clear(); + updatePolygon(circlePolygon_, *map(), circlePath_, w, h); + QList<QGeoCoordinate> pathClosed = circlePath_; + pathClosed.append(pathClosed.at(0)); + borderPolygon_.clear(); + QDeclarativePolylineMapItem::updatePolyline(borderPolygon_, *map(), pathClosed, w, h); + setWidth(w); + setHeight(h); + } - setPositionOnMap(center()->coordinate(), QPointF(size.width(),size.height()) / 2); + setPositionOnMap(center()->coordinate(), QPointF(width(),height()) / 2); update(); } @@ -292,11 +310,9 @@ void QDeclarativeCircleMapItem::handleCameraDataChanged(const CameraData& camera { if (cameraData.zoomFactor() != zoomLevel_) { zoomLevel_ = cameraData.zoomFactor(); - updateMapItem(true); - } - else { - updateMapItem(false); + dirtyPixelGeometry_ = true; } + updateMapItem(); } void QDeclarativeCircleMapItem::dragEnded() @@ -319,16 +335,12 @@ void QDeclarativeCircleMapItem::dragStarted() bool QDeclarativeCircleMapItem::contains(QPointF point) { - return mapCircleNode_->contains(point); + return circlePolygon_.containsPoint(point, Qt::OddEvenFill); } - ////////////////////////////////////////////////////////////////////// MapCircleNode::MapCircleNode(): - fillColor_(Qt::black), - borderColor_(Qt::black), - borderWidth_(3), border_(new MapPolylineNode()), geometry_(QSGGeometry::defaultAttributes_Point2D(),0) { @@ -341,98 +353,37 @@ MapCircleNode::MapCircleNode(): MapCircleNode::~MapCircleNode() {} -void MapCircleNode::update() +void MapCircleNode::update(const QColor& fillColor, const QPolygonF& circleShape, const QPointF& center, + const QPolygonF& borderShape, const QColor& borderColor, qreal borderWidth) { - //TODO: optimize , perform calculation only if polygon has changed - if (polygon_.size()==0) + if (circleShape.size() == 0 || borderShape.size() == 0) return; QSGGeometry *fill = QSGGeometryNode::geometry(); - Q_ASSERT(fill->sizeOfVertex() == sizeof(Vertex)); 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 + fill->allocate(circleShape.size() + 1 + 1); //one for center + one to close the circle Vertex *vertices = (Vertex *)fill->vertexData(); - //set center - vertices[fillVertexCount++].position = QVector2D(size_.width()/2,size_.height()/2); + vertices[fillVertexCount++].position = QVector2D(center); - for (int i = 0; i < polygon_.size(); ++i) { - vertices[fillVertexCount++].position = QVector2D(polygon_.at(i)); + for (int i = 0; i < circleShape.size(); ++i) { + vertices[fillVertexCount++].position = QVector2D(circleShape.at(i)); } //close circle - vertices[fillVertexCount++].position = QVector2D(polygon_.at(0)); - + vertices[fillVertexCount++].position = QVector2D(circleShape.at(0)); Q_ASSERT(fillVertexCount == fill->vertexCount()); markDirty(DirtyGeometry); - if (fillColor_ != fill_material_.color()) { - fill_material_.setColor(fillColor_); + if (fillColor != fill_material_.color()) { + fill_material_.setColor(fillColor); setMaterial(&fill_material_); } - - border_->setPenColor(borderColor_); - border_->setLineWidth(borderWidth_); - - border_->update(); - - //TODO: implement me : gradient -} - -void MapCircleNode::setBrushColor(const QColor &color) -{ - fillColor_= color; -} - -QColor MapCircleNode::brushColor() const -{ - return fillColor_; -} - -void MapCircleNode::setPenColor(const QColor &color) -{ - borderColor_ = color; -} - -QColor MapCircleNode::penColor() const -{ - return borderColor_; -} - -qreal MapCircleNode::lineWidth() const -{ - return borderWidth_; -} - -void MapCircleNode::setLineWidth(qreal width) -{ - borderWidth_ = width; -} - -bool MapCircleNode::contains(QPointF point) -{ - return polygon_.containsPoint(point, Qt::OddEvenFill); -} - -void MapCircleNode::setGeometry(const Map& map, qreal radius, const QGeoCoordinate ¢er) -{ - path_.clear(); - calcualtePeripheralPoints(path_, center, radius, 125); - - qreal w = 0; - qreal h = 0; - - polygon_.clear(); - updatePolygon(polygon_, map, path_, w, h); - size_ = QSizeF(w, h); - - QList<QGeoCoordinate> pathClosed = path_; - pathClosed.append(pathClosed.at(0)); - border_->setGeometry(map, pathClosed); + border_->update(borderColor, borderShape, borderWidth); } QT_END_NAMESPACE diff --git a/src/imports/location/qdeclarativecirclemapitem_p.h b/src/imports/location/qdeclarativecirclemapitem_p.h index 38efe7dd..2aa86791 100644 --- a/src/imports/location/qdeclarativecirclemapitem_p.h +++ b/src/imports/location/qdeclarativecirclemapitem_p.h @@ -89,7 +89,7 @@ Q_SIGNALS: void colorChanged(const QColor &color); protected Q_SLOTS: - virtual void updateMapItem(bool dirtyGeomoetry=true); + virtual void updateMapItem(); void handleBorderUpdated(); private Q_SLOTS: @@ -97,13 +97,19 @@ private Q_SLOTS: private: //TODO: pimpl + //TODO: this should be in base class done in QDeclarativeCoordinate internalCoordinate_; QDeclarativeCoordinate *center_; QDeclarativeMapLineProperties border_; - MapCircleNode *mapCircleNode_; QColor color_; qreal radius_; qreal zoomLevel_; + QList<QGeoCoordinate> circlePath_; + QPolygonF circlePolygon_; + QPolygonF borderPolygon_; + bool dirtyPixelGeometry_; + bool dirtyGeoGeometry_; + bool dirtyMaterial_; bool dragActive_; }; @@ -116,37 +122,13 @@ public: MapCircleNode(); ~MapCircleNode(); - void setSize(const QSize &size); - QSizeF size() const { - return size_; - } - - void setLineWidth(qreal width); - qreal lineWidth() const; - - QColor penColor() const; - void setPenColor(const QColor &pen); - - QColor brushColor() const; - void setBrushColor(const QColor &color); - - void update(); - bool contains(QPointF point); - void setGeometry(const Map &map, qreal radius, const QGeoCoordinate ¢er); + void update(const QColor& fillColor, const QPolygonF& circleShape, const QPointF& center, + const QPolygonF& borderShape, const QColor& borderColor, qreal borderWidth); private: QSGFlatColorMaterial fill_material_; - //QSGFlatColorMaterial border_material_; - QColor fillColor_; - QColor borderColor_; - qreal borderWidth_; MapPolylineNode *border_; - //keeps pixel geometry QSGGeometry geometry_; - //keeps geographic geometry - QList<QGeoCoordinate> path_; - QPolygonF polygon_; - QSizeF size_; }; QT_END_NAMESPACE diff --git a/src/imports/location/qdeclarativegeomapitembase_p.h b/src/imports/location/qdeclarativegeomapitembase_p.h index 03adff7b..fd106a9c 100644 --- a/src/imports/location/qdeclarativegeomapitembase_p.h +++ b/src/imports/location/qdeclarativegeomapitembase_p.h @@ -65,9 +65,8 @@ public: QDeclarativeGeoMap* quickMap() {return quickMap_;} Map* map() {return map_;} - protected Q_SLOT: - virtual void updateMapItem(bool dirtyGeometry = true) = 0; + virtual void updateMapItem() = 0; private: Map* map_; diff --git a/src/imports/location/qdeclarativegeomapquickitem.cpp b/src/imports/location/qdeclarativegeomapquickitem.cpp index 1de6597c..6f2bc865 100644 --- a/src/imports/location/qdeclarativegeomapquickitem.cpp +++ b/src/imports/location/qdeclarativegeomapquickitem.cpp @@ -195,9 +195,8 @@ qreal QDeclarativeGeoMapQuickItem::zoomLevel() const return zoomLevel_; } -void QDeclarativeGeoMapQuickItem::updateMapItem(bool dirtyGeometry) +void QDeclarativeGeoMapQuickItem::updateMapItem() { - Q_UNUSED(dirtyGeometry); if (!quickMap() && sourceItem_) { mapAndSourceItemSet_ = false; sourceItem_->setParentItem(0); diff --git a/src/imports/location/qdeclarativegeomapquickitem_p.h b/src/imports/location/qdeclarativegeomapquickitem_p.h index e359cecf..7a091ef7 100644 --- a/src/imports/location/qdeclarativegeomapquickitem_p.h +++ b/src/imports/location/qdeclarativegeomapquickitem_p.h @@ -86,7 +86,7 @@ Q_SIGNALS: void zoomLevelChanged(); protected Q_SLOTS: - virtual void updateMapItem(bool dirtyGeometry = true); + virtual void updateMapItem(); // from qquickitem void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); diff --git a/src/imports/location/qdeclarativepolygonmapitem.cpp b/src/imports/location/qdeclarativepolygonmapitem.cpp index 2ac68962..d65f58a0 100644 --- a/src/imports/location/qdeclarativepolygonmapitem.cpp +++ b/src/imports/location/qdeclarativepolygonmapitem.cpp @@ -85,10 +85,12 @@ static void updatePolygon(QPolygonF& points,const Map& map, const QList<QGeoCoor QDeclarativePolygonMapItem::QDeclarativePolygonMapItem(QQuickItem *parent) : QDeclarativeGeoMapItemBase(parent), - mapPolygonNode_(0), - zoomLevel_(0.0) + zoomLevel_(0.0), + dirtyGeometry_(true), + dirtyMaterial_(true) { setFlag(ItemHasContents, true); + border_.setWidth(3.0); QObject::connect(&border_, SIGNAL(colorChanged(QColor)), this, SLOT(handleBorderUpdated())); QObject::connect(&border_, SIGNAL(widthChanged(qreal)), @@ -97,7 +99,8 @@ QDeclarativePolygonMapItem::QDeclarativePolygonMapItem(QQuickItem *parent) : void QDeclarativePolygonMapItem::handleBorderUpdated() { - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); } QDeclarativePolygonMapItem::~QDeclarativePolygonMapItem() @@ -111,10 +114,12 @@ QDeclarativeMapLineProperties *QDeclarativePolygonMapItem::border() void QDeclarativePolygonMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map) { - QDeclarativeGeoMapItemBase::setMap(quickMap, map); - if (map) - QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), - this, SLOT(handleCameraDataChanged(CameraData))); + QDeclarativeGeoMapItemBase::setMap(quickMap,map); + if (map) { + QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + dirtyGeometry_ = true; + updateMapItem(); + } } QDeclarativeListProperty<QDeclarativeCoordinate> QDeclarativePolygonMapItem::declarativePath() @@ -129,7 +134,8 @@ void QDeclarativePolygonMapItem::path_append( QDeclarativePolygonMapItem* item = qobject_cast<QDeclarativePolygonMapItem*>(property->object); item->coordPath_.append(coordinate); item->path_.append(coordinate->coordinate()); - item->updateMapItem(true); + item->dirtyGeometry_ = true; + item->updateMapItem(); emit item->pathChanged(); } @@ -153,7 +159,8 @@ void QDeclarativePolygonMapItem::path_clear( qDeleteAll(item->coordPath_); item->coordPath_.clear(); item->path_.clear(); - item->updateMapItem(true); + item->dirtyGeometry_ = true; + item->updateMapItem(); emit item->pathChanged(); } @@ -161,7 +168,8 @@ void QDeclarativePolygonMapItem::addCoordinate(QDeclarativeCoordinate* coordinat { coordPath_.append(coordinate); path_.append(coordinate->coordinate()); - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit pathChanged(); } @@ -180,7 +188,8 @@ void QDeclarativePolygonMapItem::removeCoordinate(QDeclarativeCoordinate* coordi } coordPath_.removeAt(index); path_.removeAt(index); - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit pathChanged(); } @@ -195,44 +204,47 @@ void QDeclarativePolygonMapItem::setColor(const QColor &color) return; color_ = color; - updateMapItem(false); + dirtyMaterial_ = true; + updateMapItem(); emit colorChanged(color_); } QSGNode* QDeclarativePolygonMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data) { Q_UNUSED(data); - MapPolygonNode *node = static_cast<MapPolygonNode*>(oldNode); - if (!node) { - mapPolygonNode_ = new MapPolygonNode(); - updateMapItem(true); - } + if (!node) + node = new MapPolygonNode(); - mapPolygonNode_->update(); - return mapPolygonNode_; + //TODO: update only material + if (dirtyGeometry_ || dirtyMaterial_) { + node->update(color_, polygon_, borderPolygon_, border_.color(), border_.width()); + dirtyGeometry_ = false; + dirtyMaterial_ = false; + } + return node; } -void -QDeclarativePolygonMapItem::updateMapItem(bool dirtyGeometry) +void QDeclarativePolygonMapItem::updateMapItem() { - if (!map() || path_.count() == 0 || !mapPolygonNode_) + if (!map() || path_.count() == 0) return; - mapPolygonNode_->setBrushColor(color_); - mapPolygonNode_->setPenColor(border_.color()); - mapPolygonNode_->setLineWidth(border_.width()); - - 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)); + if (dirtyGeometry_) { + qreal h = 0; + qreal w = 0; + polygon_.clear(); + borderPolygon_.clear(); + updatePolygon(polygon_, *map(), path_, w, h); + + QList<QGeoCoordinate> pathClosed = path_; + pathClosed.append(pathClosed.at(0)); + QDeclarativePolylineMapItem::updatePolyline(borderPolygon_, *map(), pathClosed, w, h); + setWidth(w); + setHeight(h); + } + setPositionOnMap(path_.at(0), polygon_.at(0)); update(); } @@ -240,10 +252,9 @@ void QDeclarativePolygonMapItem::handleCameraDataChanged(const CameraData& camer { if (cameraData.zoomFactor() != zoomLevel_) { zoomLevel_ = cameraData.zoomFactor(); - updateMapItem(true); - } else { - updateMapItem(false); + dirtyGeometry_ = true; } + updateMapItem(); } void QDeclarativePolygonMapItem::dragStarted() @@ -253,15 +264,12 @@ void QDeclarativePolygonMapItem::dragStarted() bool QDeclarativePolygonMapItem::contains(QPointF point) { - return mapPolygonNode_->contains(point); + return polygon_.contains(point); } ////////////////////////////////////////////////////////////////////// MapPolygonNode::MapPolygonNode() : - fillColor_(Qt::black), - borderColor_(Qt::black), - borderWidth_(3.0), border_(new MapPolylineNode()), geometry_(QSGGeometry::defaultAttributes_Point2D(), 0) { @@ -276,10 +284,11 @@ MapPolygonNode::~MapPolygonNode() { } -void MapPolygonNode::update() +void MapPolygonNode::update(const QColor& fillColor, const QPolygonF& shape, + const QPolygonF& borderShape, const QColor& borderColor, qreal borderWidth) { - //TODO: optimize , perform calculation only if polygon has changed - if (polygon_.size()==0) return; + if (shape.size() == 0) + return; QSGGeometry *fill = QSGGeometryNode::geometry(); @@ -287,75 +296,20 @@ void MapPolygonNode::update() int fillVertexCount = 0; //note this will not allocate new buffer if the size has not changed - fill->allocate(polygon_.size()); + fill->allocate(shape.size()); Vertex *vertices = (Vertex *)fill->vertexData(); - for (int i = 0; i < polygon_.size(); ++i) { - vertices[fillVertexCount++].position = QVector2D(polygon_.at(i)); + for (int i = 0; i < shape.size(); ++i) { + vertices[fillVertexCount++].position = QVector2D(shape.at(i)); } Q_ASSERT(fillVertexCount == fill->vertexCount()); - markDirty(DirtyGeometry); - if (fillColor_ != fill_material_.color()) { - fill_material_.setColor(fillColor_); + if (fillColor != fill_material_.color()) { + fill_material_.setColor(fillColor); setMaterial(&fill_material_); } - - border_->setPenColor(borderColor_); - border_->setLineWidth(borderWidth_); - - border_->update(); - - //TODO: implement me : gradient -} - -qreal MapPolygonNode::lineWidth() const -{ - return borderWidth_; -} - -void MapPolygonNode::setLineWidth(qreal width) -{ - borderWidth_ = width; -} - -void MapPolygonNode::setBrushColor(const QColor &color) -{ - fillColor_= color; -} - -QColor MapPolygonNode::brushColor() const -{ - return fillColor_; -} - -void MapPolygonNode::setPenColor(const QColor &color) -{ - borderColor_ = color; -} - -QColor MapPolygonNode::penColor() const -{ - return borderColor_; -} - -bool MapPolygonNode::contains(QPointF point) -{ - return polygon_.containsPoint(point, Qt::OddEvenFill); -} - -void MapPolygonNode::setGeometry(const Map& map, const QList<QGeoCoordinate> &path) -{ - qreal h = 0; - qreal w = 0; - polygon_.clear(); - updatePolygon(polygon_, map, path, w, h); - size_ = QSizeF(w, h); - - QList<QGeoCoordinate> pathClosed = path; - pathClosed.append(pathClosed.at(0)); - border_->setGeometry(map, pathClosed); + border_->update(borderColor, borderShape, borderWidth); } diff --git a/src/imports/location/qdeclarativepolygonmapitem_p.h b/src/imports/location/qdeclarativepolygonmapitem_p.h index 0f8ca5eb..8b56805b 100644 --- a/src/imports/location/qdeclarativepolygonmapitem_p.h +++ b/src/imports/location/qdeclarativepolygonmapitem_p.h @@ -85,7 +85,7 @@ Q_SIGNALS: void colorChanged(const QColor &color); protected Q_SLOTS: - virtual void updateMapItem(bool dirtyGeomoetry = true); + virtual void updateMapItem(); void handleBorderUpdated(); private Q_SLOTS: @@ -100,12 +100,15 @@ private: void pathPropertyChanged(); private: - MapPolygonNode *mapPolygonNode_; QDeclarativeMapLineProperties border_; QList<QDeclarativeCoordinate*> coordPath_; QList<QGeoCoordinate> path_; QColor color_; qreal zoomLevel_; + QPolygonF polygon_; + QPolygonF borderPolygon_; + bool dirtyGeometry_; + bool dirtyMaterial_; }; ////////////////////////////////////////////////////////////////////// @@ -117,37 +120,15 @@ public: MapPolygonNode(); ~MapPolygonNode(); - void setSize(const QSize &size); - QSizeF size() const { - return size_; - } - - QColor penColor() const; - void setPenColor(const QColor &pen); - - qreal lineWidth() const; - void setLineWidth(qreal width); - - QColor brushColor() const; - void setBrushColor(const QColor &color); - - void update(); - bool contains(QPointF point); - void setGeometry(const Map &map, const QList<QGeoCoordinate> &path); - const QPolygonF& geometry() { return polygon_; } + void update(const QColor& fillColor, const QPolygonF& shape, + const QPolygonF& borderShape, const QColor& borderColor, qreal borderWidth); private: QSGFlatColorMaterial fill_material_; - QColor fillColor_; - QColor borderColor_; - qreal borderWidth_; - MapPolylineNode *border_; + MapPolylineNode* border_; QSGGeometry geometry_; - QPolygonF polygon_; - QSizeF size_; }; - QT_END_NAMESPACE QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QDeclarativePolygonMapItem)); diff --git a/src/imports/location/qdeclarativepolylinemapitem.cpp b/src/imports/location/qdeclarativepolylinemapitem.cpp index cf93404c..c794abd7 100644 --- a/src/imports/location/qdeclarativepolylinemapitem.cpp +++ b/src/imports/location/qdeclarativepolylinemapitem.cpp @@ -85,9 +85,8 @@ struct Vertex QVector2D position; }; -static void updatePolyline(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h) +void QDeclarativePolylineMapItem::updatePolyline(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h) { - qreal minX, maxX, minY, maxY; //TODO: dateline handling @@ -122,8 +121,9 @@ static void updatePolyline(QPolygonF& points,const Map& map, const QList<QGeoCoo QDeclarativePolylineMapItem::QDeclarativePolylineMapItem(QQuickItem *parent) : QDeclarativeGeoMapItemBase(parent), - mapPolylineNode_(0), - zoomLevel_(0.0) + zoomLevel_(0.0), + dirtyGeometry_(true), + dirtyMaterial_(true) { setFlag(ItemHasContents, true); QObject::connect(&line_, SIGNAL(colorChanged(QColor)), @@ -138,14 +138,18 @@ QDeclarativePolylineMapItem::~QDeclarativePolylineMapItem() void QDeclarativePolylineMapItem::updateAfterLinePropertiesChanged() { - // pass true just in case we're a width change - updateMapItem(true); + // mark dirty just in case we're a width change + dirtyGeometry_ = true; + updateMapItem(); } void QDeclarativePolylineMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map) { QDeclarativeGeoMapItemBase::setMap(quickMap,map); - if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + if (map){ + QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + updateMapItem(); + } } QDeclarativeListProperty<QDeclarativeCoordinate> QDeclarativePolylineMapItem::declarativePath() @@ -160,7 +164,8 @@ void QDeclarativePolylineMapItem::path_append(QDeclarativeListProperty<QDeclarat property->object); item->coordPath_.append(coordinate); item->path_.append(coordinate->coordinate()); - item->updateMapItem(true); + item->dirtyGeometry_ = true; + item->updateMapItem(); emit item->pathChanged(); } @@ -184,7 +189,8 @@ void QDeclarativePolylineMapItem::path_clear( qDeleteAll(item->coordPath_); item->coordPath_.clear(); item->path_.clear(); - item->updateMapItem(true); + item->dirtyGeometry_ = true; + item->updateMapItem(); emit item->pathChanged(); } @@ -192,7 +198,8 @@ void QDeclarativePolylineMapItem::addCoordinate(QDeclarativeCoordinate* coordina { coordPath_.append(coordinate); path_.append(coordinate->coordinate()); - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit pathChanged(); } @@ -211,7 +218,8 @@ void QDeclarativePolylineMapItem::removeCoordinate(QDeclarativeCoordinate* coord } coordPath_.removeAt(index); path_.removeAt(index); - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit pathChanged(); } @@ -227,31 +235,33 @@ QSGNode* QDeclarativePolylineMapItem::updatePaintNode(QSGNode* oldNode, UpdatePa MapPolylineNode *node = static_cast<MapPolylineNode*>(oldNode); if (!node) { - mapPolylineNode_ = new MapPolylineNode(); - updateMapItem(true); + node = new MapPolylineNode(); } - mapPolylineNode_->update(); - return mapPolylineNode_; + //TODO: update only material + if (dirtyGeometry_ || dirtyMaterial_) { + node->update(line_.color(), polyline_, line_.width()); + dirtyGeometry_ = false; + dirtyMaterial_ = false; + } + return node; } -void QDeclarativePolylineMapItem::updateMapItem(bool dirtyGeometry) { - - if (!map() || path_.count()==0 || !mapPolylineNode_) +void QDeclarativePolylineMapItem::updateMapItem() +{ + if (!map() || path_.count() == 0) return; - mapPolylineNode_->setPenColor(line_.color()); - mapPolylineNode_->setLineWidth(line_.width()); - - if (dirtyGeometry) - mapPolylineNode_->setGeometry(*map(), path_); - - const QSizeF& size = mapPolylineNode_->size(); - - setWidth(size.width()); - setHeight(size.height()); + if (dirtyGeometry_) { + qreal h = 0; + qreal w = 0; + polyline_.clear(); + updatePolyline(polyline_, *map(), path_, w, h); + setWidth(w); + setHeight(h); + } - setPositionOnMap(path_.at(0),mapPolylineNode_->geometry().at(0)); + setPositionOnMap(path_.at(0),polyline_.at(0)); update(); } @@ -259,9 +269,10 @@ void QDeclarativePolylineMapItem::handleCameraDataChanged(const CameraData& came { if (cameraData.zoomFactor() != zoomLevel_) { zoomLevel_ = cameraData.zoomFactor(); - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); } else { - updateMapItem(false); + updateMapItem(); } } @@ -269,7 +280,7 @@ 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 mapPolylineNode_->contains(point); + return polyline_.contains(point); } void QDeclarativePolylineMapItem::dragStarted() @@ -280,8 +291,6 @@ void QDeclarativePolylineMapItem::dragStarted() ////////////////////////////////////////////////////////////////////// MapPolylineNode::MapPolylineNode() : - fillColor_(Qt::black), - width_(2.0), geometry_(QSGGeometry::defaultAttributes_Point2D(),0) { geometry_.setDrawingMode(GL_LINE_STRIP); @@ -294,73 +303,37 @@ MapPolylineNode::~MapPolylineNode() { } -void MapPolylineNode::update() +void MapPolylineNode::update(const QColor& fillColor, const QPolygonF& shape, qreal width) { - //TODO: optimize , perform calculation only if polygon has changed - if (polyline_.size() == 0) + if (shape.size() == 0) return; QSGGeometry *fill = QSGGeometryNode::geometry(); - fill->setLineWidth(width_); + fill->setLineWidth(width); Q_ASSERT(fill->sizeOfVertex() == sizeof(Vertex)); int fillVertexCount = 0; //note this will not allocate new buffer if the size has not changed - fill->allocate(polyline_.size()); + fill->allocate(shape.size()); Vertex *vertices = (Vertex *)fill->vertexData(); - for (int i = 0; i < polyline_.size(); ++i) { - vertices[fillVertexCount++].position = QVector2D(polyline_.at(i)); + for (int i = 0; i < shape.size(); ++i) { + vertices[fillVertexCount++].position = QVector2D(shape.at(i)); } Q_ASSERT(fillVertexCount == fill->vertexCount()); markDirty(DirtyGeometry); - if (fillColor_ != fill_material_.color()) { - fill_material_.setColor(fillColor_); + if (fillColor != fill_material_.color()) { + fill_material_.setColor(fillColor); setMaterial(&fill_material_); } //TODO: implement me : borders , gradient } -bool MapPolylineNode::contains(QPointF point) -{ - //TODO: implement me - return polyline_.contains(point); -} - -void MapPolylineNode::setPenColor(const QColor &color) -{ - fillColor_ = color; -} - -QColor MapPolylineNode::penColor() const -{ - return fillColor_; -} - -qreal MapPolylineNode::lineWidth() const -{ - return width_; -} - -void MapPolylineNode::setLineWidth(qreal width) -{ - width_ = width; -} - -void MapPolylineNode::setGeometry(const Map& map, const QList<QGeoCoordinate> &path) -{ - qreal h = 0; - 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 06c3ec8b..6853ad9d 100644 --- a/src/imports/location/qdeclarativepolylinemapitem_p.h +++ b/src/imports/location/qdeclarativepolylinemapitem_p.h @@ -86,6 +86,8 @@ public: QDeclarativePolylineMapItem(QQuickItem *parent = 0); ~QDeclarativePolylineMapItem(); + static void updatePolyline(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h); + virtual void setMap(QDeclarativeGeoMap* quickMap, Map *map); //from QuickItem virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); @@ -104,7 +106,7 @@ Q_SIGNALS: void pathChanged(); protected Q_SLOTS: - virtual void updateMapItem(bool dirtyGeomoetry = true); + virtual void updateMapItem(); void updateAfterLinePropertiesChanged(); private Q_SLOTS: @@ -119,12 +121,14 @@ private: void pathPropertyChanged(); private: - MapPolylineNode *mapPolylineNode_; QDeclarativeMapLineProperties line_; QList<QDeclarativeCoordinate*> coordPath_; QList<QGeoCoordinate> path_; QColor color_; qreal zoomLevel_; + QPolygonF polyline_; + bool dirtyGeometry_; + bool dirtyMaterial_; }; ////////////////////////////////////////////////////////////////////// @@ -136,33 +140,13 @@ public: MapPolylineNode(); ~MapPolylineNode(); - void setSize(const QSize &size); - QSizeF size() const { - return size_; - } - - qreal lineWidth() const; - void setLineWidth(qreal width); - - QColor penColor() const; - void setPenColor(const QColor &pen); - - void update(); - bool contains(QPointF point); - - void setGeometry(const Map &map, const QList<QGeoCoordinate> &path); - const QPolygonF& geometry() { return polyline_; } + void update(const QColor& fillColor, const QPolygonF& shape, qreal width); private: QSGFlatColorMaterial fill_material_; - QColor fillColor_; QSGGeometry geometry_; - QPolygonF polyline_; - QSizeF size_; - qreal width_; }; - QT_END_NAMESPACE QML_DECLARE_TYPE(QT_PREPEND_NAMESPACE(QDeclarativeMapLineProperties)); diff --git a/src/imports/location/qdeclarativerectanglemapitem.cpp b/src/imports/location/qdeclarativerectanglemapitem.cpp index 24398983..94b301a0 100644 --- a/src/imports/location/qdeclarativerectanglemapitem.cpp +++ b/src/imports/location/qdeclarativerectanglemapitem.cpp @@ -51,10 +51,11 @@ struct Vertex QDeclarativeRectangleMapItem::QDeclarativeRectangleMapItem(QQuickItem *parent): QDeclarativeGeoMapItemBase(parent), - mapRectangleNode_(0), topLeft_(0), bottomRight_(0), zoomLevel_(0.0), + dirtyGeometry_(true), + dirtyMaterial_(true), dragActive_(false) { setFlag(ItemHasContents, true); @@ -67,7 +68,10 @@ 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))); + if (map) { + QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + updateMapItem(); + } } void QDeclarativeRectangleMapItem::setTopLeft(QDeclarativeCoordinate *topLeft) @@ -86,8 +90,8 @@ void QDeclarativeRectangleMapItem::setTopLeft(QDeclarativeCoordinate *topLeft) connect(topLeft_, SIGNAL(altitudeChanged(double)), this, SLOT(updateMapItem())); } - - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit topLeftChanged(topLeft_); } @@ -111,7 +115,8 @@ void QDeclarativeRectangleMapItem::setBottomRight(QDeclarativeCoordinate *bottom connect(bottomRight_, SIGNAL(altitudeChanged(double)), this, SLOT(updateMapItem())); } - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit bottomRightChanged(bottomRight_); } @@ -130,7 +135,8 @@ void QDeclarativeRectangleMapItem::setColor(const QColor &color) if (color_ == color) return; color_ = color; - updateMapItem(false); + dirtyMaterial_ = true; + updateMapItem(); emit colorChanged(color_); } @@ -141,31 +147,45 @@ QSGNode* QDeclarativeRectangleMapItem::updatePaintNode(QSGNode* oldNode, UpdateP MapRectangleNode *node = static_cast<MapRectangleNode*>(oldNode); if (!node) { - mapRectangleNode_ = new MapRectangleNode(); - updateMapItem(true); + node = new MapRectangleNode(); } - mapRectangleNode_->update(); - return mapRectangleNode_; + //TODO: update only material + if (dirtyGeometry_ || dirtyMaterial_) { + node->update(color_,rectangle_); + dirtyGeometry_ = false; + dirtyMaterial_ = false; + } + return node; } -void QDeclarativeRectangleMapItem::updateMapItem(bool dirtyGeometry) +void QDeclarativeRectangleMapItem::updateMapItem() { if (!map() || !topLeft() || !topLeft()->coordinate().isValid() - || !bottomRight() || !bottomRight()->coordinate().isValid() - || !mapRectangleNode_) + || !bottomRight() || !bottomRight()->coordinate().isValid()) return; - mapRectangleNode_->setBrushColor(color_); + if (dirtyGeometry_) { + QPointF p1 = map()->coordinateToScreenPosition(topLeft_->coordinate(), false); + QPointF p2 = map()->coordinateToScreenPosition(bottomRight_->coordinate(), false); - if (dirtyGeometry) mapRectangleNode_->setGeometry(*map(), topLeft()->coordinate(), bottomRight()->coordinate()); + qreal minX = qMin(p1.x(), p2.x()); + qreal maxX = qMax(p1.x(), p2.x()); + qreal minY = qMin(p1.y(), p2.y()); + qreal maxY = qMax(p1.y(), p2.y()); - const QSizeF& size = mapRectangleNode_->size(); + qreal w = maxX - minX; + qreal h = maxY - minY; - setWidth(size.width()); - setHeight(size.height()); + rectangle_.setTopLeft(QPointF(0, 0)); + rectangle_.setBottomRight(QPointF(w, h)); - setPositionOnMap(topLeft()->coordinate(), QPointF(0, 0)); + setWidth(w); + setHeight(h); + } + + //TODO: add AnchorCoordiante + setPositionOnMap(topLeft_->coordinate(), QPointF(0, 0)); update(); } @@ -173,15 +193,14 @@ void QDeclarativeRectangleMapItem::handleCameraDataChanged(const CameraData& cam { if (cameraData.zoomFactor() != zoomLevel_) { zoomLevel_ = cameraData.zoomFactor(); - updateMapItem(true); - } else { - updateMapItem(false); + dirtyGeometry_ = true; } + updateMapItem(); } bool QDeclarativeRectangleMapItem::contains(QPointF point) { - return mapRectangleNode_->contains(point); + return rectangle_.contains(point); } void QDeclarativeRectangleMapItem::dragEnded() @@ -202,6 +221,7 @@ void QDeclarativeRectangleMapItem::dragEnded() } } +//TODO: this is goingn to be removed by I466aa31d33a204b2f7c6c562025946371d3b6f46 void QDeclarativeRectangleMapItem::dragStarted() { dragActive_ = true; @@ -209,12 +229,10 @@ void QDeclarativeRectangleMapItem::dragStarted() ////////////////////////////////////////////////////////////////////// MapRectangleNode::MapRectangleNode(): - fillColor_(Qt::black), - borderColor_(Qt::black), geometry_(QSGGeometry::defaultAttributes_Point2D(),0) { geometry_.setDrawingMode(GL_QUADS); - QSGGeometryNode::setMaterial(&fill_material_); + QSGGeometryNode::setMaterial(&fillMaterial_); QSGGeometryNode::setGeometry(&geometry_); } @@ -222,7 +240,7 @@ MapRectangleNode::~MapRectangleNode() { } -void MapRectangleNode::update() +void MapRectangleNode::update(const QColor& fillColor, const QRectF& shape) { QSGGeometry *fill = QSGGeometryNode::geometry(); @@ -235,63 +253,20 @@ void MapRectangleNode::update() Vertex *vertices = (Vertex *)fill->vertexData(); //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()); + vertices[fillVertexCount++].position = QVector2D(shape.left(),shape.top()); + vertices[fillVertexCount++].position = QVector2D(shape.right(),shape.top()); + vertices[fillVertexCount++].position = QVector2D(shape.right(),shape.bottom()); + vertices[fillVertexCount++].position = QVector2D(shape.left(),shape.bottom()); Q_ASSERT(fillVertexCount == fill->vertexCount()); markDirty(DirtyGeometry); - if (fillColor_ != fill_material_.color()) { - fill_material_.setColor(fillColor_); - setMaterial(&fill_material_); + if (fillColor != fillMaterial_.color()) { + fillMaterial_.setColor(fillColor); + setMaterial(&fillMaterial_); } //TODO: implement me : borders , gradient } -void MapRectangleNode::setBrushColor(const QColor &color) -{ - fillColor_= color; -} - -QColor MapRectangleNode::brushColor() const -{ - return fillColor_; -} - -void MapRectangleNode::setPenColor(const QColor &color) -{ - borderColor_ = color; -} - -QColor MapRectangleNode::penColor() const -{ - return borderColor_; -} - -bool MapRectangleNode::contains(QPointF point) -{ - return rect_.contains(point); -} - -void MapRectangleNode::setGeometry(const Map& map, const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight) -{ - 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()); - qreal minY = qMin(p1.y(), p2.y()); - qreal maxY = qMax(p1.y(), p2.y()); - - qreal w = maxX - minX; - qreal h = maxY - minY; - - size_ = QSizeF(w, h); - rect_.setTopLeft(QPointF(0, 0)); - rect_.setBottomRight(QPointF(w, h)); -} - QT_END_NAMESPACE diff --git a/src/imports/location/qdeclarativerectanglemapitem_p.h b/src/imports/location/qdeclarativerectanglemapitem_p.h index bea588de..7c65bfb1 100644 --- a/src/imports/location/qdeclarativerectanglemapitem_p.h +++ b/src/imports/location/qdeclarativerectanglemapitem_p.h @@ -85,22 +85,24 @@ Q_SIGNALS: void colorChanged(const QColor &color); protected Q_SLOTS: - virtual void updateMapItem(bool dirtyGeometry = true); - + virtual void updateMapItem(); private Q_SLOTS: // map size changed void handleCameraDataChanged(const CameraData& cameraData); private: - MapRectangleNode *mapRectangleNode_; QDeclarativeCoordinate* topLeft_; QDeclarativeCoordinate* bottomRight_; QDeclarativeCoordinate internalTopLeft_; QDeclarativeCoordinate internalBottomRight_; QColor color_; qreal zoomLevel_; + QRectF rectangle_; + bool dirtyGeometry_; + bool dirtyMaterial_; bool dragActive_; + }; ////////////////////////////////////////////////////////////////////// @@ -112,28 +114,11 @@ public: MapRectangleNode(); ~MapRectangleNode(); - void setSize(const QSize &size); - QSizeF size() const { - return size_; - } - - QColor penColor() const; - void setPenColor(const QColor &pen); - - QColor brushColor() const; - void setBrushColor(const QColor &color); - - void update(); - bool contains(QPointF point); - void setGeometry(const Map& map, const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight); + void update(const QColor& fillColor, const QRectF& shape); private: - QSGFlatColorMaterial fill_material_; - QColor fillColor_; - QColor borderColor_; + QSGFlatColorMaterial fillMaterial_; QSGGeometry geometry_; - QRectF rect_; - QSizeF size_; }; diff --git a/src/imports/location/qdeclarativeroutemapitem.cpp b/src/imports/location/qdeclarativeroutemapitem.cpp index c0c7bb02..c2bc8a1e 100644 --- a/src/imports/location/qdeclarativeroutemapitem.cpp +++ b/src/imports/location/qdeclarativeroutemapitem.cpp @@ -46,13 +46,49 @@ #include <QtDeclarative/QDeclarativeInfo> #include <QtGui/QPainter> + +static void updatePolyline(QPolygonF& points,const Map& map, const QList<QGeoCoordinate> &path, qreal& w, qreal& h) +{ + + 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(); + } else { + minX = qMin(point.x(), minX); + maxX = qMax(point.x(), maxX); + minY = qMin(point.y(), minY); + maxY = qMax(point.y(), maxY); + } + points.append(point); + } + + points.translate(-minX, -minY); + + w = maxX - minX; + h = maxY - minY; +} + QDeclarativeRouteMapItem::QDeclarativeRouteMapItem(QQuickItem *parent): QDeclarativeGeoMapItemBase(parent), - mapPolylineNode_(0), route_(0), zoomLevel_(0.0) { setFlag(ItemHasContents, true); + line_.setWidth(3.0); QObject::connect(&line_, SIGNAL(colorChanged(QColor)), this, SLOT(updateAfterLinePropertiesChanged())); QObject::connect(&line_, SIGNAL(widthChanged(qreal)), @@ -65,14 +101,19 @@ QDeclarativeRouteMapItem::~QDeclarativeRouteMapItem() void QDeclarativeRouteMapItem::updateAfterLinePropertiesChanged() { - // pass true just in case we're a width change - updateMapItem(true); + // mark dirty just in case we're a width change + dirtyGeometry_ = true; + updateMapItem(); } void QDeclarativeRouteMapItem::setMap(QDeclarativeGeoMap* quickMap, Map *map) { QDeclarativeGeoMapItemBase::setMap(quickMap,map); - if (map) QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + if (map) { + QObject::connect(map, SIGNAL(cameraDataChanged(CameraData)), this, SLOT(handleCameraDataChanged(CameraData))); + dirtyGeometry_ = true; + updateMapItem(); + } } QDeclarativeGeoRoute* QDeclarativeRouteMapItem::route() const @@ -93,7 +134,8 @@ void QDeclarativeRouteMapItem::setRoute(QDeclarativeGeoRoute *route) path_ = QList<QGeoCoordinate>(); } - updateMapItem(true); + dirtyGeometry_ = true; + updateMapItem(); emit routeChanged(route_); } @@ -105,12 +147,16 @@ QSGNode* QDeclarativeRouteMapItem::updatePaintNode(QSGNode* oldNode, UpdatePaint MapPolylineNode *node = static_cast<MapPolylineNode*>(oldNode); if (!node) { - mapPolylineNode_ = new MapPolylineNode(); - updateMapItem(true); + node = new MapPolylineNode(); } - mapPolylineNode_->update(); - return mapPolylineNode_; + //TODO: update only material + if (dirtyGeometry_ || dirtyMaterial_) { + node->update(line_.color(), polyline_, line_.width()); + dirtyGeometry_ = false; + dirtyMaterial_ = false; + } + return node; } QDeclarativeMapLineProperties *QDeclarativeRouteMapItem::line() @@ -118,42 +164,37 @@ QDeclarativeMapLineProperties *QDeclarativeRouteMapItem::line() return &line_; } -void QDeclarativeRouteMapItem::updateMapItem(bool dirtyGeometry) { - - if (!map() || path_.count() == 0 || !mapPolylineNode_) +void QDeclarativeRouteMapItem::updateMapItem() +{ + if (!map() || path_.isEmpty()) return; - mapPolylineNode_->setPenColor(line_.color()); - mapPolylineNode_->setLineWidth(line_.width()); - - 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(); + if (dirtyGeometry_) { + qreal h = 0; + qreal w = 0; + polyline_.clear(); + updatePolyline(polyline_, *map(), path_, w, h); + setWidth(w); + setHeight(h); + } + setPositionOnMap(path_.at(0), polyline_.at(0)); } void QDeclarativeRouteMapItem::handleCameraDataChanged(const CameraData& cameraData) { if (cameraData.zoomFactor() != zoomLevel_) { zoomLevel_ = cameraData.zoomFactor(); - updateMapItem(true); - } else { - updateMapItem(false); + dirtyGeometry_ = true; } + updateMapItem(); } bool QDeclarativeRouteMapItem::contains(QPointF point) { - return mapPolylineNode_->contains(point); + return polyline_.contains(point); } void QDeclarativeRouteMapItem::dragStarted() { - qmlInfo(this) << "warning: mouse dragging is not currently supported with polylines/routes."; + qmlInfo(this) << "warning: mouse dragging is not currently supported with this element."; } diff --git a/src/imports/location/qdeclarativeroutemapitem_p.h b/src/imports/location/qdeclarativeroutemapitem_p.h index e72cd626..7dacc6c9 100644 --- a/src/imports/location/qdeclarativeroutemapitem_p.h +++ b/src/imports/location/qdeclarativeroutemapitem_p.h @@ -80,7 +80,7 @@ Q_SIGNALS: void routeChanged(const QDeclarativeGeoRoute *route); protected Q_SLOTS: - virtual void updateMapItem(bool dirtyGeomoetry = true); + virtual void updateMapItem(); void updateAfterLinePropertiesChanged(); private Q_SLOTS: @@ -88,12 +88,13 @@ private Q_SLOTS: void handleCameraDataChanged(const CameraData& cameraData); private: - MapPolylineNode *mapPolylineNode_; QDeclarativeMapLineProperties line_; QDeclarativeGeoRoute* route_; - QColor color_; qreal zoomLevel_; QList<QGeoCoordinate> path_; + QPolygonF polyline_; + bool dirtyGeometry_; + bool dirtyMaterial_; bool dragActive_; }; diff --git a/tests/applications/declarative_map/map3d.qml b/tests/applications/declarative_map/map3d.qml index b0101651..40f56be2 100644 --- a/tests/applications/declarative_map/map3d.qml +++ b/tests/applications/declarative_map/map3d.qml @@ -90,6 +90,10 @@ Rectangle { onDoubleClicked: {console.log('+++++++++++++++ removing item 1'); map.removeMapItem(externalStaticMapItem1);} } } + Rectangle {color: "lightblue"; width: 80; height: 40; + Text {text: "Add\nitem"} + MouseArea{ anchors.fill: parent; onClicked: map.addMapItem(extMapCircle)} + } Rectangle {color: "lightblue"; width: 80; height: 80; Text {text: "Click:\nadd item2\nDouble-click:\nrm item2"} MouseArea{ anchors.fill: parent; @@ -180,10 +184,6 @@ Rectangle { MouseArea{ anchors.fill: parent; onClicked: map.height -= 10} } Rectangle {color: "lightblue"; width: 80; height: 40; - Text {text: "Add\nitem"} - MouseArea{ anchors.fill: parent; onClicked: map.addMapItem(extMapCircle)} - } - Rectangle {color: "lightblue"; width: 80; height: 40; Text {text: "toScrPos"} MouseArea{ anchors.fill: parent; onClicked: console.log('coordinate: ' + @@ -264,6 +264,8 @@ Rectangle { center: londonCoordinate radius: 10000 color: 'red' + border.color: 'darkcyan' + border.width: 15 MapMouseArea { id: mouseAreaOfMapCircle @@ -291,7 +293,8 @@ Rectangle { MapPolyline { id: mapPolyline z: 15 - color: 'red' + line.color: 'red' + line.width: 10 path: [ Coordinate { id: pathCoord1; latitude: 50.7; longitude: 0.1}, Coordinate { id: pathCoord2; latitude: 50.8; longitude: 0.4}, @@ -321,6 +324,8 @@ Rectangle { MapPolygon { id: mapPolygon color: 'pink' + border.color: 'darkmagenta' + border.width: 10 path: [ Coordinate { id: pathCoord_1; latitude: 51; longitude: 0.2}, Coordinate { id: pathCoord_2; latitude: 51.1; longitude: 0.6}, @@ -349,7 +354,8 @@ Rectangle { MapRoute { id: mapRoute - color: 'black' + line.color: 'green' + line.width: 7 // don't do this at home - route is not user instantiable, // use polyline instead route: Route { |