#pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace LAMPMainWidget { class MapLayer; class MapTool; /** * 地图容器类,继承自QGraphicsView。 * 整个地图的渲染都是基于“Qt GraphicsView Framework”设计。 */ class MapCanvas : public QGraphicsView { Q_OBJECT signals: void zoomChanged(int zoom); void crsChanged(); void clicked(PointXY pos); void mapCenterChanged(PointXY pos); friend class MapToolPan; friend class MapToolZoomIn; friend class MapToolZoomOut; friend class MapToolSelect; public: explicit MapCanvas(QWidget* parent = nullptr); ~MapCanvas() override; public: /** * 刷新地图容器,这会更新每一个显示的图层的内容 */ void refreshMap(); /** * 向容器中添加图层,默认情况下容器会使用首个图层的坐标系作为自身的坐标系 * @param layer 图层对象 */ void addLayer(MapLayer* layer); /** * 获取地图容器的比例尺 * @return 容器的比例尺 */ double scale() const; /** * 获取地图容器的解析度 * @return */ double resolution() const; /** * 获取容器的zoom值 * @return 容器的zoom值 */ int zoomValue() const; /** * 设置容器的zoom值 * @param zoom zoom值 */ void setZoomValue(int zoom); /** * 获取容器当前所显示的地图区域 * @return 当前所显示地图区域 */ const QRectF& viewExtent() const { return mViewExtent; } /** * 设置容器坐标系,设置过后会更新所有图层坐标系。 * 默认会对容器中的图层做投影变换处理 * @param crs 坐标系 */ void setCrs(const CRS* crs); /** * 获取地图容器的坐标系 * @return 地图容器坐标系 */ const CRS& crs() const { return *mCrs; } /** * 设置地图容器的当前选中图层 * @param id 图层的id */ void setCurrentLayer(const QString& id); /** * 获取地图容器当前选中图层 * @return 当前选中图层 */ const MapLayer* currentLayer() { return mCurrentLayer; } /** * 获取地图当前视图中心点经纬度坐标 * @return 视图中心点经纬度坐标 */ const PointXY& mapCenter() const { return mMapCenter; } /** * 选择地图工具 * @param tool 工具名称 * @return 是否选择成功 */ bool selectTool(const QString& tool); void timerEvent(QTimerEvent* event); protected: /** * 更新容器的可视化区域。 * 每次拖动操作和resize事件会调用该方法 */ void updateViewExtent(bool reset = false); /** * 将屏幕坐标转换为经纬度坐标 * @param point 屏幕上点 * @return 经纬度坐标 */ PointXY pixel2Lonlat(const QPointF& point) const; /** * 初始设置地图必须具备的工具 */ void setupTools(); private: /** * 确保zoom值在限定的范围之内 * @param zoom 待设置zoom值 * @return 可使用zoom值 */ int normalizeZoom(int zoom) const; protected: void mousePressEvent(QMouseEvent* event) override; void mouseReleaseEvent(QMouseEvent* event) override; void wheelEvent(QWheelEvent* event) override; void resizeEvent(QResizeEvent* event) override; void mouseMoveEvent(QMouseEvent* event) override; protected: QGraphicsScene* mScene; // 场景对象 QRectF mMapExtent; QRectF mViewExtent; QRectF mDragRect; bool mIsDragging; QMap mLayers; MapLayer* mCurrentLayer; const CRS* mCrs; PointXY mMapCenter; int mZoomValue; PointXY mLastXY; QTimer* mMapUpdateTimer; MapTool* mCurrentTool; QHash mMapTools; private: const static int kDefaultZoomValue{ 8 }; static const int kMaxZoomValue{ 20 }; static const int kMinZoomValue{ 1 }; protected: // 设置默认地图中心点 static PointXY defaultMapCenter(); }; }