191 lines
4.1 KiB
C++
191 lines
4.1 KiB
C++
#pragma once
|
||
|
||
#include <QWheelEvent>
|
||
#include <QPaintEvent>
|
||
#include <QGraphicsView>
|
||
#include <QGraphicsScene>
|
||
#include <QTimer>
|
||
#include <QEvent>
|
||
#include <QKeyEvent>
|
||
#include <QMouseEvent>
|
||
#include <QResizeEvent>
|
||
#include <QDragEnterEvent>
|
||
#include <QRectF>
|
||
#include <QMarginsF>
|
||
#include <QHash>
|
||
|
||
#include <crs.h>
|
||
#include <pointxy.h>
|
||
#include <mapcanvasmap.h>
|
||
#include <maptool.h>
|
||
|
||
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<QString, MapLayer*> mLayers;
|
||
MapLayer* mCurrentLayer;
|
||
const CRS* mCrs;
|
||
PointXY mMapCenter;
|
||
int mZoomValue;
|
||
PointXY mLastXY;
|
||
QTimer* mMapUpdateTimer;
|
||
MapTool* mCurrentTool;
|
||
QHash<QString, MapTool*> mMapTools;
|
||
|
||
private:
|
||
const static int kDefaultZoomValue{ 8 };
|
||
static const int kMaxZoomValue{ 20 };
|
||
static const int kMinZoomValue{ 1 };
|
||
|
||
protected:
|
||
// 设置默认地图中心点
|
||
static PointXY defaultMapCenter();
|
||
};
|
||
|
||
}
|