如何从数据库中的坐标向地图添加项目?
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"
}
}
}
}
}
我有一个包含机场坐标的数据库,我需要用地图上的点 (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"
}
}
}
}
}