如何在 Windows 上使用 Qt c++ 从一个地理地址获取纬度/经度?

Posted

技术标签:

【中文标题】如何在 Windows 上使用 Qt c++ 从一个地理地址获取纬度/经度?【英文标题】:how to get latitude/longitude from one geo address using Qt c++ on windows? 【发布时间】:2017-09-01 17:49:09 【问题描述】:

在 Qt c++ 上是否可以仅使用地理地址(国家、州、城市、街道等)获取地理位置的坐标(纬度和经度)?

我知道库 QGeoCoordinates、QGeoLocation 和 QGeoAddress,但我不知道是否可以通过它们从地址获取坐标。

欢迎任何帮助。

【问题讨论】:

地址是什么意思?像 IP 地址一样? @maximdumont 地理地址:国家、州、城市、街道等... qtdeveloperdays.com/2013/sites/default/files/presentation_pdf/…,可能吗? 【参考方案1】:

我需要一些时间来掌握这一点,但最终我成功了。

一开始我尝试了你提到的类:QGeoAddressQGeoLocationQGeoCoordinate

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

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

using namespace std;

int main()

  // 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"));
  QGeoLocation qGeoLoc.setAddress(qGeoAddr);
  QGeoCoordinate qGeoCoord = qGeoLoc.coordinate();
  cout
    << "Lat.:  " << qGeoCoord.latitude() << endl
    << "Long.: " << qGeoCoord.longitude() << endl
    << "Alt.:  " << qGeoCoord.altitude() << endl;
  return 0;

这编译并运行,但输出不是很享受:

$ ./testQGeoAddress
Qt Version: 5.6.2
Lat.:  nan
Long.: nan
Alt.:  nan

那么,代码有什么问题?回过头想了想,我得到了一个线索:缺少某种服务,可以将地址转换为坐标。这可能是什么? maps.google.com 或类似网站?

我用谷歌搜索了一段时间,终于找到了关于 Qt location 库的搜索结果。经过一段时间的试验和摆弄,我终于得到了这个运行示例:

文件testQGeoAddress.pro

SOURCES = testQGeoAddress.cc

QT += widgets
QT += positioning
QT += location

文件testQGeoAddress.cc

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

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

using namespace std;

int main(int argc, char **argv)

  cout << "Qt Version: " << QT_VERSION_STR << endl;
  // main application
#undef qApp // undef macro qApp out of the way
  QCoreApplication qApp(argc, argv);
  // check for available services
  QStringList qGeoSrvList
    = QGeoServiceProvider::availableServiceProviders();
  for (QString entry : qGeoSrvList) 
    cout << "Try service: " << entry.toStdString() << endl;
    // choose provider
    QGeoServiceProvider qGeoService(entry);
    QGeoCodingManager *pQGeoCoder = qGeoService.geocodingManager();
    if (!pQGeoCoder) 
      cerr
        << "GeoCodingManager '" << entry.toStdString()
        << "' not available!" << endl;
      continue;
    
    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;
      continue;
    
    cout << "Searching..." << endl;
    QObject::connect(pQGeoCode, &QGeoCodeReply::finished,
      [&qApp, &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;
        
        qApp.exit(0);
      );
    return qApp.exec();
  
  return 0;

在 Windows 10(64 位)的 cygwin 中使用 g++ 构建:

$ qmake-qt5 

$ make
g++ -c -pipe -fno-keep-inline-dllexport -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fexceptions -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. -I/usr/include/qt5 -I/usr/include/qt5/QtWidgets -I/usr/include/qt5/QtLocation -I/usr/include/qt5/QtQuick -I/usr/include/qt5/QtGui -I/usr/include/qt5/QtPositioning -I/usr/include/qt5/QtQml -I/usr/include/qt5/QtNetwork -I/usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQGeoAddress.o testQGeoAddress.cc
g++  -o testQGeoAddress.exe testQGeoAddress.o   -lQt5Widgets -lQt5Location -lQt5Quick -lQt5Gui -lQt5Positioning -lQt5Qml -lQt5Network -lQt5Core -lGL -lpthread 

$ ./testQGeoAddress.exe
Qt Version: 5.6.2
Try service: mapbox
GeoCodingManager 'mapbox' not available!
Try service: osm
Searching...
Reply: 
NoError
1 location(s) returned.
Lat.:  47.8198
Long.: 9.63105
Alt.:  nan

$ 

第一次尝试还不错。关于 QGeoCoordinate::altitude() 值:Open Street Map (osm) 中可能没有此值。

为了检查结果是否正确,我解析了maps.google.com中的输出坐标:

红色气球是搜索的结果。我在 GIMP 中添加了蓝点来标记正确的位置。好吧,搜索接近正确的位置。差异可能是由于坐标精度有限...

【讨论】:

【参考方案2】:

我认为这是可能的。我从来没有尝试过。 请尝试以下代码。

注意:地址的属性被规范化为美国的特征名称,并且可以映射到本地特征级别(例如,德国的州匹配“Bundesland”)。(复制的表单文档)

//Create a geo address object.

QGeoAddress *add = new QGeoAddress(); 

//Assumed for USA.
//Try below order so that search may be bit quicker.
add->setCountry("Country name");
add->setCountryCode("country code");
add->setState("state");
add->setCity("city name");
add->setCounty("county name");
add->setStreet("street name")
add->setPostalCode("Zip Code")


//Create a geo location object

QGeoLocation *loc = new QGeoLocation();
QGeoLocation::setAddress(add); //Set the QGeoLocation object

//Get the coordinates by QGeoCoordinate
QGeoCoordinate cord = loc->coordinate();

//Now get the coordinates for latitude and longitude.
double latitude = cord.latitude();
doublelongitude = cord.longitude();

【讨论】:

忘了告诉...你应该已经构建了“qtlocation”库。

以上是关于如何在 Windows 上使用 Qt c++ 从一个地理地址获取纬度/经度?的主要内容,如果未能解决你的问题,请参考以下文章

在 Windows (Vista) 上使用 C++、Qt 的 GUI 设计问题

使用 Qt 在 OS X/Mac 上构建 C++ 库

如何从 C++/Qt 中的 .exe 和 .dlls 中读取图标(在 Windows 上)?

如何使用WINE在Linux上使用Windows .lib

如何使用 Visual C++ 2010 Express 从 32 位环境为 64 位 Windows 编译 Qt?

C++。如何获得进程从一开始就分配的最大内存量?