如何从数据库中的坐标向地图添加项目?

How to add items to the map from coordinates in the database?

我有一个包含机场坐标的数据库,我需要用地图上的点 (QtLocation) 来显示它们。 使用 QSqlQueryModel,我可以轻松地填充和显示 TableView,但我不知道如何创建 MapQuickItems。

class SqlModel : public QSqlQueryModel
{
    Q_OBJECT
public:
    enum Roles {
        LatitudeRole  = Qt::UserRole + 1,
        LongitudeRole = Qt::UserRole + 2
    };

    explicit SqlModel(QObject *parent = nullptr) : QSqlQueryModel(parent) {}

    QVariant data(const QModelIndex &index, int role) const override
    {
        int columnId = role - Qt::UserRole - 1;
        QModelIndex modelIndex = this->index(index.row(), columnId);
        return QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
    }

protected:
    QHash<int, QByteArray> roleNames() const override {
        QHash<int, QByteArray> roles;
        roles[LatitudeRole] = "latitude";
        roles[LongitudeRole] = "longitude";
        return roles;
    }
};

在main.cpp中:

//...
SqlModel *model = new SqlModel;
model->setQuery("SELECT air_latitude, air_longitude FROM tab_airports");
engine.rootContext()->setContextProperty("myModel", model);
//...

使用我的 previous answer 的 SqlQueryModel 允许通过具有相同字段名称的角色获取数据,并使用委派给的 MapItemView 中的 QtPositioning.coordinate 将其转换为 QCoordinate得到的MapQuickItem如下:

#include <QtGui>
#include <QtSql>
#include <QtQml>

class SqlQueryModel : public QSqlQueryModel {
    Q_OBJECT
public:
    using QSqlQueryModel::QSqlQueryModel;
    QHash<int, QByteArray> roleNames() const {
        QHash<int, QByteArray> roles;
        for (int i = 0; i < record().count(); i++) {
            roles.insert(Qt::UserRole + i + 1, record().fieldName(i).toUtf8());
        }
        return roles;
    }
    QVariant data(const QModelIndex &index, int role) const {
        QVariant value;
        if (index.isValid()) {
            if (role < Qt::UserRole) {
                value = QSqlQueryModel::data(index, role);
            } else {
                int columnIdx = role - Qt::UserRole - 1;
                QModelIndex modelIndex = this->index(index.row(), columnIdx);
                value = QSqlQueryModel::data(modelIndex, Qt::DisplayRole);
            }
        }
        return value;
    }
};

static bool createConnection(const QString &path) {
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(path);
    if (!db.open()) {
        qDebug() << "Cannot open database\n"
                "Unable to establish a database connection.\n"
                "This example needs SQLite support. Please read "
                "the Qt SQL driver documentation for information how "
                "to build it.\n\n"
                "Click Cancel to exit.";
        return false;
    }
    return true;
}

static void createData(){
    QSqlQuery query;
    query.exec("CREATE TABLE IF NOT EXISTS tab_airports(air_latitude REAL, air_longitude REAL)");
    for(int i=0; i<10; i++){
        query.prepare("INSERT INTO tab_airports(air_latitude, air_longitude) VALUES (?, ?)");
        double lat = 59.91 + .02 * (QRandomGenerator::global()->generateDouble() - .5); 
        double lng = 10.75 + .02 * (QRandomGenerator::global()->generateDouble() - .5); 
        query.addBindValue(lat);
        query.addBindValue(lng);
        query.exec();
    }
}

int main(int argc, char *argv[]) {
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;
    if (!createConnection(":memory:"))
        return -1;
    createData();
    SqlQueryModel model;
    model.setQuery("SELECT air_latitude, air_longitude FROM tab_airports");
    engine.rootContext()->setContextProperty("airport_model", &model);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}

#include "main.moc"
import QtQuick 2.9
import QtQuick.Controls 2.2

import QtLocation 5.11
import QtPositioning 5.11

ApplicationWindow {
    id: root
    visible: true
    width: 640
    height: 480

     Plugin {
        id: mapPlugin
        name: "osm"
    }

    Map {
        id: map
        anchors.fill: parent
        plugin: mapPlugin
        center: QtPositioning.coordinate(59.91, 10.75) // Oslo
        zoomLevel: 14

        MapItemView{
            id: view
            model: airport_model
            delegate: MapQuickItem{
                coordinate: QtPositioning.coordinate(model.air_latitude, model.air_longitude)
                anchorPoint.x: image.width/2
                anchorPoint.y: image.height
                sourceItem: Image {
                    id: image
                    source: "http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png"
                }
            }
        }
    }
}