如何使用模型数据绘制mappolyline段

时间:2018-02-12 12:29:18

标签: qt location qml

我想绘制对应于代表机场跑道的线段的mappolylines,坐标由模型提供。 这是预期的结果: runway 主要提供机场和跑道的数据(在芝加哥实际上有18条跑道,这里只记录了2条跑道,以简化):

#include "airportsmodel.h"
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QDebug>


int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QApplication app(argc, argv);


    AirportsModel apModel;
    Airport KORD = Airport("KORD","CHICAGO O'HARE INTL",41.97732,-87.90801,680);
    KORD.addRunway(Runway("04L",42,41.98166,-87.91392,656));
    KORD.addRunway(Runway("22R",222,41.99754,-87.89637,648));

    apModel.addAirport(KORD);


    QQmlApplicationEngine engine;

    engine.addImportPath(QStringLiteral(":/imports"));
    engine.rootContext()->setContextProperty("airportsModel", &apModel);

    engine.load(QUrl(QLatin1String("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    QObject::connect(&engine, SIGNAL(quit()), qApp, SLOT(quit()));

    QObject *item = engine.rootObjects().first();
    Q_ASSERT(item);

    return app.exec();
}

这是机场类,它集成了类跑道。 mappolyline的有用坐标由rwPosition()返回。 NameRunway()和runwayQfu()将用于识别匹配的坐标对以绘制完整的跑道。

#ifndef AIRPORT_H
#define AIRPORT_H

#include <QGeoCoordinate>
#include <QString>


class Runway
{
public:
    Runway(QString name, int qfu, double latitude, double longitude, double elevation)
        : m_name(name), m_qfu(qfu)
    {
        m_position.setLatitude(latitude);
        m_position.setLongitude(longitude);
        m_position.setAltitude(elevation);
    }

    QString nameRunway() const {
        return m_name;
    }

    int runwayQfu() const {
        return m_qfu;
    }
    QGeoCoordinate rwPosition() const{
        return m_position;
    }

private:
    QGeoCoordinate m_position;
    QString m_name;
    int m_qfu;

};


class Airport
{
public:
    Airport(QString code, QString name, double latitude, double longitude, double elevation)
        :m_code(code), m_name(name) {

        m_position.setLatitude(latitude);
        m_position.setLongitude(longitude);
        m_position.setAltitude(elevation);
    }

    QGeoCoordinate apPosition() const{
        return m_position;
    }
    QString oaciCode() const {
        return m_code;
    }
    QString airportName() const {
        return m_name;
    }

    void addRunway(const Runway &runway){
        m_runwayList << runway;
    }
    const QList<Runway> &listRunways() const {
        return m_runwayList;
    }

     private:
        QGeoCoordinate m_position;
        QString m_code;
        QString m_name;
        QList<Runway> m_runwayList;
};

#endif // AIRPORT_H

我认为模型应该返回完整的机场跑道列表。在模型中,rwRole会照顾它。

#ifndef AIRPORTSMODEL_H
#define AIRPORTSMODEL_H

#include "airport.h"
#include <QAbstractListModel>
#include <QDebug>

class AirportsModel : public QAbstractListModel
{
    Q_OBJECT

public:
    AirportsModel(QObject *parent = Q_NULLPTR):QAbstractListModel(parent){
    }
    enum AirportsRoles{rwRole = Qt::UserRole + 1};

    void addAirport(const Airport &point){
        beginInsertRows(QModelIndex(), rowCount(), rowCount());
        m_apList << point;
        endInsertRows();
    }

    Q_INVOKABLE int rowCount(const QModelIndex & parent = QModelIndex()) const{
        Q_UNUSED(parent)
        return m_apList.count();
    }

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

        if (index.row() < 0 || index.row() >= m_apList.count())
            return QVariant();
        const Airport &point = m_apList[index.row()];
        if (role == rwRole){
            QList<QGeoCoordinate> rwCoord;
            const auto &runwayList = point.listRunways();
            foreach (const Runway &runwayLabeled, runwayList)
            {
                rwCoord << runwayLabeled.rwPosition();
                qDebug() << "runway : " << runwayLabeled.nameRunway()<< " qfu : " << runwayLabeled.runwayQfu() << " coordinate : " << runwayLabeled.rwPosition();
            }
            return QVariant::fromValue(rwCoord);
        }
        return QVariant();
    }

protected:
    QHash<int, QByteArray> roleNames() const {
        QHash<int, QByteArray> roles;
        roles[rwRole] = "runways";
        return roles;
    }

private:
    QList<Airport> m_apList;
};


#endif // AIRPORTSMODEL_H

我的问题是如何利用返回的跑道列表(rwCoord)以及此行中显示的路径:path:[runways]来自main.qml:

import QtQuick 2.6
import QtQuick.Window 2.2
import QtPositioning 5.5
import QtLocation 5.6

Window {
    width: 700
    height: 500
    visible: true
    title: qsTr("Test MapPolyline for airport")
    id: win

    Map {
        id: mapOfWorld
        anchors.centerIn: parent;
        anchors.fill: parent
        zoomLevel: 12
        plugin: Plugin {name: "osm"}
        center: QtPositioning.coordinate(41.97732, -87.90801)//KORD
        MapItemView {
            model: airportsModel
            delegate:  Marker{
//                path: [runways]
                path: [
                    {latitude: 41.98166, longitude: -87.91392},
                    {latitude: 41.99754,longitude: -87.89637}
                ]
            }
        }
    }
}

这里,直接输入坐标对时路径可以正常工作,当然,这不是目标。

标记。 qml是一个简单的mappolyline,当一个机场有超过2条跑道时,会添加一个函数来收集不同的坐标对。

import QtQuick 2.5
import QtLocation 5.6

MapPolyline {

    line.color: "darkBlue"
    line.width: 5
}

所以,总结一下: 返回属于机场的所有跑道的Qlist的方法是正确的(更好的)方式,因为机场设计类? 如果是,我如何将此列表用于qml部分并将跑道添加到路径以绘制代表性线段?

非常感谢你的帮助。

1 个答案:

答案 0 :(得分:1)

如果您希望识别路线,则必须返回QVariantList,而不是QList<QGeoCoordinate>

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

    if (index.row() < 0 || index.row() >= m_apList.count())
        return QVariant();
    const Airport &point = m_apList[index.row()];
    if (role == rwRole){
        QVariantList rwCoord;
        const auto &runwayList = point.listRunways();
        for(const Runway &runwayLabeled: runwayList)
        {
            rwCoord << QVariant::fromValue(runwayLabeled.rwPosition());
            //qDebug() << "runway : " << runwayLabeled.nameRunway()<< " qfu : " << runwayLabeled.runwayQfu() << " coordinate : " << runwayLabeled.rwPosition();
        }
        return rwCoord; //; QVariant::fromValue(rwCoord);
    }
    return QVariant();
}

然后直接通过跑道而不需要括号:

delegate:  Marker{
    path: runways
}

您可以在以下link

中找到完整的测试代码