从C++中提取QT QML模型--地图渲染的问题

问题描述 投票:0回答:1

我正在建立一个应用程序来创建和编辑地图上的gpx文件。我希望能够从一个模型中呈现一条线和一组标记。

每个GPX点都有一个坐标,海拔和时间。我的目的是创建一个模型,可以用来在地图上显示它,也可以显示高程曲线。

我已经修改了这个问题的答案 当底层模型发生变化时,QT QmlMap PolyLine不能正确更新。 为了使我的模型基于GPX点的结构。

主窗口.c

#include "mainwindow.h"
#include <QApplication>
#include <QQmlApplicationEngine>
#include "mapmarker.h"
#include <QQmlContext>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    //Added for model registration
    QQmlApplicationEngine engine;


    qmlRegisterType<MarkerModel>("MarkerModel", 1, 0, "MarkerModel");

    engine.load(QUrl(QStringLiteral("qrc:/mainWindow.qml")));

    return app.exec();
}

mainWindow.qml

import QtQuick 2.3
import QtQuick.Window 2.3
import QtLocation 5.9
import MarkerModel 1.0

ApplicationWindow {
    id: appWindow
    width: 1512
    height: 1512
    visible: true
    x:100
    y:100


    MarkerModel{
        id: markerModel
    }


    Plugin {
          id: mapPlugin
          name: "osm"
      }

    Map {
        id: mapView
        anchors.fill: parent
        plugin: mapPlugin

        MapItemView {
            model: markerModel
            delegate: routeMarkers
        }

        MapPolyline {
            line.width: 5
            path: markerModel.path
        }

        Component {
            id: routeMarkers
            MapCircle {
                radius: 10
                center: positionRole
            }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: {
                var coord = parent.toCoordinate(Qt.point(mouse.x,mouse.y))
                markerModel.addMarker(coord)
            }
        }

    }

}

mapmarker.h

#ifndef MAPMARKER_H
#define MAPMARKER_H


#include <QAbstractListModel>
#include <QGeoCoordinate>
#include <QDebug>
#include <QDate>

struct gpxCoordinate {
    QGeoCoordinate latlon;
    float ele;
    QDateTime time;
};

class MarkerModel : public QAbstractListModel {
    Q_OBJECT
    Q_PROPERTY(QVariantList path READ path NOTIFY pathChanged)

public:
    enum MarkerRoles{positionRole = Qt::UserRole, pathRole};

    MarkerModel(QObject *parent=nullptr): QAbstractListModel(parent)
    {
        connect(this, &QAbstractListModel::rowsInserted, this, &MarkerModel::pathChanged);
        connect(this, &QAbstractListModel::rowsRemoved, this, &MarkerModel::pathChanged);
        connect(this, &QAbstractListModel::dataChanged, this, &MarkerModel::pathChanged);
        connect(this, &QAbstractListModel::modelReset, this, &MarkerModel::pathChanged);
        connect(this, &QAbstractListModel::rowsMoved, this, &MarkerModel::pathChanged);
    }

    Q_INVOKABLE void addMarker(const QGeoCoordinate &coordinate, float elevation = 0, QDateTime dateTime = QDateTime::currentDateTime()) {

        gpxCoordinate item;
        item.latlon = coordinate;
        item.ele = elevation;
        item.time = dateTime;

        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_coordinates.append(item);
        endInsertRows();
    }



    int rowCount(const QModelIndex &parent = QModelIndex()) const override {
        if(parent.isValid()) return 0;
        return m_coordinates.count();
    }

    bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()) override {
        if(row + count > m_coordinates.count() || row < 0)
            return false;
        beginRemoveRows(parent, row, row+count-1);
        for(int i = 0; i < count; ++i)
            m_coordinates.removeAt(row + i);
        endRemoveRows();
        return true;
    }

    bool removeRow(int row, const QModelIndex &parent = QModelIndex()) {
        return removeRows(row, 1, parent);
    }

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override {

        if (index.row() < 0 || index.row() >= m_coordinates.count())
            return QVariant();
        if(role == Qt::DisplayRole)
            return QVariant::fromValue(index.row());
        else if(role == MarkerModel::positionRole){
            return QVariant::fromValue(m_coordinates[index.row()].latlon);

        }
        return QVariant();
    }

    QHash<int, QByteArray> roleNames() const override{
        QHash<int, QByteArray> roles;
        roles[positionRole] = "positionRole";
        return roles;
    }

    QVariantList path() const{
        QVariantList path;
        for(const gpxCoordinate & coord: m_coordinates){
            path << QVariant::fromValue(coord.latlon);

        }
        return path;
    }
signals:
    void pathChanged();

private:
    QVector<gpxCoordinate> m_coordinates;
};
#endif // MARKERMODEL_H

我想我犯了一个非常基本的错误,因为我可以在地图上点击并画出一条多段线,但是在地图上的 地图圆不显示. 我看到的错误是:-

Unable to assign [undefined] to QGeoCoordinate

当我第一次点击地图的时候。

我是否误解了Qt QML中modelsroles的工作原理?

c++ qt qml qtlocation
1个回答
0
投票

我已经追踪到这是一个构建问题。我在我的.pro文件中有一些额外的路径,并且包含了一些没有被使用的库(spatialite),移除这些库就完全解决了这个问题。

我将把这个问题留下,因为它可能对想要做类似事情的人有用。

热门问题
推荐问题
最新问题