【问题标题】:QML Map: Large amount of displayed itemsQML Map:大量显示项目
【发布时间】:2017-10-14 21:10:17
【问题描述】:

我在 QML Location 模块提供的地图上显示大量 MapItem 时遇到性能问题。我已经在这里问过这个问题(https://forum.qt.io/topic/79229/large-amount-of-qml-mapitems),但是没有人可以帮助我,所以我想在这里尝试一次。我也发现了这个问题(How to use the QML/QtLocation module for displaying a large amount of offline data on a map?),但是在添加另一个依赖项之前,我想看看我的代码是否可以改进,以便 QML 可以在没有任何帮助的情况下处理这种情况。

我目前正在尝试将大量项目绘制到 QML 地图上(30,000 - 120,000 点)。这些项目应根据 QSlider 的位置进行更新。性能从大约 1,000 个项目开始急剧下降,当我使用 30,000 个项目时,QML Map 需要几分钟才能将所有数据可视化并再次响应。我有一台绝对能够完成这项任务的机器,所以我认为问题在于 QML。我正在使用 Qt 5.8。

有什么方法可以提高这种性能,还是不能使用 QML-map 一次绘制这么多 MapItem?我尝试了带有图像的 MapCircles、Polylines、Polygons 和 MapQuickItems,但对我来说,性能问题似乎只是由添加这么多 MapItems 引起的,因为我看不出这些类型之间的处理时间有显着差异。

我在可视化的地图上有更多数据,不应在每次移动 QSlider 时刷新。尽管我只是尝试清除所有 MapItems 并添加新的 MapItems 以进行性能测试,但这并没有提高性能。

我的代码(有点抽象)如下所示:

///-------------- Widget.cpp-----------------///
void ProcessInput(int qslider_pos) {
      QVariantList lat_vec;
      QVariantList lon_vec;

      // Fill vectors with lateral and longitudinal positions
      // ...

      // Clean current points on map and draw new ones
      SendToQmlFuncRemovePoints();
      SendToQmlFuncAddPoints(lat_vec, lon_vec);
}

void QmlConnector::SendToQmlFuncRemovePoints()
{
    QVariant returnedValue;
    QMetaObject::invokeMethod(QmlMapSingleton::instance()->GetRoot(), "remove_points",
        Q_RETURN_ARG(QVariant, returnedValue));
}

void QmlConnector::SendToQmlFuncAddPoints(QVariantList input_one, QVariantList input_two)
{
    QVariant returnedValue;
    QMetaObject::invokeMethod(QmlMapSingleton::instance()->GetRoot(), "add_points",
        Q_RETURN_ARG(QVariant, returnedValue),
        Q_ARG(QVariant, QVariant::fromValue(input_one)), Q_ARG(QVariant, QVariant::fromValue(input_two)));
}

.

///-------------- Map.qml -----------------///

Map {
     anchors.fill: parent
     property variant points: ({})
     property int pointCounter: 0

     Plugin
     {
        id: osmplugin
        name: "osm"
        PluginParameter { name: "osm.mapping.highdpi_tiles"; value: true }
     }

     Component.onCompleted: {
         points = new Array();
     }
    id: map
    plugin: osmplugin

    //Javascript functions
    function add_points(array_lat, array_lon) {
        var myArray = new Array()
        var component = Qt.createComponent("mapcircle.qml");
        for (var i=0; i<array_lat.length; i++)
        {
            var object = component.createObject(map, { "center": QtPositioning.coordinate(array_lat[i], array_lon[i]})
            map.addMapItem(object)
            myArray.push(object)
        }
        map.points = myArray
    }

    function remove_points() {
        var count = map.points.length
        for (var i = 0; i<count; i++){
            map.removeMapItem(map.points[i])
            map.points[i].destroy()
        }
        map.points = []
    }
}

.

///-------------- mapcircle.qml -----------------///
import QtQuick 2.0
import QtLocation 5.6

MapCircle {
      radius: 1
      border.width: 0
      color: 'green'
}

【问题讨论】:

  • 也许MapItemView 与数据模型有帮助?
  • 不,模型中的许多项目也会出现同样的问题。尝试使用这种方法为从 C++ 导出到 QML 作为模型的坐标列表中的每个条目绘制一个小十字,并连接到 MapItemViewMapQuickItem 包装 Canvas 作为视图委托。在模型中有几十个坐标的开发过程中工作得很好,但是当我们用集合中 20,000 个奇数坐标的真实真实案例进行 beta 测试时,显示它们咀嚼 500 MB 的 RAM 并将 UI 接地停下来。

标签: c++ performance qt dictionary qml


【解决方案1】:

Qt 表示性能会随着添加到地图的元素数量而降低。您是否需要同时在地图上显示所有点,如果不需要,您可以玩转可见性。
如果您有多个多边形,您不能使用QQuickPaintedItem 在 C++ 中绘制点并将其包装到MapQuickItem 中吗?但也有一些限制,不能显示大图。
如果您需要所有点,也许您可​​以根据地图缩放级别拥有不同的点,并减少在小缩放级别下添加到地图的点数,正如其他组所建议的那样......

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多