前文链接:QGraphicsView实现简易地图14『测量距离』
动态演示效果
静态展示图片
核心代码
#pragma once
#include <QObject>
#include "MapAbstractHandler.h"
#include "DataStruct/MeasureAreaData.h"
/*
* 测面积-工具类
*/
class MeasureAreaHandler : public MapHandler<MeasureAreaData>
{
Q_OBJECT
public:
explicit MeasureAreaHandler(const QString &name, QGraphicsView *parent, MeasureAreaData *data);
~MeasureAreaHandler();
static QString type() { return "MeasureAreaHandler"; }
protected:
bool eventFilter(QObject *watched, QEvent *event) override;
void connectHandlerToData(MeasureAreaData *data) override;
void connectHandlerToView(MapView *view) override;
signals:
void addPointItem(const QString &handlerName, QGraphicsItem *item);
void addAreaItem(const QString &handlerName, QGraphicsItem *item);
void clearItems();
void finished();
};
#include "MeasureAreaHandler.h"
#include "MeasureDistanceHandler.h"
#include "MapView/MapView.h"
#include "Item/Custom/MeasureDistancePointItem.h"
#include "Utility/MapUtility.h"
#include "DataStruct/MapDataManager.h"
#include "DataStruct/EnumData.h"
#include "Item/Custom/MeasureAreaItem.h"
MeasureAreaHandler::MeasureAreaHandler(const QString &name, QGraphicsView *parent, MeasureAreaData *data) : MapHandler(name, parent, data)
{
connectHandlerToData(data);
connectHandlerToView(dynamic_cast<MapView *>(m_view));
}
MeasureAreaHandler::~MeasureAreaHandler()
{
}
bool MeasureAreaHandler::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_view)
{
if (event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *ev = dynamic_cast<QMouseEvent *>(event);
// 鼠标左键取点(允许连续取点)
if (ev->button() == Qt::LeftButton)
{
m_view->setCursor(Qt::CrossCursor);
// 添加点
MeasureDistancePointItem *pointItem = new MeasureDistancePointItem;
QPointF scenePos = m_view->mapToScene(ev->pos());
GeoCoord geoCoord = MapUtility::geoCoordFromScene(scenePos, MapDataManager::instance()->mapLevel());
pointItem->setGeoPos(geoCoord.lon, geoCoord.lat);
pointItem->setZValue(QWHMapView::ML_MEASURE_POINT);
m_scene->addItem(pointItem);
emit addPointItem(m_name, pointItem);
// 添加区域点
MeasureDistancePointItem *lastPointItem = m_data->lastPoint(m_name);
GeoCoord geoCoord1(lastPointItem->lon(), lastPointItem->lat());
GeoCoord geoCoord2 = MapUtility::geoCoordFromScene(scenePos, MapDataManager::instance()->mapLevel());
MeasureAreaItem *areaItem = m_data->getOrCreate(m_name);
areaItem->addPoint(geoCoord);
areaItem->setZValue(QWHMapView::ML_MEASURE_LINE);
m_scene->addItem(areaItem);
emit addAreaItem(m_name, areaItem);
}
// 鼠标右键结束测面积
else if (ev->button() == Qt::RightButton)
{
emit finished();
}
}
}
return MapHandler::eventFilter(watched, event);
}
void MeasureAreaHandler::connectHandlerToData(MeasureAreaData *data)
{
connect(this, &MeasureAreaHandler::addPointItem, data, &MeasureAreaData::onAddPointItem);
connect(this, &MeasureAreaHandler::addAreaItem, data, &MeasureAreaData::onAddAreaItem);
connect(this, &MeasureAreaHandler::clearItems, data, &MeasureAreaData::clearAllData);
}
void MeasureAreaHandler::connectHandlerToView(MapView *view)
{
connect(this, &MeasureAreaHandler::addPointItem, this, [view](const QString &handlerName, QGraphicsItem *item) {
view->addGeoItems(item);
});
connect(this, &MeasureAreaHandler::addAreaItem, this, [view](const QString &handlerName, QGraphicsItem *item) {
view->addGeoItems(item);
});
}