#include #include #include #include #include #include #include #include #include #include #include #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->delta() / 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 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 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 { /// 视图偏移并重置偏移属性 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(point.x()), static_cast(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(mMapTools["addplane_tool"]); QList 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); } }