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


tile_map
Author(s): Marc Alban
autogenerated on Sun Sep 8 2024 02:27:24