当用户选中了需要绘制的要素时,需要通过鼠标的操作把要素绘制出来,而且同时要保证之前已经绘制完成的不在受到任何的干扰。所以在显示层面就分为两层:最下面的一层就是已经绘制好的图形数据,上面一层则是当前正在绘制的图形。
这两层的管理通过一个类来管理:
//用户自定义图形的绘制
/*
这个用来显示用户自定义绘制的图形,分为两部分
1.用户当前正在绘制的图形
2.已经绘制完成图形
*/
#define DrawGeoMapInst() (GeoDrawMap::getInstance())
class CurrentGeoDraw;
class USERDEFINEDRAW_EXPORT GeoDrawMap
:public IDisplay
, public IMouseEvent {
private:
GeoDrawMap();
static GeoDrawMap* _instance;
public:
~GeoDrawMap();
static GeoDrawMap* getInstance();
//用户当前绘制类型
void setCurrentUserDrawType(USER_DRAW_TYPE currentDrawType);
USER_DRAW_TYPE getCurrentUserDrawType() {
return _currentDrawType;
}
virtual void draw(QPainter* p)override;
virtual void mousePress(QMouseEvent * event)override;
virtual void mouseRelease(QMouseEvent *event)override;
virtual void mouseMove(QMouseEvent * event)override;
private:
CurrentGeoDraw* _currentGeoDraw = nullptr;//控制当前绘制的内容
USER_DRAW_TYPE _currentDrawType = USER_DRAW_NULL;//当前绘制用户类型
};
GeoDrawMap* GeoDrawMap::_instance = nullptr;
GeoDrawMap::GeoDrawMap() {
MouseMgr()->addMouseEvent(this);
DisplayMgr()->addRender(this);
MutualMouse()->addMutualMouseEvent(this);//鼠标操作互斥
//保存当前绘制
_currentGeoDraw = new CurrentGeoDraw;
ResumeDrawMgr()->saveCurrnenGeoDraw(_currentGeoDraw);
}
GeoDrawMap::~GeoDrawMap() {
DisplayMgr()->removeRender(this);
MutualMouse()->removeMutualMouseEvent(this);
MouseMgr()->removeMouseEvent(this);
}
GeoDrawMap* GeoDrawMap::getInstance() {
if (_instance == nullptr){
_instance = new GeoDrawMap;
}
return _instance;
}
void GeoDrawMap::setCurrentUserDrawType(USER_DRAW_TYPE currentDrawType) {
_currentDrawType = currentDrawType;
_currentGeoDraw->setDrawGeoType(_currentDrawType);
}
void GeoDrawMap::draw(QPainter* p) {
//已经保存的绘制内容
QVector<BaseGeo*>&geoList = UserDefineDataMgr()->getUseGeoList();
int num = geoList.size();
for (int i = 0; i < num;i++) {
geoList.at(i)->draw(p);
geoList.at(i)->drawNameText(p);
}
//当前绘制的内容
_currentGeoDraw->draw(p);
}
void GeoDrawMap::mousePress(QMouseEvent * event) {
_currentGeoDraw->mousePress(event);
}
void GeoDrawMap::mouseRelease(QMouseEvent *event) {
_currentGeoDraw->mouseRelease(event);
}
void GeoDrawMap::mouseMove(QMouseEvent * event) {
_currentGeoDraw->mouseMove(event);
}
当前绘制的基类:
//当前正在绘制的几何图形的基类
class DrawGeoBase :public IDisplay
, public IMouseEvent {
public:
DrawGeoBase();
~DrawGeoBase();
virtual void draw(QPainter* p)override;
virtual void mousePress(QMouseEvent * event)override;
virtual void mouseRelease(QMouseEvent *event)override;
virtual void mouseMove(QMouseEvent * event)override;
};
DrawGeoBase::DrawGeoBase() {
}
DrawGeoBase::~DrawGeoBase() {
}
void DrawGeoBase::draw(QPainter* p) {
}
void DrawGeoBase::mousePress(QMouseEvent * event) {
}
void DrawGeoBase::mouseRelease(QMouseEvent *event) {
}
点绘制:
//当前正在绘制的点
class DrawGeoPoint :public DrawGeoBase {
public:
DrawGeoPoint();
~DrawGeoPoint();
virtual void draw(QPainter* p)override;
virtual void mousePress(QMouseEvent * event)override;
virtual void mouseRelease(QMouseEvent *event)override;
virtual void mouseMove(QMouseEvent * event)override;
private:
bool _leftDown = false;//鼠标左键按下
QPoint _pt;
QPoint _mousePressPt;
};
DrawGeoPoint::DrawGeoPoint() {
}
DrawGeoPoint::~DrawGeoPoint() {
}
void DrawGeoPoint::draw(QPainter* p) {
GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
if (pointProp != nullptr&&_pt.x() != -999 && _pt.y() != -999) {
p->setPen(QPen(pointProp->getOuterColor(), pointProp->getOuterWidth(), Qt::SolidLine));
p->setBrush(pointProp->getFillColor());
p->drawEllipse(_pt.x() - pointProp->getRadius()
, _pt.y() - pointProp->getRadius()
, pointProp->getRadius() * 2
, pointProp->getRadius() * 2);
}
}
void DrawGeoPoint::mousePress(QMouseEvent * event) {
if (event->button() == Qt::LeftButton){
_leftDown = true;
_pt = event->pos();
_mousePressPt = _pt;
}
}
void DrawGeoPoint::mouseRelease(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
PointGeo* point = new StoragePointGeo;
point->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
point->setGeoName(QStringLiteral("点"));//设置名称
point->setPointProp(pointProp);//保存点属性
double lon = 0.0, lat = 0.0;
CoordInst()->screen2LonLat(_pt, lon, lat);
point->setLon(lon);
point->setLat(lat);
point->setAlt(0.0);
UserDefineDataMgr()->addUseGeo(point);
_leftDown = false;
_pt = QPoint(-999, -999);
} else if (event->button() == Qt::RightButton) {
CurrentDrawFinishMgr()->currentFinish(USER_DRAW_POINT);
} else if (event->button() == Qt::MidButton) {//删除点
QVector<BaseGeo*>&geoList = UserDefineDataMgr()->getUseGeoList();
int num = geoList.size();
for (int i = num - 1; i >= 0;i--) {
BaseGeo* geo = geoList.at(i);
if (geo->getUserDrawDataType() == USER_DRAW_POINT){
UserDefineDataMgr()->removeUseGeo(geo);
break;
} else {
break;
}
}
}
}
void DrawGeoPoint::mouseMove(QMouseEvent * event) {
GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
if (_leftDown){
_pt -= (_mousePressPt - event->pos());
_mousePressPt = event->pos();
}
}
线绘制:
DrawGeoPoint::DrawGeoPoint() {
}
DrawGeoPoint::~DrawGeoPoint() {
}
void DrawGeoPoint::draw(QPainter* p) {
GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
if (pointProp != nullptr&&_pt.x() != -999 && _pt.y() != -999) {
p->setPen(QPen(pointProp->getOuterColor(), pointProp->getOuterWidth(), Qt::SolidLine));
p->setBrush(pointProp->getFillColor());
p->drawEllipse(_pt.x() - pointProp->getRadius()
, _pt.y() - pointProp->getRadius()
, pointProp->getRadius() * 2
, pointProp->getRadius() * 2);
}
}
void DrawGeoPoint::mousePress(QMouseEvent * event) {
if (event->button() == Qt::LeftButton){
_leftDown = true;
_pt = event->pos();
_mousePressPt = _pt;
}
}
void DrawGeoPoint::mouseRelease(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
PointGeo* point = new StoragePointGeo;
point->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
point->setGeoName(QStringLiteral("点"));//设置名称
point->setPointProp(pointProp);//保存点属性
double lon = 0.0, lat = 0.0;
CoordInst()->screen2LonLat(_pt, lon, lat);
point->setLon(lon);
point->setLat(lat);
point->setAlt(0.0);
UserDefineDataMgr()->addUseGeo(point);
_leftDown = false;
_pt = QPoint(-999, -999);
} else if (event->button() == Qt::RightButton) {
CurrentDrawFinishMgr()->currentFinish(USER_DRAW_POINT);
} else if (event->button() == Qt::MidButton) {//删除点
QVector<BaseGeo*>&geoList = UserDefineDataMgr()->getUseGeoList();
int num = geoList.size();
for (int i = num - 1; i >= 0;i--) {
BaseGeo* geo = geoList.at(i);
if (geo->getUserDrawDataType() == USER_DRAW_POINT){
UserDefineDataMgr()->removeUseGeo(geo);
break;
} else {
break;
}
}
}
}
void DrawGeoPoint::mouseMove(QMouseEvent * event) {
GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
if (_leftDown){
_pt -= (_mousePressPt - event->pos());
_mousePressPt = event->pos();
}
}
DrawGeoLine::DrawGeoLine() {
}
DrawGeoLine::~DrawGeoLine() {
}
void DrawGeoLine::draw(QPainter* p) {
p->setRenderHint(QPainter::Antialiasing, true);
GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
if (lineProp != nullptr) {
QPen pen;
pen.setColor(lineProp->getLineColor());
pen.setWidth(lineProp->getLineWidth());
pen.setStyle((Qt::PenStyle)lineProp->getLineType());
p->setPen(pen);
}
if (_useElastic) {
p->drawLine(_elasticStart, _elasticEnd);
}
QPointF ptSrc;
QPoint ptDes;
QVector<QPoint> ptList;
int num = _ptList.size();
for (int i = 0; i < num; i++) {
ptSrc = _ptList.at(i);
CoordInst()->lonlat2Screen(ptSrc.x(), ptSrc.y(), ptDes);
ptList.push_back(ptDes);
}
p->drawPolyline(ptList);
}
void DrawGeoLine::mousePress(QMouseEvent * event) {
if (event->button() == Qt::LeftButton) {
_leftDown = true;
_useElastic = true;
_elasticStart = event->pos();
_elasticEnd = event->pos();
double lon = 0.0, lat = 0.0;
CoordInst()->screen2LonLat(_elasticStart.x(), _elasticStart.y(), lon, lat);
_ptList.push_back(QPointF(lon, lat));
}
}
void DrawGeoLine::mouseRelease(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_leftDown = false;
} else if (event->button() == Qt::RightButton) {
if (_useElastic) {
#if 0
//当前移动的点不绘制
double lon = 0.0, lat = 0.0;
CoordInst()->screen2LonLat(event->pos().x(), event->pos().y(), lon, lat);
_ptList.push_back(QPointF(lon, lat));
#endif
_useElastic = false;
GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
LineGeo* line = new StorageLineGeo;
line->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
line->setGeoName(QStringLiteral("线"));//设置名称
line->setLineProp(lineProp);//保存线属性
int num = _ptList.size();
for (int i = 0; i < num; i++) {
QPointF pt = _ptList.at(i);
line->addLinePoint(UserGeoPoint(pt.x(), pt.y(), 0.0));
}
UserDefineDataMgr()->addUseGeo(line);
_ptList.clear();
GlobalUseInst()->load2DMapUpdate()->update2DMap();
} else {
CurrentDrawFinishMgr()->currentFinish(USER_DRAW_LINE);
}
} else if (event->button() == Qt::MidButton) {//删除
if (_ptList.size() == 0){
_elasticStart = QPointF(-100.0, -100.0);
_elasticEnd = QPointF(-100.0, -100.0);
return;
}
_ptList.pop_back();
if (_ptList.size() == 0){
_useElastic = false;
}
QPointF ptLast = _ptList.at(_ptList.size() - 1);
CoordInst()->lonlat2Screen(ptLast.x(), ptLast.y(), _elasticStart);
}
}
void DrawGeoLine::mouseMove(QMouseEvent * event) {
GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
_elasticEnd = event->pos();
}
当前正在绘制的内容:
DrawGeoLine::DrawGeoLine() {
}
DrawGeoLine::~DrawGeoLine() {
}
void DrawGeoLine::draw(QPainter* p) {
p->setRenderHint(QPainter::Antialiasing, true);
GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
if (lineProp != nullptr) {
QPen pen;
pen.setColor(lineProp->getLineColor());
pen.setWidth(lineProp->getLineWidth());
pen.setStyle((Qt::PenStyle)lineProp->getLineType());
p->setPen(pen);
}
if (_useElastic) {
p->drawLine(_elasticStart, _elasticEnd);
}
QPointF ptSrc;
QPoint ptDes;
QVector<QPoint> ptList;
int num = _ptList.size();
for (int i = 0; i < num; i++) {
ptSrc = _ptList.at(i);
CoordInst()->lonlat2Screen(ptSrc.x(), ptSrc.y(), ptDes);
ptList.push_back(ptDes);
}
p->drawPolyline(ptList);
}
void DrawGeoLine::mousePress(QMouseEvent * event) {
if (event->button() == Qt::LeftButton) {
_leftDown = true;
_useElastic = true;
_elasticStart = event->pos();
_elasticEnd = event->pos();
double lon = 0.0, lat = 0.0;
CoordInst()->screen2LonLat(_elasticStart.x(), _elasticStart.y(), lon, lat);
_ptList.push_back(QPointF(lon, lat));
}
}
void DrawGeoLine::mouseRelease(QMouseEvent *event) {
if (event->button() == Qt::LeftButton) {
_leftDown = false;
} else if (event->button() == Qt::RightButton) {
if (_useElastic) {
#if 0
//当前移动的点不绘制
double lon = 0.0, lat = 0.0;
CoordInst()->screen2LonLat(event->pos().x(), event->pos().y(), lon, lat);
_ptList.push_back(QPointF(lon, lat));
#endif
_useElastic = false;
GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
LineGeo* line = new StorageLineGeo;
line->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
line->setGeoName(QStringLiteral("线"));//设置名称
line->setLineProp(lineProp);//保存线属性
int num = _ptList.size();
for (int i = 0; i < num; i++) {
QPointF pt = _ptList.at(i);
line->addLinePoint(UserGeoPoint(pt.x(), pt.y(), 0.0));
}
UserDefineDataMgr()->addUseGeo(line);
_ptList.clear();
GlobalUseInst()->load2DMapUpdate()->update2DMap();
} else {
CurrentDrawFinishMgr()->currentFinish(USER_DRAW_LINE);
}
} else if (event->button() == Qt::MidButton) {//删除
if (_ptList.size() == 0){
_elasticStart = QPointF(-100.0, -100.0);
_elasticEnd = QPointF(-100.0, -100.0);
return;
}
_ptList.pop_back();
if (_ptList.size() == 0){
_useElastic = false;
}
QPointF ptLast = _ptList.at(_ptList.size() - 1);
CoordInst()->lonlat2Screen(ptLast.x(), ptLast.y(), _elasticStart);
}
}
void DrawGeoLine::mouseMove(QMouseEvent * event) {
GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
_elasticEnd = event->pos();
}
CurrentGeoDraw::CurrentGeoDraw() {
_currentGeoDrawFactory = new CurrentGeoDrawFactory;
}
CurrentGeoDraw::~CurrentGeoDraw() {
}
void CurrentGeoDraw::setDrawGeoType(USER_DRAW_TYPE drawType) {
_drawType = drawType;
_currentDraw = _currentGeoDrawFactory->getCurrentDraw(_drawType);
}
void CurrentGeoDraw::draw(QPainter* p) {
if (_currentDraw!=nullptr) {
_currentDraw->draw(p);
}
}
void CurrentGeoDraw::mousePress(QMouseEvent * event) {
if (_currentDraw != nullptr) {
_currentDraw->mousePress(event);
}
}
void CurrentGeoDraw::mouseRelease(QMouseEvent *event) {
if (_currentDraw != nullptr) {
_currentDraw->mouseRelease(event);
}
}
void CurrentGeoDraw::mouseMove(QMouseEvent * event) {
if (_currentDraw != nullptr) {
_currentDraw->mouseMove(event);
}
}
绘制工厂,通过工厂选择不同的绘制类型:
//当前绘制的创建工厂
class CurrentGeoDrawFactory {
public:
CurrentGeoDrawFactory();
~CurrentGeoDrawFactory();
DrawGeoBase* getCurrentDraw(USER_DRAW_TYPE drawType);
private:
DrawGeoBase* _drawGeo = nullptr;
DrawGeoPoint* _drawGeoPoint = nullptr;
ResumeDrawLine* _drawGeoLine = nullptr;
ResumeDrawPath* _drawGeoPath = nullptr;
DrawGeoRect* _drawGeoRect = nullptr;
ResumeDrawPolygon* _drawGeoPolygon = nullptr;
DrawGeoCircle* _drawGeoCircle = nullptr;
DrawGeoPie* _drawGeoPie = nullptr;
DrawGeoCircleArc* _drawGeoCircleArc = nullptr;
DrawGeoText* _drawGeoText = nullptr;
};
CurrentGeoDrawFactory::CurrentGeoDrawFactory() {
}
CurrentGeoDrawFactory::~CurrentGeoDrawFactory() {
}
DrawGeoBase* CurrentGeoDrawFactory::getCurrentDraw(USER_DRAW_TYPE drawType) {
switch (drawType) {
case USER_DRAW_NULL:
_drawGeo = nullptr;
break;
case USER_DRAW_POINT:
if (_drawGeoPoint == nullptr) {
_drawGeoPoint = new DrawGeoPoint;
}
_drawGeo = _drawGeoPoint;
break;
case USER_DRAW_LINE:
if (_drawGeoLine == nullptr) {
_drawGeoLine = new ResumeDrawLine;
ResumeDrawMgr()->addResumeDraw(_drawGeoLine);
}
_drawGeo = _drawGeoLine;
break;
case USER_DRAW_PATH:
if (_drawGeoPath == nullptr){
_drawGeoPath = new ResumeDrawPath;
ResumeDrawMgr()->addResumeDraw(_drawGeoPath);
}
_drawGeo = _drawGeoPath;
break;
case USER_DRAW_RECT:
if (_drawGeoRect == nullptr) {
_drawGeoRect = new DrawGeoRect;
}
_drawGeo = _drawGeoRect;
break;
case USER_DRAW_POLYGON:
if (_drawGeoPolygon == nullptr) {
_drawGeoPolygon = new ResumeDrawPolygon;
ResumeDrawMgr()->addResumeDraw(_drawGeoPolygon);
}
_drawGeo = _drawGeoPolygon;
break;
case USER_DRAW_CIRCLE:
if (_drawGeoCircle == nullptr) {
_drawGeoCircle = new DrawGeoCircle;
}
_drawGeo = _drawGeoCircle;
break;
case USER_DRAW_PIE:
if (_drawGeoPie == nullptr) {
_drawGeoPie = new DrawGeoPie;
}
_drawGeo = _drawGeoPie;
break;
case USER_DRAW_CIRCLE_ARC:
if (_drawGeoCircleArc == nullptr) {
_drawGeoCircleArc = new DrawGeoCircleArc;
}
_drawGeo = _drawGeoCircleArc;
break;
case USER_DRAW_TEXT:
if (_drawGeoText == nullptr) {
_drawGeoText = new QtDrawTextCursor(nullptr);
}
_drawGeo = _drawGeoText;
break;
default:
_drawGeo = nullptr;
break;
}
return _drawGeo;
}
aaa