二维地图组件开发

发布时间:2024年01月06日

? ? ? 很多的业务项目中,都会用到二维地图,二维地图功能简洁,并且很多在很多的业务中采用,维护难度也比三维地图小一些。而开发二维地图的开源库有QGis, Mapwingis等。

? ? ? ?采用mapwingis开发了一个二维地图组件,可以实现常用的地图功能。比如地图的放大,缩小,移动,添加矩形,添加圆形,测量距离,获取经纬度等常用功能。并且提供了较多的接口,方便后期二次开发和维护等。组件采用vs2015+qt5.9.8开发。

? ? ? ? 使用地图接口的代码为:

//主要有mymap.h, mymap.cpp, main.cpp三个代码文件

//mymap.h

#pragma once

#include <QtWidgets/QDialog>
#include <QTimer>

#include "ui_mymap.h"

#include "hlMap/imapview.h"

#include "hlLinker/IEntity.h"

class CEngine;
class mymap : public QDialog
{
?? ?Q_OBJECT

public:
?? ?mymap(QWidget* parent = Q_NULLPTR);
?? ?virtual ~mymap();

private slots:
?? ?/*
?? ?@brief 刷新兵力数据
?? ?*/
?? ?void slotTimeout();

?? ?/*
?? ?@brief?? ?鼠标在地图点击信号
?? ?@param?? ?btn?? ?鼠标按键,1表示左键,2表示右键
?? ?@param lon 经度
?? ?@param lat 纬度
?? ?*/
?? ?void slotMouseClicked(int btn, double lon, double lat);

?? ?/*
?? ?@brief?? ?鼠标在地图双击信号
?? ?@param?? ?btn?? ?鼠标按键,1表示左键,2表示右键
?? ?@param lon 经度
?? ?@param lat 纬度
?? ?*/
?? ?void slotMouseDoubleClicked(int btn, double lon, double lat);

?? ?/*
?? ?@brief 鼠标位置改变
?? ?@param lon 经度
?? ?@param lat 纬度
?? ?*/
?? ?void slotMouseMoved(double lon, double lat);

?? ?图元信号
?? ?/*
?? ?@brief 兵力增加消息
?? ?@param id 兵力ID
?? ?*/
?? ?void slotForceJoined(unsigned int id);

?? ?/*
?? ?@brief 兵力删除消息
?? ?@param id 兵力ID
?? ?*/
?? ?void slotForceResigned(unsigned int id);

?? ?/*
?? ?@brief 兵力选中消息
?? ?@param id 兵力ID
?? ?@param selected true表示选中,false表示未选中
?? ?*/
?? ?void slotForceSelected(unsigned int id, bool selected);

?? ?/*
?? ?@brief 新产生标绘
?? ?@param id 标绘ID
?? ?*/
?? ?void slotGraphicsAdded(unsigned int id);

?? ?/*
?? ?@brief 标绘删除
?? ?@param id 标绘ID
?? ?*/
?? ?void slotGraphicsRemoved(unsigned int id);

?? ?/*
?? ?@brief 标绘选中消息
?? ?@param id 标绘ID
?? ?@param selected true表示选中,false表示未选中
?? ?*/
?? ?void slotGraphicsSelected(unsigned int id, bool selected);

private:
?? ?Ui::MapTestClass ui;

?? ?CEngine* _engine;
?? ?QTimer _timer;

?? ?hlLinker::EntityPtrType _pentity;

?? ?hlgis::IMapView* _pmapview;
};
?

//mymap.cpp

#include "mymap.h"

#include <QDebug>
#include <QHBoxLayout>
#include <QMenu>
#include <QGraphicsItem>

#include "Math/Geography.h"
#include "Math/Constant.h"
#include "Math/RandomGenerator.h"

#include "Thread/Thread.h"

#include "Utility/JsonFile.h"

#include "KernelDefine.inl"

#include "hlMap/iforcemgr.h"
#include "hlMap/igraphicsmgr.h"
#include "hlLinker/IEntity.h"

#include "hlLinker/SimLinker.h"

#include "ui_mywgt.h"

#define TEST_FORCE_NUM?? ??? ??? ?0

class CEngine : public Common::CThread
{
public:
?? ?CEngine(hlgis::IForceManager* forcemgr) : _forcemgr(forcemgr) {
?? ??? ?Start();
?? ?}
?? ?virtual ~CEngine() {
?? ??? ?Stop();
?? ?}

protected:
?? ?virtual void run() {
?? ??? ?{// 性能测试
?? ??? ??? ?for (int i = 0; i < TEST_FORCE_NUM; ++i)
?? ??? ??? ?{
?? ??? ??? ??? ?hlLinker::EntityPtrType e = _forcemgr->getForce(i + 1);
?? ??? ??? ??? ?if (e == NULL) return;

?? ??? ??? ??? ?double lon = e->getLon();
?? ??? ??? ??? ?double lat = e->getLat();
?? ??? ??? ??? ?double heading = e->getHeading();

?? ??? ??? ??? ?double dlon, dlat;
?? ??? ??? ??? ?Common::dr_to_ll(lon, lat, heading, 100, dlon, dlat);
?? ??? ??? ??? ?e->setLon(dlon);
?? ??? ??? ??? ?e->setLat(dlat);
?? ??? ??? ?}
?? ??? ?}

?? ??? ?_tsleep(1);
?? ?}

private:
?? ?hlgis::IForceManager* _forcemgr;
};

class MyWgt : public QWidget
{
public:
?? ?MyWgt(QWidget* parent) : QWidget(parent){
?? ??? ?_ui.setupUi(this);
?? ?}

private:
?? ?Ui_mywgt _ui;

};


mymap::mymap(QWidget* parent)
?? ?: QDialog(parent)
{
?? ?ui.setupUi(this);

?? ?connect(&_timer, SIGNAL(timeout()), this, SLOT(slotTimeout()));

?? ?//创建地图控件

?? ?_pmapview = hlgis::create_mapview();
?? ?//加载地图
?? ?if (_pmapview->load())
?? ?{
?? ??? ?//将地图加入窗口
?? ??? ?QHBoxLayout* layout = new QHBoxLayout(ui.widget);
?? ??? ?layout->addWidget(_pmapview->widget());
?? ??? ?QObject* mapview_bus = _pmapview->msgBus();

?? ??? ?MyWgt* mywgt = new MyWgt(_pmapview->widget());


?? ??? ?bool bConnect = true;
?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigMouseClicked(int, double, double)),
?? ??? ??? ?this, SLOT(slotMouseClicked(int, double, double)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigMouseDoubleClicked(int, double, double)),
?? ??? ??? ?this, SLOT(slotMouseDoubleClicked(int, double, double)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigMouseMoved(double, double)),
?? ??? ??? ?this, SLOT(slotMouseMoved(double, double)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigForceJoined(unsigned int)),
?? ??? ??? ?this, SLOT(slotForceJoined(unsigned int)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigForceResigned(unsigned int)),
?? ??? ??? ?this, SLOT(slotForceResigned(unsigned int)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigForceSelected(unsigned int, bool)),
?? ??? ??? ?this, SLOT(slotForceSelected(unsigned int, bool)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigGraphicsAdded(unsigned int)),
?? ??? ??? ?this, SLOT(slotGraphicsAdded(unsigned int)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigGraphicsRemoved(unsigned int)),
?? ??? ??? ?this, SLOT(slotGraphicsRemoved(unsigned int)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?bConnect &= (bool)connect(mapview_bus, SIGNAL(sigGraphicsSelected(unsigned int, bool)),
?? ??? ??? ?this, SLOT(slotGraphicsSelected(unsigned int, bool)));
?? ??? ?Q_ASSERT(bConnect);

?? ??? ?//_pmapview->setOwner("zhangsan");
?? ??? ?_pmapview->setSyncGroup("mygroup");

?? ??? ?_pmapview->setEventWindowVisible(false);

?? ??? ?QAction* myact = _pmapview->menu()->addAction(u8"我的地图菜单");


?? ??? ?double lon = 120, lat = 22;

?? ??? ?double x, y;
?? ??? ?hlgis::map_to_screen(lon, lat, x, y);

?? ??? ?double lon1, lat1;
?? ??? ?hlgis::screen_to_map(x, y, lon1, lat1);

?? ??? ?double centerlon = 114.2081;
?? ??? ?double centerlat = 30.7838;

?? ??? ?_pmapview->centerOn(centerlon, centerlat);

?? ??? ?hlgis::IForceManager* forcemgr = _pmapview->forceMgr();

?? ??? ?// 隐藏标识为myeffect下面的原始包络
?? ??? ?_pmapview->setLayerVisible("effects/myeffect/self/origin", false);

?? ??? ?{
?? ??? ??? ?_pentity = NULL;
?? ??? ??? ?const char* props1 = R"({
?? ??? ??? ??? ??? ?"id":123,?? ??? ??? ?
?? ??? ??? ??? ??? ?"name":"001_1",?? ?
?? ??? ??? ??? ??? ?"entity":123,?? ?
?? ??? ??? ??? ??? ?"iff":3,?? ?
?? ??? ??? ??? ??? ?"lon":115.0,
?? ??? ??? ??? ??? ?"lat":21.0,
?? ??? ??? ??? ??? ?"alt":100.0,
?? ??? ??? ??? ??? ?"heading":0.0,
?? ??? ??? ??? ??? ?"roll":0.0,
?? ??? ??? ??? ??? ?"pitch":0.0})";
?? ??? ??? ?hlLinker::EntityPtrType e = forcemgr->addForce(props1);


?? ??? ??? ?{
?? ??? ??? ??? ?unsigned int effectid = e->addEffect(1);

?? ??? ??? ??? ?const char* estr = R"({
?? ??? ??? ??? ??? ??? ?"symbol":"myeffect",
?? ??? ??? ??? ??? ??? ?"fuse":true,
?? ??? ??? ??? ??? ??? ?"framecolor":"#FF0000",
?? ??? ??? ??? ??? ??? ?"fillcolor":"#1F00FF00",
?? ??? ??? ??? ??? ??? ?"points":[["30-60#200000",3000]]})";
?? ??? ??? ??? ?e->setEffect(effectid, estr);
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?{
?? ??? ??? ??? ?const char* props = R"({
?? ??? ??? ??? ??? ?"id":456,?? ??? ??? ?
?? ??? ??? ??? ??? ?"name":"001_2",?? ?
?? ??? ??? ??? ??? ?"entity":123,?? ?
?? ??? ??? ??? ??? ?"iff":3,?? ?
?? ??? ??? ??? ??? ?"lon":116.0,
?? ??? ??? ??? ??? ?"lat":22.0,
?? ??? ??? ??? ??? ?"alt":100.0,
?? ??? ??? ??? ??? ?"heading":0.0,
?? ??? ??? ??? ??? ?"roll":0.0,
?? ??? ??? ??? ??? ?"pitch":0.0})";
?? ??? ??? ??? ?e = forcemgr->addForce(props);
?? ??? ??? ?}

?? ??? ??? ?{
?? ??? ??? ??? ?unsigned int effectid = e->addEffect(2);

?? ??? ??? ??? ?const char* estr2 = u8R"({
?? ??? ??? ??? ??? ??? ?"type":2,
?? ??? ??? ??? ??? ??? ?"label":"我的特效线",
?? ??? ??? ??? ??? ??? ?"color":"#9F00FF00",
?? ??? ??? ??? ??? ??? ?"width" : 10,
?? ??? ??? ??? ??? ??? ?"src" : "123",
?? ??? ??? ??? ??? ??? ?"dest" : "456"})";

?? ??? ??? ??? ?e->setEffect(effectid, estr2);
?? ??? ??? ?}

?? ??? ??? ?{
?? ??? ??? ??? ?unsigned int effectid = e->addEffect(1);
?? ??? ?/*?? ??? ?const char* estr = R"({
?? ??? ??? ??? ??? ??? ?"symbol":"myeffect",
?? ??? ??? ??? ??? ??? ?"fuse":true,
?? ??? ??? ??? ??? ??? ?"framecolor":"#FF0000",
?? ??? ??? ??? ??? ??? ?"fillcolor":"#1F00FF00",
?? ??? ??? ??? ??? ??? ?"points":[[500000,500000,500000,500000,500000,300000,300000,300000,300000,300000,300000,300000,300000,300000,300000,300000,300000,350000,350000,350000,350000,350000,350000,350000,3000]]})";*/

?? ??? ??? ??? ?const char* estr = R"({
?? ??? ??? ??? ??? ??? ?"symbol":"myeffect",
?? ??? ??? ??? ??? ??? ?"fuse":true,
?? ??? ??? ??? ??? ??? ?"framecolor":"#FF0000",
?? ??? ??? ??? ??? ??? ?"fillcolor":"#1F00FF00",
?? ??? ??? ??? ??? ??? ?"points":[[300000,300000,300000,300000,"30-60#500000","80-160#100000",3000]]})";
?? ??? ??? ??? ?e->setEffect(effectid, estr);
?? ??? ??? ?}
?? ??? ??? ?
?? ??? ??? ?_pentity = e;
?? ??? ??? ?int nTest = 0;


?? ??? ?}

?? ??? ?{
?? ??? ??? ?Common::CUniformDistributionRandom lonrand, latrand, headingrand;
?? ??? ??? ?lonrand.Input(-180, 180);
?? ??? ??? ?latrand.Input(-90, 90);

?? ??? ??? ?//lonrand.Input(90, 130);
?? ??? ??? ?//latrand.Input(0, 60);
?? ??? ??? ?headingrand.Input(0, 360);
?? ??? ??? ?for (int i = 0; i < TEST_FORCE_NUM; ++i)
?? ??? ??? ?{
?? ??? ??? ??? ?double lon = lonrand.Generate();
?? ??? ??? ??? ?double lat = latrand.Generate();

?? ??? ??? ??? ?double heading = headingrand.Generate();

?? ??? ??? ??? ?char props[1024];
?? ??? ??? ??? ?_tsprintf(props, R"({
?? ??? ??? ??? ??? ??? ??? ?"id":%d,?? ??? ?
?? ??? ??? ??? ??? ??? ??? ?"name":"J-10_1",?? ??? ?
?? ??? ??? ??? ??? ??? ??? ?"entity":460,?? ?
?? ??? ??? ??? ??? ??? ??? ?"iff":%d,?? ?
?? ??? ??? ??? ??? ??? ??? ?"lon":%f,
?? ??? ??? ??? ??? ??? ??? ?"lat":%f,
?? ??? ??? ??? ??? ??? ??? ?"alt":0,
?? ??? ??? ??? ??? ??? ??? ?"heading":%f,
?? ??? ??? ??? ??? ??? ??? ?"roll":0.0,
?? ??? ??? ??? ??? ??? ??? ?"pitch":0.0})", i + 1, i % 7 + 1, lon, lat, heading);
?? ??? ??? ??? ?hlLinker::EntityPtrType e = forcemgr->addForce(props);

?? ?
?? ??? ??? ?}

?? ??? ??? ?_engine = new CEngine(forcemgr);
?? ??? ?}

?? ??? ?hlgis::IGraphicsManager* graphicsmgr = _pmapview->graphicsMgr();
?? ??? ?{
?? ??? ??? ?const char* props = R"({
?? ??? ??? ??? ??? ?"id":555,?? ??? ??? ?
?? ??? ??? ??? ??? ?"name" : "area_1",?? ?
?? ??? ??? ??? ??? ?"type" : "area",?? ??? ?
?? ??? ??? ??? ??? ?"shape" : {
?? ??? ??? ??? ??? ??? ?"framecolor": "#FF0000",
?? ??? ??? ??? ??? ??? ?"fillcolor" : ""
?? ??? ??? ??? ??? ?},
?? ??? ??? ??? ??? ?"anchors" : [
?? ??? ??? ??? ??? ??? ?{"lon": 120, "lat" : 22},
?? ??? ??? ??? ??? ??? ?{"lon": 120, "lat" : 21},
?? ??? ??? ??? ??? ??? ?{"lon": 119, "lat" : 21},
?? ??? ??? ??? ??? ??? ?{"lon": 119, "lat" : 22}
?? ??? ??? ??? ??? ?]})";

?? ??? ??? ?//hlLinker::GraphicsPtrType ovl = graphicsmgr->addGraphics(props);

?? ??? ??? ?int nTest = 0;
?? ??? ?}

?? ??? ?{
?? ??? ??? ?//const char* props = R"({
?? ??? ??? ?//?? ??? ?"id":0,?? ??? ??? ?
?? ??? ??? ?//?? ??? ?"type" : "route",?? ??? ?
?? ??? ??? ?//?? ??? ?"shape" : {
?? ??? ??? ?//?? ??? ??? ?"framecolor": "#FF0000",
?? ??? ??? ?//?? ??? ??? ?"fillcolor" : ""
?? ??? ??? ?//?? ??? ?},
?? ??? ??? ?//?? ??? ?"anchors" : [
?? ??? ??? ?//?? ??? ??? ?{"lon": 115.0, "lat" : 21.0},
?? ??? ??? ?//?? ??? ??? ?{"lon": 120, "lat" : 22}
?? ??? ??? ?//?? ??? ?]})";

?? ??? ??? ?const char* props = R"({
?? ??? ??? ??? ??? ?"type" : "route",?? ??? ?
?? ??? ??? ??? ??? ?"shape" : {
?? ??? ??? ??? ??? ??? ?"framecolor": "#FF0000",
?? ??? ??? ??? ??? ??? ?"fillcolor" : ""
?? ??? ??? ??? ??? ?}})";

?? ??? ??? ?//hlLinker::GraphicsPtrType ovl = graphicsmgr->addGraphics(props);
?? ??? ??? ?//ovl->addAnchor(115, 21, 0);
?? ??? ??? ?//ovl->addAnchor(120, 22, 0);


?? ??? ??? ?int nTest = 0;
?? ??? ?}

?? ??? ?//_timer.start(1000);
?? ?}
}

mymap::~mymap()
{

}

void mymap::slotTimeout()
{
?? ?{// 单例功能测试
?? ??? ?if (_pentity == NULL) return;

?? ??? ?double lon = _pentity->getLon();
?? ??? ?double lat = _pentity->getLat();
?? ??? ?double heading = _pentity->getHeading();

?? ??? ?double dlon, dlat;
?? ??? ?Common::dr_to_ll(lon, lat, heading, 1000, dlon, dlat);
?? ??? ?_pentity->setLon(dlon);
?? ??? ?_pentity->setLat(dlat);
?? ?}
}

void mymap::slotMouseClicked(int btn, double lon, double lat)
{

}

void mymap::slotMouseDoubleClicked(int btn, double lon, double lat)
{

}

void mymap::slotMouseMoved(double lon, double lat)
{

}

void mymap::slotForceJoined(unsigned int id)
{

}

void mymap::slotForceResigned(unsigned int id)
{

}

void mymap::slotForceSelected(unsigned int id, bool selected)
{

}

void mymap::slotGraphicsAdded(unsigned int id)
{

}

void mymap::slotGraphicsRemoved(unsigned int id)
{

}

void mymap::slotGraphicsSelected(unsigned int id, bool selected)
{

}
?

//main.cpp

#include "mymap.h"
#include <QtWidgets/QApplication>

#include <QTextCodec>

#include "Log/TxtLog.h"
#include "Utility/OSHelper.h"

#include "Qt/qtCommon.h"


int main(int argc, char* argv[])
{
?? ?SYSTEM_LOG_RENAME("map-test");

?? ?//支持中文格式
?? ?QTextCodec::setCodecForLocale(QTextCodec::codecForName("system"));

?? ?// 加入插件路径

?? ?std::string home = Common::env_value("DBDK_HOME");
?? ?if (home.empty())home = ".";

?? ?QString lib_path = UDQ_L8(home.c_str()) + ("/plugins");
?? ?QGuiApplication::addLibraryPath(lib_path);
?? ?QGuiApplication::addLibraryPath(lib_path + "/platforms");
?? ?QGuiApplication::addLibraryPath(lib_path + "/sqldrivers");
?? ?QGuiApplication::addLibraryPath(lib_path + "/imageformats");
?? ?QApplication a(argc, argv);

?? ?mymap w;
?? ?w.showMaximized();
?? ?return a.exec();
}
?

//运行后的界面如下:

文章来源:https://blog.csdn.net/xiaoouh/article/details/135431492
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。