我试图通过QGeoServiceProvider和QGeoCodingManager使用osm api从给定的物理地址导出纬度和经度。 因此我偶然发现了Question,这似乎完全符合我的需要。
但是我想在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...
但没有坐标。我假设与获取lat和lon数据的位置的连接失败。但正如我所提到的,我不明白这里的联系。 任何帮助表示赞赏
修改 所以我尝试建立一个连接来捕获完成的信号,如建议的那样。 代码现在看起来像这样:
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()));
使用Slot:
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;
}
}
然而,完成的信号没有被触发。因此结果是一样的。 的修改
从您的Gui实施代码答案:
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();
}
这里是MainWindow的头文件:
#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
答案 0 :(得分:1)
我使用GUI将my older sample转换为最小的应用程序:
// 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;
}
在Windows 10(64位)上的cygwin中进行了编译和测试:
$ 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
备注:强>
当我写这个样本时,我非常仔细地考虑了涉及变量的范围和生命周期。 (实际上,我将一些局部变量更改为使用new
创建的指针和实例来实现此目的。)这是我对任何读者的提示。
在我的1 st 测试中,应用程序最终在CommunicationError
。我很确定我们公司的安全政策是对此负责的。 (我对我在家中成功测试的旧样本做了同样的事情 - 结果相同。)
2 nd 测试(在家里)变得更好。首先,我试图找到服务提供商osm
的地址,结果为0。将服务提供商更改为esri
会返回一个结果。
我将输出复制到maps.google.de
:
这实际上是正确的结果 - 因为我测试了我正在工作的公司EKS InTec的(新)地址。
在上面的示例中使用lambda会使它有点难以阅读。因此,我重新访问了样本。现在,所有相关内容已移至class MainWindow
(希望更接近OP的要求)。 lambda被简单的方法所取代。
// 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
的地址,因为它已经存在。恕我直言,有趣的是返回的地址看起来与请求的有点不同。它似乎以(我想说的)标准化形式返回。