File: NominatimGeocoder.cpp

package info (click to toggle)
tulip 6.0.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 196,224 kB
  • sloc: cpp: 571,851; ansic: 13,983; python: 4,105; sh: 1,555; yacc: 522; xml: 484; makefile: 168; pascal: 148; lex: 55
file content (103 lines) | stat: -rw-r--r-- 2,852 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
 *
 * This file is part of Tulip (https://tulip.labri.fr)
 *
 * Authors: David Auber and the Tulip development Team
 * from LaBRI, University of Bordeaux
 *
 * Tulip is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation, either version 3
 * of the License, or (at your option) any later version.
 *
 * Tulip is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 */

#include <QEventLoop>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>

#include <tulip/TlpQtTools.h>
#include <tulip/YajlFacade.h>

#include "NominatimGeocoder.h"

using namespace std;
using namespace tlp;

class NominatimResultsParser : public YajlParseFacade {

public:
  void parseString(string &value) override {
    if (_currentKey == "display_name") {
      addresses.push_back(value);
    } else if (_currentKey == "lat") {
      _lat = stod(value);
    } else if (_currentKey == "lon") {
      _lng = stod(value);
      latLngs.emplace_back(_lat, _lng);
    }
  }

  void parseMapKey(string &value) override {
    _currentKey = value;
  }

  vector<string> addresses;
  vector<pair<double, double>> latLngs;

private:
  string _currentKey;
  double _lat;
  double _lng;
};

NominatimGeocoder::NominatimGeocoder() {
  _networkAccessManager = new QNetworkAccessManager();
}

NominatimGeocoder::~NominatimGeocoder() {
  delete _networkAccessManager;
}

vector<NominatimGeocoderResult> NominatimGeocoder::getLatLngForAddress(const string &address) {

  QUrl nominatimSearchUrl;
  nominatimSearchUrl.setScheme("https");
  nominatimSearchUrl.setHost("nominatim.openstreetmap.org");
  nominatimSearchUrl.setPath("/search");
  nominatimSearchUrl.setQuery("q=" + tlpStringToQString(address) +
                              "&format=json&dedupe=1&limit=20");

  QNetworkRequest request;
  request.setUrl(nominatimSearchUrl);

  QNetworkReply *reply = _networkAccessManager->get(request);
  QEventLoop loop;
  QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
  loop.exec();
  QByteArray jsonData = reply->readAll();

  NominatimResultsParser nominatimParser;
  nominatimParser.parse(reinterpret_cast<const unsigned char *>(jsonData.constData()),
                        jsonData.size());

  unsigned int nbResults = nominatimParser.addresses.size();

  vector<NominatimGeocoderResult> ret;

  for (unsigned int i = 0; i < nbResults; ++i) {
    NominatimGeocoderResult result;
    result.address = nominatimParser.addresses[i];
    result.latLng = nominatimParser.latLngs[i];
    ret.push_back(result);
  }

  return ret;
}