QtLocation添加MapCircle至地图无显示问题求助及代码排查
QtLocation地图添加MapCircle不显示问题
我有一个基于QtQuick Widget的Qt应用,用QtLocation和QtPositioning展示地图。尝试通过C++传入的坐标数组,在组件加载时向地图添加MapCircle,日志显示圆圈已成功添加,但地图上始终看不到。
第一种实现方案(QML直接创建)
QML代码
import QtQuick 2.15 import QtQuick.Window 2.15 import QtQuick.Controls 2.15 import QtLocation 5.15 import QtPositioning 5.15 import QtQuick.Layouts 1.15 Rectangle { id: rec function addCircle(latitude, longitude, radius) { map.addCircle(latitude, longitude, radius) } width: 800 height: 600 Plugin { id: mapPlugin name: "osm" PluginParameter { name: "osm.mapping.custom.host" value: "https://tile.openstreetmap.org/" } } Map { id: map property MapCircle circle anchors.fill: parent plugin: mapPlugin center: QtPositioning.coordinate(70, -175.5) zoomLevel: 6 Component.onCompleted: { for (var i = 0; i < myArray.length; i += 2) { console.log(QtPositioning.coordinate(myArray[i], myArray[i + 1])); var circle = Qt.createQmlObject('import QtPositioning 5.6; import QtLocation 5.6; MapCircle { }', map); circle.center = QtPositioning.coordinate(myArray[i], myArray[i + 1]); circle.radius = 5000; circle.color = 'red'; circle.z = 1000; console.log(circle.center, circle.radius); map.addMapItem(circle); console.log("Circle added:", circle); } } } }
C++主文件代码
#include "mainwindow.h" #include "GSN_model.h" #include "for_SQLite_db.h" #include "mapcontroller.h" #include <QApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include <QVariantList> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; // 创建坐标列表 QVariantList myArray; myArray << 70.3 << -175.4 << 69.3 << -175.4 << 71 << -175.4 ; // 向QML上下文注册列表 QQmlApplicationEngine engine; engine.rootContext()->setContextProperty("myArray", myArray); const QUrl url(QStringLiteral("qrc:/map.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &a, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); w.show(); return a.exec(); }
日志输出
qml: 70° 18' 0.0" N, 175° 24' 0.0" W qml: 70° 18' 0.0" N, 175° 24' 0.0" W 5000 qml: Circle added: QDeclarativeCircleMapItem(0x243b9fe9c80) qml: 69° 18' 0.0" N, 175° 24' 0.0" W qml: 69° 18' 0.0" N, 175° 24' 0.0" W 5000 qml: Circle added: QDeclarativeCircleMapItem(0x243b9fea100) qml: 71° 0' 0.0" N, 175° 24' 0.0" W qml: 71° 0' 0.0" N, 175° 24' 0.0" W 5000 qml: Circle added: QDeclarativeCircleMapItem(0x243b9feb000)
第二种实现方案(C++调用QML函数)
main.cpp代码
QQmlApplicationEngine engine; MapController mapController; engine.rootContext()->setContextProperty("mapController", &mapController); const QUrl url(QStringLiteral("qrc:/map.qml")); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &a, [url, &mapController](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); mapController.setRootObject(obj); mapController.drawCircle(70.6, -175.6, 10000.0); mapController.drawCircle(70.3, -175.4, 5000000); }, Qt::QueuedConnection); engine.load(url);
mapcontroller.h代码
#ifndef MAPCONTROLLER_H #define MAPCONTROLLER_H #include <QObject> #include <QGeoCoordinate> class MapController : public QObject { Q_OBJECT public: explicit MapController(QObject *parent = nullptr); Q_INVOKABLE void drawCircle(double latitude, double longitude, double radius); void setRootObject(QObject *rootObject); private: QObject *m_rootObject; }; #endif // MAPCONTROLLER_H
mapcontroller.cpp代码
#include "mapcontroller.h" #include <QQmlProperty> #include <QDebug> MapController::MapController(QObject *parent) : QObject(parent), m_rootObject(nullptr) {} void MapController::setRootObject(QObject *rootObject) { m_rootObject = rootObject; } void MapController::drawCircle(double latitude, double longitude, double radius) { if (!m_rootObject) { qWarning() << "Root object is not set!"; return; } QVariant returnedValue; QVariant lat = latitude; QVariant lon = longitude; QVariant rad = radius; QMetaObject::invokeMethod(m_rootObject, "addCircle", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, lat), Q_ARG(QVariant, lon), Q_ARG(QVariant, rad)); }
map.qml代码(片段)
... Item { id: circlesLayer width: parent.width height: parent.height function addCircle(latitude, longitude, radius) { console.log(QtPositioning.coordinate(latitude, longitude), radius); var circle = Qt.createQmlObject('import QtPositioning 5.6; import QtLocation 5.6; MapCircle { }', map); circle.center = QtPositioning.coordinate(latitude, longitude); circle.radius = radius; circle.color = 'red'; circle.z = 1000; console.log(circle.center, circle.radius); map.addMapItem(circle); console.log("Circle added:", circle); } }
两种方案均显示圆圈已添加,但地图上无法看到。请问问题出在哪里?如何在QtLocation中正确添加显示MapCircle?
解决方案
以下是几个关键问题点及修复方式:
1. 调整MapCircle的半径大小
MapCircle的radius单位是米,你第一个方案中设置的5000(5公里)在缩放级别6的地图上尺寸极小,几乎无法识别。先尝试放大半径,比如设置为50000(50公里),观察是否显示。
2. 改用Component创建MapCircle(更可靠)
使用Qt.createQmlObject动态创建对象可能存在隐式问题,改用预定义Component的方式更稳定:
Map { id: map ... // 预定义圆圈组件 Component { id: circleComponent MapCircle { color: "#FF0000" // 不透明红色 border.width: 2 border.color: "black" z: 1000 } } Component.onCompleted: { for (var i = 0; i < myArray.length; i += 2) { var circle = circleComponent.createObject(map); circle.center = QtPositioning.coordinate(myArray[i], myArray[i + 1]); circle.radius = 50000; // 放大半径测试 map.addMapItem(circle); // 可选:自动定位到圆圈位置 // map.centerOn(circle.center); } } }
3. 确保地图初始化完成后再添加圆圈
Component.onCompleted触发时,地图可能尚未完全加载瓦片或初始化完成,导致地图项无法渲染。可以用Timer延迟添加:
Map { id: map ... Timer { interval: 500 // 延迟500毫秒 running: true repeat: false onTriggered: { // 在这里执行添加圆圈的逻辑 } } }
4. 统一QML导入版本
你的QML文件导入的是QtLocation 5.15,但创建MapCircle时用的是5.6版本,虽然向下兼容,但保持版本一致可以避免潜在问题:
var circle = Qt.createQmlObject('import QtPositioning 5.15; import QtLocation 5.15; MapCircle { }', map);
5. 验证圆圈可见性样式
为圆圈添加边框、使用不透明颜色,确保不会和地图背景融合:
MapCircle { color: "#FF0000" border.width: 2 border.color: "#000000" z: 1000 }
内容的提问来源于stack exchange,提问作者Артём Михайлов
相关产品推荐
相关产品推荐

