Using Google's Geocoding API

In this example, we will learn how to obtain the full address of a specific location by using Google's Geocoding API.

How to do it…

Let's create a program that utilizes the Geocoding API by following these steps:

  1. First, create a new Qt Widgets Application project.
  2. Next, open up mainwindow.ui and add a couple of text labels, input fields, and a button to make your UI to look similar to this:
    How to do it…
  3. After that, open up your project (.pro) file and add the network module to your project. You can do that by simply adding the network text after core and gui, like so:
    QT += core gui network
  4. Then, open up mainwindow.h and add the following headers to the source code, right after the line #include <QMainWindow>:
    #include <QDebug>
    #include <QtNetwork/QNetworkAccessManager>
    #include <QtNetwork/QNetworkReply>
    #include <QXmlStreamReader>
  5. Next, declare a slot function manually and call it getAddressFinished():
    private slots:
      void getAddressFinished(QNetworkReply* reply);
  6. Right after that, declare a private variable called addressRequest:
    private:
      QNetworkAccessManager* addressRequest;
  7. Once you are done with that, open up mainwindow.ui again, right-click on the Get Address button, and select Go to slot…. Then choose the clicked() option and press OK. A slot function will now be added to both the mainwindow.h and mainwindow.cpp source files.
  8. Now, open up mainwindow.cpp and add the following code to the class constructor:
    MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent),
      ui(new Ui::MainWindow)
    {
      ui->setupUi(this);
    
      addressRequest = new QNetworkAccessManager();
      connect(addressRequest, SIGNAL(finished(QNetworkReply*)),   SLOT(getAddressFinished(QNetworkReply*)));
    }
  9. Then, we will add the following code to the getAddressFinished() slot function we declared manually just now:
    void MainWindow::getAddressFinished(QNetworkReply* reply)
    {
      QByteArray bytes = reply->readAll();
    
      //qDebug() << QString::fromUtf8(bytes.data(), bytes.size());
    
      QXmlStreamReader xml;
      xml.addData(bytes);
    
      while(!xml.atEnd())
      {
        if (xml.isStartElement())
        {
          QString name = xml.name().toString();
          //qDebug() << name;
    
          if (name == "formatted_address")
          {
            QString text = xml.readElementText();
            qDebug() << "Address:" << text;
            return;
          }
        }
    
        xml.readNext();
      }
    
      if (xml.hasError())
      {
        qDebug() << "Error loading XML:" << xml.errorString();
        return;
      }
    
      qDebug() << "No result.";
    }
  10. Finally, add the following code to the clicked() slot function created by Qt:
    void MainWindow::on_getAddressButton_clicked()
    {
      QString latitude = ui->latitude->text();
      QString longitude = ui->longitude->text();
    
      QNetworkRequest request;
      request.setUrl(QUrl("http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latitude + "," + longitude + "&sensor=false"));
      addressRequest->get(request);
    }
  11. Build and run the program now and you should be able to obtain the address by inserting the longitude and latitude values and clicking the Get Address button:
    How to do it…
  12. Let's try with longitude -73.9780838 and latitude 40.6712957. Click the Get Address button and you will see the following result in the application output window:
    Address: "180-190 7th Ave, Brooklyn, NY 11215, USA"

How it works…

I won't be able to tell you exactly how Google obtains the address from its backend system, but I can teach you how to request the data from Google by using QNetworkRequest. Basically, all you need to do is to set the URL of the network request to the URL I used in the previous source code and append both the latitude and longitude information to the URL. After that, all we can do is wait for the response from the Google API server.

Do notice that we need to specify XML as the desired format when sending the request to Google; otherwise, it may return the results in JSON format instead. This can be done by adding the xml keyword within the network request URL, as highlighted here:

request.setUrl(QUrl("http://maps.googleapis.com/maps/api/geocode/xml?latlng=" + latitude + "," + longitude + "&sensor=false"));

When the program the received the response from Google, the getAddressFinished() slot function will be called and we will be able to obtain the data sent by Google through QNetworkReply.

Google usually replies with a long text in XML format, which contains a ton of data we don't need. We used QXmlStreamReader to parse the data because in this case we don't have to care about the parent-child relationship of the XML structure.

All we need is the text stored in the formatted_address element in the XML data. Since there is more than one element by the name of formatted_address, we just need to find the first one and ignore the rest.

You can also do the reverse by providing an address to Google and obtain the location's coordinate from its network response.

There's more…

Google's Geocoding API is part of the Google Maps APIs Web Services, which provides geographical data for your map applications. Besides the Geocoding API, you can also use their Location API, Geolocation API, Time Zone API, and so on to achieve your desired results.

Note

For more information regarding the Google Maps APIs Web Services, visit this link: https://developers.google.com/maps/web-services

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.123.189