#pragma once #include "mappresent_global.h" #include #include #include #include /// /// 绘制索引 /// struct MAPPRESENT_EXPORT PresentIndex { /// /// 行号 /// int row = INT_MAX; /// /// 列号 /// int col = INT_MAX; bool isValid() const; PresentIndex& operator+=(const PresentIndex& other); bool operator!=(const PresentIndex& other) const; bool operator==(const PresentIndex& other) const; bool operator<(const PresentIndex& other) const; }; /// /// 地图数据模型 /// class MapDataModel : public QObject { Q_OBJECT public: enum class DataType { UnitType, AltMeters }; virtual QVariant mapData(DataType type, const PresentIndex& idx) const = 0; virtual void mapDataSet(DataType type, const PresentIndex& idx, const QVariant& val) = 0; signals: void dataChanged(const PresentIndex& idx); }; /// /// 绘制选项 /// struct MAPPRESENT_EXPORT PresentOption { /// /// 当前所绘制索引 /// PresentIndex index; /// /// 当前绘制外缘 /// QRectF outline; /// /// 数据模型指针 /// MapDataModel* dataModel = nullptr; PresentOption& operator=(const PresentOption& other); }; /// /// 单元绘制委托 /// class MAPPRESENT_EXPORT UnitPresentDelegate : public QObject { Q_OBJECT public: UnitPresentDelegate(QObject* parent = nullptr); virtual ~UnitPresentDelegate() = default; /// /// 匹配单元类型 /// /// virtual int unitType() const = 0; /// /// 绘制本单元瓦片 /// /// /// virtual void paint(QPainter* p, const PresentOption& option) = 0; signals: /// /// 更新通知/重绘请求 /// void updateRequest(const QList& idx_list); }; /// /// 基础瓦片地图绘制 /// class MAPPRESENT_EXPORT MapPresent : public QWidget { Q_OBJECT private: /// /// 地图数据模型 /// MapDataModel* _map_data_model = nullptr; // =================================== /// /// 初级区域矩形变长 /// const float _primitive_region_len = 64; /// /// 缩放倍数 /// double _scale_times = 1; /// /// 当前瓦片地图中心索引 /// PresentIndex _center_index; // =================================== /// /// 绘制中转缓冲区 /// QPixmap _paint_buffer; /// /// 试图核心索引 /// QMap _visible_units; /// /// 被更新的单元索引 /// QList _updated_index_list; /// /// 可视化单元整理 /// void visible_units_tidy(); /// /// 可视化索引填充 /// /// /// /// QList item_supply(const PresentIndex& a, const PresentIndex& b) const; // =================================== /// /// 类型化绘制委托 /// QHash _type_present_delegate; public: MapPresent(QWidget* parent = nullptr); void zoomTo(double percent); double zoomTimes() const; /// /// 设置绘制委托 /// /// /// bool setDelegate(UnitPresentDelegate* ins); /// /// 设置地图数据模型 /// /// void setDataModel(MapDataModel* model); MapDataModel* dataModel() const; /// /// 通过widget上定位获取绘制索引 /// /// /// PresentIndex indexGet(const QPointF& pos) const; /// /// 通过绘制索引获取指定单元外接矩形 /// /// /// QRectF outlineGet(const PresentIndex& idx) const; /// /// 获取周围包裹单元 /// /// 核心单元索引 /// 单元距离 /// QList siblingsGet(const PresentIndex& center, uint16_t dist = 1) const; signals: void mouseInNotify(); void mouseOutNotify(); void mouseHoverNotify(const PresentIndex& unit_index); void mousePressNotify(QMouseEvent* ev); void mouseReleaseNotify(QMouseEvent* ev); protected: void paintEvent(QPaintEvent* ev) override; void resizeEvent(QResizeEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; void enterEvent(QEvent* event) override; void leaveEvent(QEvent* event) override; void mousePressEvent(QMouseEvent* ev) override; void mouseReleaseEvent(QMouseEvent* ev) override; };