2025-02-07 09:16:22 +00:00
|
|
|
|
#include <QDebug>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
2025-02-09 18:16:07 +00:00
|
|
|
|
#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>
|
2025-02-07 09:16:22 +00:00
|
|
|
|
#include "mapautoplane.h"
|
|
|
|
|
#pragma execution_character_set("utf-8")
|
|
|
|
|
|
|
|
|
|
namespace LAMPMainWidget {
|
|
|
|
|
|
2025-04-01 10:23:24 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::resizeEvent(QResizeEvent* event) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
updateViewExtent(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void MapCanvas::mouseMoveEvent(QMouseEvent* event)
|
|
|
|
|
{
|
|
|
|
|
if (mCurrentTool) {
|
|
|
|
|
mCurrentTool->execute(event);
|
|
|
|
|
}
|
|
|
|
|
QGraphicsView::mouseMoveEvent(event);
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::refreshMap() {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
QMapIterator<QString, MapLayer*> iterator(mLayers);
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
|
iterator.next();
|
2025-05-02 05:19:00 +00:00
|
|
|
|
iterator.value()->map()->setViewExtent(mViewExtent);//设置当前图层的可视范围
|
|
|
|
|
iterator.value()->update();//更新当前图层的显示内容
|
2025-04-01 10:23:24 +00:00
|
|
|
|
}
|
|
|
|
|
mScene->update();
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::addLayer(MapLayer* const layer) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
if (!layer)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (mLayers.contains(layer->id())) {
|
|
|
|
|
qWarning() << layer->id() << "图层已存在";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mLayers.insert(layer->id(), layer);
|
2025-05-02 05:19:00 +00:00
|
|
|
|
if (mLayers.count() == 1) {//判断是否是第唯一个图层
|
2025-04-01 10:23:24 +00:00
|
|
|
|
setCurrentLayer(layer->id());
|
|
|
|
|
}
|
2025-05-02 05:19:00 +00:00
|
|
|
|
mScene->addItem(layer->map());//将当前图层添加到场景中
|
2025-04-01 10:23:24 +00:00
|
|
|
|
refreshMap();
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::setZoomValue(const int zoom) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
mZoomValue = normalizeZoom(zoom);
|
|
|
|
|
zoomChanged(mZoomValue);
|
|
|
|
|
|
|
|
|
|
/// 更新每个图层的zoom值
|
|
|
|
|
QMapIterator<QString, MapLayer*> iterator(mLayers);
|
|
|
|
|
while (iterator.hasNext()) {
|
|
|
|
|
iterator.next();
|
|
|
|
|
iterator.value()->setZoomValue(mZoomValue);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 更新可视区域的内容
|
|
|
|
|
updateViewExtent(true);
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::updateViewExtent(bool reset) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
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 {
|
2025-05-02 05:19:00 +00:00
|
|
|
|
qDebug() << "视图区域更新 平移范围 x ,y " << -mDragRect.width() << " , " << -mDragRect.height();
|
2025-04-01 10:23:24 +00:00
|
|
|
|
/// 视图偏移并重置偏移属性
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::setCrs(const CRS* const crs) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
mCrs = crs;
|
|
|
|
|
crsChanged();
|
|
|
|
|
updateViewExtent(true);
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::setCurrentLayer(const QString& id) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
if (!mLayers.contains(id)) {
|
|
|
|
|
qWarning() << "未添加图层=>" << id;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
mCurrentLayer = mLayers[id];
|
|
|
|
|
if (!mCrs) {
|
2025-05-02 05:19:00 +00:00
|
|
|
|
setCrs(&mCurrentLayer->crs());//设置当前图层的坐标系,后期考虑继续拆分
|
2025-04-01 10:23:24 +00:00
|
|
|
|
}
|
2025-05-02 05:19:00 +00:00
|
|
|
|
updateViewExtent(true);// 更新视图区域
|
2025-04-01 10:23:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
double MapCanvas::scale() const {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
return logicalDpiX() * resolution() * 39.37 / 100;;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
double MapCanvas::resolution() const {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
if (!mCurrentLayer) {
|
|
|
|
|
qWarning() << "未设置当前图层,无法获取分辨率";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mCurrentLayer->resolution();
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
int MapCanvas::zoomValue() const {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
if (!mCurrentLayer) {
|
|
|
|
|
qWarning() << "未设置当前图层,默认返回zoom值为0";
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mCurrentLayer->zoomValue();
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
int MapCanvas::normalizeZoom(const int zoom) const {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
int z{};
|
|
|
|
|
if (zoom <= kMinZoomValue) {
|
|
|
|
|
z = kMinZoomValue;
|
|
|
|
|
}
|
|
|
|
|
else if (z >= kMaxZoomValue) {
|
|
|
|
|
z = kMaxZoomValue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
z = zoom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return z;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
PointXY MapCanvas::pixel2Lonlat(const QPointF& point) const {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
bool MapCanvas::selectTool(const QString& tool) {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-05-02 05:19:00 +00:00
|
|
|
|
void MapCanvas::setupTools() {
|
2025-04-01 10:23:24 +00:00
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2025-02-07 09:16:22 +00:00
|
|
|
|
|
|
|
|
|
}
|