Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <tile_map/bing_source.h>
00032 #include <boost/lexical_cast.hpp>
00033 #include <boost/random.hpp>
00034
00035 #include <QRegExp>
00036 #include <QString>
00037
00038 #include <json/json.h>
00039
00040 namespace tile_map
00041 {
00042 const QString BingSource::BING_TYPE = "bing";
00043 const std::string BingSource::BING_IMAGE_URL_KEY = "imageUrl";
00044 const std::string BingSource::BING_IMAGE_URL_SUBDOMAIN_KEY = "imageUrlSubdomains";
00045 const std::string BingSource::BING_RESOURCE_SET_KEY = "resourceSets";
00046 const std::string BingSource::BING_RESOURCE_KEY = "resources";
00047 const std::string BingSource::BING_STATUS_CODE_KEY = "statusCode";
00048
00049 BingSource::BingSource(const QString& name) :
00050 network_manager_(this)
00051 {
00052 name_ = name;
00053 is_custom_ = false;
00054 max_zoom_ = 19;
00055 base_url_ = "https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?uriScheme=https&include=ImageryProviders&key={api_key}";
00056 tile_url_ = "";
00057 min_zoom_ = 2;
00058
00059 QObject::connect(&network_manager_, SIGNAL(finished(QNetworkReply*)),
00060 this, SLOT(ReplyFinished(QNetworkReply*)));
00061 }
00062
00063 size_t BingSource::GenerateTileHash(int32_t level, int64_t x, int64_t y)
00064 {
00065 size_t hash = hash_((base_url_ + api_key_ + GenerateQuadKey(level, x, y)).toStdString());
00066 return hash;
00067 }
00068
00069 QString BingSource::GenerateTileUrl(int32_t level, int64_t x, int64_t y)
00070 {
00071 QString url = tile_url_;
00072 if (!subdomains_.empty())
00073 {
00074 boost::random::uniform_int_distribution<> random(0, (int) subdomains_.size() - 1);
00075 url.replace(QString::fromStdString("{subdomain}"), subdomains_[random(rng_)]);
00076 }
00077 url.replace(QString::fromStdString("{quadkey}"), GenerateQuadKey(level, x, y));
00078 return url;
00079 }
00080
00081 QString BingSource::GetType() const
00082 {
00083 return BING_TYPE;
00084 }
00085
00086 QString BingSource::GetApiKey() const
00087 {
00088 return api_key_;
00089 }
00090
00091 void BingSource::SetApiKey(const QString& api_key)
00092 {
00093 api_key_ = api_key.trimmed();
00094 if (!api_key_.isEmpty())
00095 {
00096 QString url(base_url_);
00097 url.replace(QString::fromStdString("{api_key}"), api_key_);
00098
00099
00100 tile_url_= "";
00101 subdomains_.clear();
00102 network_manager_.get(QNetworkRequest(QUrl(url)));
00103 }
00104 }
00105
00106 QString BingSource::GenerateQuadKey(int32_t level, int64_t x, int64_t y) const
00107 {
00108 QString quadkey;
00109 for (int32_t i = level; i > 0; i--)
00110 {
00111 int32_t bitmask = 1 << (i-1);
00112 int32_t digit = 0;
00113 if ((x & bitmask) != 0)
00114 {
00115 digit |= 1;
00116 }
00117 if ((y & bitmask) != 0)
00118 {
00119 digit |= 2;
00120 }
00121 quadkey.append(QString::number(digit));
00122 }
00123
00124 return quadkey;
00125 }
00126
00127 void BingSource::ReplyFinished(QNetworkReply* reply)
00128 {
00129 QString reply_string(reply->readAll());
00130 Json::Reader reader;
00131 Json::Value root;
00132 reader.parse(reply_string.toStdString(), root);
00133
00134 int status = root[BING_STATUS_CODE_KEY].asInt();
00135 if (status != 200)
00136 {
00137 Q_EMIT ErrorMessage("Bing authorization error: " + boost::lexical_cast<std::string>(status));
00138 }
00139 else
00140 {
00141 if (!root[BING_RESOURCE_SET_KEY].isArray() ||
00142 root[BING_RESOURCE_SET_KEY].size() == 0)
00143 {
00144 Q_EMIT ErrorMessage("No Bing resource sets found.");
00145 return;
00146 }
00147 Json::Value firstResourceSet = root[BING_RESOURCE_SET_KEY][0];
00148
00149 if (!firstResourceSet[BING_RESOURCE_KEY].isArray() ||
00150 firstResourceSet[BING_RESOURCE_KEY].size() == 0)
00151 {
00152 Q_EMIT ErrorMessage("No Bing resources found.");
00153 return;
00154 }
00155
00156 Json::Value first_resource = firstResourceSet[BING_RESOURCE_KEY][0];
00157
00158 std::string image_url = first_resource[BING_IMAGE_URL_KEY].asString();
00159
00160 if (image_url.empty())
00161 {
00162 Q_EMIT ErrorMessage("No Bing image URL found.");
00163 return;
00164 }
00165
00166 tile_url_ = QString::fromStdString(image_url);
00167 SetMaxZoom(19);
00168
00169
00170 if (!first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].isArray() ||
00171 first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].size() == 0)
00172 {
00173 Q_EMIT ErrorMessage("No image URL subdomains; maybe that's ok sometimes?");
00174 }
00175
00176 for (int i = 0; i < first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY].size(); i++)
00177 {
00178 Json::Value subdomain = first_resource[BING_IMAGE_URL_SUBDOMAIN_KEY][i];
00179 subdomains_.push_back(QString::fromStdString(subdomain.asString()));
00180 }
00181
00182 Q_EMIT InfoMessage("API Key Set.");
00183 }
00184 }
00185 }