302 lines
6.8 KiB
C++
302 lines
6.8 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 {
|
|||
|
/// 视图偏移并重置偏移属性
|
|||
|
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);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|