diff options
author | Mike Morris <michael.patrick.morris@gmail.com> | 2014-08-25 16:13:24 -0400 |
---|---|---|
committer | Mike Morris <michael.patrick.morris@gmail.com> | 2014-08-25 16:13:24 -0400 |
commit | 7ae3b8e8ee5f59481fb8373df1d17d25cccce2f0 (patch) | |
tree | 4fd36aa34fc9f5f3096cb60a6eb4c083fced9d43 /src | |
parent | 3466f364121b3a0a157ce62c417c94802484351a (diff) | |
parent | 3d9a2932584b1230c8be47e6935f794cede8fe85 (diff) | |
download | qtlocation-mapboxgl-7ae3b8e8ee5f59481fb8373df1d17d25cccce2f0.tar.gz |
Merge branch 'master' into libuv010
Diffstat (limited to 'src')
-rw-r--r-- | src/geometry/resample.cpp (renamed from src/geometry/interpolate.cpp) | 13 | ||||
-rw-r--r-- | src/map/map.cpp | 6 | ||||
-rw-r--r-- | src/map/source.cpp | 59 | ||||
-rw-r--r-- | src/map/sprite.cpp | 4 | ||||
-rw-r--r-- | src/map/tile_data.cpp | 23 | ||||
-rw-r--r-- | src/renderer/symbol_bucket.cpp | 6 | ||||
-rw-r--r-- | src/style/function_properties.cpp | 30 | ||||
-rw-r--r-- | src/style/style_layer.cpp | 116 | ||||
-rw-r--r-- | src/style/style_parser.cpp | 22 | ||||
-rw-r--r-- | src/style/style_source.cpp | 77 | ||||
-rw-r--r-- | src/text/glyph_store.cpp | 6 | ||||
-rw-r--r-- | src/text/rotation_range.cpp | 6 | ||||
-rw-r--r-- | src/util/mapbox.cpp | 44 | ||||
-rw-r--r-- | src/util/transition.cpp | 62 | ||||
-rw-r--r-- | src/util/url.cpp | 29 |
15 files changed, 299 insertions, 204 deletions
diff --git a/src/geometry/interpolate.cpp b/src/geometry/resample.cpp index 618136ff47..abb3ef1e3c 100644 --- a/src/geometry/interpolate.cpp +++ b/src/geometry/resample.cpp @@ -1,6 +1,6 @@ -#include <mbgl/geometry/interpolate.hpp> +#include <mbgl/geometry/resample.hpp> -#include <mbgl/util/math.hpp> +#include <mbgl/util/interpolate.hpp> #include <cmath> @@ -15,9 +15,9 @@ const std::array<std::vector<float>, 4> minScaleArrays = {{ }}; -Anchors interpolate(const std::vector<Coordinate> &vertices, float spacing, - const float /*minScale*/, float maxScale, const float tilePixelRatio, - const int start) { +Anchors resample(const std::vector<Coordinate> &vertices, float spacing, + const float /*minScale*/, float maxScale, const float tilePixelRatio, + const int start) { maxScale = std::round(std::fmax(std::fmin(8.0f, maxScale / 2.0f), 1.0f)); spacing *= tilePixelRatio / maxScale; @@ -43,7 +43,8 @@ Anchors interpolate(const std::vector<Coordinate> &vertices, float spacing, markedDistance += spacing; float t = (markedDistance - distance) / segmentDist, - x = util::interp(a.x, b.x, t), y = util::interp(a.y, b.y, t), + x = util::interpolate(a.x, b.x, t), + y = util::interpolate(a.y, b.y, t), s = minScales[added % len]; if (x >= 0 && x < 4096 && y >= 0 && y < 4096) { diff --git a/src/map/map.cpp b/src/map/map.cpp index 8caea4c797..8590b464bb 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -11,6 +11,7 @@ #include <mbgl/util/constants.hpp> #include <mbgl/util/uv_detail.hpp> #include <mbgl/util/std.hpp> +#include <mbgl/util/mapbox.hpp> #include <mbgl/style/style.hpp> #include <mbgl/text/glyph_store.hpp> #include <mbgl/geometry/glyph_atlas.hpp> @@ -211,7 +212,7 @@ void Map::setStyleJSON(std::string newStyleJSON, const std::string &base) { sprite.reset(); style->loadJSON((const uint8_t *)styleJSON.c_str()); fileSource->setBase(base); - glyphStore->setURL(style->glyph_url); + glyphStore->setURL(util::mapbox::normalizeGlyphsURL(style->glyph_url, getAccessToken())); update(); } @@ -469,7 +470,8 @@ void Map::updateSources() { for (const std::shared_ptr<StyleSource> &style_source : activeSources) { if (style_source->enabled) { if (!style_source->source) { - style_source->source = std::make_shared<Source>(style_source->info, getAccessToken()); + style_source->source = std::make_shared<Source>(style_source->info); + style_source->source->load(*this); } } else { style_source->source.reset(); diff --git a/src/map/source.cpp b/src/map/source.cpp index 523a7f3bc7..b83384f25f 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -6,40 +6,59 @@ #include <mbgl/util/raster.hpp> #include <mbgl/util/string.hpp> #include <mbgl/util/texturepool.hpp> +#include <mbgl/util/filesource.hpp> #include <mbgl/util/vec.hpp> #include <mbgl/util/std.hpp> +#include <mbgl/util/mapbox.hpp> #include <mbgl/geometry/glyph_atlas.hpp> #include <mbgl/style/style_layer.hpp> - +#include <mbgl/platform/log.hpp> #include <mbgl/map/vector_tile_data.hpp> #include <mbgl/map/raster_tile_data.hpp> namespace mbgl { -Source::Source(SourceInfo info, const std::string &access_token) - : info( - info.type, - normalizeSourceURL(info.url, access_token), - info.tile_size, - info.min_zoom, - info.max_zoom - ) {} - -std::string Source::normalizeSourceURL(const std::string &url, const std::string &access_token) { - const std::string t = "mapbox://"; - if (url.compare(0, t.length(), t) == 0) { - if (access_token.empty()) { - throw std::runtime_error("You must provide a Mapbox API access token for Mapbox tile sources"); - } - return std::string("https://api.tiles.mapbox.com/v4/") + url.substr(t.length()) + "/{z}/{x}/{y}.vector.pbf?access_token=" + access_token; - } else { - return url; +Source::Source(SourceInfo& info) + : info(info) +{ +} + +// Note: This is a separate function that must be called exactly once after creation +// The reason this isn't part of the constructor is that calling shared_from_this() in +// the constructor fails. +void Source::load(Map& map) { + if (info.url.empty()) { + loaded = true; + return; } + + std::string url = util::mapbox::normalizeSourceURL(info.url, map.getAccessToken()); + std::shared_ptr<Source> source = shared_from_this(); + + map.getFileSource()->load(ResourceType::JSON, url, [source, &map](platform::Response *res) { + if (res->code != 200) { + Log::Warning(Event::General, "failed to load source TileJSON"); + return; + } + + rapidjson::Document d; + d.Parse<0>(res->body.c_str()); + + if (d.HasParseError()) { + Log::Warning(Event::General, "invalid source TileJSON"); + return; + } + + source->info.parseTileJSONProperties(d); + source->loaded = true; + + map.update(); + }); } bool Source::update(Map &map) { - if (map.getTime() > updated) { + if (loaded && map.getTime() > updated) { return updateTiles(map); } else { return false; diff --git a/src/map/sprite.cpp b/src/map/sprite.cpp index 88e940c00e..a8f4f97185 100644 --- a/src/map/sprite.cpp +++ b/src/map/sprite.cpp @@ -13,7 +13,7 @@ using namespace mbgl; -SpritePosition::SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t pixelRatio) +SpritePosition::SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, float pixelRatio) : x(x), y(y), width(width), @@ -122,7 +122,7 @@ void Sprite::parseJSON() { uint16_t y = 0; uint16_t width = 0; uint16_t height = 0; - uint8_t pixelRatio = 1; + float pixelRatio = 1.0f; if (value.HasMember("x")) x = value["x"].GetInt(); if (value.HasMember("y")) y = value["y"].GetInt(); diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 4333e2d2fd..57afb8dadb 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -14,13 +14,6 @@ TileData::TileData(Tile::ID id, Map &map, const SourceInfo &source) state(State::initial), map(map), source(source), - url(util::replaceTokens(source.url, [&](const std::string &token) -> std::string { - if (token == "z") return std::to_string(id.z); - if (token == "x") return std::to_string(id.x); - if (token == "y") return std::to_string(id.y); - if (token == "ratio") return (map.getState().getPixelRatio() > 1.0 ? "@2x" : ""); - return ""; - })), debugBucket(debugFontBuffer) { // Initialize tile debug coordinates const std::string str = util::sprintf<32>("%d/%d/%d", id.z, id.x, id.y); @@ -36,11 +29,23 @@ const std::string TileData::toString() const { } void TileData::request() { + if (source.tiles.empty()) + return; + + std::string url = source.tiles[(id.x + id.y) % source.tiles.size()]; + url = util::replaceTokens(url, [&](const std::string &token) -> std::string { + if (token == "z") return std::to_string(id.z); + if (token == "x") return std::to_string(id.x); + if (token == "y") return std::to_string(id.y); + if (token == "ratio") return (map.getState().getPixelRatio() > 1.0 ? "@2x" : ""); + return ""; + }); + state = State::loading; // Note: Somehow this feels slower than the change to request_http() std::weak_ptr<TileData> weak_tile = shared_from_this(); - map.getFileSource()->load(ResourceType::Tile, url, [weak_tile](platform::Response *res) { + map.getFileSource()->load(ResourceType::Tile, url, [weak_tile, url](platform::Response *res) { std::shared_ptr<TileData> tile = weak_tile.lock(); if (!tile || tile->state == State::obsolete) { // noop. Tile is obsolete and we're now just waiting for the refcount @@ -54,7 +59,7 @@ void TileData::request() { tile->reparse(); } else { #if defined(DEBUG) - fprintf(stderr, "[%s] tile loading failed: %d, %s\n", tile->url.c_str(), res->code, res->error_message.c_str()); + fprintf(stderr, "[%s] tile loading failed: %d, %s\n", url.c_str(), res->code, res->error_message.c_str()); #endif } }); diff --git a/src/renderer/symbol_bucket.cpp b/src/renderer/symbol_bucket.cpp index 30110faf02..e8c0fd1829 100644 --- a/src/renderer/symbol_bucket.cpp +++ b/src/renderer/symbol_bucket.cpp @@ -5,7 +5,7 @@ #include <mbgl/geometry/sprite_atlas.hpp> #include <mbgl/geometry/geometry.hpp> #include <mbgl/geometry/anchor.hpp> -#include <mbgl/geometry/interpolate.hpp> +#include <mbgl/geometry/resample.hpp> #include <mbgl/renderer/painter.hpp> #include <mbgl/text/glyph_store.hpp> #include <mbgl/text/placement.hpp> @@ -218,8 +218,8 @@ void SymbolBucket::addFeature(const std::vector<Coordinate> &line, const Shaping if (properties.placement == PlacementType::Line) { // Line labels - anchors = interpolate(line, properties.min_distance, minScale, collision.maxPlacementScale, - collision.tilePixelRatio); + anchors = resample(line, properties.min_distance, minScale, collision.maxPlacementScale, + collision.tilePixelRatio); // Sort anchors by segment so that we can start placement with the // anchors that can be shown at the lowest zoom levels. diff --git a/src/style/function_properties.cpp b/src/style/function_properties.cpp index 879de84f85..346efe65b6 100644 --- a/src/style/function_properties.cpp +++ b/src/style/function_properties.cpp @@ -1,35 +1,11 @@ #include <mbgl/style/function_properties.hpp> #include <mbgl/style/types.hpp> +#include <mbgl/util/interpolate.hpp> #include <cmath> namespace mbgl { - -template <typename T> -inline T interpolate(T smaller, T larger, const float factor); - -template <> -inline float interpolate(const float smaller, const float larger, const float factor) { - return (smaller * (1 - factor)) + (larger * factor); -} - -template <> -inline bool interpolate(const bool smaller, const bool larger, const float factor) { - return interpolate(float(smaller), float(larger), factor); -} - -template <> -inline Color interpolate(const Color smaller, const Color larger, const float factor) { - return {{ - interpolate(smaller[0], larger[0], factor), - interpolate(smaller[1], larger[1], factor), - interpolate(smaller[2], larger[2], factor), - interpolate(smaller[3], larger[3], factor) - }}; -} - - template <typename T> inline T defaultStopsValue(); @@ -70,10 +46,10 @@ T StopsFunction<T>::evaluate(float z) const { const float zoomProgress = z - smaller_z; if (base == 1.0f) { const float t = zoomProgress / zoomDiff; - return interpolate<T>(smaller_val, larger_val, t); + return util::interpolate(smaller_val, larger_val, t); } else { const float t = (std::pow(base, zoomProgress) - 1) / (std::pow(base, zoomDiff) - 1); - return interpolate<T>(smaller_val, larger_val, t); + return util::interpolate(smaller_val, larger_val, t); } } else if (larger) { return larger_val; diff --git a/src/style/style_layer.cpp b/src/style/style_layer.cpp index 4994cf3efa..71916afe23 100644 --- a/src/style/style_layer.cpp +++ b/src/style/style_layer.cpp @@ -3,6 +3,8 @@ #include <mbgl/style/style_layer_group.hpp> #include <mbgl/style/property_fallback.hpp> +#include <mbgl/util/interpolate.hpp> + namespace mbgl { StyleLayer::StyleLayer(const std::string &id, std::map<ClassID, ClassProperties> &&styles) @@ -117,27 +119,26 @@ private: const float z; }; -inline float interpolate(const float a, const float b, const float t) { - return (1.0f - t) * a + t * b; -} - -inline Color interpolate(const Color &a, const Color &b, const float t) { - const float rt = 1.0f - t; - return Color {{ - rt * a[0] + t * b[0], - rt * a[1] + t * b[1], - rt * a[2] + t * b[2], - rt * a[3] + t * b[3] - }}; -} - template <typename T> -inline T interpolate(const T a, const T b, const float t) { - return t >= 0.5 ? b : a; +void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, const timestamp now) { + auto it = appliedStyle.find(key); + if (it != appliedStyle.end()) { + AppliedClassProperties &applied = it->second; + // Iterate through all properties that we need to apply in order. + const PropertyEvaluator<T> evaluator(z); + for (AppliedClassProperty &property : applied.properties) { + if (now >= property.begin) { + // We overwrite the current property with the new value. + target = mapbox::util::apply_visitor(evaluator, property.value); + } else { + // Do not apply this property because its transition hasn't begun yet. + } + } + } } template <typename T> -void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, const timestamp now) { +void StyleLayer::applyTransitionedStyleProperty(PropertyKey key, T &target, const float z, const timestamp now) { auto it = appliedStyle.find(key); if (it != appliedStyle.end()) { AppliedClassProperties &applied = it->second; @@ -150,7 +151,7 @@ void StyleLayer::applyStyleProperty(PropertyKey key, T &target, const float z, c } else if (now >= property.begin) { // We overwrite the current property partially with the new value. float progress = float(now - property.begin) / float(property.end - property.begin); - target = interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress); + target = util::interpolate(target, mapbox::util::apply_visitor(evaluator, property.value), progress); } else { // Do not apply this property because its transition hasn't begun yet. } @@ -163,11 +164,11 @@ void StyleLayer::applyStyleProperties<FillProperties>(const float z, const times properties.set<FillProperties>(); FillProperties &fill = properties.get<FillProperties>(); applyStyleProperty(PropertyKey::FillAntialias, fill.antialias, z, now); - applyStyleProperty(PropertyKey::FillOpacity, fill.opacity, z, now); - applyStyleProperty(PropertyKey::FillColor, fill.fill_color, z, now); - applyStyleProperty(PropertyKey::FillOutlineColor, fill.stroke_color, z, now); - applyStyleProperty(PropertyKey::FillTranslateX, fill.translate[0], z, now); - applyStyleProperty(PropertyKey::FillTranslateY, fill.translate[1], z, now); + applyTransitionedStyleProperty(PropertyKey::FillOpacity, fill.opacity, z, now); + applyTransitionedStyleProperty(PropertyKey::FillColor, fill.fill_color, z, now); + applyTransitionedStyleProperty(PropertyKey::FillOutlineColor, fill.stroke_color, z, now); + applyTransitionedStyleProperty(PropertyKey::FillTranslateX, fill.translate[0], z, now); + applyTransitionedStyleProperty(PropertyKey::FillTranslateY, fill.translate[1], z, now); applyStyleProperty(PropertyKey::FillTranslateAnchor, fill.translateAnchor, z, now); applyStyleProperty(PropertyKey::FillImage, fill.image, z, now); } @@ -176,16 +177,16 @@ template <> void StyleLayer::applyStyleProperties<LineProperties>(const float z, const timestamp now) { properties.set<LineProperties>(); LineProperties &line = properties.get<LineProperties>(); - applyStyleProperty(PropertyKey::LineOpacity, line.opacity, z, now); - applyStyleProperty(PropertyKey::LineColor, line.color, z, now); - applyStyleProperty(PropertyKey::LineTranslateX, line.translate[0], z, now); - applyStyleProperty(PropertyKey::LineTranslateY, line.translate[1], z, now); + applyTransitionedStyleProperty(PropertyKey::LineOpacity, line.opacity, z, now); + applyTransitionedStyleProperty(PropertyKey::LineColor, line.color, z, now); + applyTransitionedStyleProperty(PropertyKey::LineTranslateX, line.translate[0], z, now); + applyTransitionedStyleProperty(PropertyKey::LineTranslateY, line.translate[1], z, now); applyStyleProperty(PropertyKey::LineTranslateAnchor, line.translateAnchor, z, now); - applyStyleProperty(PropertyKey::LineWidth, line.width, z, now); - applyStyleProperty(PropertyKey::LineOffset, line.offset, z, now); - applyStyleProperty(PropertyKey::LineBlur, line.blur, z, now); - applyStyleProperty(PropertyKey::LineDashLand, line.dash_array[0], z, now); - applyStyleProperty(PropertyKey::LineDashGap, line.dash_array[1], z, now); + applyTransitionedStyleProperty(PropertyKey::LineWidth, line.width, z, now); + applyTransitionedStyleProperty(PropertyKey::LineOffset, line.offset, z, now); + applyTransitionedStyleProperty(PropertyKey::LineBlur, line.blur, z, now); + applyTransitionedStyleProperty(PropertyKey::LineDashLand, line.dash_array[0], z, now); + applyTransitionedStyleProperty(PropertyKey::LineDashGap, line.dash_array[1], z, now); applyStyleProperty(PropertyKey::LineImage, line.image, z, now); } @@ -193,47 +194,46 @@ template <> void StyleLayer::applyStyleProperties<SymbolProperties>(const float z, const timestamp now) { properties.set<SymbolProperties>(); SymbolProperties &symbol = properties.get<SymbolProperties>(); - applyStyleProperty(PropertyKey::IconOpacity, symbol.icon.opacity, z, now); - applyStyleProperty(PropertyKey::IconRotate, symbol.icon.rotate, z, now); - applyStyleProperty(PropertyKey::IconSize, symbol.icon.size, z, now); - applyStyleProperty(PropertyKey::IconColor, symbol.icon.color, z, now); - applyStyleProperty(PropertyKey::IconHaloColor, symbol.icon.halo_color, z, now); - applyStyleProperty(PropertyKey::IconHaloWidth, symbol.icon.halo_width, z, now); - applyStyleProperty(PropertyKey::IconHaloBlur, symbol.icon.halo_blur, z, now); - applyStyleProperty(PropertyKey::IconTranslateX, symbol.icon.translate[0], z, now); - applyStyleProperty(PropertyKey::IconTranslateY, symbol.icon.translate[1], z, now); + applyTransitionedStyleProperty(PropertyKey::IconOpacity, symbol.icon.opacity, z, now); + applyTransitionedStyleProperty(PropertyKey::IconRotate, symbol.icon.rotate, z, now); + applyTransitionedStyleProperty(PropertyKey::IconSize, symbol.icon.size, z, now); + applyTransitionedStyleProperty(PropertyKey::IconColor, symbol.icon.color, z, now); + applyTransitionedStyleProperty(PropertyKey::IconHaloColor, symbol.icon.halo_color, z, now); + applyTransitionedStyleProperty(PropertyKey::IconHaloWidth, symbol.icon.halo_width, z, now); + applyTransitionedStyleProperty(PropertyKey::IconHaloBlur, symbol.icon.halo_blur, z, now); + applyTransitionedStyleProperty(PropertyKey::IconTranslateX, symbol.icon.translate[0], z, now); + applyTransitionedStyleProperty(PropertyKey::IconTranslateY, symbol.icon.translate[1], z, now); applyStyleProperty(PropertyKey::IconTranslateAnchor, symbol.icon.translate_anchor, z, now); - applyStyleProperty(PropertyKey::TextOpacity, symbol.text.opacity, z, now); - applyStyleProperty(PropertyKey::TextSize, symbol.text.size, z, now); - applyStyleProperty(PropertyKey::TextColor, symbol.text.color, z, now); - applyStyleProperty(PropertyKey::TextHaloColor, symbol.text.halo_color, z, now); - applyStyleProperty(PropertyKey::TextHaloWidth, symbol.text.halo_width, z, now); - applyStyleProperty(PropertyKey::TextHaloBlur, symbol.text.halo_blur, z, now); - applyStyleProperty(PropertyKey::TextTranslateX, symbol.text.translate[0], z, now); - applyStyleProperty(PropertyKey::TextTranslateY, symbol.text.translate[1], z, now); + applyTransitionedStyleProperty(PropertyKey::TextOpacity, symbol.text.opacity, z, now); + applyTransitionedStyleProperty(PropertyKey::TextSize, symbol.text.size, z, now); + applyTransitionedStyleProperty(PropertyKey::TextColor, symbol.text.color, z, now); + applyTransitionedStyleProperty(PropertyKey::TextHaloColor, symbol.text.halo_color, z, now); + applyTransitionedStyleProperty(PropertyKey::TextHaloWidth, symbol.text.halo_width, z, now); + applyTransitionedStyleProperty(PropertyKey::TextHaloBlur, symbol.text.halo_blur, z, now); + applyTransitionedStyleProperty(PropertyKey::TextTranslateX, symbol.text.translate[0], z, now); + applyTransitionedStyleProperty(PropertyKey::TextTranslateY, symbol.text.translate[1], z, now); applyStyleProperty(PropertyKey::TextTranslateAnchor, symbol.text.translate_anchor, z, now); - } template <> void StyleLayer::applyStyleProperties<RasterProperties>(const float z, const timestamp now) { properties.set<RasterProperties>(); RasterProperties &raster = properties.get<RasterProperties>(); - applyStyleProperty(PropertyKey::RasterOpacity, raster.opacity, z, now); - applyStyleProperty(PropertyKey::RasterHueRotate, raster.hue_rotate, z, now); - applyStyleProperty(PropertyKey::RasterBrightnessLow, raster.brightness[0], z, now); - applyStyleProperty(PropertyKey::RasterBrightnessHigh, raster.brightness[1], z, now); - applyStyleProperty(PropertyKey::RasterSaturation, raster.saturation, z, now); - applyStyleProperty(PropertyKey::RasterContrast, raster.contrast, z, now); - applyStyleProperty(PropertyKey::RasterFade, raster.fade, z, now); + applyTransitionedStyleProperty(PropertyKey::RasterOpacity, raster.opacity, z, now); + applyTransitionedStyleProperty(PropertyKey::RasterHueRotate, raster.hue_rotate, z, now); + applyTransitionedStyleProperty(PropertyKey::RasterBrightnessLow, raster.brightness[0], z, now); + applyTransitionedStyleProperty(PropertyKey::RasterBrightnessHigh, raster.brightness[1], z, now); + applyTransitionedStyleProperty(PropertyKey::RasterSaturation, raster.saturation, z, now); + applyTransitionedStyleProperty(PropertyKey::RasterContrast, raster.contrast, z, now); + applyTransitionedStyleProperty(PropertyKey::RasterFade, raster.fade, z, now); } template <> void StyleLayer::applyStyleProperties<BackgroundProperties>(const float z, const timestamp now) { properties.set<BackgroundProperties>(); BackgroundProperties &background = properties.get<BackgroundProperties>(); - applyStyleProperty(PropertyKey::BackgroundColor, background.color, z, now); + applyTransitionedStyleProperty(PropertyKey::BackgroundColor, background.color, z, now); } void StyleLayer::updateProperties(float z, const timestamp now) { diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index c2689162e2..2fccf1f404 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -1,3 +1,4 @@ +#include <mbgl/style/style_source.hpp> #include <mbgl/style/style_parser.hpp> #include <mbgl/style/style_layer_group.hpp> #include <mbgl/util/constants.hpp> @@ -175,21 +176,14 @@ void StyleParser::parseSources(JSVal value) { rapidjson::Value::ConstMemberIterator itr = value.MemberBegin(); for (; itr != value.MemberEnd(); ++itr) { std::string name { itr->name.GetString(), itr->name.GetStringLength() }; - SourceType type = SourceType::Vector; - std::string url; - uint16_t tile_size = 512; - int32_t min_zoom = 0; - int32_t max_zoom = 22; - - parseRenderProperty<SourceTypeClass>(itr->value, type, "type"); - parseRenderProperty(itr->value, url, "url"); - if (type == SourceType::Raster) { - parseRenderProperty(itr->value, tile_size, "tileSize"); - } - parseRenderProperty(itr->value, min_zoom, "minZoom"); - parseRenderProperty(itr->value, max_zoom, "maxZoom"); + SourceInfo info; + + parseRenderProperty<SourceTypeClass>(itr->value, info.type, "type"); + parseRenderProperty(itr->value, info.url, "url"); + parseRenderProperty(itr->value, info.tile_size, "tileSize"); + info.parseTileJSONProperties(itr->value); - sources.emplace(std::move(name), std::make_shared<StyleSource>(SourceInfo { type, url, tile_size, min_zoom, max_zoom })); + sources.emplace(std::move(name), std::make_shared<StyleSource>(info)); } } else { Log::Warning(Event::ParseStyle, "sources must be an object"); diff --git a/src/style/style_source.cpp b/src/style/style_source.cpp new file mode 100644 index 0000000000..f46a6fb09b --- /dev/null +++ b/src/style/style_source.cpp @@ -0,0 +1,77 @@ +#include <mbgl/style/style_source.hpp> +#include <mbgl/platform/platform.hpp> +#include <mbgl/platform/log.hpp> + +#include <limits> + +namespace mbgl { + +void parse(const rapidjson::Value& value, std::vector<std::string>& target, const char *name) { + if (!value.HasMember(name)) + return; + + const rapidjson::Value& property = value[name]; + if (!property.IsArray()) + return; + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) + if (!property[i].IsString()) + return; + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) + target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength())); +} + +void parse(const rapidjson::Value& value, std::string& target, const char* name) { + if (!value.HasMember(name)) + return; + + const rapidjson::Value& property = value[name]; + if (!property.IsString()) + return; + + target = { property.GetString(), property.GetStringLength() }; +} + +void parse(const rapidjson::Value& value, uint16_t& target, const char* name) { + if (!value.HasMember(name)) + return; + + const rapidjson::Value& property = value[name]; + if (!property.IsUint()) + return; + + unsigned int uint = property.GetUint(); + if (uint > std::numeric_limits<uint16_t>::max()) + return; + + target = uint; +} + +template <size_t N> +void parse(const rapidjson::Value& value, std::array<float, N>& target, const char* name) { + if (!value.HasMember(name)) + return; + + const rapidjson::Value& property = value[name]; + if (!property.IsArray() || property.Size() != N) + return; + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) + if (!property[i].IsNumber()) + return; + + for (rapidjson::SizeType i = 0; i < property.Size(); i++) + target[i] = property[i].GetDouble(); +} + +void SourceInfo::parseTileJSONProperties(const rapidjson::Value& value) { + parse(value, tiles, "tiles"); + parse(value, min_zoom, "minzoom"); + parse(value, max_zoom, "maxzoom"); + parse(value, attribution, "attribution"); + parse(value, center, "center"); + parse(value, bounds, "bounds"); +} + +} diff --git a/src/text/glyph_store.cpp b/src/text/glyph_store.cpp index 09f2fbc7b3..65941e91f7 100644 --- a/src/text/glyph_store.cpp +++ b/src/text/glyph_store.cpp @@ -4,6 +4,7 @@ #include <mbgl/util/string.hpp> #include <mbgl/util/utf.hpp> #include <mbgl/util/pbf.hpp> +#include <mbgl/util/url.hpp> #include <mbgl/util/constants.hpp> #include <mbgl/util/token.hpp> #include <mbgl/util/math.hpp> @@ -141,14 +142,11 @@ GlyphPBF::GlyphPBF(const std::string &glyphURL, const std::string &fontStack, Gl { // Load the glyph set URL std::string url = util::replaceTokens(glyphURL, [&](const std::string &name) -> std::string { - if (name == "fontstack") return fontStack; + if (name == "fontstack") return util::percentEncode(fontStack); if (name == "range") return std::to_string(glyphRange.first) + "-" + std::to_string(glyphRange.second); return ""; }); - // TODO: Find more reliable URL normalization function - std::replace(url.begin(), url.end(), ' ', '+'); - #if defined(DEBUG) fprintf(stderr, "%s\n", url.c_str()); #endif diff --git a/src/text/rotation_range.cpp b/src/text/rotation_range.cpp index 2596cf1bb6..3ebdfe91cb 100644 --- a/src/text/rotation_range.cpp +++ b/src/text/rotation_range.cpp @@ -1,5 +1,7 @@ #include <mbgl/text/rotation_range.hpp> +#include <mbgl/util/interpolate.hpp> + #include <cassert> #include <algorithm> @@ -117,8 +119,8 @@ rotatingRotatingCollisions(const CollisionRect &a, const CollisionRect &b, double getAngle(const CollisionPoint &p1, const CollisionPoint &p2, CollisionAngle d, const CollisionPoint &corner) { - return std::fmod(util::angle_between(util::interp(p1.x, p2.x, d), - util::interp(p1.y, p2.y, d), corner.x, + return std::fmod(util::angle_between(util::interpolate(p1.x, p2.x, d), + util::interpolate(p1.y, p2.y, d), corner.x, corner.y) + 2 * M_PI, 2 * M_PI); diff --git a/src/util/mapbox.cpp b/src/util/mapbox.cpp new file mode 100644 index 0000000000..277b647f34 --- /dev/null +++ b/src/util/mapbox.cpp @@ -0,0 +1,44 @@ +#include <mbgl/util/mapbox.hpp> + +#include <stdexcept> + +namespace mbgl { +namespace util { +namespace mapbox { + +const std::string mapbox = "mapbox://"; + +std::string normalizeURL(const std::string& url, const std::string& accessToken) { + if (accessToken.empty()) + throw std::runtime_error("You must provide a Mapbox API access token for Mapbox tile sources"); + + return std::string("https://api.tiles.mapbox.com/v4/") + + url.substr(mapbox.length()) + + "?access_token=" + + accessToken; +} + +std::string normalizeSourceURL(const std::string& url, const std::string& accessToken) { + if (url.compare(0, mapbox.length(), mapbox) != 0) + return url; + + std::string result = normalizeURL(url + ".json", accessToken); + + // TileJSON requests need a secure flag appended to their URLs so + // that the server knows to send SSL-ified resource references. + if (url.compare(0, 5, "https") == 0) + result += "&secure"; + + return result; +} + +std::string normalizeGlyphsURL(const std::string& url, const std::string& accessToken) { + if (url.compare(0, mapbox.length(), mapbox) != 0) + return url; + + return normalizeURL(url, accessToken); +} + +} +} +} diff --git a/src/util/transition.cpp b/src/util/transition.cpp index c91c8019b7..e63a5c311f 100644 --- a/src/util/transition.cpp +++ b/src/util/transition.cpp @@ -1,5 +1,6 @@ #include <mbgl/util/transition.hpp> #include <mbgl/util/unitbezier.hpp> +#include <mbgl/util/interpolate.hpp> #include <mbgl/platform/platform.hpp> namespace mbgl { namespace util { @@ -8,71 +9,18 @@ UnitBezier ease(0, 0, 0.25, 1); transition::~transition() {} -double transition::interpolateDouble(double from, double to, double t) const { - return from + (to - from) * t; -} - -float transition::interpolateFloat(float from, float to, double t) const { - return from + (to - from) * (float)t; -} - -mbgl::Color transition::interpolateColor(mbgl::Color from, mbgl::Color to, double t) const { - return {{ interpolateFloat(from[0], to[0], t), - interpolateFloat(from[1], to[1], t), - interpolateFloat(from[2], to[2], t), - interpolateFloat(from[3], to[3], t) }}; -} - -std::array<float, 2> transition::interpolateFloatArray(std::array<float, 2> from, std::array<float, 2> to, double t) const { - return {{ interpolateFloat(from[0], to[0], t), interpolateFloat(from[1], to[1], t) }}; -} - -template <> -transition::state ease_transition<double>::update(timestamp now) const { - float t = progress(now); - if (t >= 1) { - value = to; - return complete; - } else { - value = interpolateDouble(from, to, ease.solve(t, 0.001)); - return running; - } -} - -template <> -transition::state ease_transition<mbgl::Color>::update(timestamp now) const { +template <typename T> +transition::state ease_transition<T>::update(timestamp now) const { float t = progress(now); if (t >= 1) { value = to; return complete; } else { - value = interpolateColor(from, to, ease.solve(t, 0.001)); + value = interpolate(from, to, ease.solve(t, 0.001)); return running; } } -template <> -transition::state ease_transition<float>::update(timestamp now) const { - float t = progress(now); - if (t >= 1) { - value = to; - return complete; - } else { - value = interpolateFloat(from, to, ease.solve(t, 0.001)); - return running; - } -} - -template <> -transition::state ease_transition<std::array<float, 2>>::update(timestamp now) const { - float t = progress(now); - if (t >= 1) { - value = to; - return complete; - } else { - value = interpolateFloatArray(from, to, ease.solve(t, 0.001)); - return running; - } -} +template class ease_transition<double>; }} diff --git a/src/util/url.cpp b/src/util/url.cpp new file mode 100644 index 0000000000..b1a721d860 --- /dev/null +++ b/src/util/url.cpp @@ -0,0 +1,29 @@ +#include <mbgl/util/url.hpp> + +#include <cctype> +#include <iomanip> +#include <sstream> +#include <string> + +namespace mbgl { +namespace util { + +std::string percentEncode(const std::string& input) { + std::ostringstream encoded; + + encoded.fill('0'); + encoded << std::hex; + + for (auto c : input) { + if (std::isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { + encoded << c; + } else { + encoded << '%' << std::setw(2) << int(c); + } + } + + return encoded.str(); +} + +} +} |