前言
之前开发的地图组件依赖浏览器控件,在嵌入式板子或低配置国产硬件上性能受限。经过改造,实现了不依赖浏览器控件和 QML 的纯 QWidget 绘制方案,利用 Qt 的 Painter 灵活可靠特性,显著提升性能和控制度。
该方案主要解决两个难点:一是地理坐标到像素绘制坐标的映射;二是快速加载瓦片的多线程绘制机制。采用分层绘制,支持面积自适应(如多边形)和固定大小(如标注点)的图形,拖动时自动同步位置。
效果图
代码示例
#include "frmoverlay.h"
#include "ui_frmoverlay.h"
#include "qthelper.h"
#include "maphelper.h"
#include "overlayhelper.h"
#include "magicfish.h"
frmOverlay::frmOverlay(QWidget *parent) : QWidget(parent), ui(new Ui::frmOverlay) {
ui->setupUi(this);
this->initForm();
this->initConfig();
this->loadMap();
}
frmOverlay::~frmOverlay() {
delete ui;
}
void {
lng = ;
lat = ;
(ui->mapWidget, ((qreal, qreal)), , ((qreal, qreal)));
(ui->cboxFlag->(), ((QString)), , ((QString)));
}
{
MapHelper::(ui->cboxTileSource, AppConfig::OverlaySource);
(ui->cboxTileSource, (()), , (()));
(ui->cboxTileSource, (()), , (()));
MapHelper::(ui->cboxTileType, AppConfig::OverlayType);
(ui->cboxTileType, (()), , (()));
(ui->cboxTileType, (()), , (()));
ui->cboxOffline->(AppConfig::OverlayOffline);
(ui->cboxOffline, (()), , (()));
(ui->cboxOffline, (()), , (()));
ui->cboxCache->(AppConfig::OverlayCache);
(ui->cboxCache, (()), , (()));
(ui->cboxCache, (()), , (()));
}
{
AppConfig::OverlaySource = ui->cboxTileSource->(ui->cboxTileSource->()).();
AppConfig::OverlayType = ui->cboxTileType->(ui->cboxTileType->()).();
AppConfig::OverlayOffline = ui->cboxOffline->();
AppConfig::OverlayCache = ui->cboxCache->();
AppConfig::();
}
{
index = ;
flag = ;
ui->cboxFlag->();
ui->cboxFlag->()->(flag);
}
{
->();
tileSource = ui->cboxTileSource->(ui->cboxTileSource->()).();
ui->mapWidget->((tileSource));
tileType = ui->cboxTileType->(ui->cboxTileType->()).();
ui->mapWidget->((tileType));
QString offlinePath = TileHelper::((tileSource));
ui->mapWidget->(ui->cboxOffline->() == );
ui->mapWidget->(offlinePath);
QString cachePath = (ui->cboxCache->() == ? QtHelper::() + : );
ui->mapWidget->(cachePath);
}
{
->lng = lng;
->lat = lat;
ui->txtLng->(QString::(lng, , ));
ui->txtLat->(QString::(lat, , ));
}
{
index++;
QString text = ().(index);
QString item = ().(index - );
ui->cboxFlag->(item);
ui->cboxFlag->()->(text);
}
{
(!arg()) {
->flag = arg1;
}
}
{
QString file = ;
OverlayBase *marker = ui->mapWidget->(flag, lng, lat, file);
OverlayHelper::(marker, , , , , );
->();
}
{
ui->mapWidget->(flag);
}
{
QString file = ;
OverlayBase *marker = ui->mapWidget->(flag, lng, lat, file);
OverlayHelper::(marker, , , , , , );
}
{
ui->mapWidget->(flag, , , (), (), );
}
{
ui->mapWidget->(flag, lng, lat, , , );
->();
}
{
ui->mapWidget->(flag, lng, lat, , , , );
}
{
;
QList<QPointF> points = MapHelper::(point, , );
ui->mapWidget->(flag, points, , );
->();
}
{
ui->mapWidget->(flag, (), (, , , ), );
}
{
;
QList<QPointF> points = MapHelper::(point, , );
ui->mapWidget->(flag, points, , , (, , , ));
->();
}
{
ui->mapWidget->(flag, (), Qt::yellow, , (, , , ));
}
{
;
QList<QPointF> points = MapHelper::(point, , );
ui->mapWidget->(flag, points.(), points.(), , , (, , , ));
->();
}
{
ui->mapWidget->(flag, (), (), Qt::red, , (, , , ));
}
{
distance = MapHelper::(ui->mapWidget->());
qreal radius = MapHelper::(distance);
ui->mapWidget->(flag, lng, lat, radius, , , (, , , ));
->();
}
{
qreal radius = MapHelper::();
ui->mapWidget->(flag, lng, lat, radius, );
}
{
MagicFish *widget = (ui->mapWidget);
ui->mapWidget->(flag, lng, lat, widget);
->();
}
{
ui->mapWidget->(flag, lng, lat);
}
{
();
QString fileName = QtHelper::(, QtHelper::() + );
(!fileName.()) {
;
(file.(QFile::ReadOnly | QFile::Text)) {
QString points = file.();
ui->mapWidget->(, points, , , (, , , ));
}
}
}
{
OverlayHelper::redraw = ;
();
ui->mapWidget->();
ui->mapWidget->(, );
( i = ; i < ; ++i) {
qreal lng = QtHelper::(, );
qreal lat = QtHelper::(, );
qreal r = QtHelper::(, );
QColor color = QtHelper::();
QColor bgColor = color;
bgColor.();
ui->mapWidget->(().(i), lng, lat, r, color, , bgColor);
}
OverlayHelper::redraw = ;
}
{
ui->mapWidget->(flag);
}
{
ui->mapWidget->();
}
{
->();
ui->mapWidget->();
}
{
(ui->btnVisibleOverlay->() == ) {
ui->mapWidget->(, );
ui->btnVisibleOverlay->();
} {
ui->mapWidget->(, );
ui->btnVisibleOverlay->();
}
}


