Модель QT QML из C ++ - проблема с отображением карты - PullRequest
0 голосов
/ 19 апреля 2020

Я создаю приложение для создания и редактирования файлов gpx на карте. Я хочу иметь возможность визуализировать линию и набор маркеров из одной модели.

Каждая точка GPX имеет координату, высоту и время. Я стремлюсь создать модель, которую можно использовать для отображения ее на карте, а также для отображения профиля высот.

Я изменил ответ на этот вопрос QT QmlMap PolyLine не обновляется должным образом, когда базовая модель изменяет , чтобы основать мою модель на структуре точек GPX.

main. 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

Я думаю, что где-то допустил ошибку c, так как я могу нажать на карту и нарисуйте ломаную линию, но MapCircles не отображают . Я вижу ошибку: -

Unable to assign [undefined] to QGeoCoordinate

Когда я впервые нажимаю на карту.

Я неправильно понял, как работают модели / роли в Qt QML?

1 Ответ

0 голосов
/ 20 апреля 2020

Я отследил это до проблемы сборки. У меня были некоторые дополнительные пути в моем файле .pro, и я включал некоторые библиотеки, которые не использовались (пространственный), и удалил их, чтобы полностью устранить проблему.

Я оставлю вопрос, так как он может быть полезен всем, кто хочет сделать что-то подобное.

...