Support v8 sprite, glyph, and style mapbox:// urls
This commit is contained in:
@@ -13,8 +13,8 @@ struct Resource {
|
||||
Source,
|
||||
Tile,
|
||||
Glyphs,
|
||||
JSON,
|
||||
Image
|
||||
SpriteImage,
|
||||
SpriteJSON
|
||||
};
|
||||
|
||||
const Kind kind;
|
||||
|
||||
@@ -217,7 +217,7 @@ void SQLiteCache::Impl::put(const Resource& resource, std::shared_ptr<const Resp
|
||||
putStmt->bind(6 /* expires */, response->expires);
|
||||
|
||||
std::string data;
|
||||
if (resource.kind != Resource::Image) {
|
||||
if (resource.kind != Resource::SpriteImage) {
|
||||
// Do not compress images, since they are typically compressed already.
|
||||
data = util::compress(response->data);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/util/raster.hpp>
|
||||
#include <mbgl/util/thread.hpp>
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
|
||||
@@ -49,7 +50,7 @@ Sprite::Sprite(const std::string& baseUrl, float pixelRatio_)
|
||||
loader = std::make_unique<Loader>();
|
||||
|
||||
FileSource* fs = util::ThreadContext::getFileSource();
|
||||
loader->jsonRequest = fs->request({ Resource::Kind::JSON, jsonURL }, util::RunLoop::getLoop(),
|
||||
loader->jsonRequest = fs->request({ Resource::Kind::SpriteJSON, jsonURL }, util::RunLoop::getLoop(),
|
||||
[this, jsonURL](const Response& res) {
|
||||
loader->jsonRequest = nullptr;
|
||||
if (res.status == Response::Successful) {
|
||||
@@ -65,7 +66,7 @@ Sprite::Sprite(const std::string& baseUrl, float pixelRatio_)
|
||||
});
|
||||
|
||||
loader->spriteRequest =
|
||||
fs->request({ Resource::Kind::Image, spriteURL }, util::RunLoop::getLoop(),
|
||||
fs->request({ Resource::Kind::SpriteImage, spriteURL }, util::RunLoop::getLoop(),
|
||||
[this, spriteURL](const Response& res) {
|
||||
loader->spriteRequest = nullptr;
|
||||
if (res.status == Response::Successful) {
|
||||
|
||||
@@ -55,6 +55,11 @@ Request* DefaultFileSource::request(const Resource& resource,
|
||||
url = util::mapbox::normalizeGlyphsURL(resource.url, accessToken);
|
||||
break;
|
||||
|
||||
case Resource::Kind::SpriteImage:
|
||||
case Resource::Kind::SpriteJSON:
|
||||
url = util::mapbox::normalizeSpriteURL(resource.url, accessToken);
|
||||
break;
|
||||
|
||||
default:
|
||||
url = resource.url;
|
||||
}
|
||||
|
||||
@@ -1,59 +1,90 @@
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
namespace mapbox {
|
||||
|
||||
const std::string mapbox = "mapbox://";
|
||||
const std::string protocol = "mapbox://";
|
||||
const std::string baseURL = "https://api.mapbox.com/";
|
||||
|
||||
std::string normalizeURL(const std::string& url, const std::string& pathPrefix, const std::string& accessToken) {
|
||||
if (accessToken.empty())
|
||||
throw std::runtime_error("You must provide a Mapbox API access token for Mapbox tile sources");
|
||||
bool isMapboxURL(const std::string& url) {
|
||||
return url.compare(0, protocol.length(), protocol) == 0;
|
||||
}
|
||||
|
||||
return std::string("https://api.tiles.mapbox.com")
|
||||
+ pathPrefix
|
||||
+ url.substr(mapbox.length())
|
||||
+ "?access_token="
|
||||
+ accessToken;
|
||||
std::vector<std::string> getMapboxURLPathname(const std::string& url) {
|
||||
std::vector<std::string> pathname;
|
||||
std::size_t startIndex = protocol.length();
|
||||
while (startIndex < url.length()) {
|
||||
std::size_t endIndex = url.find("/", startIndex);
|
||||
if (endIndex == std::string::npos) endIndex = url.length();
|
||||
pathname.push_back(url.substr(startIndex, endIndex - startIndex));
|
||||
startIndex = endIndex + 1;
|
||||
}
|
||||
return pathname;
|
||||
}
|
||||
|
||||
std::string normalizeSourceURL(const std::string& url, const std::string& accessToken) {
|
||||
if (url.compare(0, mapbox.length(), mapbox) != 0)
|
||||
if (!isMapboxURL(url)) {
|
||||
return url;
|
||||
}
|
||||
|
||||
std::string result = normalizeURL(url + ".json", "/v4/", accessToken);
|
||||
if (accessToken.empty()) {
|
||||
throw std::runtime_error("You must provide a Mapbox API access token for Mapbox tile sources");
|
||||
}
|
||||
|
||||
// TileJSON requests need a secure flag appended to their URLs so
|
||||
// that the server knows to send SSL-ified resource references.
|
||||
result += "&secure";
|
||||
|
||||
return result;
|
||||
return baseURL + "v4/" + url.substr(protocol.length()) + ".json?access_token=" + accessToken + "&secure";
|
||||
}
|
||||
|
||||
std::string normalizeStyleURL(const std::string& url, const std::string& accessToken) {
|
||||
if (url.compare(0, mapbox.length(), mapbox) != 0)
|
||||
if (!isMapboxURL(url)) {
|
||||
return url;
|
||||
}
|
||||
|
||||
const std::string user = url.substr(mapbox.length(), url.find('.') - mapbox.length());
|
||||
std::vector<std::string> pathname = getMapboxURLPathname(url);
|
||||
std::string user = pathname[1];
|
||||
std::string id = pathname[2];
|
||||
bool isDraft = pathname.size() > 3;
|
||||
return baseURL + "styles/v1/" + user + "/" + id + (isDraft ? "/draft" : "") + "?access_token=" + accessToken;
|
||||
}
|
||||
|
||||
return normalizeURL(url, "/styles/v1/" + user + "/", accessToken);
|
||||
std::string normalizeSpriteURL(const std::string& url, const std::string& accessToken) {
|
||||
if (!isMapboxURL(url)) {
|
||||
return url;
|
||||
}
|
||||
|
||||
std::vector<std::string> pathname = getMapboxURLPathname(url);
|
||||
std::string user = pathname[1];
|
||||
bool isDraft = pathname.size() > 3;
|
||||
|
||||
std::string id, extension;
|
||||
if (isDraft) {
|
||||
size_t index = pathname[3].find_first_of("@.");
|
||||
id = pathname[2];
|
||||
extension = pathname[3].substr(index);
|
||||
} else {
|
||||
size_t index = pathname[2].find_first_of("@.");
|
||||
id = pathname[2].substr(0, index);
|
||||
extension = pathname[2].substr(index);
|
||||
}
|
||||
|
||||
return baseURL + "styles/v1/" + user + "/" + id + "/" + (isDraft ? "draft/" : "") + "sprite" + extension + "?access_token=" + accessToken;
|
||||
}
|
||||
|
||||
std::string normalizeGlyphsURL(const std::string& url, const std::string& accessToken) {
|
||||
if (url.compare(0, mapbox.length(), mapbox) != 0) {
|
||||
if (!isMapboxURL(url)) {
|
||||
return url;
|
||||
} else {
|
||||
const std::string prefix = "mapbox://fonts/";
|
||||
const std::string user = url.substr(prefix.length(), url.find("/", prefix.length()) - prefix.length());
|
||||
return normalizeURL("mapbox://" + user + "/{fontstack}/{range}.pbf", "/fonts/v1/", accessToken);
|
||||
}
|
||||
|
||||
std::vector<std::string> pathname = getMapboxURLPathname(url);
|
||||
std::string user = pathname[1];
|
||||
return baseURL + "fonts/v1/" + user + "/{fontstack}/{range}.pbf?access_token=" + accessToken;
|
||||
}
|
||||
|
||||
std::string normalizeTileURL(const std::string& url, const std::string& sourceURL, SourceType sourceType) {
|
||||
if (sourceURL.empty() || sourceURL.compare(0, mapbox.length(), mapbox) != 0 ||
|
||||
sourceType != SourceType::Raster) {
|
||||
if (sourceURL.empty() || !isMapboxURL(sourceURL) || sourceType != SourceType::Raster) {
|
||||
return url;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ namespace mapbox {
|
||||
|
||||
std::string normalizeSourceURL(const std::string& url, const std::string& accessToken);
|
||||
std::string normalizeStyleURL(const std::string& url, const std::string& accessToken);
|
||||
std::string normalizeSpriteURL(const std::string& url, const std::string& accessToken);
|
||||
std::string normalizeGlyphsURL(const std::string& url, const std::string& accessToken);
|
||||
std::string normalizeTileURL(const std::string& url, const std::string& sourceURL, SourceType sourceType);
|
||||
|
||||
|
||||
@@ -8,21 +8,29 @@
|
||||
using namespace mbgl;
|
||||
|
||||
TEST(Mapbox, SourceURL) {
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "key"), "https://api.tiles.mapbox.com/v4/user.map.json?access_token=key&secure");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "token"), "https://api.tiles.mapbox.com/v4/user.map.json?access_token=token&secure");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "key"), "https://api.mapbox.com/v4/user.map.json?access_token=key&secure");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "token"), "https://api.mapbox.com/v4/user.map.json?access_token=token&secure");
|
||||
EXPECT_THROW(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", ""), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST(Mapbox, GlyphsURL) {
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("mapbox://fonts/boxmap/{fontstack}/{range}.pbf", "key"), "https://api.tiles.mapbox.com/fonts/v1/boxmap/{fontstack}/{range}.pbf?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("mapbox://fonts/boxmap/{fontstack}/{range}.pbf", "key"), "https://api.mapbox.com/fonts/v1/boxmap/{fontstack}/{range}.pbf?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("http://path", "key"), "http://path");
|
||||
}
|
||||
|
||||
TEST(Mapbox, StyleURL) {
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("mapbox://user.style", "key"), "https://api.tiles.mapbox.com/styles/v1/user/user.style?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("mapbox://styles/user/style", "key"), "https://api.mapbox.com/styles/v1/user/style?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("mapbox://styles/user/style/draft", "key"), "https://api.mapbox.com/styles/v1/user/style/draft?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("http://path", "key"), "http://path");
|
||||
}
|
||||
|
||||
TEST(Mapbox, SpriteURL) {
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("map/box/sprites@2x.json", "key"), "map/box/sprites@2x.json");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("mapbox://sprites/mapbox/streets-v8.json", "key"), "https://api.mapbox.com/styles/v1/mapbox/streets-v8/sprite.json?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("mapbox://sprites/mapbox/streets-v8@2x.png", "key"), "https://api.mapbox.com/styles/v1/mapbox/streets-v8/sprite@2x.png?access_token=key");
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("mapbox://sprites/mapbox/streets-v8/draft@2x.png", "key"), "https://api.mapbox.com/styles/v1/mapbox/streets-v8/draft/sprite@2x.png?access_token=key");
|
||||
}
|
||||
|
||||
TEST(Mapbox, TileURL) {
|
||||
try {
|
||||
EXPECT_EQ(mbgl::util::mapbox::normalizeTileURL("http://path.png/tile.png", "mapbox://user.map", SourceType::Raster), "http://path.png/tile{ratio}.png");
|
||||
|
||||
Reference in New Issue
Block a user