RasterProcessTool/RasterMainWidgetGUI/RasterMainWidget/mapcanvas.cpp

293 lines
7.2 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 <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);
}
}