RasterProcessTool/LAMPMainWidget/mapcanvas.cpp

302 lines
6.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <QDebug>
#include <QTimer>
#include <include/maptool.h>
#include <include/maplayer.h>
#include <include/tools/maptoolpan.h>
#include <include/tools/maptoolselect.h>
#include <include/tools/maptoolzoomin.h>
#include <include/tools/maptoolzoomout.h>
#include <include/tools/maptooldrawline.h>
#include <include/tools/maptooldrawarea.h>
#include <include/tools/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->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<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 {
/// 视图偏移并重置偏移属性
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);
}
}