震惊都6202年了/地图控件居然支持Qt4这个老古董/支持国产军工低配Qt环境

一、前言说明

为什么还要支持Qt4,很多人不理解,因为这个地图控件的诞生初期的需求,有一个需求就是为了满足国产化低配电脑上运行的要求,旧时代遗留的产物,包括有些古董项目,当时用的就是Qt4,而且无法升级到Qt5及以上,必须保证原有的代码能够正常在Qt4编译运行,而又需要增加新的地图相关的功能,甚至一些旧的环境尤其是军工企业,上面只能跑很老的linux系统,当时也只有Qt4支持上面运行,系统是固定的肯定不能换了,那就只能让代码适配Qt版本,这是没有办法的办法,所以本地图控件的设计初期,也就没有去采用c++11的标准,还是按照c99的标准写的。

说到这里又有些人要抬杠了,用这么古老的语法,会不会性能很低下啊,以前我也是这么认为的,后面实际大量使用下来,发现是错误的,新标准只是增加了新特性以及一些语法糖,是为了方便写,或者语法检查,并不能带来多少性能提升,或者说根本就没有性能提升,比如Qt5引入的信号槽的新写法,只是为了编译期间做参数检查,更严格更标准,性能提升完全没有,还有什么lm表达式啥的,纯粹是语法糖。用c99标准写的代码,在新的编译器编译,依旧溜得起飞。

二、效果图

Snipaste_2026-08-26_13-16-42

Snipaste_2026-08-26_13-18-37

三、相关代码

#include "mapwidget.h"
#include "maphelper.h"
#include "layermap.h"
#include "overlayhelper.h"
#include "overlaycluster.h"
#include "drawhelper.h"

MapWidget::MapWidget(QWidget *parent) : MapControl(QSize(100, 30), parent)
{
    tileSource = TileSource_None;
    tileType = TileType_Street;
    offline = false;
    offlinePath = ".";

    //转发鼠标事件信号到绘图处理/信号来自基类/槽为本类实现
    connect(this, SIGNAL(mouseEvent(int, QMouseEvent *, PointWorldCoord, PointWorldCoord)), this, SLOT(mouseEvent(int, QMouseEvent *, PointWorldCoord, PointWorldCoord)));

    //添加瓦片图层
    TileHelper::loadTile(this, tileSource, tileType, offline, offlinePath);

    //添加图形图层
    overlayLayer = new LayerOverlay("overlayLayer");
    overlayLayer->setTileSize(this->tileSize());
    overlayLayer->setEpsgType(this->epsgType());
    overlayLayer->setMouseEventsEnabled(true);
    this->addLayer(overlayLayer);
}

void MapWidget::mouseEvent(int mouse_type, QMouseEvent *mouse_event, PointWorldCoord press_coord, PointWorldCoord current_coord)
{
    DrawHelper::doMouseEvent(this, mouse_type, mouse_event, press_coord, current_coord);
}

void MapWidget::load()
{
    emit mapLoading();
    QMutexLocker locker(&mutex);
    bool gcj02 = (tileSource == TileSource_GaoDe || tileSource == TileSource_TengXun || tileSource == TileSource_Google || (tileSource == TileSource_Bing && tileType == TileType_Street));
    this->setGcj02Base(gcj02, false);
    this->setGcj02Tile(gcj02, false);
    TileHelper::changeTile(this, tileSource, tileType, offline, offlinePath);
}

QString MapWidget::getFlag() const
{
    return this->objectName().split('_').last();
}

void MapWidget::setFlag(const QString &flag)
{
    MapControl::setFlag(flag);
    this->setObjectName(QString("MapWidget_%1").arg(flag));
}

QPointF MapWidget::getCenter() const
{
    return this->mapFocusPoint().rawPoint();
}

void MapWidget::setCenter(const QPointF &point, bool redraw)
{
    this->setMapFocusPoint(point, redraw);
}

void MapWidget::setCenter(const QString &point, bool redraw)
{
    this->setCenter(MapHelper::textToPoint(point), redraw);
}

QRectF MapWidget::getRect() const
{
    return this->viewportRect().rawRect();
}

void MapWidget::setRect(const QRectF &rect)
{
    this->setAutoView(rect);
}

LayerOverlay *MapWidget::getOverlayLayer()
{
    return this->overlayLayer;
}

void MapWidget::setLayerVisible(bool visible)
{
    if (overlayLayer) {
        overlayLayer->setVisible(visible);
    }
}

QList<OverlayBase *> MapWidget::getOverlays()
{
    return overlayLayer->getOverlays();
}

OverlayBase *MapWidget::getOverlay(const QString &flag)
{
    return overlayLayer->getOverlay(flag);
}

QList<OverlayBase *> MapWidget::getOverlays(OverlayType type)
{
    return overlayLayer->getOverlays(type);
}

void MapWidget::addOverlay(OverlayBase *overlay, bool redraw)
{
    if (overlayLayer && overlay) {
        overlayLayer->addOverlay(overlay, redraw);
        if (receivers(SIGNAL(overlayChanged(int, OverlayBase *))) > 0) {
            emit overlayChanged(ChangedType_Add, overlay);
        }
    }
}

void MapWidget::deleteOverlay(OverlayBase *overlay, bool redraw)
{
    if (overlayLayer && overlay) {
        overlayLayer->removeOverlay(overlay, redraw);
        if (receivers(SIGNAL(overlayChanged(int, OverlayBase *))) > 0) {
            emit overlayChanged(ChangedType_Delete, overlay);
        }
    }
}

void MapWidget::clearOverlay(bool redraw)
{
    if (overlayLayer) {
        overlayLayer->clearOverlays(redraw);
        if (receivers(SIGNAL(overlayChanged(int, OverlayBase *))) > 0) {
            emit overlayChanged(ChangedType_Clear, NULL);
        }
    }
}

void MapWidget::setTileSource(TileSource tileSource)
{
    this->tileSource = tileSource;
}

void MapWidget::setTileType(TileType tileType)
{
    this->tileType = tileType;
}

void MapWidget::setOffline(bool offline)
{
    this->offline = offline;
}

void MapWidget::setOfflinePath(const QString &offlinePath)
{
    this->offlinePath = offlinePath;
}

void MapWidget::setCachePath(const QString &cachePath)
{
    this->enableCache(cachePath, offline);
}

void MapWidget::savePixmap(const QString &fileName, bool full, const QVector<QPointF> &points)
{
    MapHelper::savePixmap(this, fileName, full, points);
}

void MapWidget::setAutoView(const QRectF &rect)
{
    MapHelper::setAutoView(this, rect);
}

void MapWidget::setAutoView(const QString &points)
{
    MapHelper::setAutoView(this, MapHelper::pointsToRect(points));
}

void MapWidget::setAutoView(const QVector<QPointF> &points)
{
    MapHelper::setAutoView(this, MapHelper::pointsToRect(points));
}

OverlayBase *MapWidget::addShape(const QString &flag, const QPointF &point, const QColor &color, int width, int style, bool redraw)
{
    return OverlayHelper::addShape(this, flag, point, color, width, style, redraw);
}

void MapWidget::updateShape(const QString &flag, const QPointF &point, const QColor &color, int width, int style, bool redraw)
{
    OverlayHelper::updateShape(this, flag, point, color, width, style, redraw);
}

QPointF MapWidget::getShapeCoord(const QString &flag)
{
    return OverlayHelper::getShapeCoord(this, flag);
}

OverlayBase *MapWidget::addLabel(const QString &flag, const QPointF &point, const QColor &color, const QString &text, int align, int size, int rotate, bool redraw)
{
    return OverlayHelper::addLabel(this, flag, point, color, text, align, size, rotate, redraw);
}

void MapWidget::updateLabel(const QString &flag, const QPointF &point, const QColor &color, const QString &text, int align, int size, int rotate, bool redraw)
{
    OverlayHelper::updateLabel(this, flag, point, color, text, align, size, rotate, redraw);
}

QPointF MapWidget::getLabelPara(const QString &flag, QString *text, int *rotate)
{
    return OverlayHelper::getLabelPara(this, flag, text, rotate);
}

OverlayBase *MapWidget::addMarker(const QString &flag, const QPointF &point, const QString &image, const QPixmap &pixmap, int rotate, int align, bool redraw)
{
    return OverlayHelper::addMarker(this, flag, point, image, pixmap, rotate, align, redraw);
}

void MapWidget::updateMarker(const QString &flag, const QPointF &point, const QString &image, const QPixmap &pixmap, int rotate, int align, bool redraw)
{
    OverlayHelper::updateMarker(this, flag, point, image, pixmap, rotate, align, redraw);
}

void MapWidget::updateMarkerSize(const QString &flag, const QSize &size, bool keepAspectRatio, bool redraw)
{
    OverlayHelper::updateMarkerSize(this, flag, size, keepAspectRatio, redraw);
}

QPointF MapWidget::getMarkerPara(const QString &flag, QPixmap *image, int *rotate, int *align)
{
    return OverlayHelper::getMarkerPara(this, flag, image, rotate, align);
}

OverlayBase *MapWidget::addMarkerCircle(const QString &flag, const QPointF &point, const QString &text, const QSize &size, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, const QColor &textColor, bool redraw)
{
    return OverlayHelper::addMarkerCircle(this, flag, point, text, size, color, width, style, bgColor, bgStyle, textColor, redraw);
}

void MapWidget::updateMarkerCircle(const QString &flag, const QPointF &point, const QString &text, const QSize &size, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, const QColor &textColor, bool redraw)
{
    OverlayHelper::updateMarkerCircle(this, flag, point, text, size, color, width, style, bgColor, bgStyle, textColor, redraw);
}

QPointF MapWidget::getMarkerCirclePara(const QString &flag, QString *text)
{
    return OverlayHelper::getMarkerCirclePara(this, flag, text);
}

OverlayBase *MapWidget::addPolyline(const QString &flag, const QStringList &points, const QColor &color, int width, int style, bool redraw)
{
    return OverlayHelper::addPolyline(this, flag, MapHelper::pointsToCoords(points), color, width, style, redraw);
}

OverlayBase *MapWidget::addPolyline(const QString &flag, const QVector<QPointF> &points, const QColor &color, int width, int style, bool redraw)
{
    return OverlayHelper::addPolyline(this, flag, MapHelper::pointsToCoords(points), color, width, style, redraw);
}

void MapWidget::updatePolyline(const QString &flag, const QColor &color, int width, int style, bool redraw)
{
    OverlayHelper::updatePolyline(this, flag, color, width, style, redraw);
}

QVector<QPointF> MapWidget::getPolylinePoints(const QString &flag)
{
    return OverlayHelper::getPolylinePoints(this, flag);
}

void MapWidget::addPolylinePoint(const QString &flag, const QPointF &point, bool redraw)
{
    OverlayHelper::addPolylinePoint(this, flag, point, redraw);
}

void MapWidget::setPolylinePoints(const QString &flag, const QVector<QPointF> &points, bool redraw)
{
    OverlayHelper::setPolylinePoints(this, flag, MapHelper::pointsToCoords(points), redraw);
}

OverlayBase *MapWidget::addPolygon(const QString &flag, const QStringList &points, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    return OverlayHelper::addPolygon(this, flag, MapHelper::pointsToCoords(points), color, width, style, bgColor, bgStyle, redraw);
}

void MapWidget::addPolygon(const QString &flag, const QVector<QPointF> &points, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    OverlayHelper::addPolygon(this, flag, MapHelper::pointsToCoords(points), color, width, style, bgColor, bgStyle, redraw);
}

void MapWidget::updatePolygon(const QString &flag, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    OverlayHelper::updatePolygon(this, flag, color, width, style, bgColor, bgStyle, redraw);
}

QVector<QPointF> MapWidget::getPolygonPoints(const QString &flag)
{
    return OverlayHelper::getPolygonPoints(this, flag);
}

void MapWidget::addPolygonPoint(const QString &flag, const QPointF &point, bool redraw)
{
    OverlayHelper::addPolygonPoint(this, flag, point, redraw);
}

void MapWidget::setPolygonPoints(const QString &flag, const QVector<QPointF> &points, bool redraw)
{
    OverlayHelper::setPolygonPoints(this, flag, MapHelper::pointsToCoords(points), redraw);
}

void MapWidget::addBoundary(const QString &flag, const QString &points, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    OverlayHelper::addBoundary(this, flag, points, color, width, style, bgColor, bgStyle, redraw);
}

void MapWidget::addBoundary(const QString &flag, const QList<QPolygonF> &plys, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    OverlayHelper::addBoundary(this, flag, plys, color, width, style, bgColor, bgStyle, redraw);
}

OverlayBase *MapWidget::addRectangle(const QString &flag, const QRectF &rect, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    return this->addRectangle(flag, rect.topLeft(), rect.bottomRight(), color, width, style, bgColor, bgStyle, redraw);
}

OverlayBase *MapWidget::addRectangle(const QString &flag, const QPointF &topLeft, const QPointF &bottomRight, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    return OverlayHelper::addRectangle(this, flag, topLeft, bottomRight, color, width, style, bgColor, bgStyle, redraw);
}

void MapWidget::updateRectangle(const QString &flag, const QPointF &topLeft, const QPointF &bottomRight, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    OverlayHelper::updateRectangle(this, flag, topLeft, bottomRight, color, width, style, bgColor, bgStyle, redraw);
}

QRectF MapWidget::getRectangleRect(const QString &flag)
{
    return OverlayHelper::getRectangleRect(this, flag);
}

OverlayBase *MapWidget::addCircle(const QString &flag, const QPointF &point, qreal radius, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    return OverlayHelper::addCircle(this, flag, point, radius, color, width, style, bgColor, bgStyle, redraw);
}

void MapWidget::updateCircle(const QString &flag, const QPointF &point, qreal radius, const QColor &color, int width, int style, const QColor &bgColor, int bgStyle, bool redraw)
{
    OverlayHelper::updateCircle(this, flag, point, radius, color, width, style, bgColor, bgStyle, redraw);
}

QRectF MapWidget::getCirclePara(const QString &flag, qreal *lng, qreal *lat, qreal *radius)
{
    return OverlayHelper::getCirclePara(this, flag, lng, lat, radius);
}

OverlayBase *MapWidget::addRadar(const QString &flag, const QPointF &point, qreal radius, const QColor &color, int width, int alpha, bool redraw)
{
    return OverlayHelper::addRadar(this, flag, point, radius, color, width, alpha, redraw);
}

void MapWidget::updateRadar(const QString &flag, const QPointF &point, qreal radius, qreal sweepAngle, qreal headingAngle, const QColor &color, int width, int alpha, bool redraw)
{
    OverlayHelper::updateRadar(this, flag, point, radius, sweepAngle, headingAngle, color, width, alpha, redraw);
}

QRectF MapWidget::getRadarPara(const QString &flag, qreal *lng, qreal *lat, qreal *radius, qreal *sweepAngle, qreal *headingAngle)
{
    return OverlayHelper::getRadarPara(this, flag, lng, lat, radius, sweepAngle, headingAngle);
}

OverlayBase *MapWidget::addCluster(const QString &flag, const QVector<QPointF> &points, bool redraw)
{
    return OverlayHelper::addCluster(this, flag, MapHelper::pointsToClusterPoints(points), redraw);
}

OverlayBase *MapWidget::addCluster(const QString &flag, const QVector<ClusterPoint> &points, bool redraw)
{
    return OverlayHelper::addCluster(this, flag, points, redraw);
}

void MapWidget::updateCluster(const QString &flag, int distance, int radius, const QColor &color, int textSize, const QColor &textColor, int pointRadius, const QColor &pointColor, bool redraw)
{
    OverlayHelper::updateCluster(this, flag, distance, radius, color, textSize, textColor, pointRadius, pointColor, redraw);
}

QVector<QPointF> MapWidget::getClusterPoints(const QString &flag)
{
    return OverlayHelper::getClusterPoints(this, flag);
}

void MapWidget::addClusterPoint(const QString &flag, const ClusterPoint &point, bool redraw)
{
    OverlayHelper::addClusterPoint(this, flag, point, redraw);
}

void MapWidget::setClusterPoints(const QString &flag, const QVector<QPointF> &points, bool redraw)
{
    OverlayHelper::setClusterPoints(this, flag, MapHelper::pointsToClusterPoints(points), redraw);
}

void MapWidget::setClusterPoints(const QString &flag, const QVector<ClusterPoint> &points, bool redraw)
{
    OverlayHelper::setClusterPoints(this, flag, points, redraw);
}

OverlayBase *MapWidget::addHeatmap(const QString &flag, const QVector<QPointF> &points, bool redraw)
{
    return OverlayHelper::addHeatmap(this, flag, MapHelper::pointsToHeatPoints(points), redraw);
}

OverlayBase *MapWidget::addHeatmap(const QString &flag, const QVector<HeatPoint> &points, bool redraw)
{
    return OverlayHelper::addHeatmap(this, flag, points, redraw);
}

void MapWidget::updateHeatmap(const QString &flag, int radius, int intensity, int opacity, bool redraw)
{
    OverlayHelper::updateHeatmap(this, flag, radius, intensity, opacity, redraw);
}

QVector<QPointF> MapWidget::getHeatmapPoints(const QString &flag)
{
    return OverlayHelper::getHeatmapPoints(this, flag);
}

void MapWidget::addHeatmapPoint(const QString &flag, const HeatPoint &point, bool redraw)
{
    OverlayHelper::addHeatmapPoint(this, flag, point, redraw);
}

void MapWidget::setHeatmapPoints(const QString &flag, const QVector<QPointF> &points, bool redraw)
{
    OverlayHelper::setHeatmapPoints(this, flag, MapHelper::pointsToHeatPoints(points), redraw);
}

void MapWidget::setHeatmapPoints(const QString &flag, const QVector<HeatPoint> &points, bool redraw)
{
    OverlayHelper::setHeatmapPoints(this, flag, points, redraw);
}

void MapWidget::addWidget(const QString &flag, const QPointF &point, QWidget *form, bool redraw)
{
    OverlayHelper::addWidget(this, flag, point, form, redraw);
}

void MapWidget::updateWidget(const QString &flag, const QPointF &point, bool redraw)
{
    OverlayHelper::updateWidget(this, flag, point, redraw);
}

QWidget *MapWidget::getWidget(const QString &flag)
{
    return OverlayHelper::getWidget(this, flag);
}

void MapWidget::deleteOverlay(const QString &flag, bool redraw)
{
    OverlayHelper::deleteOverlay(this, flag, redraw);
}

void MapWidget::deleteGroup(const QString &group, bool redraw)
{
    OverlayHelper::deleteGroup(this, group, redraw);
}

void MapWidget::setOverlayZIndex(const QString &flag, int zindex)
{
    OverlayHelper::setOverlayZIndex(this, flag, zindex);
}

void MapWidget::setOverlayZIndex(OverlayBase *overlay, int zindex, bool redraw)
{
    overlayLayer->setOverlayZIndex(overlay, zindex, redraw);
}

void MapWidget::setOverlayVisible(const QString &flag, bool visible)
{
    OverlayHelper::setOverlayVisible(this, flag, visible);
}

void MapWidget::setOverlayVisible(OverlayBase *overlay, bool visible, bool redraw)
{
    overlay->setVisible(visible, redraw);
}

void MapWidget::setOverlayEdit(const QString &flag, bool edit)
{
    OverlayHelper::setOverlayEdit(this, flag, edit);
}

void MapWidget::setOverlayEdit(OverlayBase *overlay, bool edit, bool redraw)
{
    overlay->setEdit(edit, redraw);
}

四、相关地址

  1. 国内站点:https://gitee.com/feiyangqingyun
  2. 国际站点:https://github.com/feiyangqingyun
  3. 个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
  4. 文件地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取码:o05q 文件名:bin_mapwidget.zip

五、功能特点

  1. 支持各种地图源,包括天地图、高德地图、腾讯地图、谷歌地图、微软地图、电子海图、ArcGis、OpenStreet、360地图等。
  2. 同时支持WGS-84地球坐标系和GCJ-02火星坐标系,如果是天地图、谷歌地图,自动应用WGS-84坐标系,如果是高德地图、腾讯地图,自动应用GCJ-02坐标系。也可以主动设置在WGS-84坐标系加载高德地图,内部会自动处理坐标偏移。
  3. 同时支持默卡托投影和经纬度投影,比如天地图的地图源可以是默卡托投影或者经纬度投影。
  4. 每一种地图源都支持在线和离线两种场景需求,可以自定义在线瓦片地址格式和离线瓦片地址格式。
  5. 多线程下载和加载瓦片图片文件,多线程绘制,自动缓存瓦片文件。
  6. 在线模式下,可以开启是否缓存文件,指定缓存路径,将下载的瓦片文件存放到本地,默认优先从缓存文件查找,如果存在缓存文件则加载缓存文件,不存在则联网下载。
  7. 可以任意拖曳地图,鼠标滚轮放大和缩小地图,以鼠标所在位置作为缩放中心点,提供缩放控件手动单击进行操作,支持鼠标左键双击放大和右键双击缩小。
  8. 多图层机制,支持多个瓦片叠加图层和图形绘制图层,全部采用双缓冲技术,所有的图形和瓦片全部绘制到一个图片文件上,最终再将图片文件绘制到地图控件。不可见区域的图层包括覆盖物不会触发绘制,最大程度降低CPU占用。
  9. 动态图层机制,瓦片图层和图形图层分离,图形图层不更新的情况下,动态更新底图瓦片图层,任意切换更新多个瓦片图层。无需重新加载整个地图。
  10. 预加载机制,默认绘制的图层大小以当前区域往四周放大一倍,这样在鼠标拖动和缩放的时候,不会看到明显的加载过程,因为已经提前预加载好了,体验友好。
  11. 内置了多种图形覆盖物,包括坐标点、纯文本、标注点、折线条、多边形、矩形、圆形、雷达、点聚合、热力图等,可以设置边框颜色粗细、填充颜色和透明度等众多参数。
  12. 标注点支持旋转角度和提示文本,其中提示文本可以设置在标注点的相对位置,标注点图片支持gif动图,可以动态切换静态图和动图。
  13. 标注点和提示文本可以设置相对位置,位置包括左侧、右侧、上侧、下侧、中间、左上角、右上角、左下角、右下角。标注点默认按照底部居中对齐,一般圆形图标可以设置中心点对齐。
  14. 标注点提示文本可设置背景颜色,透明度、颜色边框和粗细,支持换行和多行文字。
  15. 所有的图形可以动态更新前景色、颜色粗细、背景颜色、颜色透明度等。
  16. 支持删除单个图形、删除一种类型的图形、删除所有图形、隐藏单个或者所有图形等。
  17. 支持动态绘制各种图形,开启后直接在地图上鼠标按下绘制,鼠标右键结束绘制,非常方便快捷。
  18. 在对应图形区域鼠标按下,发出图形单击信号,精准识别单击区域,比如折线以鼠标在折线条上作为判断依据,多边形区域以鼠标在整个多边形区域内为准,而不是以矩形区域,包括圆形也是以圆形内部为准。
  19. 可以动态启动禁用比例尺、十字线、缩放控件、地图拖曳、键盘操作、滚轮缩放、双击缩放、鼠标追踪等特性。
  20. 可以任意指定经纬度区域进行瓦片拼接保存成图片文件,也可以直接对整个可视区域或者缓存区域的地图图片文件保存。支持任意多边形轮廓保存成图片,比如某个行政区的瓦片保存。
  21. 图形可以动态设置zindex层叠顺序,值越大,越显示在前面,内部维护着一个zindex表,默认按照添加的先后顺序增加,后面添加的显示在前面,主动设置后,按照设置的zindex来绘制。
  22. 支持将QWidget对象作为覆盖物添加到地图控件中,跟随地图移动位置,极大提高灵活性,比如可以将自定义控件直接作为地图控件的子对象加入进去。
  23. 支持测距和测面积,动态绘制多边形区域,实时动态调整位置和点坐标自动重新计算,可以关闭单个测距测面的图形。
  24. 内置MarkerMove轨迹移动类,支持历史轨迹数据回放和实时轨迹移动,可设置图标、轨迹线的颜色和粗细、移动速度、移动间隔、平滑移动、自动中心等,支持多条轨迹线条同时移动。
  25. 内置MarkerLine航迹规划类,支持动态添加航迹点,显示对应箭头,可以动态拖曳调整航迹点的位置,选中点高亮显示。
  26. 大量使用按需绘制机制,包括内部提供合理的默认值来触发绘制,也可以手动传入参数指定是否需要立即绘制,比如删除了某个覆盖物,有些频繁的操作可以不指定立即绘制,等操作完成后再统一一起绘制,效率更高。
  27. 默认开启内存瓦片机制,所有加载过的瓦片文件都存储在内存中,下次再次绘制直接从内存取出来绘制,既不需要从联网获取,也不需要从缓存文件获取,直接内存取出来绘制,响应迅速效率最高体验最佳。
  28. 支持批量添加覆盖物,比如几万个标注点和圆形,都是瞬间完成绘制,相比web网页的方式,性能提升百倍以上。
  29. 支持街道图、卫星图、混合图、路网图等各种图层,可以任意叠加N个图层,甚至杂交不同地图厂家的瓦片文件。
  30. 内置缩放动画效果,在缩放的时候先截取上一个地图画面作为缩放动画基准图片,逐步过渡到下一个层级。
  31. 内置电子放大机制,瓦片图片不存在的时候,优先获取该区域上一图层的瓦片,按照规则裁切图片缩放填充,支持无极缩放。在线和离线模式都支持电子放大,在线情况下主动获取上一级的瓦片,离线情况下主动本地文件查找。
  32. 电子放大除了支持找上级瓦片,还支持找下级瓦片,比如地图缩小的时候,先找4张下级瓦片按照规则合并到对应区域瓦片,防止缩小的时候看到空白区域。
  33. 支持双指捏合缩放,在移动端或者任何可以触摸的地方,双指拉大放大地图,双指聚拢缩小地图,平滑动画过渡缩放。
  34. 提供离线地图下载模块,多线程高速并发下载,可框选指定区域下载瓦片,可指定任意级别下载。
  35. 提供高程海拔显示模块,离线识别高程海拔数据,传入经纬度即可,无需引入任何第三方模块。
  36. 纯QWidget绘制,非qml也非web,不依赖qml或者浏览器控件,没有任何第三方库依赖,支持极低性能的嵌入式环境。
  37. 原创轻量级,核心代码5000行,整体代码10000行,架构漂亮,注释详细,拓展方便,容易学习,适合各种初学者和进阶者,方便二次开发。
  38. 支持任意Qt版本、任意系统、任意编译器,包括嵌入式linux和各种国产电脑环境。
  39. 全部原创自研,古法编程,不含任何AI代码,持续迭代更新,商业级别、品质保证。
posted @ 2026-08-26 13:40  飞扬青云  阅读(62)  评论(0)    收藏  举报