0

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

每个 GPX 点都有一个坐标、高度和时间。我的目标是创建一个模型,该模型可用于在地图上显示它并显示高程剖面。

为了使我的模型基于 GPX 点的结构,我已经修改了这个问题的答案QT QmlMap PolyLine not updated proper when based model changes 。

主程序

#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();
}

主窗口.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)
            }
        }

    }

}

地图标记.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

我认为我在某处犯了一个非常基本的错误,因为我可以单击地图并绘制一条折线,但MapCircles 没有呈现。我看到了错误:-

Unable to assign [undefined] to QGeoCoordinate

当我第一次点击地图时。

我是否误解了 Qt QML 中模型/角色的工作方式?

4

1 回答 1

0

我已将此归结为构建问题。我的 .pro 文件中有一些额外的路径,并且包括一些未使用的库(spatialite),删除这些完全解决了问题。

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

于 2020-04-20T17:21:48.617 回答