服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - Qt编写地图之实现跨平台功能

Qt编写地图之实现跨平台功能

2022-09-23 15:48feiyangqingyun C/C++

这篇文章主要介绍了如何利用Qt编写地图应用时实现跨平台功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

一、前言

跨平台着实花了不少的精力,为了从Qt4.7兼容到Qt6.2及后续版本,头发掉了不少,仅有的几根毛所剩无几,哎,可能这就是程序员的命,本人写Qt程序这么多年,比较喜欢支持多个Qt版本,尤其是钟情于支持任意Qt版本+任意系统+任意编译器,这句话说起来简单其实实现起来就不容易了,首先你得有个很多版本的测试环境,起码十几个Qt环境要的吧,四五种操作系统要的吧,还要安装各种VS版本免不了的,毕竟win上除了默认的mingw编译器还有很多人用的是msvc编译器,这么一大堆环境折腾下来,没有个1T硬盘是不够的,而且官网发布Qt版本的速度相当快,最慢半年肯定来一个版本,又得测试了,每次发布一个大的版本,除了常用的windows以外,linux要测试吧,而且现在还多出来一些国产linux系统比如deepin new start UOS之类的,也要试试吧,哎呀好累。

二、功能特点

1 省市区域地图封装类功能特点

  1. 同时支持闪烁点图、迁徙图、区域地图、世界地图、仪表盘等。
  2. 可以设置标题、提示信息、背景颜色、文字颜色、线条颜色、区域颜色等各种颜色。
  3. 可设置城市的名称、值、经纬度 集合。
  4. 可设置地图的放大倍数、是否允许鼠标滚轮缩放。
  5. 内置世界地图、全国地图、省份地图、地区地图,可以精确到县,所有地图全部离线使用。
  6. 内置了各省市json数据文件转js文件功能,如有数据更新自行转换即可,支持单个文件转换和一键转换所有文件。
  7. 内置了从json文件或者js文件获取该区域的所有名称和经纬度信息集合的功能,可以通过该方法获取到信息用来显示。
  8. 依赖浏览器组件显示地图,提供的demo支持webkit/webengine/miniblink/ie 多种方式加载网页。
  9. 采用miniblink浏览器内核打通了Qt5.6及后续版本+mingw编译器缺少浏览器模块的遗憾,使得整个项目支持所有Qt版本,亲测4.7到6.2等任意版本。
  10. 闪烁点迁徙图等设置的点支持单独设置颜色。
  11. 提供接口直接获取点击的点相关信息,方便程序联动处理。
  12. 拓展性极强,可以依葫芦画瓢自行增加各种精美的echarts组件,做出牛逼的效果。
  13. 内置的仪表盘组件提供交互功能,demo演示中包含了对应的代码。
  14. 函数接口友好和统一,使用简单方便,就一个类。
  15. 支持任意Qt版本、任意系统、任意编译器。

2 百度地图封装类功能特点

  1. 同时支持在线地图和离线地图两种模式。
  2. 同时支持webkit内核、webengine内核、miniblink内核、IE内核。
  3. 支持设置多个标注点,信息包括名称、地址、经纬度。
  4. 可设置地图是否可单击、拖动、鼠标滚轮缩放。
  5. 可设置协议版本、秘钥、主题样式、中心坐标、中心城市、地理编码位置等。
  6. 可设置地图缩放比例和级别,缩略图、比例尺、路况信息等控件的可见。
  7. 支持地图交互,比如鼠标按下获取对应位置的经纬度。
  8. 支持查询路线,可设置起点位置、终点位置、路线模式、路线方式、路线方案(最少时间、最少换乘、最少步行、不乘地铁、最短距离、避开高速)。
  9. 可显示点线面工具,可直接在地图上划线、点、矩形、圆形等。
  10. 可设置行政区划,指定某个城市区域绘制图层,在线地图自动输出行政区划边界点集合到js文件给离线地图使用。
  11. 可静态或者动态添加多个覆盖物。支持点、折线、多边形、矩形、圆形、弧线、点聚合等。
  12. 提供函数接口处理经纬度解析成地址和地址解析成经纬度坐标。
  13. 提供的demo直接可以单独选点执行对应的处理比如路线查询。
  14. 可以拿到路线查询到的点坐标信息集合,比如用于机器人坐标导航等。
  15. 封装了丰富的函数比如删除指定点和所有点,删除指定覆盖物和所有覆盖物等。
  16. 标注点弹框信息可以自定义内容,标准html格式。
  17. 标注点单击事件可选 0-不处理 1-自己弹框 2-发送信号。
  18. 标注点可设置动画效果 0-不处理 1-跳动 2-坠落
  19. 标注点可设置本地图片文件等。
  20. 函数接口友好和统一,使用简单方便,就一个类。
  21. 支持js动态交互添加点、删除点、清空点、重置点,不需要刷新页面。
  22. 支持任意Qt版本、任意系统、任意编译器。

3 离线地图下载类功能特点

  1. 多线程同步下载多级别瓦片地图,不卡界面。
  2. 内置多个离线地图下载请求地址,自动随机选择一个发送请求。
  3. 下载地图类型同时支持街道图和卫星图。
  4. 自动计算可视区域或者行政区域的下载瓦片数量。
  5. 下载的级别可以自定义范围和选择。
  6. 每个瓦片下载完成都发送信号通知,参数包括下载用时。
  7. 可设置下载最大超时时间,超过了则丢弃跳到下一个下载任务。
  8. 实时显示下载进度,以及当前级别已经下载的瓦片数和总瓦片数。
  9. 下载过程中可以停止下载,下载完成自动统计总用时。
  10. 内置经纬度和屏幕坐标互相转换函数。
  11. 目前支持百度地图,其他地图比如谷歌地图、腾讯地图、高德地图可以定制。
  12. 函数接口友好和统一,使用简单方便,就一个类。
  13. 支持任意Qt版本、任意系统、任意编译器。

4 省市轮廓下载类功能特点

  1. 定时器排队下载省市轮廓图点坐标集合存储到JS文件。
  2. 支持一个行政区域多个不规则区域下载。
  3. 自动计算行政区域的下载轮廓数量。
  4. 可精确选择省份、市区、县城,也可直接输入行政区域的名称。
  5. 可以设置下载间隔、随时开始下载和停止下载。
  6. 提供编辑边界功能,可以直接在地图上编辑好不规则区域的点集合,然后获取边界点集合数据,这个可以用来自己绘制区域拿到数据,比如某个乡镇甚至某个小区的行政区域数据,很牛逼。

三、体验地址

体验地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg  提取码:uyes 文件名:bin_map.zip

国内站点:https://gitee.com/feiyangqingyun

国际站点:https://github.com/feiyangqingyun

四、效果图

Qt编写地图之实现跨平台功能

Qt编写地图之实现跨平台功能

Qt编写地图之实现跨平台功能

五、相关代码

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include "webview.h"
#include "qevent.h"
#include "qdatetime.h"
#include "qdebug.h"
 
#ifdef webkit
#include <QtWebKit>
#if (QT_VERSION >= QT_VERSION_CHECK(5,0,0))
#include <QtWebKitWidgets>
#endif
#elif webengine
#include <QtWebEngineWidgets>
#elif webie
#include <QAxWidget>
#elif webminiblink
#include "miniblink.h"
#endif
 
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
WebView::WebView(QWidget *parent) : QObject(parent)
{
    //初始化web控件配置信息
    WebView::initWebSetting();
    //初始化通用地图数据
    WebHelper::initMapData();
 
    //数据交互类
    webJsData = new WebJsData(this);
    connect(webJsData, SIGNAL(receiveDataFromJs(QString, QVariant)),
            this, SIGNAL(receiveDataFromJs(QString, QVariant)));
 
#ifdef webkit
    webView = new QWebView(parent);
#elif webengine
    webView = new QWebEngineView(parent);
    //设置对应的通信通道
    QWebChannel *channel = new QWebChannel(this);
    channel->registerObject("objName", webJsData);
    webView->page()->setWebChannel(channel);
#elif webie
    webView = new QAxWidget(parent);
    //注册浏览器控件
    webView->setControl("{8856F961-340A-11D0-A96B-00C04FD705A2}");
    //不显示警告信息
    webView->setProperty("DisplayAlerts", false);
    //不显示滚动条
    webView->setProperty("DisplayScrollBars", true);
#elif webminiblink
    webView = new miniblink(parent);
#endif
 
    //关联加载完成信号
#if (defined webkit) || (defined webengine)
    connect(webView->page(), SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
    connect(webView->page(), SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool)));
#elif webminiblink
    connect(webView, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished()));
    connect(webView, SIGNAL(loadFinished(bool)), this, SIGNAL(loadFinished(bool)));
    connect(webView, SIGNAL(receiveDataFromJs(QString, QVariant)),
            this, SIGNAL(receiveDataFromJs(QString, QVariant)));
#endif
 
    //设置没有右键菜单
#if (defined webkit) || (defined webengine) || (defined webie) || (defined webminiblink)
    webView->setContextMenuPolicy(Qt::NoContextMenu);
#endif
 
    //安装事件过滤器
#ifdef webminiblink
    webView->installEventFilter(this);
#endif
}
 
void WebView::initWebSetting()
{
    //全局配置只需要设置一次就行
    static bool isInit = false;
    if (!isInit) {
        isInit = true;
        QString webcore = "other";
#ifdef webkit
        webcore = "webkit";
        QWebSettings *webSetting = QWebSettings::globalSettings();
        webSetting->setAttribute(QWebSettings::JavascriptEnabled, true);
        webSetting->setAttribute(QWebSettings::PluginsEnabled, true);
        webSetting->setAttribute(QWebSettings::JavascriptCanOpenWindows, true);
#elif webengine
        webcore = "webengine";
        QWebEngineSettings *webSetting = QWebEngineProfile::defaultProfile()->settings();
        webSetting->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
        webSetting->setAttribute(QWebEngineSettings::PluginsEnabled, true);
        webSetting->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
#elif webie
        webcore = "ie";
#elif webminiblink
        webcore = "miniblink";
#endif
        qDebug() << TIMEMS << QString("init webview ok, core: %1").arg(webcore);
    }
}
 
bool WebView::eventFilter(QObject *watched, QEvent *event)
{
    //测试发现miniblink内核(其他内核正常),网页中的右键有消息会传给父类
    if (event->type() == QEvent::MouseButtonPress) {
        return true;
    }
    return QObject::eventFilter(watched, event);
}
 
void WebView::setLayout(QLayout *layout)
{
    //把控件加入到布局
#if (defined webkit) || (defined webengine) || (defined webie) || (defined webminiblink)
    layout->addWidget(webView);
#endif
}
 
void WebView::setVisible(bool visible)
{
#if (defined webkit) || (defined webengine) || (defined webie) || (defined webminiblink)
    webView->setVisible(visible);
#endif
}
 
void WebView::setBgColor(const QColor &color)
{
#if (defined webkit) || (defined webie)
    webView->setStyleSheet(QString("background:%1;").arg(color.name()));
#elif (defined webengine)
    webView->page()->setBackgroundColor(color);
#elif (defined webminiblink)
    webView->setBgColor(color);
#endif
}
 
void WebView::loadFinished()
{
#ifdef webkit
    webView->page()->mainFrame()->addToJavaScriptWindowObject("objName", webJsData);
#endif
}
 
void WebView::load(const QString &url, const QString &html, const QString &baseUrl)
{
    //如果存在网址则优先直接加载网址
    if (!url.isEmpty()) {
#if (defined webkit) || (defined webengine)
        webView->load(QUrl(url));
#elif webie
        webView->dynamicCall("Navigate(const QString&)", url);
#elif webminiblink
        webView->load(url);
#endif
    } else {
#if (defined webkit) || (defined webengine)
        webView->setHtml(html, QUrl(baseUrl));
#elif webminiblink
        webView->setHtml(html, baseUrl);
#endif
    }
}
 
void WebView::runJs(const QString &js)
{
    if (js.isEmpty()) {
        return;
    }
#ifdef webkit
    webView->page()->mainFrame()->evaluateJavaScript(js);
#elif webengine
    webView->page()->runJavaScript(js);
#elif webminiblink
    webView->runJs(js);
#endif
}

以上就是Qt编写地图之实现跨平台功能的详细内容,更多关于Qt地图 跨平台的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/feiyangqingyun/article/details/122905715

延伸 · 阅读

精彩推荐
  • C/C++C++递归线性阵列搜索数字的方法

    C++递归线性阵列搜索数字的方法

    这篇文章主要介绍了C++递归线性阵列搜索数字的方法,涉及C++递归及数组操作的相关技巧,需要的朋友可以参考下...

    小卒过河9242021-02-27
  • C/C++C++单例类模板详解

    C++单例类模板详解

    这篇文章主要介绍了C++单例类模板,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一...

    NQian4832021-07-25
  • C/C++C语言中初始、增加和删除进程信号的操作方法简介

    C语言中初始、增加和删除进程信号的操作方法简介

    这篇文章主要介绍了C语言中初始、增加和删除进程信号的操作方法简介,分别是sigemptyset函数、sigaddset函数和sigdelset函数的用法,需要的朋友可以参考下...

    C语言教程网10112021-03-11
  • C/C++C语言自定义类型全解析

    C语言自定义类型全解析

    在C语言中自定义类型主要有结构体类型、位段、枚举类型、联合体类型,自定义类型是面试常会碰到的内容,今天我们来详细了解一下它...

    诚挚的乔治4072022-09-16
  • C/C++利用C语言实现“百马百担”问题方法示例

    利用C语言实现“百马百担”问题方法示例

    百马百担是道经典的算法题,下面这篇文章主要给大家介绍了利用C语言实现“百马百担”问题的相关资料,文中通过示例代码介绍的非常详细,需要的朋友...

    诸葛玥10242021-06-11
  • C/C++C语言实现简易文本编辑器

    C语言实现简易文本编辑器

    这篇文章主要为大家详细介绍了C语言实现简易文本编辑器,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    l4557027074462021-11-04
  • C/C++详解C++编程中的静态成员与可变数据成员

    详解C++编程中的静态成员与可变数据成员

    这篇文章主要介绍了详解C++编程中的静态成员与可变数据成员,是C++入门学习中的基础知识,需要的朋友可以参考下...

    C++教程网10622021-03-23
  • C/C++头文件不宜定义变量的原因全面解析

    头文件不宜定义变量的原因全面解析

    以下是对头文件不宜定义变量的原因进行了详细的分析介绍,需要的朋友可以过来参考下...

    C语言教程网6582020-12-29