2017-11-20 10 views
0

Qt/QMLを使って地図上に膨大な数の点を表示します。これらの点は、.txtファイルに記述されています。ファイルからQMLで位置を表示する方法

私は使用するプロセスを探していますが、残念ながら、サーバー(osm、google ...)からプレースメントを表示するためのプラグイン経由のクエリメソッドしか見つかりません。私はそれを使用することはできません、これらの点は非常に具体的です。

このタスクを達成する最良の方法は何ですか?

また、これらの点を特定のレイヤーに表示するには、「osmプラグイン」に加えて「plugin itemsoverlay」を使用する必要がありますか?

ありがとうございました。

[OK]をクリックして、今すぐコードと対戦してください。ここで

は、メインの.cpp

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 
#include <QQmlContext> 
#include <QObject> 
#include <QGeoCoordinate> 
#include <QDebug> 

class NavaidsPoint: public QObject 
{ 
    Q_OBJECT 
    Q_PROPERTY(QGeoCoordinate position READ position WRITE setPosition NOTIFY positionChanged) 

public: 
    NavaidsPoint(QString code, double latitude, double longitude, QString country = "") 
    { 
     m_code = code; 
     m_latitude = latitude; 
     m_longitude = longitude; 
     m_country = country; 
     m_position.setLatitude(latitude); 
     m_position.setLongitude(longitude); 
    } 

    void setPosition(const QGeoCoordinate &c) { //Affectation des nouvelles coordonnées de position 
     if (m_position == c) 
      return; 

     m_position = c; 
     emit positionChanged(); //Emission du signal de changement de position 
    } 

    QGeoCoordinate position() const 
    { 
     return m_position; //Lecture des coordonnées de position 
    } 

    Q_INVOKABLE QString oaciCode() const { 
     return m_code; 
    } 

    Q_INVOKABLE QString countryCode() const { 
     return m_country; 
    } 

signals: 
    void positionChanged(); 

private: 
    QGeoCoordinate m_position; 
    double m_latitude; 
    double m_longitude; 
    double m_altitude; 
    QString m_code; 
    QString m_country; 
}; 




int main(int argc, char *argv[]) 
{ 
    QGuiApplication app(argc, argv); 

    NavaidsPoint oslo("Oslo", 59.9154, 10.7425, "NG"); 

    QQmlApplicationEngine engine; 
    engine.rootContext()->setContextProperty("oslo", &oslo); 
    engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); 
    if (engine.rootObjects().isEmpty()) 
     return -1; 

    return app.exec(); 
} 

#include "main.moc" 

そして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 implantation coordonnées") 

    property variant topLeftEurope: QtPositioning.coordinate(60.5, 0.0) 
    property variant bottomRightEurope: QtPositioning.coordinate(51.0, 14.0) 
    property variant viewOfEurope: 
      QtPositioning.rectangle(topLeftEurope, bottomRightEurope) 

    Map { 
     id: mapOfEurope 
     anchors.centerIn: parent; 
     anchors.fill: parent 
     plugin: Plugin { 
      name: "osm" 
     } 

     MapCircle { 
      center: oslo.position 
      radius: 5000.0 
      color: 'green' 
      border.width: 3 
      MouseArea { 
       anchors.fill: parent 
       onDoubleClicked: { 
        console.log("Doubleclick on " + oslo.oaciCode()) 
       } 
       onClicked: { 
        console.log("Point : " + oslo.oaciCode() + " " + oslo.position + " " + oslo.countryCode()) 
       } 
      } 
     } 
    visibleRegion: viewOfEurope 
    } 
} 

すべては、このユニークなポイントオスロで正常に動作しています。今私は数千点を配置する必要があります。このような構造は、それぞれのために1つのNavaidsPointを実装し、それぞれに対してもう一度setContextPropertyを実装する必要があるため、うまく動作しません。 main.QMLに円がオブジェクトに関連付けられています同様に、:

center : oslo.position 

と加えて、私はoaciCodeとCOUNTRYCODEをnead。したがって、コードのこの部分は、単一オブジェクトに固有ではなく、汎用でなければなりません。

この問題を解決するにはどうすればよいでしょうか?

私はこれらの精度でSOの範囲に収まることを望みます。

もう一度お手数をおかけします。

+0

あなたの.txtください – eyllanesc

+0

ROBSO、21.75000、-107.12556、MM ROBSU、49.83348、-64.04158、CY ROBTE、45.40642、-91.、K5 ROBUC、41.67892、-71.58512、K6 ROBUD、40.64376を示します - 118.70789、K2 ROBUE、62.45198、-160.23723、PA ROBUM、69.43252,15.91136、EN ROBUN、74.83083,74.18083、UL ROBUR、61.88620、-6.57648、EK ROBUS、55.10944,11.71972、EK ROBUT、46.00639、 42.70333、UR ROBVE、36.30598、-99.19448、K4 ROBVI、52.57165,3.77645、EH ROBVO、51.68444、-8.19925、EI ROBVY、38.78295、-10 6.10674、K2 ROBYE、35.72012、-89.81856、K7 ROBYN、19.76366、-156.11584、PH ...ここではスニペットと何千もの行があります。 – kontiki

+0

あなたの問題を解決しようとするのは難しいことですが、問題があれば詳細を公表し、試したコードを表示することをお勧めします。その後、私たちはあなたを助けようとします。 SOはコーディングサービスではありません。 – eyllanesc

答えて

0

多くの要素をロードする場合は、MapItemViewを使用することをお勧めします。これには、データを提供するモデルが必要であり、適切なデリゲートを示す必要があります。

モデルは、我々はそれが次のようになります。この場合には、必ずしもQObjectから継承する必要はありませんクラスを作成するために、QMLにプロパティを公開するためにロールを使用しますQAbstractListModelに基づいて作成されます。後

#ifndef NAVAIDSMODEL_H 
#define NAVAIDSMODEL_H 

#include "navaidspoint.h" 

#include <QAbstractListModel> 
#include <QFile> 
#include <QTextStream> 

#include <QDebug> 

class NavaidsModel : public QAbstractListModel 
{ 
    Q_OBJECT 
public: 
    NavaidsModel(QObject *parent = Q_NULLPTR):QAbstractListModel(parent){ 
    } 
    enum NavaidsRoles { 
     PositionRole = Qt::UserRole + 1, 
     OACICodeRole, 
     CountryCodeRole 
    }; 

    void readFromCSV(const QString &filename){ 
     QFile file(filename); 
     if(!file.open(QFile::ReadOnly | QFile::Text)) 
      return; 
     QTextStream in(&file); 
     while (!in.atEnd()) { 
      QString line = in.readLine(); 
      QStringList elements = line.split(","); 
      if(elements.count()==4){ 
       QString code = elements[0]; 
       double latitude = elements[1].toDouble(); 
       double longitude = elements[2].toDouble(); 
       QString country = elements[3]; 
       NavaidsPoint p(code, latitude, longitude, country); 
       addNavaidsPoint(p); 
      } 
     } 
    } 

    void addNavaidsPoint(const NavaidsPoint &point){ 
     beginInsertRows(QModelIndex(), rowCount(), rowCount()); 
     mPoints << point; 
     endInsertRows(); 
    } 

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

    QVariant data(const QModelIndex & index, int role=Qt::DisplayRole) const { 
     if (index.row() < 0 || index.row() >= mPoints.count()) 
      return QVariant(); 

     const NavaidsPoint &point = mPoints[index.row()]; 
     if (role == PositionRole) 
      return QVariant::fromValue(point.position()); 
     else if (role == OACICodeRole) 
      return point.oaciCode(); 
     else if (role == CountryCodeRole) 
      return point.countryCode(); 
     return QVariant(); 
    } 

protected: 
    QHash<int, QByteArray> roleNames() const { 
     QHash<int, QByteArray> roles; 
     roles[PositionRole] = "position"; 
     roles[OACICodeRole] = "oaci"; 
     roles[CountryCodeRole] = "country"; 
     return roles; 
    } 
private: 
    QList<NavaidsPoint> mPoints; 
}; 

#endif // NAVAIDSMODEL_H 

に従うよう

#ifndef NAVAIDSPOINT_H 
#define NAVAIDSPOINT_H 

#include <QGeoCoordinate> 
#include <QString> 

class NavaidsPoint 
{ 
public: 
    NavaidsPoint(QString code, double latitude, double longitude, QString country = ""){ 
     m_code = code; 
     m_country = country; 
     m_position.setLatitude(latitude); 
     m_position.setLongitude(longitude); 
     m_position.setAltitude(0.0); 
    } 

    void setPosition(const QGeoCoordinate &c) { //Affectation des nouvelles coordonnées de position 
     m_position = c; 
    } 

    QGeoCoordinate position() const{ 
     return m_position; //Lecture des coordonnées de position 
    } 

    QString oaciCode() const { 
     return m_code; 
    } 

    QString countryCode() const { 
     return m_country; 
    } 

private: 
    QGeoCoordinate m_position; 
    QString m_code; 
    QString m_country; 
}; 


#endif // NAVAIDSPOINT_H 

QAbstractListModelは、あなたが方法rowCountdataroleNamesを実装する必要があり、また、私はあなたが変化のモデルに通知しなければならないaddメソッドを実装している例がありますモデルが作成され、モデルが追加され、QMLに公開されます。

#include "navaidsmodel.h" 

#include <QGuiApplication> 
#include <QQmlApplicationEngine> 
#include <QQmlContext> 

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

    NavaidsModel model; 
    model.readFromCSV("/home/eyllanesc/data.csv"); //from file 

    model.addNavaidsPoint(NavaidsPoint("Oslo", 59.9154, 10.7425, "NG")); // add new point 

    QQmlApplicationEngine engine; 
    engine.rootContext()->setContextProperty("navaidsModel", &model); 
    engine.load(QUrl(QLatin1String("qrc:/main.qml"))); 
    if (engine.rootObjects().isEmpty()) 
     return -1; 

    return app.exec(); 
} 

終わりに、MapItemViewは、適切なモデルとデリゲートで使用され、次のlink

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 implantation coordonnées") 

    property variant topLeftEurope: QtPositioning.coordinate(60.5, 0.0) 
    property variant bottomRightEurope: QtPositioning.coordinate(51.0, 14.0) 
    property variant viewOfEurope: 
     QtPositioning.rectangle(topLeftEurope, bottomRightEurope) 

    Map { 
     id: mapOfEurope 
     anchors.centerIn: parent; 
     anchors.fill: parent 
     plugin: Plugin { 
      name: "osm" 
     } 
     MapItemView { 
      model: navaidsModel 
      delegate: MapCircle{ 
       center: position 
       radius: 10000 
       color: 'green' 
       border.width: 3 
       MouseArea { 
        anchors.fill: parent 
        onDoubleClicked: { 
         console.log("Doubleclick on " + oaci) 
        } 
        onClicked: { 
         console.log("Point : " + oaci + " " + position + " " + country) 
        } 
       } 
      } 
     } 
     visibleRegion: viewOfEurope 
    } 
} 

は完全な例です。

+0

Eyllanesc、あなたはすばらしい仕事をしてくれました。これで、この完全なプロセスの詳細を理解するのに少し時間がかかります。本当にありがとう。 – kontiki

+0

受け入れ済み。私はあなたのコード、特にnavaidsModelを研究し続けます。それの部分と理解するのが難しいメカニズムの間に非常に複雑な関係があるように見えますが、私はあきらめません。もう一度おねがいしますeyllanesc – kontiki

+0

これを読んでください:https://doc-snapshots.qt.io/qt5-dev/qtquick-modelviewsdata-modelview.html – eyllanesc

関連する問題