日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

qt 二维地图库_Qt轻量级地图解决方案:基于QtLocation的二次开发(四)

發(fā)布時(shí)間:2023/12/29 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qt 二维地图库_Qt轻量级地图解决方案:基于QtLocation的二次开发(四) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

寫(xiě)在前面

在本系列的上一篇中,我將從《Qt之美1:數(shù)據(jù)指針和私有實(shí)現(xiàn)》中的例子抄過(guò)來(lái),說(shuō)明了Qt中源碼中(同時(shí)也是QtLcation模塊中)大量存在的D-P機(jī)制。這種設(shè)計(jì)模式實(shí)現(xiàn)了動(dòng)態(tài)庫(kù)的二進(jìn)制兼容,同時(shí)也隱藏了私有成員和潛在的實(shí)現(xiàn)細(xì)節(jié);除此之外,還能基于它實(shí)現(xiàn)另一種Qt中大量采用的技術(shù),即“隱式共享技術(shù)”。

以下關(guān)于“隱式共享技術(shù)”的說(shuō)明內(nèi)容,大多出自《Qt中的C++技術(shù)》這本書(shū)的第8章《隱式共享與d-pointer技術(shù)》。

一般地,一個(gè)類(lèi)型的多個(gè)實(shí)例所占內(nèi)存是相互獨(dú)立的,如果其中某些數(shù)據(jù)成員的取值完全相同,那么這些實(shí)例可共享這些數(shù)據(jù)成員,當(dāng)某實(shí)例需要修改其中的數(shù)據(jù)成員時(shí)才為該對(duì)象重新分配內(nèi)存;這種技術(shù)被稱(chēng)為“隱式共享技術(shù)”,又被形象地描述為“寫(xiě)時(shí)復(fù)制(copy on write)”。如下圖所示,假如對(duì)象O1、O2、O3和O4都有部分?jǐn)?shù)據(jù)成員取值相同,都共享這部分?jǐn)?shù)據(jù)成員所占用的內(nèi)存A;此后需要修改O4位于共享內(nèi)存A中的某個(gè)數(shù)據(jù)成員,此時(shí)不能直接修改內(nèi)存A,否則會(huì)影響O1、O2和O3的數(shù)據(jù)成員;只好先復(fù)制將內(nèi)存A復(fù)制成B,然后重新分配給O4,在B中修改O4需要修改的數(shù)據(jù)成員。

由于共享內(nèi)存A的存在,假如要析構(gòu)O3時(shí),O1和O2還未析構(gòu),則不能簡(jiǎn)單地釋放共享內(nèi)存A,因?yàn)檫@樣做會(huì)使O1和O2受到牽連。只有當(dāng)僅存在一個(gè)對(duì)象引用共享內(nèi)存時(shí),析構(gòu)這個(gè)僅存的實(shí)例才完全釋放共享內(nèi)存,其他時(shí)候僅需要“斷開(kāi)”析構(gòu)實(shí)例與共享內(nèi)存的引用關(guān)系即可。這就需要維護(hù)一個(gè)共享內(nèi)存的引用計(jì)數(shù)器(reference counter),每當(dāng)析構(gòu)了一個(gè)引用該塊共享內(nèi)存的對(duì)象時(shí),就減少一個(gè)引用計(jì)數(shù),直到引用計(jì)數(shù)為1(即僅存一個(gè)引用該內(nèi)存塊的對(duì)象)時(shí),下一次再進(jìn)行減少引用計(jì)數(shù)的操作(即析構(gòu)引用該內(nèi)存的對(duì)象)才會(huì)完全釋放這塊內(nèi)存。

剛才我們講了同一類(lèi)型不同實(shí)例之間實(shí)現(xiàn)隱式共享的基本原理,但這并不適用于所有應(yīng)用場(chǎng)景。其實(shí),Qt已經(jīng)在“隱式共享技術(shù)”上為我們做了很多基礎(chǔ)性和示范性工作,其提供了一個(gè)名為QSharedData的共享數(shù)據(jù)類(lèi)型,還提供了QSharedDataPointer等共享數(shù)據(jù)類(lèi)的指針,利用QSharedData和QSharedDataPointer等類(lèi)型就可以實(shí)現(xiàn)隱式共享的進(jìn)階操作,比如同一基類(lèi)不同子類(lèi)之間的隱式共享。

了解QGeoShape為基類(lèi)的地理數(shù)據(jù)類(lèi)型

這里以QtPositioning中QGeoShape類(lèi)型體系的源碼作為示例,QGeoShape是所有地理形狀類(lèi)型的基類(lèi),其繼承者們包括:QGeoRectangle、QGeoCircle、QGeoPath和QGeoPolygon。QGeoShape類(lèi)似于 Simple Feature標(biāo)準(zhǔn) 中的Geometry類(lèi)型,但QGeoShape坐標(biāo)點(diǎn)都是QGeoCoordinate類(lèi)型,只能表示經(jīng)緯高坐標(biāo)。

QGeoShape的源碼如下:

class QGeoRectangle;

class QGeoShapePrivate;

class Q_POSITIONING_EXPORT QGeoShape

{

Q_GADGET

Q_PROPERTY(ShapeType type READ type)

Q_PROPERTY(bool isValid READ isValid)

Q_PROPERTY(bool isEmpty READ isEmpty)

Q_ENUMS(ShapeType)

public:

QGeoShape();

QGeoShape(const QGeoShape &other);

~QGeoShape();

enum ShapeType {

UnknownType,

RectangleType,

CircleType,

PathType,

PolygonType

};

ShapeType type() const;

bool isValid() const;

bool isEmpty() const;

Q_INVOKABLE bool contains(const QGeoCoordinate &coordinate) const;

Q_INVOKABLE QGeoRectangle boundingGeoRectangle() const;

Q_INVOKABLE QGeoCoordinate center() const;

Q_INVOKABLE void extendShape(const QGeoCoordinate &coordinate);

bool operator==(const QGeoShape &other) const;

bool operator!=(const QGeoShape &other) const;

QGeoShape &operator=(const QGeoShape &other);

Q_INVOKABLE QString toString() const;

protected:

QGeoShape(QGeoShapePrivate *d);

QSharedDataPointer d_ptr;

private:

inline QGeoShapePrivate *d_func();

inline const QGeoShapePrivate *d_func() const;

};

其給出了私有共享數(shù)據(jù)類(lèi)型QGeoShapePrivate的前向聲明:

class QGeoShapePrivate : public QSharedData

{

public:

explicit QGeoShapePrivate(QGeoShape::ShapeType type);

virtual ~QGeoShapePrivate();

virtual bool isValid() const = 0;

virtual bool isEmpty() const = 0;

virtual bool contains(const QGeoCoordinate &coordinate) const = 0;

virtual QGeoCoordinate center() const = 0;

virtual QGeoRectangle boundingGeoRectangle() const = 0;

virtual void extendShape(const QGeoCoordinate &coordinate) = 0;

virtual QGeoShapePrivate *clone() const = 0;

virtual bool operator==(const QGeoShapePrivate &other) const;

QGeoShape::ShapeType type;

};

本來(lái)QGeoShapePrivate應(yīng)該是QGeoShape的具體實(shí)現(xiàn),但是由于QGeoShape被定義為抽象基類(lèi),QGeoShapePrivate中的接口都被定義為純虛函數(shù),實(shí)際上QGeoShape接口都是在其子類(lèi)對(duì)應(yīng)的私有數(shù)據(jù)類(lèi)型中具體實(shí)現(xiàn)的,比如QGeoRectanglePrivate(繼承自QGeoShapePrivate):

class QGeoRectanglePrivate : public QGeoShapePrivate

{

public:

QGeoRectanglePrivate();

QGeoRectanglePrivate(const QGeoCoordinate &topLeft, const QGeoCoordinate &bottomRight);

QGeoRectanglePrivate(const QGeoRectanglePrivate &other);

~QGeoRectanglePrivate();

bool isValid() const override;

bool isEmpty() const override;

bool contains(const QGeoCoordinate &coordinate) const override;

QGeoCoordinate center() const override;

QGeoRectangle boundingGeoRectangle() const override;

void extendShape(const QGeoCoordinate &coordinate) override;

QGeoShapePrivate *clone() const override;

bool operator==(const QGeoShapePrivate &other) const override;

QGeoCoordinate topLeft;

QGeoCoordinate bottomRight;

};

QGeoShape及其子類(lèi)是地圖要素的幾何數(shù)據(jù)的主要表達(dá)形式。前端的MapPolyline、MapRectangle、MapCircle和MapPolygon等地圖元素(MapItem),其宿主對(duì)象是由后端Qt提供的QDeclarativePolylineMapItem、QDeclarativeRectangleMapItem、QDeclarativeCircleMapItem和QDeclarativePolygonMapItem等類(lèi)型,它們的地理幾何數(shù)據(jù)(geoShape方法)就分別由QGeoPath、QGeoRectangle、QGeoCircle和QGeoPolygon的實(shí)例表示。

下面以QDeclarativeRectangleMapItem源碼為例:

class Q_LOCATION_PRIVATE_EXPORT QDeclarativeRectangleMapItem: public QDeclarativeGeoMapItemBase

{

Q_OBJECT

Q_PROPERTY(QGeoCoordinate topLeft READ topLeft WRITE setTopLeft NOTIFY topLeftChanged)

Q_PROPERTY(QGeoCoordinate bottomRight READ bottomRight WRITE setBottomRight NOTIFY bottomRightChanged)

Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)

Q_PROPERTY(QDeclarativeMapLineProperties *border READ border CONSTANT)

public:

explicit QDeclarativeRectangleMapItem(QQuickItem *parent = 0);

~QDeclarativeRectangleMapItem();

virtual void setMap(QDeclarativeGeoMap *quickMap, QGeoMap *map) override;

//from QuickItem

virtual QSGNode *updateMapItemPaintNode(QSGNode *, UpdatePaintNodeData *) override;

QGeoCoordinate topLeft();

void setTopLeft(const QGeoCoordinate &center);

QGeoCoordinate bottomRight();

void setBottomRight(const QGeoCoordinate &center);

QColor color() const;

void setColor(const QColor &color);

QDeclarativeMapLineProperties *border();

bool contains(const QPointF &point) const override;

const QGeoShape &geoShape() const override;

QGeoMap::ItemType itemType() const override;

Q_SIGNALS:

void topLeftChanged(const QGeoCoordinate &topLeft);

void bottomRightChanged(const QGeoCoordinate &bottomRight);

void colorChanged(const QColor &color);

protected:

void updatePath();

void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override;

void updatePolish() override;

protected Q_SLOTS:

void markSourceDirtyAndUpdate();

virtual void afterViewportChanged(const QGeoMapViewportChangeEvent &event) override;

private:

QGeoRectangle rectangle_;

QDeclarativeMapLineProperties border_;

QColor color_;

bool dirtyMaterial_;

QGeoMapPolygonGeometry geometry_;

QGeoMapPolylineGeometry borderGeometry_;

bool updatingGeometry_;

QList pathMercator_;

};

總結(jié)

以上是生活随笔為你收集整理的qt 二维地图库_Qt轻量级地图解决方案:基于QtLocation的二次开发(四)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。