как получить широту / долготу от географического адреса, используя Qt c ++ QGeoServiceProvider? - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь использовать osm api через QGeoServiceProvider и QGeoCodingManager для получения широты и долготы по заданному физическому адресу.Тем самым я наткнулся на этот Вопрос , который, кажется, делает именно то, что мне нужно.

Однако я хочу реализовать это в приложении qt gui как отдельную функцию, и я не понимаю, чтопроисходит в соединении.Может кто-нибудь объяснить, или как я могу изменить его, чтобы он работал в функции?

    cout << "Try service: " << "osm" << endl;
    // choose provider
    QGeoServiceProvider qGeoService("osm");
    QGeoCodingManager *pQGeoCoder = qGeoService.geocodingManager();
    if (!pQGeoCoder) {
      cerr
        << "GeoCodingManager '" << "osm"
        << "' not available!" << endl;

    }
    QLocale qLocaleC(QLocale::C, QLocale::AnyCountry);
    pQGeoCoder->setLocale(qLocaleC);
    // build address
    QGeoAddress qGeoAddr;
    qGeoAddr.setCountry(QString::fromUtf8("Germany"));
    qGeoAddr.setPostalCode(QString::fromUtf8("88250"));
    qGeoAddr.setCity(QString::fromUtf8("Weingarten"));
    qGeoAddr.setStreet(QString::fromUtf8("Heinrich-Hertz-Str. 6"));
    QGeoCodeReply *pQGeoCode = pQGeoCoder->geocode(qGeoAddr);
    if (!pQGeoCode) {
      cerr << "GeoCoding totally failed!" << endl;

    }
    cout << "Searching..." << endl;
    QObject::connect(pQGeoCode, &QGeoCodeReply::finished,
      [&qGeoAddr, pQGeoCode](){
        cout << "Reply: " << pQGeoCode->errorString().toStdString() << endl;
        switch (pQGeoCode->error()) {
#define CASE(ERROR) \
case QGeoCodeReply::ERROR: cerr << #ERROR << endl; break
          CASE(NoError);
          CASE(EngineNotSetError);
          CASE(CommunicationError);
          CASE(ParseError);
          CASE(UnsupportedOptionError);
          CASE(CombinationError);
          CASE(UnknownError);
#undef CASE
          default: cerr << "Undocumented error!" << endl;
        }
        if (pQGeoCode->error() != QGeoCodeReply::NoError) return;
        // eval. result
        QList<QGeoLocation> qGeoLocs = pQGeoCode->locations();
        cout << qGeoLocs.size() << " location(s) returned." << endl;
        for (QGeoLocation &qGeoLoc : qGeoLocs) {
          qGeoLoc.setAddress(qGeoAddr);
          QGeoCoordinate qGeoCoord = qGeoLoc.coordinate();
          cout
            << "Lat.:  " << qGeoCoord.latitude() << endl
            << "Long.: " << qGeoCoord.longitude() << endl
            << "Alt.:  " << qGeoCoord.altitude() << endl;
        }
      });

Поэтому я просто удалил часть QApplication, потому что у меня нет этой ссылки в функции.В результате я получаю:

Qt Version: 5.10.0
Try service: osm
Searching...

но без координат.Я предполагаю, что соединение с тем, где получены данные широты и долготы, не работает.Но, как я уже упоминал, я не понимаю, связь здесь.Любая помощь приветствуется

РЕДАКТИРОВАТЬ , поэтому я попытался создать соединение, чтобы перехватить готовый сигнал, как было предложено.Код теперь выглядит следующим образом:

QGeoServiceProvider qGeoService("osm");
  QGeoCodingManager *pQGeoCoder = qGeoService.geocodingManager();
  if (!pQGeoCoder) {
    cerr
      << "GeoCodingManager '" << "osm"
      << "' not available!" << endl;

  }
  QLocale qLocaleC(QLocale::C, QLocale::AnyCountry);
  pQGeoCoder->setLocale(qLocaleC);
  // build address
  //QGeoAddress qGeoAddr;
  qGeoAddr.setCountry(QString::fromUtf8("Germany"));
  qGeoAddr.setPostalCode(QString::fromUtf8("88250"));
  qGeoAddr.setCity(QString::fromUtf8("Weingarten"));
  qGeoAddr.setStreet(QString::fromUtf8("Heinrich-Hertz-Str. 6"));
  this->pQGeoCode = pQGeoCoder->geocode(qGeoAddr);
  if (!pQGeoCode) {
    cerr << "GeoCoding totally failed!" << endl;

  }
  cout << "Searching..." << endl;

  connect(pQGeoCode,SIGNAL(finished()),this,SLOT(getlonlat()));

со слотом:

void MainWindow::getlonlat()
    {
      QList<QGeoLocation> qGeoLocs = pQGeoCode->locations();
                cout << qGeoLocs.size() << " location(s) returned." << endl;
                for (QGeoLocation &qGeoLoc : qGeoLocs) {
                  qGeoLoc.setAddress(qGeoAddr);
                  QGeoCoordinate qGeoCoord = qGeoLoc.coordinate();
                  cout
                    << "Lat.:  " << qGeoCoord.latitude() << endl
                    << "Long.: " << qGeoCoord.longitude() << endl
                    << "Alt.:  " << qGeoCoord.altitude() << endl;
                }
    }

Однако готовый сигнал не запускается.Поэтому результат тот же. РЕДАКТИРОВАТЬ

Реализация кода из вашего графического интерфейса Ответ:

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"

// standard C++ header:
#include <iostream>
#include <sstream>

// Qt header:
#include <QGeoAddress>
#include <QGeoCodingManager>
#include <QGeoCoordinate>
#include <QGeoLocation>
#include <QGeoServiceProvider>



MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{


  QGeoServiceProvider *pQGeoProvider = nullptr;

  ui->setupUi(this);


  qDebug() << "Qt Version:" << QT_VERSION_STR;
    // main application
    //QApplication app(argc, argv);

    // install signal handlers
    QObject::connect(this->ui->qBtnInit, &QPushButton::clicked,
      [&]() {
        if (pQGeoProvider) delete pQGeoProvider;
        std::ostringstream out;
        pQGeoProvider = init(out);
        log(out.str());
      });
    QObject::connect(this->ui->qBtnFind, &QPushButton::clicked,
      [&]() {
        // init geo coder if not yet done
        if (!pQGeoProvider) {
          std::ostringstream out;
          pQGeoProvider = init(out);
          log(out.str());
          if (!pQGeoProvider) return; // failed
        }
        // fill in request
        QGeoAddress *pQGeoAddr = new QGeoAddress;
        pQGeoAddr->setCountry(this->ui->qTxtCountry->text());
        pQGeoAddr->setPostalCode(this->ui->qTxtZipCode->text());
        pQGeoAddr->setCity(this->ui->qTxtCity->text());
        pQGeoAddr->setStreet(this->ui->qTxtStreet->text());
        QGeoCodeReply *pQGeoCode
          = pQGeoProvider->geocodingManager()->geocode(*pQGeoAddr);
        if (!pQGeoCode) {
          delete pQGeoAddr;
          log("GeoCoding totally failed!\n");
          return;
        }
        { std::ostringstream out;
          out << "Sending request for:\n"
            << pQGeoAddr->country().toUtf8().data() << "; "
            << pQGeoAddr->postalCode().toUtf8().data() << "; "
            << pQGeoAddr->city().toUtf8().data() << "; "
            << pQGeoAddr->street().toUtf8().data() << "...\n";
          log(out.str());
        }
        // install signal handler to process result later
        QObject::connect(pQGeoCode, &QGeoCodeReply::finished,
          [&,pQGeoAddr, pQGeoCode]() {
            // process reply
            std::ostringstream out;
            out << "Reply: " << pQGeoCode->errorString().toStdString() << '\n';
            switch (pQGeoCode->error()) {
              case QGeoCodeReply::NoError: {
                // eval result
                QList<QGeoLocation> qGeoLocs = pQGeoCode->locations();
                out << qGeoLocs.size() << " location(s) returned.\n";
                for (QGeoLocation &qGeoLoc : qGeoLocs) {
                  qGeoLoc.setAddress(*pQGeoAddr);
                  QGeoCoordinate qGeoCoord = qGeoLoc.coordinate();
                  out
                    << "Lat.:  " << qGeoCoord.latitude() << '\n'
                    << "Long.: " << qGeoCoord.longitude() << '\n'
                    << "Alt.:  " << qGeoCoord.altitude() << '\n';
                }
              } break;
  #define CASE(ERROR) \
  case QGeoCodeReply::ERROR: out << #ERROR << '\n'; break
              CASE(EngineNotSetError);
              CASE(CommunicationError);
              CASE(ParseError);
              CASE(UnsupportedOptionError);
              CASE(CombinationError);
              CASE(UnknownError);
  #undef CASE
              default: out << "Undocumented error!\n";
            }
            // log result
            log(out.str());
            // clean-up
            delete pQGeoAddr;
            /* delete sender in signal handler could be lethal
             * Hence, delete it later...
             */
            pQGeoCode->deleteLater();
          });
      });
    // fill in a sample request with a known address initially
    this->ui->qTxtCountry->setText(QString::fromUtf8("Germany"));
    this->ui->qTxtZipCode->setText(QString::fromUtf8("88250"));
    this->ui->qTxtCity->setText(QString::fromUtf8("Weingarten"));
    this->ui->qTxtStreet->setText(QString::fromUtf8("Danziger Str. 3"));


}

MainWindow::~MainWindow()
{
  delete ui;
}


void MainWindow::log(const QString &qString)
{
  this->ui->qTxtLog->setPlainText(this->ui->qTxtLog->toPlainText() + qString);
  this->ui->qTxtLog->moveCursor(QTextCursor::End);
}
void MainWindow::log(const char *text)
{
  log(QString::fromUtf8(text));
}
void MainWindow::log(const std::string &text)
{
  log(text.c_str());
}

QGeoServiceProvider* MainWindow::init(std::ostream &out)
{
  // check for available services
  QStringList qGeoSrvList
    = QGeoServiceProvider::availableServiceProviders();
  for (QString entry : qGeoSrvList) {
    out << "Try service: " << entry.toStdString() << '\n';
    // choose provider
    QGeoServiceProvider *pQGeoProvider = new QGeoServiceProvider(entry);
    if (!pQGeoProvider) {
      out
        << "ERROR: GeoServiceProvider '" << entry.toStdString()
        << "' not available!\n";
      continue;
    }
    QGeoCodingManager *pQGeoCoder = pQGeoProvider->geocodingManager();
    if (!pQGeoCoder) {
      out
        << "ERROR: GeoCodingManager '" << entry.toStdString()
        << "' not available!\n";
      delete pQGeoProvider;
      continue;
    }
    QLocale qLocaleC(QLocale::C, QLocale::AnyCountry);
    pQGeoCoder->setLocale(qLocaleC);
    out << "Using service " << entry.toStdString() << '\n';
    return pQGeoProvider; // success
  }
  out << "ERROR: No suitable GeoServiceProvider found!\n";
  return nullptr; // all attempts failed
}

Main.cpp:

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  MainWindow w;
  w.show();

  return a.exec();
}

А вот заголовочный файл для главного окна:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
// standard C++ header:
#include <iostream>
#include <sstream>

// Qt header:

#include <QGeoAddress>
#include <QGeoCodingManager>
#include <QGeoCoordinate>
#include <QGeoLocation>
#include <QGeoServiceProvider>
namespace Ui {
  class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT

public:
  explicit MainWindow(QWidget *parent = 0);
  virtual ~MainWindow();


  void log(const QString &qString);

  void log(const char *text);

  void log(const std::string &text);


  QGeoServiceProvider* init(std::ostream &out);

private:
  Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

1 Ответ

0 голосов
/ 15 мая 2018

Я преобразовал мой старый образец в минимальное приложение с графическим интерфейсом:

// standard C++ header:
#include <iostream>
#include <sstream>

// Qt header:
#include <QtWidgets>
#include <QGeoAddress>
#include <QGeoCodingManager>
#include <QGeoCoordinate>
#include <QGeoLocation>
#include <QGeoServiceProvider>

void log(QTextEdit &qTxtLog, const QString &qString)
{
  qTxtLog.setPlainText(qTxtLog.toPlainText() + qString);
  qTxtLog.moveCursor(QTextCursor::End);
}
void log(QTextEdit &qTxtLog, const char *text)
{
  log(qTxtLog, QString::fromUtf8(text));
}
void log(QTextEdit &qTxtLog, const std::string &text)
{
  log(qTxtLog, text.c_str());
}

int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  // main application
  QApplication app(argc, argv);
  // setup GUI
  QWidget qWin;
  QVBoxLayout qBox;
  QFormLayout qForm;
  QLabel qLblCountry(QString::fromUtf8("Country:"));
  QLineEdit qTxtCountry;
  qForm.addRow(&qLblCountry, &qTxtCountry);
  QLabel qLblZipCode(QString::fromUtf8("Postal Code:"));
  QLineEdit qTxtZipCode;
  qForm.addRow(&qLblZipCode, &qTxtZipCode);
  QLabel qLblCity(QString::fromUtf8("City:"));
  QLineEdit qTxtCity;
  qForm.addRow(&qLblCity, &qTxtCity);
  QLabel qLblStreet(QString::fromUtf8("Street:"));
  QLineEdit qTxtStreet;
  qForm.addRow(&qLblStreet, &qTxtStreet);
  QLabel qLblProvider(QString::fromUtf8("Provider:"));
  QComboBox qLstProviders;
  qForm.addRow(&qLblProvider, &qLstProviders);
  qBox.addLayout(&qForm);
  QPushButton qBtnFind(QString::fromUtf8("Find Coordinates"));
  qBox.addWidget(&qBtnFind);
  QLabel qLblLog(QString::fromUtf8("Log:"));
  qBox.addWidget(&qLblLog);
  QTextEdit qTxtLog;
  qTxtLog.setReadOnly(true);
  qBox.addWidget(&qTxtLog);
  qWin.setLayout(&qBox);
  qWin.show();
  // initialize Geo Service Providers
  std::vector<QGeoServiceProvider*> pQGeoProviders;
  { std::ostringstream out;
    QStringList qGeoSrvList
      = QGeoServiceProvider::availableServiceProviders();
    for (QString entry : qGeoSrvList) {
      out << "Try service: " << entry.toStdString() << '\n';
      // choose provider
      QGeoServiceProvider *pQGeoProvider = new QGeoServiceProvider(entry);
      if (!pQGeoProvider) {
        out
          << "ERROR: GeoServiceProvider '" << entry.toStdString()
          << "' not available!\n";
        continue;
      }
      QGeoCodingManager *pQGeoCoder = pQGeoProvider->geocodingManager();
      if (!pQGeoCoder) {
        out
          << "ERROR: GeoCodingManager '" << entry.toStdString()
          << "' not available!\n";
        delete pQGeoProvider;
        continue;
      }
      QLocale qLocaleC(QLocale::C, QLocale::AnyCountry);
      pQGeoCoder->setLocale(qLocaleC);
      qLstProviders.addItem(entry);
      pQGeoProviders.push_back(pQGeoProvider);
      out << "Service " << entry.toStdString() << " available.\n";
    }
    log(qTxtLog, out.str());
  }
  if (pQGeoProviders.empty()) qBtnFind.setEnabled(false);
  // install signal handlers
  QObject::connect(&qBtnFind, QPushButton::clicked,
    [&]() {
      // get current geo service provider
      QGeoServiceProvider *pQGeoProvider
        = pQGeoProviders[qLstProviders.currentIndex()];
      // fill in request
      QGeoAddress *pQGeoAddr = new QGeoAddress;
      pQGeoAddr->setCountry(qTxtCountry.text());
      pQGeoAddr->setPostalCode(qTxtZipCode.text());
      pQGeoAddr->setCity(qTxtCity.text());
      pQGeoAddr->setStreet(qTxtStreet.text());
      QGeoCodeReply *pQGeoCode
        = pQGeoProvider->geocodingManager()->geocode(*pQGeoAddr);
      if (!pQGeoCode) {
        delete pQGeoAddr;
        log(qTxtLog, "GeoCoding totally failed!\n");
        return;
      }
      { std::ostringstream out;
        out << "Sending request for:\n"
          << pQGeoAddr->country().toUtf8().data() << "; "
          << pQGeoAddr->postalCode().toUtf8().data() << "; "
          << pQGeoAddr->city().toUtf8().data() << "; "
          << pQGeoAddr->street().toUtf8().data() << "...\n";
        log(qTxtLog, out.str());
      }
      // install signal handler to process result later
      QObject::connect(pQGeoCode, &QGeoCodeReply::finished,
        [&qTxtLog, pQGeoAddr, pQGeoCode]() {
          // process reply
          std::ostringstream out;
          out << "Reply: " << pQGeoCode->errorString().toStdString() << '\n';
          switch (pQGeoCode->error()) {
            case QGeoCodeReply::NoError: {
              // eval result
              QList<QGeoLocation> qGeoLocs = pQGeoCode->locations();
              out << qGeoLocs.size() << " location(s) returned.\n";
              for (QGeoLocation &qGeoLoc : qGeoLocs) {
                qGeoLoc.setAddress(*pQGeoAddr);
                QGeoCoordinate qGeoCoord = qGeoLoc.coordinate();
                out
                  << "Lat.:  " << qGeoCoord.latitude() << '\n'
                  << "Long.: " << qGeoCoord.longitude() << '\n'
                  << "Alt.:  " << qGeoCoord.altitude() << '\n';
              }     
            } break;
#define CASE(ERROR) \
            case QGeoCodeReply::ERROR: out << #ERROR << '\n'; break
            CASE(EngineNotSetError);
            CASE(CommunicationError);
            CASE(ParseError);
            CASE(UnsupportedOptionError);
            CASE(CombinationError);
            CASE(UnknownError);
#undef CASE
            default: out << "Undocumented error!\n";
          }
          // log result
          log(qTxtLog, out.str());
          // clean-up
          delete pQGeoAddr;
          /* delete sender in signal handler could be lethal
           * Hence, delete it later...
           */
          pQGeoCode->deleteLater();
        });
    });
  // fill in a sample request with a known address initially
  qTxtCountry.setText(QString::fromUtf8("Germany"));
  qTxtZipCode.setText(QString::fromUtf8("88250"));
  qTxtCity.setText(QString::fromUtf8("Weingarten"));
  qTxtStreet.setText(QString::fromUtf8("Danziger Str. 3"));
  // runtime loop
  app.exec();
  // done
  return 0;
}

Скомпилировано и протестировано в cygwin в Windows 10 (64 бит):

$ g++ --version
g++ (GCC) 6.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ qmake-qt5 testQGeoAddressGUI.pro

$ make
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_LOCATION_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_POSITIONING_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtLocation -isystem /usr/include/qt5/QtQuick -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtPositioning -isystem /usr/include/qt5/QtQml -isystem /usr/include/qt5/QtNetwork -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQGeoAddressGUI.o testQGeoAddressGUI.cc
g++  -o testQGeoAddressGUI.exe testQGeoAddressGUI.o   -lQt5Widgets -lQt5Location -lQt5Quick -lQt5Gui -lQt5Positioning -lQt5Qml -lQt5Network -lQt5Core -lGL -lpthread 

$ ./testQGeoAddressGUI
Qt Version: 5.9.2

Snapshot of testQGeoAddressGUI

Примечания:

Когда я писал этот пример, я очень внимательно относился к области действия и времени жизни задействованных переменных. (На самом деле я изменил некоторые локальные переменные на указатели и экземпляры, созданные с помощью new, чтобы добиться этого.) Это мой совет для любого читателя.

В моем тесте 1 st приложение оказалось в CommunicationError. Я вполне уверен, что за это отвечает политика безопасности нашей компании. (Я проделал то же самое с моим старым образцом, который успешно протестировал дома - с тем же результатом.)

Тест 2 и (дома) прошел лучше. Сначала я попытался найти адрес у поставщика услуг osm, который дал 0 результатов. Изменение поставщика услуг на esri вернул один результат.

Я скопировал вывод в maps.google.de:

Snapshot of maps.google.de after request of 47.8187, 9.64387

Это действительно правильный результат & ndash; как я проверял (новый) адрес компании EKS InTec где я работаю.


Использование лямбд в приведенном выше примере делает его немного трудным для чтения. Поэтому я повторно посетил образец. Теперь все соответствующие материалы переместились на class MainWindow (надеюсь, ближе к требованию ОП). Лямбды были заменены простыми методами.

// standard C++ header:
#include <iostream>
#include <sstream>

// Qt header:
#include <QtWidgets>
#include <QGeoAddress>
#include <QGeoCodingManager>
#include <QGeoCoordinate>
#include <QGeoLocation>
#include <QGeoServiceProvider>

// main window class
class MainWindow: public QWidget {
  // variables:
  private:
    // list of service providers
    std::vector<QGeoServiceProvider*> pQGeoProviders;
    // Qt widgets (contents of main window)
    QVBoxLayout qBox;
    QFormLayout qForm;
    QLabel qLblCountry;
    QLineEdit qTxtCountry;
    QLabel qLblZipCode;
    QLineEdit qTxtZipCode;
    QLabel qLblCity;
    QLineEdit qTxtCity;
    QLabel qLblStreet;
    QLineEdit qTxtStreet;
    QLabel qLblProvider;
    QComboBox qLstProviders;
    QPushButton qBtnFind;
    QLabel qLblLog;
    QTextEdit qTxtLog;

  // methods:
  public: // ctor/dtor
    MainWindow(QWidget *pQParent = nullptr);
    virtual ~MainWindow();
    MainWindow(const MainWindow&) = delete;
    MainWindow& operator=(const MainWindow&) = delete;

  private: // internal stuff
    void init(); // initializes geo service providers
    void find(); // sends request
    void report(); // processes reply
    void log(const QString &qString)
    {
      qTxtLog.setPlainText(qTxtLog.toPlainText() + qString);
      qTxtLog.moveCursor(QTextCursor::End);
    }
    void log(const char *text) { log(QString::fromUtf8(text)); }
    void log(const std::string &text) { log(text.c_str()); }
};

MainWindow::MainWindow(QWidget *pQParent):
  QWidget(pQParent),
  qLblCountry(QString::fromUtf8("Country:")),
  qLblZipCode(QString::fromUtf8("Postal Code:")),
  qLblCity(QString::fromUtf8("City:")),
  qLblStreet(QString::fromUtf8("Street:")),
  qLblProvider(QString::fromUtf8("Provider:")),
  qBtnFind(QString::fromUtf8("Find Coordinates")),
  qLblLog(QString::fromUtf8("Log:"))
{
  // setup child widgets
  qForm.addRow(&qLblCountry, &qTxtCountry);
  qForm.addRow(&qLblZipCode, &qTxtZipCode);
  qForm.addRow(&qLblCity, &qTxtCity);
  qForm.addRow(&qLblStreet, &qTxtStreet);
  qForm.addRow(&qLblProvider, &qLstProviders);
  qBox.addLayout(&qForm);
  qBox.addWidget(&qBtnFind);
  qBox.addWidget(&qLblLog);
  qBox.addWidget(&qTxtLog);
  setLayout(&qBox);
  // init service provider list
  init();
  // install signal handlers
  QObject::connect(&qBtnFind, &QPushButton::clicked,
    this, &MainWindow::find);
  // fill in a sample request with a known address initially
  qTxtCountry.setText(QString::fromUtf8("Germany"));
  qTxtZipCode.setText(QString::fromUtf8("88250"));
  qTxtCity.setText(QString::fromUtf8("Weingarten"));
  qTxtStreet.setText(QString::fromUtf8("Danziger Str. 3"));
}

MainWindow::~MainWindow()
{
  // clean-up
  for (QGeoServiceProvider *pQGeoProvider : pQGeoProviders) {
    delete pQGeoProvider;
  }
}

void MainWindow::init()
{
  // initialize Geo Service Providers
  { std::ostringstream out;
    QStringList qGeoSrvList
      = QGeoServiceProvider::availableServiceProviders();
    for (QString entry : qGeoSrvList) {
      out << "Try service: " << entry.toStdString() << '\n';
      // choose provider
      QGeoServiceProvider *pQGeoProvider = new QGeoServiceProvider(entry);
      if (!pQGeoProvider) {
        out
          << "ERROR: GeoServiceProvider '" << entry.toStdString()
          << "' not available!\n";
        continue;
      }
      QGeoCodingManager *pQGeoCoder = pQGeoProvider->geocodingManager();
      if (!pQGeoCoder) {
        out
          << "ERROR: GeoCodingManager '" << entry.toStdString()
          << "' not available!\n";
        delete pQGeoProvider;
        continue;
      }
      QLocale qLocaleC(QLocale::C, QLocale::AnyCountry);
      pQGeoCoder->setLocale(qLocaleC);
      qLstProviders.addItem(entry);
      pQGeoProviders.push_back(pQGeoProvider);
      out << "Service " << entry.toStdString() << " available.\n";
    }
    log(out.str());
  }
  if (pQGeoProviders.empty()) qBtnFind.setEnabled(false);
}

std::string format(const QGeoAddress &qGeoAddr)
{
  std::ostringstream out;
  out
    << qGeoAddr.country().toUtf8().data() << "; "
    << qGeoAddr.postalCode().toUtf8().data() << "; "
    << qGeoAddr.city().toUtf8().data() << "; "
    << qGeoAddr.street().toUtf8().data();
  return out.str();
}

void MainWindow::find()
{
  // get current geo service provider
  QGeoServiceProvider *pQGeoProvider
    = pQGeoProviders[qLstProviders.currentIndex()];
  // fill in request
  QGeoAddress qGeoAddr;
  qGeoAddr.setCountry(qTxtCountry.text());
  qGeoAddr.setPostalCode(qTxtZipCode.text());
  qGeoAddr.setCity(qTxtCity.text());
  qGeoAddr.setStreet(qTxtStreet.text());
  QGeoCodeReply *pQGeoCode
    = pQGeoProvider->geocodingManager()->geocode(qGeoAddr);
  if (!pQGeoCode) {
    log("GeoCoding totally failed!\n");
    return;
  }
  { std::ostringstream out;
    out << "Sending request for:\n"
      << format(qGeoAddr) << "...\n";
    log(out.str());
  }
  // install signal handler to process result later
  QObject::connect(pQGeoCode, &QGeoCodeReply::finished,
    this, &MainWindow::report);
  /* This signal handler will delete it's own sender.
   * Hence, the connection need not to be remembered
   * although it has only a limited life-time.
   */
}

void MainWindow::report()
{
  QGeoCodeReply *pQGeoCode
    = dynamic_cast<QGeoCodeReply*>(sender());
  // process reply
  std::ostringstream out;
  out << "Reply: " << pQGeoCode->errorString().toStdString() << '\n';
  switch (pQGeoCode->error()) {
    case QGeoCodeReply::NoError: {
      // eval result
      QList<QGeoLocation> qGeoLocs = pQGeoCode->locations();
      out << qGeoLocs.size() << " location(s) returned.\n";
      for (QGeoLocation &qGeoLoc : qGeoLocs) {
        QGeoAddress qGeoAddr = qGeoLoc.address();
        QGeoCoordinate qGeoCoord = qGeoLoc.coordinate();
        out
          << "Coordinates for "
          << qGeoAddr.text().toUtf8().data() << ":\n"
          << "Lat.:  " << qGeoCoord.latitude() << '\n'
          << "Long.: " << qGeoCoord.longitude() << '\n'
          << "Alt.:  " << qGeoCoord.altitude() << '\n';
      }     
    } break;
#define CASE(ERROR) \
case QGeoCodeReply::ERROR: out << #ERROR << '\n'; break
    CASE(EngineNotSetError);
    CASE(CommunicationError);
    CASE(ParseError);
    CASE(UnsupportedOptionError);
    CASE(CombinationError);
    CASE(UnknownError);
#undef CASE
    default: out << "Undocumented error!\n";
  }
  // log result
  log(out.str());
  // clean-up
  /* delete sender in signal handler could be lethal
   * Hence, delete it later...
   */
  pQGeoCode->deleteLater();
}

int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  // main application
  QApplication app(argc, argv);
  // setup GUI
  MainWindow win;
  win.show();
  // runtime loop
  app.exec();
  // done
  return 0;
}

Примечание:

Внешний вид и поведение такие же, как и в приведенном выше примере. Я немного изменил вывод ответа.

При подготовке этого примера я понял, что на самом деле нет необходимости устанавливать адрес возвращаемого QGeoLocation, поскольку он уже есть. ИМХО, интересно, что возвращаемый адрес выглядит несколько иначе, чем запрашиваемый. Кажется, что он возвращается в (я бы сказал) нормализованной форме.

...