293 lines
7.2 KiB
C++
293 lines
7.2 KiB
C++
#include <QDebug>
|
||
#include <QTimer>
|
||
|
||
#include <maptool.h>
|
||
#include <maplayer.h>
|
||
#include <maptoolpan.h>
|
||
#include <maptoolselect.h>
|
||
#include <maptoolzoomin.h>
|
||
#include <maptoolzoomout.h>
|
||
#include <maptooldrawline.h>
|
||
#include <maptooldrawarea.h>
|
||
#include <maptooladdplane.h>
|
||
#include "mapautoplane.h"
|
||
#pragma execution_character_set("utf-8")
|
||
|
||
namespace LAMPMainWidget {
|
||
|
||
PointXY
|
||
MapCanvas::defaultMapCenter() {
|
||
return PointXY{ 116.4074, 39.9042 };
|
||
}
|
||
|
||
MapCanvas::MapCanvas(QWidget* parent)
|
||
: QGraphicsView(parent),
|
||
mScene(nullptr),
|
||
mMapExtent(),
|
||
mViewExtent(),
|
||
mDragRect(),
|
||
mIsDragging(false),
|
||
mLayers(),
|
||
mCurrentLayer(nullptr),
|
||
mCrs(nullptr),
|
||
mMapCenter(defaultMapCenter()),
|
||
mZoomValue(kDefaultZoomValue),
|
||
mLastXY(),
|
||
mMapUpdateTimer(nullptr),
|
||
mCurrentTool(nullptr),
|
||
mMapTools() {
|
||
|
||
setAutoFillBackground(true);
|
||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||
setMouseTracking(true);
|
||
setFocusPolicy(Qt::StrongFocus);
|
||
mScene = new QGraphicsScene();
|
||
setScene(mScene);
|
||
mMapUpdateTimer = new QTimer();
|
||
QObject::connect(mMapUpdateTimer, &QTimer::timeout, [this]() {
|
||
this->mScene->update();
|
||
});
|
||
mMapUpdateTimer->start(200);
|
||
setupTools();
|
||
this->startTimer(1000);
|
||
}
|
||
|
||
MapCanvas::~MapCanvas() {
|
||
mLayers.clear();
|
||
delete mScene;
|
||
delete mCurrentLayer;
|
||
delete mMapUpdateTimer;
|
||
}
|
||
|
||
void
|
||
MapCanvas::mousePressEvent(QMouseEvent* event) {
|
||
if (mCurrentTool) {
|
||
mCurrentTool->execute(event);
|
||
}
|
||
QGraphicsView::mousePressEvent(event);
|
||
}
|
||
|
||
void
|
||
MapCanvas::mouseReleaseEvent(QMouseEvent* event) {
|
||
if (mCurrentTool) {
|
||
mCurrentTool->execute(event);
|
||
}
|
||
QGraphicsView::mouseReleaseEvent(event);
|
||
}
|
||
|
||
void
|
||
MapCanvas::wheelEvent(QWheelEvent* event) {
|
||
int delta = event->angleDelta().y() / 120;
|
||
int zoom = zoomValue();
|
||
zoom += delta;
|
||
setZoomValue(zoom);
|
||
}
|
||
|
||
void MapCanvas::resizeEvent(QResizeEvent* event) {
|
||
updateViewExtent(true);
|
||
}
|
||
|
||
void MapCanvas::mouseMoveEvent(QMouseEvent* event)
|
||
{
|
||
if (mCurrentTool) {
|
||
mCurrentTool->execute(event);
|
||
}
|
||
QGraphicsView::mouseMoveEvent(event);
|
||
}
|
||
|
||
void MapCanvas::refreshMap() {
|
||
QMapIterator<QString, MapLayer*> iterator(mLayers);
|
||
while (iterator.hasNext()) {
|
||
iterator.next();
|
||
iterator.value()->map()->setViewExtent(mViewExtent);//设置当前图层的可视范围
|
||
iterator.value()->update();//更新当前图层的显示内容
|
||
}
|
||
mScene->update();
|
||
}
|
||
|
||
void MapCanvas::addLayer(MapLayer* const layer) {
|
||
if (!layer)
|
||
return;
|
||
|
||
if (mLayers.contains(layer->id())) {
|
||
qWarning() << layer->id() << "图层已存在";
|
||
return;
|
||
}
|
||
|
||
mLayers.insert(layer->id(), layer);
|
||
if (mLayers.count() == 1) {//判断是否是第唯一个图层
|
||
setCurrentLayer(layer->id());
|
||
}
|
||
mScene->addItem(layer->map());//将当前图层添加到场景中
|
||
refreshMap();
|
||
}
|
||
|
||
void MapCanvas::setZoomValue(const int zoom) {
|
||
mZoomValue = normalizeZoom(zoom);
|
||
zoomChanged(mZoomValue);
|
||
|
||
/// 更新每个图层的zoom值
|
||
QMapIterator<QString, MapLayer*> iterator(mLayers);
|
||
while (iterator.hasNext()) {
|
||
iterator.next();
|
||
iterator.value()->setZoomValue(mZoomValue);
|
||
}
|
||
|
||
/// 更新可视区域的内容
|
||
updateViewExtent(true);
|
||
}
|
||
|
||
void MapCanvas::updateViewExtent(bool reset) {
|
||
if (!mCurrentLayer) {
|
||
qDebug() << "未设置当前图层,视图区域无法更新";
|
||
return;
|
||
}
|
||
|
||
if (reset) {
|
||
/// 重置视图区域
|
||
mScene->setSceneRect(mCurrentLayer->extent());
|
||
QRectF testrect = mCurrentLayer->extent();
|
||
mViewExtent.setRect(0, 0, 0, 0);
|
||
mViewExtent.setSize(size());
|
||
PointXY crsCenter = mCrs->forward(mMapCenter);
|
||
QPointF mapCenter{ crsCenter.x() / resolution(), crsCenter.y() / resolution() };
|
||
QPointF offset = mapCenter - mViewExtent.center();
|
||
mViewExtent.translate(offset.x(), offset.y());
|
||
}
|
||
else {
|
||
qDebug() << "视图区域更新 平移范围 x ,y " << -mDragRect.width() << " , " << -mDragRect.height();
|
||
/// 视图偏移并重置偏移属性
|
||
mViewExtent.translate(-mDragRect.width(), -mDragRect.height());
|
||
mDragRect.setRect(0, 0, 0, 0);
|
||
|
||
/// 更新地图可视区域中心点
|
||
QPointF mapCenter = mViewExtent.center();
|
||
PointXY crsCenter{ mapCenter.x() * resolution(), mapCenter.y() * resolution() };
|
||
mMapCenter = mCrs->inverse(crsCenter);
|
||
mapCenterChanged(mMapCenter);
|
||
}
|
||
|
||
/// 刷新地图
|
||
centerOn(mViewExtent.center());
|
||
refreshMap();
|
||
}
|
||
|
||
void MapCanvas::setCrs(const CRS* const crs) {
|
||
mCrs = crs;
|
||
crsChanged();
|
||
updateViewExtent(true);
|
||
}
|
||
|
||
void MapCanvas::setCurrentLayer(const QString& id) {
|
||
if (!mLayers.contains(id)) {
|
||
qWarning() << "未添加图层=>" << id;
|
||
return;
|
||
}
|
||
mCurrentLayer = mLayers[id];
|
||
if (!mCrs) {
|
||
setCrs(&mCurrentLayer->crs());//设置当前图层的坐标系,后期考虑继续拆分
|
||
}
|
||
updateViewExtent(true);// 更新视图区域
|
||
}
|
||
|
||
double MapCanvas::scale() const {
|
||
return logicalDpiX() * resolution() * 39.37 / 100;;
|
||
}
|
||
|
||
double MapCanvas::resolution() const {
|
||
if (!mCurrentLayer) {
|
||
qWarning() << "未设置当前图层,无法获取分辨率";
|
||
return 0;
|
||
}
|
||
|
||
return mCurrentLayer->resolution();
|
||
}
|
||
|
||
int MapCanvas::zoomValue() const {
|
||
if (!mCurrentLayer) {
|
||
qWarning() << "未设置当前图层,默认返回zoom值为0";
|
||
return 0;
|
||
}
|
||
|
||
return mCurrentLayer->zoomValue();
|
||
}
|
||
|
||
int MapCanvas::normalizeZoom(const int zoom) const {
|
||
int z{};
|
||
if (zoom <= kMinZoomValue) {
|
||
z = kMinZoomValue;
|
||
}
|
||
else if (z >= kMaxZoomValue) {
|
||
z = kMaxZoomValue;
|
||
}
|
||
else {
|
||
z = zoom;
|
||
}
|
||
|
||
return z;
|
||
}
|
||
|
||
PointXY MapCanvas::pixel2Lonlat(const QPointF& point) const {
|
||
QPointF scenePoint = mapToScene(QPoint{ static_cast<int>(point.x()), static_cast<int>(point.y()) });
|
||
QPointF mapPoint{ scenePoint.x() * resolution(), scenePoint.y() * resolution() };
|
||
PointXY crsPoint = mCrs->inverse(PointXY{ mapPoint });
|
||
qDebug() << "坐标装换=>{" << point << "=>" << crsPoint << "}";
|
||
return crsPoint;
|
||
}
|
||
|
||
bool MapCanvas::selectTool(const QString& tool) {
|
||
if (!mMapTools.contains(tool)) {
|
||
qWarning() << QString("%1工具不存在").arg(tool);
|
||
return false;
|
||
}
|
||
|
||
auto toolPtr = mMapTools.value(tool);
|
||
if (mCurrentTool) {
|
||
mCurrentTool->deSetup();
|
||
}
|
||
mCurrentTool = toolPtr;
|
||
toolPtr->setup();
|
||
|
||
return true;
|
||
}
|
||
|
||
void MapCanvas::timerEvent(QTimerEvent* event)
|
||
{
|
||
MapToolAddplane* maptoolAddplane = dynamic_cast<MapToolAddplane*>(mMapTools["addplane_tool"]);
|
||
QList<MapAutoplane*> planes = maptoolAddplane->getPlanes();
|
||
foreach(MapAutoplane * plane, planes) {
|
||
plane->updatePos();
|
||
}
|
||
}
|
||
|
||
void MapCanvas::setupTools() {
|
||
auto panTool = new MapToolPan(this);
|
||
mMapTools.insert(panTool->id(), panTool);
|
||
|
||
auto zoominTool = new MapToolZoomIn(this);
|
||
mMapTools.insert(zoominTool->id(), zoominTool);
|
||
|
||
auto zoomoutTool = new MapToolZoomOut(this);
|
||
mMapTools.insert(zoomoutTool->id(), zoomoutTool);
|
||
|
||
auto selectTool = new MapToolSelect(this);
|
||
mMapTools.insert(selectTool->id(), selectTool);
|
||
|
||
auto drawlineTool = new MapToolDrawline(this);
|
||
mMapTools.insert(drawlineTool->id(), drawlineTool);
|
||
|
||
auto drawareTool = new MapToolDrawarea(this);
|
||
mMapTools.insert(drawareTool->id(), drawareTool);
|
||
|
||
auto addplaneTool = new MapToolAddplane(this);
|
||
mMapTools.insert(addplaneTool->id(), addplaneTool);
|
||
|
||
|
||
|
||
|
||
|
||
}
|
||
|
||
}
|