bing_source.cpp
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2015, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28 //
29 // *****************************************************************************
30 
31 #include <tile_map/bing_source.h>
32 #include <boost/lexical_cast.hpp>
33 #include <boost/random.hpp>
34 
35 #include <QRegExp>
36 #include <QString>
37 
38 #include <json/json.h>
39 
40 namespace tile_map
41 {
42  const QString BingSource::BING_TYPE = "bing";
43  const std::string BingSource::BING_IMAGE_URL_KEY = "imageUrl";
44  const std::string BingSource::BING_IMAGE_URL_SUBDOMAIN_KEY = "imageUrlSubdomains";
45  const std::string BingSource::BING_RESOURCE_SET_KEY = "resourceSets";
46  const std::string BingSource::BING_RESOURCE_KEY = "resources";
47  const std::string BingSource::BING_STATUS_CODE_KEY = "statusCode";
48 
49  BingSource::BingSource(const QString& name) :
50  network_manager_(this)
51  {
52  name_ = name;
53  is_custom_ = false;
54  max_zoom_ = 19;
55  base_url_ = "https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?uriScheme=https&include=ImageryProviders&key={api_key}";
56  tile_url_ = "";
57  min_zoom_ = 2;
58 
59  QObject::connect(&network_manager_, SIGNAL(finished(QNetworkReply*)),
60  this, SLOT(ReplyFinished(QNetworkReply*)));
61  }
62 
63  size_t BingSource::GenerateTileHash(int32_t level, int64_t x, int64_t y)
64  {
65  size_t hash = hash_((base_url_ + api_key_ + GenerateQuadKey(level, x, y)).toStdString());
66  return hash;
67  }
68 
69  QString BingSource::GenerateTileUrl(int32_t level, int64_t x, int64_t y)
70  {
71  QString url = tile_url_;
72  if (!subdomains_.empty())
73  {
74  boost::random::uniform_int_distribution<> random(0, (int) subdomains_.size() - 1);
75  url.replace(QString::fromStdString("{subdomain}"), subdomains_[random(rng_)]);
76  }
77  url.replace(QString::fromStdString("{quadkey}"), GenerateQuadKey(level, x, y));
78  return url;
79  }
80 
81  QString BingSource::GetType() const
82  {
83  return BING_TYPE;
84  }
85 
86  QString BingSource::GetApiKey() const
87  {
88  return api_key_;
89  }
90 
91  void BingSource::SetApiKey(const QString& api_key)
92  {
93  api_key_ = api_key.trimmed();
94  if (!api_key_.isEmpty())
95  {
96  QString url(base_url_);
97  url.replace(QString::fromStdString("{api_key}"), api_key_);
98  // Changing the API key will result in the tile URL changing; go ahead
99  // and blank it out so we don't make requests using the old one.
100  tile_url_= "";
101  subdomains_.clear();
102  network_manager_.get(QNetworkRequest(QUrl(url)));
103  }
104  }
105 
106  QString BingSource::GenerateQuadKey(int32_t level, int64_t x, int64_t y) const
107  {
108  QString quadkey;
109  for (int32_t i = level; i > 0; i--)
110  {
111  int32_t bitmask = 1 << (i-1);
112  int32_t digit = 0;
113  if ((x & bitmask) != 0)
114  {
115  digit |= 1;
116  }
117  if ((y & bitmask) != 0)
118  {
119  digit |= 2;
120  }
121  quadkey.append(QString::number(digit));
122  }
123 
124  return quadkey;
125  }
126 
127  void BingSource::ReplyFinished(QNetworkReply* reply)
128  {
129  QString reply_string(reply->readAll());
130  Json::Reader reader;
131  Json::Value root;
132  reader.parse(reply_string.toStdString(), root);
133 
134  int status = root[BING_STATUS_CODE_KEY].asInt();
135  if (status != 200)
136  {
137  Q_EMIT ErrorMessage("Bing authorization error: " + boost::lexical_cast<std::string>(status));
138  }
139  else
140  {
141  if (!root[BING_RESOURCE_SET_KEY].isArray() ||
142  root[BING_RESOURCE_SET_KEY].size() == 0)
143  {
144  Q_EMIT ErrorMessage("No Bing resource sets found.");
145  return;
146  }
147  Json::Value firstResourceSet = root[BING_RESOURCE_SET_KEY][0];
148 
149  if (!firstResourceSet[BING_RESOURCE_KEY].isArray() ||
150  firstResourceSet[BING_RESOURCE_KEY].size() == 0)
151  {
152  Q_EMIT ErrorMessage("No Bing resources found.");
153  return;
154  }
155 
156  Json::Value first_resource = firstResourceSet[BING_RESOURCE_KEY][0];
157 
158  std::string image_url = first_resource[BING_IMAGE_URL_KEY].asString();
159 
160  if (image_url.empty())
161  {
162  Q_EMIT ErrorMessage("No Bing image URL found.");
163  return;
164  }
165 
166  tile_url_ = QString::fromStdString(image_url);
167  SetMaxZoom(19);
168 
169 
170  if (!first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].isArray() ||
171  first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].size() == 0)
172  {
173  Q_EMIT ErrorMessage("No image URL subdomains; maybe that's ok sometimes?");
174  }
175 
176  for (int i = 0; i < first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].size(); i++)
177  {
178  Json::Value subdomain = first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY][i];
179  subdomains_.push_back(QString::fromStdString(subdomain.asString()));
180  }
181 
182  Q_EMIT InfoMessage("API Key Set.");
183  }
184  }
185 }
boost::random::mt19937 rng_
Definition: bing_source.h:129
root
QString GenerateQuadKey(int32_t level, int64_t x, int64_t y) const
static const std::string BING_IMAGE_URL_KEY
Definition: bing_source.h:133
static const QString BING_TYPE
Definition: bing_source.h:107
QString GetApiKey() const
Definition: bing_source.cpp:86
boost::hash< std::string > hash_
Definition: bing_source.h:127
virtual void SetMaxZoom(int32_t max_zoom)
Definition: tile_source.cpp:60
static const std::string BING_STATUS_CODE_KEY
Definition: bing_source.h:137
BingSource(const QString &name)
Definition: bing_source.cpp:49
void InfoMessage(const std::string &info_msg) const
void ErrorMessage(const std::string &error_msg) const
static const std::string BING_IMAGE_URL_SUBDOMAIN_KEY
Definition: bing_source.h:134
static const std::string BING_RESOURCE_KEY
Definition: bing_source.h:136
virtual QString GetType() const
Definition: bing_source.cpp:81
static const std::string BING_RESOURCE_SET_KEY
Definition: bing_source.h:135
void SetApiKey(const QString &api_key)
Definition: bing_source.cpp:91
std::vector< QString > subdomains_
Definition: bing_source.h:130
QNetworkAccessManager network_manager_
Definition: bing_source.h:128
virtual QString GenerateTileUrl(int32_t level, int64_t x, int64_t y)
Definition: bing_source.cpp:69
virtual size_t GenerateTileHash(int32_t level, int64_t x, int64_t y)
Definition: bing_source.cpp:63
void ReplyFinished(QNetworkReply *reply)


tile_map
Author(s): Marc Alban
autogenerated on Thu Jun 6 2019 19:25:35