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  TileSource(),
51  network_manager_(this)
52  {
53  name_ = name;
54  is_custom_ = false;
55  max_zoom_ = 19;
56  base_url_ = "https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?uriScheme=https&include=ImageryProviders&key={api_key}";
57  tile_url_ = "";
58  min_zoom_ = 2;
59 
60  QObject::connect(&network_manager_, SIGNAL(finished(QNetworkReply*)),
61  this, SLOT(ReplyFinished(QNetworkReply*)));
62  }
63 
64  size_t BingSource::GenerateTileHash(int32_t level, int64_t x, int64_t y)
65  {
66  size_t hash = hash_((base_url_ + api_key_ + GenerateQuadKey(level, x, y)).toStdString());
67  return hash;
68  }
69 
70  QString BingSource::GenerateTileUrl(int32_t level, int64_t x, int64_t y)
71  {
72  QString url = tile_url_;
73  if (!subdomains_.empty())
74  {
75  boost::random::uniform_int_distribution<> random(0, (int) subdomains_.size() - 1);
76  url.replace(QString::fromStdString("{subdomain}"), subdomains_[random(rng_)]);
77  }
78  url.replace(QString::fromStdString("{quadkey}"), GenerateQuadKey(level, x, y));
79  return url;
80  }
81 
82  QString BingSource::GetType() const
83  {
84  return BING_TYPE;
85  }
86 
87  QString BingSource::GetApiKey() const
88  {
89  return api_key_;
90  }
91 
92  void BingSource::SetApiKey(const QString& api_key)
93  {
94  api_key_ = api_key.trimmed();
95  if (!api_key_.isEmpty())
96  {
97  QString url(base_url_);
98  url.replace(QString::fromStdString("{api_key}"), api_key_);
99  // Changing the API key will result in the tile URL changing; go ahead
100  // and blank it out so we don't make requests using the old one.
101  tile_url_= "";
102  subdomains_.clear();
103  network_manager_.get(QNetworkRequest(QUrl(url)));
104  }
105  }
106 
107  QString BingSource::GenerateQuadKey(int32_t level, int64_t x, int64_t y) const
108  {
109  QString quadkey;
110  for (int32_t i = level; i > 0; i--)
111  {
112  int32_t bitmask = 1 << (i-1);
113  int32_t digit = 0;
114  if ((x & bitmask) != 0)
115  {
116  digit |= 1;
117  }
118  if ((y & bitmask) != 0)
119  {
120  digit |= 2;
121  }
122  quadkey.append(QString::number(digit));
123  }
124 
125  return quadkey;
126  }
127 
128  void BingSource::ReplyFinished(QNetworkReply* reply)
129  {
130  QString reply_string(reply->readAll());
131  Json::Reader reader;
132  Json::Value root;
133  reader.parse(reply_string.toStdString(), root);
134 
135  int status = root[BING_STATUS_CODE_KEY].asInt();
136  if (status != 200)
137  {
138  Q_EMIT ErrorMessage("Bing authorization error: " + boost::lexical_cast<std::string>(status));
139  }
140  else
141  {
142  if (!root[BING_RESOURCE_SET_KEY].isArray() ||
143  root[BING_RESOURCE_SET_KEY].size() == 0)
144  {
145  Q_EMIT ErrorMessage("No Bing resource sets found.");
146  return;
147  }
148  Json::Value firstResourceSet = root[BING_RESOURCE_SET_KEY][0];
149 
150  if (!firstResourceSet[BING_RESOURCE_KEY].isArray() ||
151  firstResourceSet[BING_RESOURCE_KEY].size() == 0)
152  {
153  Q_EMIT ErrorMessage("No Bing resources found.");
154  return;
155  }
156 
157  Json::Value first_resource = firstResourceSet[BING_RESOURCE_KEY][0];
158 
159  std::string image_url = first_resource[BING_IMAGE_URL_KEY].asString();
160 
161  if (image_url.empty())
162  {
163  Q_EMIT ErrorMessage("No Bing image URL found.");
164  return;
165  }
166 
167  tile_url_ = QString::fromStdString(image_url);
168  SetMaxZoom(19);
169 
170 
171  if (!first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].isArray() ||
172  first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].size() == 0)
173  {
174  Q_EMIT ErrorMessage("No image URL subdomains; maybe that's ok sometimes?");
175  }
176 
177  for (int i = 0; i < first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].size(); i++)
178  {
179  Json::Value subdomain = first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY][i];
180  subdomains_.push_back(QString::fromStdString(subdomain.asString()));
181  }
182 
183  Q_EMIT InfoMessage("API Key Set.");
184 
185  is_ready_ = true;
186  }
187  }
188 }
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:87
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:82
static const std::string BING_RESOURCE_SET_KEY
Definition: bing_source.h:135
void SetApiKey(const QString &api_key)
Definition: bing_source.cpp:92
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:70
virtual size_t GenerateTileHash(int32_t level, int64_t x, int64_t y)
Definition: bing_source.cpp:64
void ReplyFinished(QNetworkReply *reply)


tile_map
Author(s): Marc Alban
autogenerated on Fri Mar 19 2021 02:44:47