diff options
author | Lauren Budorick <lbudorick@gmail.com> | 2014-08-12 10:55:22 -0700 |
---|---|---|
committer | Lauren Budorick <lbudorick@gmail.com> | 2014-08-12 10:55:22 -0700 |
commit | 3941908cee9d91ac505908e3443b4490644b2cf7 (patch) | |
tree | df14f963c5b2d42c027c371b64aa0b9383c096b9 | |
parent | 46e754f806e24af7b88ef19dcf786e7ee006ba40 (diff) | |
parent | 28d8c13c2c1852062857070c17bc211d26902ba0 (diff) | |
download | qtlocation-mapboxgl-3941908cee9d91ac505908e3443b4490644b2cf7.tar.gz |
Merge pull request #400 from mapbox/rasterize
raster prerendering (parity)
47 files changed, 2504 insertions, 252 deletions
diff --git a/include/mbgl/geometry/geometry.hpp b/include/mbgl/geometry/geometry.hpp index 47981ce83b..961569204d 100644 --- a/include/mbgl/geometry/geometry.hpp +++ b/include/mbgl/geometry/geometry.hpp @@ -12,7 +12,7 @@ class Geometry : private util::noncopyable { public: inline explicit Geometry(pbf& data); - + enum command : uint8_t { end = 0, move_to = 1, diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 554962c713..fba38879ed 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -45,6 +45,8 @@ public: // Triggers a lazy rerender: only performs a render when the map is not clean. void rerender(); + void renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass, const Tile::ID* id = nullptr, const mat4* matrix = nullptr); + // Forces a map update: always triggers a rerender. void update(); @@ -123,6 +125,7 @@ public: inline std::shared_ptr<uv::loop> getLoop() { return loop; } inline timestamp getAnimationTime() const { return animationTime; } inline timestamp getTime() const { return animationTime; } + void updateTiles(); private: // uv async callbacks @@ -137,7 +140,6 @@ private: void updateSources(); void updateSources(const std::shared_ptr<StyleLayerGroup> &group); - void updateTiles(); void updateRenderState(); size_t countLayers(const std::vector<LayerDescription>& layers); @@ -146,12 +148,10 @@ private: // the stylesheet. void prepare(); - enum RenderPass { Opaque, Translucent }; // Unconditionally performs a render with the current map state. void render(); void renderLayers(std::shared_ptr<StyleLayerGroup> group); - void renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass); private: bool async = false; diff --git a/include/mbgl/map/raster_tile_data.hpp b/include/mbgl/map/raster_tile_data.hpp index bf8691454f..98aa3baaf5 100644 --- a/include/mbgl/map/raster_tile_data.hpp +++ b/include/mbgl/map/raster_tile_data.hpp @@ -22,10 +22,11 @@ public: ~RasterTileData(); virtual void parse(); - virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc); + virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix); virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const; protected: + StyleBucketRaster properties; RasterBucket bucket; }; diff --git a/include/mbgl/map/source.hpp b/include/mbgl/map/source.hpp index c3f2d4fe8b..4ffd097193 100644 --- a/include/mbgl/map/source.hpp +++ b/include/mbgl/map/source.hpp @@ -32,6 +32,7 @@ public: void drawClippingMasks(Painter &painter); size_t getTileCount() const; void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc); + void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix); void finishRender(Painter &painter); std::forward_list<Tile::ID> getIDs() const; diff --git a/include/mbgl/map/tile_data.hpp b/include/mbgl/map/tile_data.hpp index c349ea2bae..5991613a2d 100644 --- a/include/mbgl/map/tile_data.hpp +++ b/include/mbgl/map/tile_data.hpp @@ -53,7 +53,7 @@ public: virtual void beforeParse(); virtual void parse() = 0; virtual void afterParse(); - virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc) = 0; + virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix) = 0; virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const = 0; diff --git a/include/mbgl/map/tile_parser.hpp b/include/mbgl/map/tile_parser.hpp index 9aa0f4dc66..f011d47a38 100644 --- a/include/mbgl/map/tile_parser.hpp +++ b/include/mbgl/map/tile_parser.hpp @@ -14,6 +14,7 @@ namespace mbgl { class Bucket; +class Texturepool; class FontStack; class GlyphAtlas; class GlyphStore; @@ -22,6 +23,7 @@ class Sprite; class Style; class StyleBucket; class StyleBucketFill; +class StyleBucketRaster; class StyleBucketLine; class StyleBucketSymbol; class StyleLayerGroup; @@ -45,6 +47,7 @@ private: std::unique_ptr<Bucket> createBucket(std::shared_ptr<StyleBucket> bucket_desc); std::unique_ptr<Bucket> createFillBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketFill &fill); + std::unique_ptr<Bucket> createRasterBucket(const std::shared_ptr<Texturepool> &texturepool, const StyleBucketRaster &raster); std::unique_ptr<Bucket> createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line); std::unique_ptr<Bucket> createSymbolBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketSymbol &symbol); @@ -60,6 +63,7 @@ private: std::shared_ptr<GlyphStore> glyphStore; std::shared_ptr<SpriteAtlas> spriteAtlas; std::shared_ptr<Sprite> sprite; + std::shared_ptr<Texturepool> texturePool; Collision collision; }; diff --git a/include/mbgl/map/vector_tile_data.hpp b/include/mbgl/map/vector_tile_data.hpp index edad228999..deb628e485 100644 --- a/include/mbgl/map/vector_tile_data.hpp +++ b/include/mbgl/map/vector_tile_data.hpp @@ -32,7 +32,7 @@ public: virtual void beforeParse(); virtual void parse(); virtual void afterParse(); - virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc); + virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix); virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const; protected: diff --git a/include/mbgl/renderer/bucket.hpp b/include/mbgl/renderer/bucket.hpp index 18f58ee464..1391f6e3e3 100644 --- a/include/mbgl/renderer/bucket.hpp +++ b/include/mbgl/renderer/bucket.hpp @@ -5,7 +5,6 @@ #include <memory> #include <mbgl/map/tile.hpp> #include <mbgl/util/noncopyable.hpp> -#include <mbgl/renderer/prerendered_texture.hpp> namespace mbgl { @@ -14,11 +13,10 @@ class StyleLayer; class Bucket : private util::noncopyable { public: - virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id) = 0; + virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) = 0; virtual bool hasData() const = 0; virtual ~Bucket() {} - std::unique_ptr<PrerenderedTexture> prerendered; }; } diff --git a/include/mbgl/renderer/debug_bucket.hpp b/include/mbgl/renderer/debug_bucket.hpp index ac4f18cc2c..660b7fcba8 100644 --- a/include/mbgl/renderer/debug_bucket.hpp +++ b/include/mbgl/renderer/debug_bucket.hpp @@ -20,7 +20,7 @@ class DebugBucket : public Bucket { public: DebugBucket(DebugFontBuffer& fontBuffer); - virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); + virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); virtual bool hasData() const; void drawLines(PlainShader& shader); diff --git a/include/mbgl/renderer/fill_bucket.hpp b/include/mbgl/renderer/fill_bucket.hpp index 9193b09149..e9340cce68 100644 --- a/include/mbgl/renderer/fill_bucket.hpp +++ b/include/mbgl/renderer/fill_bucket.hpp @@ -44,7 +44,7 @@ public: const StyleBucketFill& properties); ~FillBucket(); - virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); + virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); virtual bool hasData() const; void addGeometry(pbf& data); diff --git a/include/mbgl/renderer/line_bucket.hpp b/include/mbgl/renderer/line_bucket.hpp index d42b10bfb7..f65ca35605 100644 --- a/include/mbgl/renderer/line_bucket.hpp +++ b/include/mbgl/renderer/line_bucket.hpp @@ -28,7 +28,7 @@ public: PointElementsBuffer& pointElementsBuffer, const StyleBucketLine& properties); - virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); + virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); virtual bool hasData() const; void addGeometry(pbf& data); diff --git a/include/mbgl/renderer/painter.hpp b/include/mbgl/renderer/painter.hpp index b4023de167..db85d8703d 100644 --- a/include/mbgl/renderer/painter.hpp +++ b/include/mbgl/renderer/painter.hpp @@ -29,6 +29,8 @@ namespace mbgl { +enum class RenderPass : bool { Opaque, Translucent }; + class Transform; class Style; class Tile; @@ -40,8 +42,10 @@ class FillBucket; class LineBucket; class SymbolBucket; class RasterBucket; +class PrerenderedTexture; struct FillProperties; +struct RasterProperties; struct CompositeProperties; class LayerDescription; @@ -69,27 +73,27 @@ public: void changeMatrix(); // Renders a particular layer from a tile. - void renderTileLayer(const Tile& tile, std::shared_ptr<StyleLayer> layer_desc); + void renderTileLayer(const Tile& tile, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix); // Renders debug information for a tile. void renderTileDebug(const Tile& tile); // Renders the red debug frame around a tile, visualizing its perimeter. - void renderDebugFrame(); + void renderDebugFrame(const mat4 &matrix); - void renderDebugText(DebugBucket& bucket); + void renderDebugText(DebugBucket& bucket, const mat4 &matrix); void renderDebugText(const std::vector<std::string> &strings); - void renderFill(FillBucket& bucket, const FillProperties& properties, const Tile::ID& id, const mat4 &mat); - void renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); - void renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); - void renderSymbol(SymbolBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); - void renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); + void renderFill(FillBucket& bucket, const FillProperties& properties, const Tile::ID& id, const mat4 &matrix); + void renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); + void renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); + void renderSymbol(SymbolBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); + void renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); + + void preparePrerender(RasterBucket &bucket); - void preparePrerender(PrerenderedTexture &texture); - void finishPrerender(PrerenderedTexture &texture); + void renderPrerenderedTexture(RasterBucket &bucket, const mat4 &matrix, const RasterProperties& properties); - template <typename Properties> - void renderPrerenderedTexture(PrerenderedTexture &texture, const Properties &properties); + void createPrerendered(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); void resize(); @@ -117,7 +121,7 @@ public: bool needsAnimation() const; private: void setupShaders(); - const mat4 &translatedMatrix(const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor = TranslateAnchorType::Map); + const mat4 &translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor = TranslateAnchorType::Map); void prepareTile(const Tile& tile); @@ -127,7 +131,6 @@ public: void depthMask(bool value); public: - mat4 matrix; mat4 vtxMatrix; mat4 projMatrix; mat4 nativeMatrix; @@ -153,7 +156,7 @@ private: bool gl_depthMask = true; std::array<uint16_t, 2> gl_viewport = {{ 0, 0 }}; float strata = 0; - enum { Opaque, Translucent } pass = Opaque; + RenderPass pass = RenderPass::Opaque; const float strata_epsilon = 1.0f / (1 << 16); public: diff --git a/include/mbgl/renderer/prerendered_texture.hpp b/include/mbgl/renderer/prerendered_texture.hpp index 9c72e14b88..e4dc610418 100644 --- a/include/mbgl/renderer/prerendered_texture.hpp +++ b/include/mbgl/renderer/prerendered_texture.hpp @@ -3,15 +3,15 @@ #include <mbgl/util/noncopyable.hpp> #include <mbgl/platform/gl.hpp> -#include <mbgl/style/rasterize_properties.hpp> namespace mbgl { +class StyleBucketRaster; class Painter; class PrerenderedTexture : private util::noncopyable { public: - PrerenderedTexture(const RasterizedProperties &properties); + PrerenderedTexture(const StyleBucketRaster &properties); ~PrerenderedTexture(); void bindTexture(); @@ -23,12 +23,13 @@ public: void blur(Painter& painter, uint16_t passes); public: - const RasterizedProperties properties; + const StyleBucketRaster &properties; private: GLint previous_fbo = 0; GLuint fbo = 0; GLuint texture = 0; + GLuint fbo_depth_stencil = 0; }; } diff --git a/include/mbgl/renderer/raster_bucket.hpp b/include/mbgl/renderer/raster_bucket.hpp index c111193126..a68475565b 100644 --- a/include/mbgl/renderer/raster_bucket.hpp +++ b/include/mbgl/renderer/raster_bucket.hpp @@ -3,6 +3,10 @@ #include <mbgl/renderer/bucket.hpp> #include <mbgl/util/raster.hpp> +#include <mbgl/renderer/prerendered_texture.hpp> +#include <mbgl/style/style_bucket.hpp> + + namespace mbgl { @@ -12,17 +16,23 @@ class VertexArrayObject; class RasterBucket : public Bucket { public: - RasterBucket(const std::shared_ptr<Texturepool> &texturepool); + RasterBucket(const std::shared_ptr<Texturepool> &texturepool, const StyleBucketRaster& properties); - virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id); + virtual void render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix); virtual bool hasData() const; bool setImage(const std::string &data); + const StyleBucketRaster &properties; + PrerenderedTexture texture; + void drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array); -private: + void drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array, GLuint texture); + Raster raster; + +private: }; } diff --git a/include/mbgl/renderer/symbol_bucket.hpp b/include/mbgl/renderer/symbol_bucket.hpp index c003230cae..e890274238 100644 --- a/include/mbgl/renderer/symbol_bucket.hpp +++ b/include/mbgl/renderer/symbol_bucket.hpp @@ -53,7 +53,7 @@ class SymbolBucket : public Bucket { public: SymbolBucket(const StyleBucketSymbol &properties, Collision &collision); - virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id); + virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix); virtual bool hasData() const; virtual bool hasTextData() const; virtual bool hasIconData() const; diff --git a/include/mbgl/style/property_key.hpp b/include/mbgl/style/property_key.hpp index 68dc709597..7d24981765 100644 --- a/include/mbgl/style/property_key.hpp +++ b/include/mbgl/style/property_key.hpp @@ -54,7 +54,7 @@ enum class PropertyKey { CompositeOpacity, RasterOpacity, - RasterSpin, + RasterHueRotate, RasterBrightnessLow, RasterBrightnessHigh, RasterSaturation, diff --git a/include/mbgl/style/rasterize_properties.hpp b/include/mbgl/style/rasterize_properties.hpp deleted file mode 100644 index aea90dfbdd..0000000000 --- a/include/mbgl/style/rasterize_properties.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef MBGL_STYLE_RASTERIZE_PROPERTIES -#define MBGL_STYLE_RASTERIZE_PROPERTIES - -#include <mbgl/style/function_properties.hpp> - -namespace mbgl { - -// The calculated properties for a layer in a tile. -class RasterizedProperties { -public: - float buffer = 1.0f / 32.0f; - uint16_t size = 256; - uint8_t blur = 0; -}; - -class RasterizeProperties { -public: - Function<bool> enabled = ConstantFunction<bool>(false); - Function<float> buffer = ConstantFunction<float>(1.0f / 32.0f); - Function<float> size = ConstantFunction<float>(256); - Function<float> blur = ConstantFunction<float>(0); - - inline bool isEnabled(const int8_t z) const { - return util::apply_visitor(FunctionEvaluator<bool>(z), enabled); - } - - inline RasterizedProperties get(const int8_t z) const { - RasterizedProperties properties; - properties.buffer = util::apply_visitor(FunctionEvaluator<float>(z), buffer); - properties.size = util::apply_visitor(FunctionEvaluator<float>(z), size); - properties.blur = util::apply_visitor(FunctionEvaluator<float>(z), blur); - return properties; - } -}; - -} - -#endif diff --git a/include/mbgl/style/style_bucket.hpp b/include/mbgl/style/style_bucket.hpp index 530e0c1259..11b87d849d 100644 --- a/include/mbgl/style/style_bucket.hpp +++ b/include/mbgl/style/style_bucket.hpp @@ -82,6 +82,10 @@ public: class StyleBucketRaster { public: + bool prerendered = false; + uint16_t size = 256; + float blur = 0.0f; + float buffer = 0.03125f; }; typedef util::variant<StyleBucketFill, StyleBucketLine, StyleBucketSymbol, diff --git a/include/mbgl/style/style_layer.hpp b/include/mbgl/style/style_layer.hpp index 14d60ed9b6..f8cfff7f63 100644 --- a/include/mbgl/style/style_layer.hpp +++ b/include/mbgl/style/style_layer.hpp @@ -4,7 +4,6 @@ #include <mbgl/style/class_dictionary.hpp> #include <mbgl/style/class_properties.hpp> #include <mbgl/style/style_properties.hpp> -#include <mbgl/style/rasterize_properties.hpp> #include <mbgl/style/applied_class_properties.hpp> #include <vector> @@ -20,8 +19,7 @@ class StyleLayerGroup; class StyleLayer { public: - StyleLayer(const std::string &id, std::map<ClassID, ClassProperties> &&styles, - std::unique_ptr<const RasterizeProperties> &&rasterize); + StyleLayer(const std::string &id, std::map<ClassID, ClassProperties> &&styles); template <typename T> const T &getProperties() { if (properties.is<T>()) { @@ -80,11 +78,6 @@ public: // layer's type. StyleProperties properties; - // Rasterization properties are used for prerendering the tile to a bitmap, - // which is then used as a raster image instead of rendering this layer - // directly in every frame. - const std::unique_ptr<const RasterizeProperties> rasterize; - // Child layer array (if this layer has child layers). std::shared_ptr<StyleLayerGroup> layers; }; diff --git a/include/mbgl/style/style_parser.hpp b/include/mbgl/style/style_parser.hpp index 8b8dc74f21..e4e1b7f632 100644 --- a/include/mbgl/style/style_parser.hpp +++ b/include/mbgl/style/style_parser.hpp @@ -6,7 +6,6 @@ #include <mbgl/style/style_source.hpp> #include <mbgl/style/filter_expression.hpp> #include <mbgl/style/class_properties.hpp> -#include <mbgl/style/rasterize_properties.hpp> #include <mbgl/style/style_bucket.hpp> #include <unordered_map> @@ -52,7 +51,6 @@ private: void parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair); void parseStyles(JSVal value, std::map<ClassID, ClassProperties> &styles); void parseStyle(JSVal, ClassProperties &properties); - std::unique_ptr<RasterizeProperties> parseRasterize(JSVal value); void parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer); void parseBucket(JSVal value, std::shared_ptr<StyleLayer> &layer); void parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer); diff --git a/include/mbgl/style/style_properties.hpp b/include/mbgl/style/style_properties.hpp index 35ea97781b..f12ab430e3 100644 --- a/include/mbgl/style/style_properties.hpp +++ b/include/mbgl/style/style_properties.hpp @@ -89,7 +89,7 @@ struct CompositeProperties { struct RasterProperties { inline RasterProperties() {} float opacity = 1.0f; - float spin = 0.0f; + float hue_rotate = 0.0f; std::array<float, 2> brightness = {{ 0, 1 }}; float saturation = 0.0f; float contrast = 0.0f; diff --git a/include/mbgl/util/raster.hpp b/include/mbgl/util/raster.hpp index 04c85169e2..e526ffa5ac 100644 --- a/include/mbgl/util/raster.hpp +++ b/include/mbgl/util/raster.hpp @@ -4,6 +4,7 @@ #include <mbgl/util/transition.hpp> #include <mbgl/util/texturepool.hpp> #include <mbgl/util/image.hpp> +#include <mbgl/renderer/prerendered_texture.hpp> #include <string> #include <mutex> @@ -25,6 +26,9 @@ public: // bind current texture void bind(bool linear = false); + // bind prerendered texture + void bind(const GLuint texture); + // loaded status bool isLoaded() const; diff --git a/src/map/map.cpp b/src/map/map.cpp index 81cbd394ba..60ddaa5976 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -611,7 +611,7 @@ void Map::renderLayers(std::shared_ptr<StyleLayerGroup> group) { for (auto it = group->layers.rbegin(), end = group->layers.rend(); it != end; ++it, ++i) { painter.setOpaque(); painter.setStrata(i * strata_thickness); - renderLayer(*it, Opaque); + renderLayer(*it, RenderPass::Opaque); } if (debug::renderTree) { std::cout << std::string(--indent * 4, ' ') << "}" << std::endl; @@ -627,17 +627,17 @@ void Map::renderLayers(std::shared_ptr<StyleLayerGroup> group) { for (auto it = group->layers.begin(), end = group->layers.end(); it != end; ++it, --i) { painter.setTranslucent(); painter.setStrata(i * strata_thickness); - renderLayer(*it, Translucent); + renderLayer(*it, RenderPass::Translucent); } if (debug::renderTree) { std::cout << std::string(--indent * 4, ' ') << "}" << std::endl; } } -void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass) { - if (layer_desc->layers) { +void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass, const Tile::ID* id, const mat4* matrix) { + if (layer_desc->layers && layer_desc->type != StyleLayerType::Raster) { // This is a layer group. We render them during our translucent render pass. - if (pass == Translucent) { + if (pass == RenderPass::Translucent) { const CompositeProperties &properties = layer_desc->getProperties<CompositeProperties>(); if (properties.isVisible()) { gl::group group(std::string("group: ") + layer_desc->id); @@ -698,15 +698,15 @@ void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass) { if (!layer_desc->getProperties<FillProperties>().isVisible()) return; break; case StyleLayerType::Line: - if (pass == Opaque) return; + if (pass == RenderPass::Opaque) return; if (!layer_desc->getProperties<LineProperties>().isVisible()) return; break; case StyleLayerType::Symbol: - if (pass == Opaque) return; + if (pass == RenderPass::Opaque) return; if (!layer_desc->getProperties<SymbolProperties>().isVisible()) return; break; case StyleLayerType::Raster: - if (pass == Translucent) return; + if (pass == RenderPass::Opaque) return; if (!layer_desc->getProperties<RasterProperties>().isVisible()) return; break; default: @@ -717,7 +717,10 @@ void Map::renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass) { std::cout << std::string(indent * 4, ' ') << "- " << layer_desc->id << " (" << layer_desc->type << ")" << std::endl; } - - style_source.source->render(painter, layer_desc); + if (!id) { + style_source.source->render(painter, layer_desc); + } else { + style_source.source->render(painter, layer_desc, *id, *matrix); + } } } diff --git a/src/map/raster_tile_data.cpp b/src/map/raster_tile_data.cpp index a3c6d21a68..182a614393 100644 --- a/src/map/raster_tile_data.cpp +++ b/src/map/raster_tile_data.cpp @@ -7,7 +7,7 @@ using namespace mbgl; RasterTileData::RasterTileData(Tile::ID id, Map &map, const SourceInfo &source) : TileData(id, map, source), - bucket(map.getTexturepool()) { + bucket(map.getTexturepool(), properties) { } RasterTileData::~RasterTileData() { @@ -25,8 +25,8 @@ void RasterTileData::parse() { } } -void RasterTileData::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc) { - bucket.render(painter, layer_desc, id); +void RasterTileData::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix) { + bucket.render(painter, layer_desc, id, matrix); } bool RasterTileData::hasData(std::shared_ptr<StyleLayer> /*layer_desc*/) const { diff --git a/src/map/source.cpp b/src/map/source.cpp index f9e34d926d..523a7f3bc7 100644 --- a/src/map/source.cpp +++ b/src/map/source.cpp @@ -83,11 +83,18 @@ void Source::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc) { for (const std::pair<const Tile::ID, std::unique_ptr<Tile>> &pair : tiles) { Tile &tile = *pair.second; if (tile.data && tile.data->state == TileData::State::parsed) { - painter.renderTileLayer(tile, layer_desc); + painter.renderTileLayer(tile, layer_desc, tile.matrix); } } } +void Source::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix) { + auto it = tiles.find(id); + if (it != tiles.end() && it->second->data && it->second->data->state == TileData::State::parsed) { + painter.renderTileLayer(*it->second, layer_desc, matrix); + } +} + void Source::finishRender(Painter &painter) { for (std::pair<const Tile::ID, std::unique_ptr<Tile>> &pair : tiles) { Tile &tile = *pair.second; diff --git a/src/map/tile_parser.cpp b/src/map/tile_parser.cpp index 97b071a163..6069ad82cb 100644 --- a/src/map/tile_parser.cpp +++ b/src/map/tile_parser.cpp @@ -14,6 +14,7 @@ #include <mbgl/geometry/glyph_atlas.hpp> #include <mbgl/text/glyph_store.hpp> #include <mbgl/text/glyph.hpp> +#include <mbgl/map/map.hpp> #include <mbgl/util/std.hpp> #include <mbgl/util/utf.hpp> @@ -69,7 +70,8 @@ void TileParser::parseStyleLayers(std::shared_ptr<StyleLayerGroup> group) { } else if (layer_desc->layers) { // This is a layer group. parseStyleLayers(layer_desc->layers); - } else if (layer_desc->bucket) { + } + if (layer_desc->bucket) { // This is a singular layer. Check if this bucket already exists. If not, // parse this bucket. auto bucket_it = tile.buckets.find(layer_desc->bucket->name); @@ -112,6 +114,8 @@ std::unique_ptr<Bucket> TileParser::createBucket(std::shared_ptr<StyleBucket> bu } else { fprintf(stderr, "[WARNING] unknown bucket render type for layer '%s' (source layer '%s')\n", bucket_desc->name.c_str(), bucket_desc->source_layer.c_str()); } + } else if (bucket_desc->render.is<StyleBucketRaster>() && bucket_desc->render.get<StyleBucketRaster>().prerendered == true) { + return createRasterBucket(texturePool, bucket_desc->render.get<StyleBucketRaster>()); } else { // The layer specified in the bucket does not exist. Do nothing. if (debug::tileParseWarnings) { @@ -147,6 +151,11 @@ std::unique_ptr<Bucket> TileParser::createFillBucket(const VectorTileLayer& laye return obsolete() ? nullptr : std::move(bucket); } +std::unique_ptr<Bucket> TileParser::createRasterBucket(const std::shared_ptr<Texturepool> &texturepool, const StyleBucketRaster &raster) { + std::unique_ptr<RasterBucket> bucket = std::make_unique<RasterBucket>(texturepool, raster); + return obsolete() ? nullptr : std::move(bucket); +} + std::unique_ptr<Bucket> TileParser::createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line) { std::unique_ptr<LineBucket> bucket = std::make_unique<LineBucket>(tile.lineVertexBuffer, tile.triangleElementsBuffer, tile.pointElementsBuffer, line); addBucketGeometries(bucket, layer, filter); diff --git a/src/map/vector_tile.cpp b/src/map/vector_tile.cpp index 8644c3e044..4ec25d6cf6 100644 --- a/src/map/vector_tile.cpp +++ b/src/map/vector_tile.cpp @@ -128,7 +128,7 @@ FilteredVectorTileLayer::iterator::iterator(const FilteredVectorTileLayer& paren // return true; // } // -// +// // // // if (filterExpression.is<util::recursive_wrapper<PropertyFilter>>()) { diff --git a/src/map/vector_tile_data.cpp b/src/map/vector_tile_data.cpp index 2bf339b65f..1f74cab1d7 100644 --- a/src/map/vector_tile_data.cpp +++ b/src/map/vector_tile_data.cpp @@ -21,7 +21,7 @@ VectorTileData::~VectorTileData() { } void VectorTileData::beforeParse() { - + parser = std::make_unique<TileParser>(data, *this, map.getStyle(), map.getGlyphAtlas(), map.getGlyphStore(), map.getSpriteAtlas(), map.getSprite()); } @@ -52,12 +52,12 @@ void VectorTileData::afterParse() { parser.reset(); } -void VectorTileData::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc) { +void VectorTileData::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix) { if (state == State::parsed && layer_desc->bucket) { auto databucket_it = buckets.find(layer_desc->bucket->name); if (databucket_it != buckets.end()) { assert(databucket_it->second); - databucket_it->second->render(painter, layer_desc, id); + databucket_it->second->render(painter, layer_desc, id, matrix); } } } diff --git a/src/renderer/debug_bucket.cpp b/src/renderer/debug_bucket.cpp index e51dd75b1e..a3ac329f49 100644 --- a/src/renderer/debug_bucket.cpp +++ b/src/renderer/debug_bucket.cpp @@ -14,8 +14,8 @@ DebugBucket::DebugBucket(DebugFontBuffer& fontBuffer) : fontBuffer(fontBuffer) { } -void DebugBucket::render(Painter& painter, std::shared_ptr<StyleLayer> /*layer_desc*/, const Tile::ID& /*id*/) { - painter.renderDebugText(*this); +void DebugBucket::render(Painter& painter, std::shared_ptr<StyleLayer> /*layer_desc*/, const Tile::ID& /*id*/, const mat4 &matrix) { + painter.renderDebugText(*this, matrix); } bool DebugBucket::hasData() const { diff --git a/src/renderer/fill_bucket.cpp b/src/renderer/fill_bucket.cpp index 17aa2bccfc..4b4000ce97 100644 --- a/src/renderer/fill_bucket.cpp +++ b/src/renderer/fill_bucket.cpp @@ -204,8 +204,8 @@ void FillBucket::tessellate() { lineGroup.vertex_length += total_vertex_count; } -void FillBucket::render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id) { - painter.renderFill(*this, layer_desc, id); +void FillBucket::render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) { + painter.renderFill(*this, layer_desc, id, matrix); } bool FillBucket::hasData() const { diff --git a/src/renderer/line_bucket.cpp b/src/renderer/line_bucket.cpp index 2e04820e42..949d71e134 100644 --- a/src/renderer/line_bucket.cpp +++ b/src/renderer/line_bucket.cpp @@ -341,8 +341,8 @@ void LineBucket::addGeometry(const std::vector<Coordinate>& vertices) { } } -void LineBucket::render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id) { - painter.renderLine(*this, layer_desc, id); +void LineBucket::render(Painter& painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) { + painter.renderLine(*this, layer_desc, id, matrix); } bool LineBucket::hasData() const { diff --git a/src/renderer/painter.cpp b/src/renderer/painter.cpp index e6977171a4..956543d26b 100644 --- a/src/renderer/painter.cpp +++ b/src/renderer/painter.cpp @@ -144,16 +144,16 @@ void Painter::clear() { } void Painter::setOpaque() { - if (pass != Opaque) { - pass = Opaque; + if (pass != RenderPass::Opaque) { + pass = RenderPass::Opaque; glDisable(GL_BLEND); depthMask(true); } } void Painter::setTranslucent() { - if (pass != Translucent) { - pass = Translucent; + if (pass != RenderPass::Translucent) { + pass = RenderPass::Translucent; glEnable(GL_BLEND); depthMask(false); } @@ -164,25 +164,23 @@ void Painter::setStrata(float value) { } void Painter::prepareTile(const Tile& tile) { - matrix = tile.matrix; - GLint id = (GLint)tile.clip.mask.to_ulong(); GLuint mask = clipMask[tile.clip.length]; glStencilFunc(GL_EQUAL, id, mask); } -void Painter::renderTileLayer(const Tile& tile, std::shared_ptr<StyleLayer> layer_desc) { +void Painter::renderTileLayer(const Tile& tile, std::shared_ptr<StyleLayer> layer_desc, const mat4 &matrix) { assert(tile.data); - if (tile.data->hasData(layer_desc)) { + if (tile.data->hasData(layer_desc) || layer_desc->type == StyleLayerType::Raster) { gl::group group(util::sprintf<32>("render %d/%d/%d\n", tile.id.z, tile.id.y, tile.id.z)); prepareTile(tile); - tile.data->render(*this, layer_desc); + tile.data->render(*this, layer_desc, matrix); frameHistory.record(map.getAnimationTime(), map.getState().getNormalizedZoom()); } } -const mat4 &Painter::translatedMatrix(const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor) { +const mat4 &Painter::translatedMatrix(const mat4& matrix, const std::array<float, 2> &translation, const Tile::ID &id, TranslateAnchorType anchor) { if (translation[0] == 0 && translation[1] == 0) { return matrix; } else { diff --git a/src/renderer/painter_debug.cpp b/src/renderer/painter_debug.cpp index d79493e61e..eae655f1f5 100644 --- a/src/renderer/painter_debug.cpp +++ b/src/renderer/painter_debug.cpp @@ -10,12 +10,12 @@ void Painter::renderTileDebug(const Tile& tile) { assert(tile.data); if (debug) { prepareTile(tile); - renderDebugText(tile.data->debugBucket); - renderDebugFrame(); + renderDebugText(tile.data->debugBucket, tile.matrix); + renderDebugFrame(tile.matrix); } } -void Painter::renderDebugText(DebugBucket& bucket) { +void Painter::renderDebugText(DebugBucket& bucket, const mat4 &matrix) { gl::group group("debug text"); glDisable(GL_DEPTH_TEST); @@ -42,7 +42,7 @@ void Painter::renderDebugText(DebugBucket& bucket) { glEnable(GL_DEPTH_TEST); } -void Painter::renderDebugFrame() { +void Painter::renderDebugFrame(const mat4 &matrix) { gl::group group("debug frame"); // Disable depth test and don't count this towards the depth buffer, diff --git a/src/renderer/painter_fill.cpp b/src/renderer/painter_fill.cpp index 29d77e05d9..8306dd0a2e 100644 --- a/src/renderer/painter_fill.cpp +++ b/src/renderer/painter_fill.cpp @@ -38,7 +38,7 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) - if (outline && pass == Translucent) { + if (outline && pass == RenderPass::Translucent) { useProgram(outlineShader->program); outlineShader->setMatrix(vtxMatrix); lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio! @@ -70,7 +70,7 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c // glStencilOp(GL_KEEP, GL_KEEP, GL_INCR_WRAP); } - if ((fill_color[3] >= 1.0f) == (pass == Opaque)) { + if ((fill_color[3] >= 1.0f) == (pass == RenderPass::Opaque)) { Sprite &sprite = *map.getSprite(); if (properties.image.size() && sprite) { SpriteAtlas &spriteAtlas = *map.getSpriteAtlas(); @@ -128,7 +128,7 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c // Because we're drawing top-to-bottom, and we update the stencil mask // below, we have to draw the outline first (!) - if (fringeline && pass == Translucent) { + if (fringeline && pass == RenderPass::Translucent) { useProgram(outlineShader->program); outlineShader->setMatrix(vtxMatrix); lineWidth(2.0f); // This is always fixed and does not depend on the pixelRatio! @@ -146,59 +146,10 @@ void Painter::renderFill(FillBucket& bucket, const FillProperties& properties, c } } -void Painter::renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id) { +void Painter::renderFill(FillBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) { // Abort early. if (!bucket.hasData()) return; - const FillProperties &properties = layer_desc->getProperties<FillProperties>(); - - if (layer_desc->rasterize && layer_desc->rasterize->isEnabled(id.z)) { - if (pass == Translucent) { - const RasterizedProperties rasterize = layer_desc->rasterize->get(id.z); - // Buffer value around the 0..4096 extent that will be drawn into the 256x256 pixel - // texture. We later scale the texture so that the actual bounds will align with this - // tile's bounds. The reason we do this is so that the - if (!bucket.prerendered) { - bucket.prerendered = std::make_unique<PrerenderedTexture>(rasterize); - bucket.prerendered->bindFramebuffer(); - - preparePrerender(*bucket.prerendered); - - const FillProperties modifiedProperties = [&]{ - FillProperties modifiedProperties = properties; - modifiedProperties.opacity = 1; - return modifiedProperties; - }(); - - // When drawing the fill, we want to draw a buffer around too, so we - // essentially downscale everyting, and then upscale it later when rendering. - const int buffer = rasterize.buffer * 4096.0f; - const mat4 vtxMatrix = [&]{ - mat4 vtxMatrix; - matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); - matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); - return vtxMatrix; - }(); - - setOpaque(); - renderFill(bucket, modifiedProperties, id, vtxMatrix); - - setTranslucent(); - renderFill(bucket, modifiedProperties, id, vtxMatrix); - - if (rasterize.blur > 0) { - bucket.prerendered->blur(*this, rasterize.blur); - } - - // RESET STATE - bucket.prerendered->unbindFramebuffer(); - finishPrerender(*bucket.prerendered); - } - - renderPrerenderedTexture(*bucket.prerendered, properties); - } - } else { - const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); - renderFill(bucket, properties, id, vtxMatrix); - } + const mat4 &vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor); + renderFill(bucket, properties, id, vtxMatrix); } diff --git a/src/renderer/painter_line.cpp b/src/renderer/painter_line.cpp index dc09f58951..375b99297d 100644 --- a/src/renderer/painter_line.cpp +++ b/src/renderer/painter_line.cpp @@ -5,9 +5,9 @@ using namespace mbgl; -void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id) { +void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) { // Abort early. - if (pass == Opaque) return; + if (pass == RenderPass::Opaque) return; if (!bucket.hasData()) return; const LineProperties &properties = layer_desc->getProperties<LineProperties>(); @@ -31,7 +31,7 @@ void Painter::renderLine(LineBucket& bucket, std::shared_ptr<StyleLayer> layer_d float dash_length = properties.dash_array[0]; float dash_gap = properties.dash_array[1]; - const mat4 &vtxMatrix = translatedMatrix(properties.translate, id, properties.translateAnchor); + const mat4 &vtxMatrix = translatedMatrix(matrix, properties.translate, id, properties.translateAnchor); glDepthRange(strata, 1.0f); diff --git a/src/renderer/painter_prerender.cpp b/src/renderer/painter_prerender.cpp index 5d61b95535..f17014b622 100644 --- a/src/renderer/painter_prerender.cpp +++ b/src/renderer/painter_prerender.cpp @@ -1,9 +1,11 @@ #include <mbgl/renderer/painter.hpp> #include <mbgl/style/style_properties.hpp> +#include <mbgl/renderer/prerendered_texture.hpp> +#include <mbgl/renderer/raster_bucket.hpp> using namespace mbgl; -void Painter::preparePrerender(PrerenderedTexture &texture) { +void Painter::preparePrerender(RasterBucket &bucket) { glDisable(GL_DEPTH_TEST); glDisable(GL_STENCIL_TEST); @@ -12,21 +14,14 @@ void Painter::preparePrerender(PrerenderedTexture &texture) { const GLenum discards[] = {GL_COLOR_ATTACHMENT0}; glDiscardFramebufferEXT(GL_FRAMEBUFFER, 1, discards); #endif + glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, texture.properties.size, texture.properties.size); + glViewport(0, 0, bucket.properties.size, bucket.properties.size); } -void Painter::finishPrerender(PrerenderedTexture &/*texture*/) { - glEnable(GL_DEPTH_TEST); - glEnable(GL_STENCIL_TEST); - - glViewport(0, 0, gl_viewport[0], gl_viewport[1]); -} - -template <typename Properties> -void Painter::renderPrerenderedTexture(PrerenderedTexture &texture, const Properties &properties) { - const int buffer = texture.properties.buffer * 4096.0f; +void Painter::renderPrerenderedTexture(RasterBucket &bucket, const mat4 &matrix, const RasterProperties& properties) { + const int buffer = bucket.properties.buffer * 4096.0f; // draw the texture on a quad useProgram(rasterShader->program); @@ -39,9 +34,7 @@ void Painter::renderPrerenderedTexture(PrerenderedTexture &texture, const Proper rasterShader->setImage(0); rasterShader->setBuffer(buffer); rasterShader->setOpacity(properties.opacity); - texture.bindTexture(); + bucket.texture.bindTexture(); coveringRasterArray.bind(*rasterShader, tileStencilBuffer, BUFFER_OFFSET(0)); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)tileStencilBuffer.index()); } - -template void Painter::renderPrerenderedTexture(PrerenderedTexture &, const FillProperties &); diff --git a/src/renderer/painter_raster.cpp b/src/renderer/painter_raster.cpp index ef2eab2a6c..7dcc9b24d6 100644 --- a/src/renderer/painter_raster.cpp +++ b/src/renderer/painter_raster.cpp @@ -1,25 +1,78 @@ #include <mbgl/renderer/painter.hpp> +#include <mbgl/platform/gl.hpp> #include <mbgl/renderer/raster_bucket.hpp> #include <mbgl/style/style_layer.hpp> +#include <mbgl/style/style_layer_group.hpp> +#include <mbgl/util/std.hpp> #include <mbgl/map/map.hpp> +#include <mbgl/map/transform.hpp> using namespace mbgl; -void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> /*layer_desc*/, const Tile::ID& /*id*/) { - if (pass == Translucent) return; +void Painter::renderRaster(RasterBucket& bucket, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID& id, const mat4 &matrix) { + if (pass != RenderPass::Translucent) return; - // const RasterProperties &properties = layer_desc->getProperties<RasterProperties>(); + const RasterProperties &properties = layer_desc->getProperties<RasterProperties>(); - depthMask(false); + if (layer_desc->layers) { - useProgram(rasterShader->program); - rasterShader->setMatrix(matrix); - rasterShader->setBuffer(0); - rasterShader->setOpacity(1); - // rasterShader->setOpacity(properties.opacity * tile_data->raster->opacity); + if (!bucket.texture.getTexture()) { - glDepthRange(strata + strata_epsilon, 1.0f); - bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray); + bucket.texture.bindFramebuffer(); + + preparePrerender(bucket); + + const int buffer = bucket.properties.buffer * 4096.0f; + + const mat4 preMatrix = [&]{ + mat4 vtxMatrix; + matrix::ortho(vtxMatrix, -buffer, 4096 + buffer, -4096 - buffer, buffer, 0, 1); + matrix::translate(vtxMatrix, vtxMatrix, 0, -4096, 0); + return vtxMatrix; + }(); + + // call updateTiles to get parsed data for sublayers + map.updateTiles(); + + int i = 0; + for (auto it = layer_desc->layers->layers.begin(), end = layer_desc->layers->layers.end(); it != end; ++it, --i) { + setOpaque(); + map.renderLayer(*it, RenderPass::Opaque, &id, &preMatrix); + setTranslucent(); + map.renderLayer(*it, RenderPass::Translucent, &id, &preMatrix); + } + + if (bucket.properties.blur > 0) { + bucket.texture.blur(*this, bucket.properties.blur); + } + + bucket.texture.unbindFramebuffer(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); + + glViewport(0, 0, gl_viewport[0], gl_viewport[1]); + + } + + renderPrerenderedTexture(bucket, matrix, properties); + + } + + // Only draw non-prerendered raster here + if (bucket.hasData()) { + depthMask(false); + + useProgram(rasterShader->program); + rasterShader->setMatrix(matrix); + rasterShader->setBuffer(0); + rasterShader->setOpacity(properties.opacity); + + glDepthRange(strata + strata_epsilon, 1.0f); + + bucket.drawRaster(*rasterShader, tileStencilBuffer, coveringRasterArray); + + depthMask(true); + } - depthMask(true); } diff --git a/src/renderer/painter_symbol.cpp b/src/renderer/painter_symbol.cpp index a2238a3544..720f84d24e 100644 --- a/src/renderer/painter_symbol.cpp +++ b/src/renderer/painter_symbol.cpp @@ -10,9 +10,9 @@ namespace mbgl { void Painter::renderSymbol(SymbolBucket &bucket, std::shared_ptr<StyleLayer> layer_desc, - const Tile::ID &/*id*/) { + const Tile::ID &/*id*/, const mat4 &matrix) { // Abort early. - if (pass == Opaque) { + if (pass == RenderPass::Opaque) { return; } diff --git a/src/renderer/prerendered_texture.cpp b/src/renderer/prerendered_texture.cpp index 6b08a38a4c..52f7edc50b 100644 --- a/src/renderer/prerendered_texture.cpp +++ b/src/renderer/prerendered_texture.cpp @@ -1,10 +1,11 @@ #include <mbgl/renderer/prerendered_texture.hpp> #include <mbgl/renderer/painter.hpp> +#include <mbgl/style/style_bucket.hpp> using namespace mbgl; -PrerenderedTexture::PrerenderedTexture(const RasterizedProperties &properties) +PrerenderedTexture::PrerenderedTexture(const StyleBucketRaster &properties) : properties(properties) { } @@ -44,10 +45,24 @@ void PrerenderedTexture::bindFramebuffer() { glBindTexture(GL_TEXTURE_2D, 0); } + if (fbo_depth_stencil == 0) { + // Create depth/stencil buffer + glGenRenderbuffers(1, &fbo_depth_stencil); + glBindRenderbuffer(GL_RENDERBUFFER, fbo_depth_stencil); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, properties.size, properties.size); + glBindRenderbuffer(GL_RENDERBUFFER, 0); + } + if (fbo == 0) { glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); +#ifdef GL_ES_VERSION_2_0 + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, fbo_depth_stencil); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo_depth_stencil); +#else + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo_depth_stencil); +#endif GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { diff --git a/src/renderer/raster_bucket.cpp b/src/renderer/raster_bucket.cpp index 0d5bf21226..ddfff119e0 100644 --- a/src/renderer/raster_bucket.cpp +++ b/src/renderer/raster_bucket.cpp @@ -3,12 +3,14 @@ using namespace mbgl; -RasterBucket::RasterBucket(const std::shared_ptr<Texturepool> &texturepool) - : raster(texturepool) { +RasterBucket::RasterBucket(const std::shared_ptr<Texturepool> &texturepool, const StyleBucketRaster& properties) +: properties(properties), + texture(properties), + raster(texturepool) { } -void RasterBucket::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id) { - painter.renderRaster(*this, layer_desc, id); +void RasterBucket::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, const Tile::ID &id, const mat4 &matrix) { + painter.renderRaster(*this, layer_desc, id, matrix); } bool RasterBucket::setImage(const std::string &data) { @@ -22,6 +24,13 @@ void RasterBucket::drawRaster(RasterShader& shader, VertexBuffer &vertices, Vert glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index()); } +void RasterBucket::drawRaster(RasterShader& shader, VertexBuffer &vertices, VertexArrayObject &array, GLuint texture) { + raster.bind(texture); + shader.setImage(0); + array.bind(shader, vertices, BUFFER_OFFSET(0)); + glDrawArrays(GL_TRIANGLES, 0, (GLsizei)vertices.index()); +} + bool RasterBucket::hasData() const { return raster.isLoaded(); } diff --git a/src/renderer/symbol_bucket.cpp b/src/renderer/symbol_bucket.cpp index 4072cf0c61..459c235da7 100644 --- a/src/renderer/symbol_bucket.cpp +++ b/src/renderer/symbol_bucket.cpp @@ -23,8 +23,8 @@ SymbolBucket::SymbolBucket(const StyleBucketSymbol &properties, Collision &colli : properties(properties), collision(collision) {} void SymbolBucket::render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc, - const Tile::ID &id) { - painter.renderSymbol(*this, layer_desc, id); + const Tile::ID &id, const mat4 &matrix) { + painter.renderSymbol(*this, layer_desc, id, matrix); } bool SymbolBucket::hasData() const { return hasTextData() || hasIconData(); } diff --git a/src/style/property_fallback.cpp b/src/style/property_fallback.cpp index 4401c8105a..4028980cbe 100644 --- a/src/style/property_fallback.cpp +++ b/src/style/property_fallback.cpp @@ -47,7 +47,7 @@ const std::map<PropertyKey, PropertyValue> PropertyFallbackValue::properties = { { PropertyKey::CompositeOpacity, defaultStyleProperties<CompositeProperties>().opacity }, { PropertyKey::RasterOpacity, defaultStyleProperties<RasterProperties>().opacity }, - { PropertyKey::RasterSpin, defaultStyleProperties<RasterProperties>().spin }, + { PropertyKey::RasterHueRotate, defaultStyleProperties<RasterProperties>().hue_rotate }, { PropertyKey::RasterBrightnessLow, defaultStyleProperties<RasterProperties>().brightness[0] }, { PropertyKey::RasterBrightnessHigh, defaultStyleProperties<RasterProperties>().brightness[1] }, { PropertyKey::RasterSaturation, defaultStyleProperties<RasterProperties>().saturation }, diff --git a/src/style/style_layer.cpp b/src/style/style_layer.cpp index 1672ad4a8b..520c183780 100644 --- a/src/style/style_layer.cpp +++ b/src/style/style_layer.cpp @@ -5,9 +5,8 @@ namespace mbgl { -StyleLayer::StyleLayer(const std::string &id, std::map<ClassID, ClassProperties> &&styles, - std::unique_ptr<const RasterizeProperties> &&rasterize) - : id(id), styles(std::move(styles)), rasterize(std::move(rasterize)) {} +StyleLayer::StyleLayer(const std::string &id, std::map<ClassID, ClassProperties> &&styles) + : id(id), styles(std::move(styles)) {} bool StyleLayer::isBackground() const { return type == StyleLayerType::Background; @@ -229,7 +228,7 @@ void StyleLayer::applyStyleProperties<RasterProperties>(const float z, const tim properties.set<RasterProperties>(); RasterProperties &raster = properties.get<RasterProperties>(); applyStyleProperty(PropertyKey::RasterOpacity, raster.opacity, z, now); - applyStyleProperty(PropertyKey::RasterSpin, raster.spin, 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); diff --git a/src/style/style_parser.cpp b/src/style/style_parser.cpp index bc3878144f..67d3f81a02 100644 --- a/src/style/style_parser.cpp +++ b/src/style/style_parser.cpp @@ -344,7 +344,7 @@ bool StyleParser::parseOptionalProperty(const char *property_name, PropertyKey k template <typename T> bool StyleParser::parseOptionalProperty(const char *property_name, T &target, JSVal value) { if (!value.HasMember(property_name)) { - return false; + return false; } else { return setProperty<T>(replaceConstant(value[property_name]), property_name, target); } @@ -492,14 +492,8 @@ std::shared_ptr<StyleLayer> StyleParser::createLayer(JSVal value) { std::map<ClassID, ClassProperties> styles; parseStyles(value, styles); - // Parse Rasterization options, as they can't be inherited anyway. - std::unique_ptr<const RasterizeProperties> rasterize; - if (value.HasMember("rasterize")) { - rasterize = parseRasterize(replaceConstant(value["rasterize"])); - } - std::shared_ptr<StyleLayer> layer = std::make_shared<StyleLayer>( - layer_id, std::move(styles), std::move(rasterize)); + layer_id, std::move(styles)); if (value.HasMember("layers")) { layer->layers = createLayers(value["layers"]); @@ -525,11 +519,6 @@ void StyleParser::parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair JSVal value = pair.first; std::shared_ptr<StyleLayer> &layer = pair.second; - if (layer->bucket || layer->layers) { - // Skip parsing this again. We already have a valid layer definition. - return; - } - if (value.HasMember("type")) { JSVal type = value["type"]; if (!type.IsString()) { @@ -539,6 +528,11 @@ void StyleParser::parseLayer(std::pair<JSVal, std::shared_ptr<StyleLayer>> &pair } } + if (layer->bucket || (layer->layers && layer->type != StyleLayerType::Raster)) { + // Skip parsing this again. We already have a valid layer definition. + return; + } + // Make sure we have not previously attempted to parse this layer. if (std::find(stack.begin(), stack.end(), layer.get()) != stack.end()) { Log::Warning(Event::ParseStyle, "layer reference of '%s' is circular", layer->id.c_str()); @@ -637,10 +631,11 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) { parseOptionalProperty<Function<float>>("composite-opacity", Key::CompositeOpacity, klass, value); parseOptionalProperty<PropertyTransition>("transition-composite-opacity", Key::CompositeOpacity, klass, value); +// TODO edit these?: parseOptionalProperty<Function<float>>("raster-opacity", Key::RasterOpacity, klass, value); parseOptionalProperty<PropertyTransition>("transition-raster-opacity", Key::RasterOpacity, klass, value); - parseOptionalProperty<Function<float>>("raster-spin", Key::RasterSpin, klass, value); - parseOptionalProperty<PropertyTransition>("transition-raster-spin", Key::RasterSpin, klass, value); + parseOptionalProperty<Function<float>>("raster-hue-rotate", Key::RasterHueRotate, klass, value); + parseOptionalProperty<PropertyTransition>("transition-raster-hue-rotate", Key::RasterHueRotate, klass, value); parseOptionalProperty<Function<float>>("raster-brightness-low", Key::RasterBrightnessLow, klass, value); parseOptionalProperty<PropertyTransition>("transition-raster-brightness-low", Key::RasterBrightnessLow, klass, value); parseOptionalProperty<Function<float>>("raster-brightness-high", Key::RasterBrightnessHigh, klass, value); @@ -655,19 +650,6 @@ void StyleParser::parseStyle(JSVal value, ClassProperties &klass) { parseOptionalProperty<Function<Color>>("background-color", Key::BackgroundColor, klass, value); } -std::unique_ptr<RasterizeProperties> StyleParser::parseRasterize(JSVal value) { - auto rasterize = std::make_unique<RasterizeProperties>(); - - if (value.IsObject()) { - parseOptionalProperty("enabled", rasterize->enabled, value); - parseOptionalProperty("buffer", rasterize->buffer, value); - parseOptionalProperty("size", rasterize->size, value); - parseOptionalProperty("blur", rasterize->blur, value); - } - - return rasterize; -} - void StyleParser::parseReference(JSVal value, std::shared_ptr<StyleLayer> &layer) { if (!value.IsString()) { Log::Warning(Event::ParseStyle, "layer ref of '%s' must be a string", layer->id.c_str()); @@ -925,6 +907,18 @@ void StyleParser::parseRender(JSVal value, std::shared_ptr<StyleLayer> &layer) { parseRenderProperty(value, render.text.ignore_placement, "text-ignore-placement"); parseRenderProperty(value, render.text.optional, "text-optional"); } break; + + case StyleLayerType::Raster: { + StyleBucketRaster &render = bucket.render.get<StyleBucketRaster>(); + + parseRenderProperty(value, render.size, "raster-size"); + parseRenderProperty(value, render.blur, "raster-blur"); + parseRenderProperty(value, render.buffer, "raster-buffer"); + if (layer->layers) { + render.prerendered = true; + } + } break; + default: // There are no render properties for these layer types. break; diff --git a/src/util/raster.cpp b/src/util/raster.cpp index fe5acbd526..9a71573d01 100644 --- a/src/util/raster.cpp +++ b/src/util/raster.cpp @@ -68,6 +68,28 @@ void Raster::bind(bool linear) { } } +// overload ::bind for prerendered raster textures +void Raster::bind(const GLuint texture) { + if (img && !textured) { + glBindTexture(GL_TEXTURE_2D, texture); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->getData()); + img.reset(); + textured = true; + } else if (textured) { + glBindTexture(GL_TEXTURE_2D, texture); + } + + GLuint filter = GL_LINEAR; + if (filter != this->filter) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + this->filter = filter; + } + +} + void Raster::beginFadeInTransition() { timestamp start = util::now(); fade_transition = std::make_shared<util::ease_transition<double>>(opacity, 1.0, opacity, start, 250_milliseconds); diff --git a/src/util/texturepool.cpp b/src/util/texturepool.cpp index 67685eeee1..04511348e9 100644 --- a/src/util/texturepool.cpp +++ b/src/util/texturepool.cpp @@ -25,7 +25,7 @@ GLuint Texturepool::getTextureID() { return id; } - + void Texturepool::removeTextureID(GLuint texture_id) { bool needs_clear = false; diff --git a/styles/outdoors/style.json b/styles/outdoors/style.json new file mode 100644 index 0000000000..9abf917868 --- /dev/null +++ b/styles/outdoors/style.json @@ -0,0 +1,2220 @@ +{ + "version": 4, + "sprite": "https://www.mapbox.com/mapbox-gl-styles/sprites/outdoors", + "glyphs": "https://mapbox.s3.amazonaws.com/gl-glyphs-256/{fontstack}/{range}.pbf", + "constants": { + "@land": "rgb(244,239,225)", + "@water": "#cdd", + "@water_dark": "#185869", + "@crop": "#eeeed4", + "@grass": "#e6e6cc", + "@scrub": "#dfe5c8", + "@wood": "#cee2bd", + "@snow": "#f4f8ff", + "@rock": "#ddd", + "@sand": "#ffd", + "@cemetery": "#edf4ed", + "@pitch": "#fff", + "@park": "#d4e4bc", + "@piste": "blue", + "@school": "#e8dfe0", + "@hospital": "#f8eee0", + "@builtup": "#f6faff", + "@case": "#fff", + "@motorway": "#cda0a0", + "@main": "#ddc0b9", + "@street": "#fff", + "@text": "#666", + "@text_stroke": "rgba(255,255,255,0.8)", + "@country_text": "#222", + "@marine_text": "#a0bdc0", + "@water_text": "#185869", + "@land_night": "#017293", + "@water_night": "#103", + "@water_dark_night": "#003366", + "@crop_night": "#178d96", + "@grass_night": "#23948a", + "@scrub_night": "#31a186", + "@wood_night": "#45b581", + "@park_night": "#51bd8b", + "@snow_night": "#5ad9fe", + "@rock_night": "#999", + "@sand_night": "#437162", + "@cemetery_night": "#218c96", + "@pitch_night": "rgba(255,255,255,0.2)", + "@school_night": "#01536a", + "@hospital_night": "#015e7a", + "@builtup_night": "#014b60", + "@admin_night": "#ffb680", + "@text_night": "#fff", + "@text_water_night": "#2a5b8a", + "@text_stroke_night": "#103", + "@text2_stroke_night": "rgba(1,69,89,0.8)", + "@case_night": "#015e7a", + "@street_case_night": "#015b76", + "@motorway_night": "#bbdde7", + "@main_night": "#64b2c9", + "@street_night": "#0186ac", + "@contour_night": "#ffff80", + "@river_canal_width": { + "stops": [[10, 0.5], [11, 1], [13, 2], [15, 3]] + }, + "@stream_width": { + "stops": [[12, 0.25], [13, 0.5], [15, 1.5], [17, 2]] + }, + "@motorway_width": { + "stops": [[4, 0], [5, 0.5], [7, 0.8], [9, 1], [10, 1.2], [11, 2], [12, 3], [13, 4], [14, 6], [15, 9], [16, 12], [17, 14]] + }, + "@motorway_casing_width": { + "stops": [[6.5, 0.6], [7, 0.8], [9, 2.8], [10, 3], [11, 4], [12, 5], [13, 6.5], [14, 9], [15, 12], [16, 15], [17, 17]] + }, + "@motorway_link_width": { + "stops": [[11, 1.2], [13, 2], [15, 3], [17, 4]] + }, + "@motorway_link_casing_width": { + "stops": [[11, 2.8], [13, 3.5], [15, 5], [17, 6]] + }, + "@main_width": { + "stops": [[4, 1], [11, 1], [12, 1.5], [13, 2], [14, 3], [15, 6], [16, 10], [17, 12]] + }, + "@main_casing_width": { + "stops": [[8, 2.9], [11, 2.9], [12, 3.5], [13, 4], [14, 5.5], [15, 9], [16, 12], [17, 14]] + }, + "@street_width": { + "stops": [[13.5, 0], [14, 1.5], [15, 3], [16, 8]] + }, + "@street_casing_width": { + "stops": [[12, 0.4], [13, 1], [14, 2.5], [15, 4], [16, 10]] + }, + "@street_casing_opacity": { + "stops": [[13, 0], [13.5, 1]] + }, + "@service_casing_width": { + "stops": [[13, 0.5], [14, 3], [15, 3.5], [16, 4], [17, 5], [18, 6]] + }, + "@runway_width": { + "stops": [[9, 1], [10, 2], [11, 3], [12, 5], [13, 7], [14, 11], [15, 15], [16, 19], [17, 23]] + }, + "@taxiway_width": { + "stops": [[9, 0.2], [11, 0.2], [12, 1], [13, 1.5], [14, 2], [15, 3], [16, 4], [17, 5]] + }, + "@aerialway_width": { + "stops": [[12.5, 0.8], [13, 1.4], [14, 1.6], [15, 2], [16, 2.4], [17, 3]] + }, + "@aerialway_casing_width": { + "stops": [[12.5, 2], [13, 2.5], [14, 3], [15, 3.5], [16, 4], [21, 5]] + }, + "@path_width": { + "stops": [[13, 1.2], [14, 1.5], [15, 1.8]] + }, + "@admin_l2_width": { + "stops": [[1, 0.5], [2, 0.7], [3, 0.7], [4, 0.8], [5, 1], [7, 2], [9, 3]] + }, + "@admin_l3_width": { + "stops": [[5, 0.6], [7, 1], [11, 2]] + }, + "@road_label_1_size": { + "stops": [[12, 11], [13, 12], [14, 13], [15, 14], [16, 16], [17, 18]] + }, + "@road_label_2_size": { + "stops": [[12, 11], [13, 12], [15, 14], [17, 16]] + }, + "@road_label_3_size": { + "stops": [[14, 10], [15, 12], [17, 14]] + }, + "@fence_width": { + "stops": [[16, 0.6], [18, 1]] + }, + "@hedge_width": { + "stops": [[15, 0.6], [16, 1.2], [18, 1.6]] + }, + "@barrier_line_land_width": { + "stops": [[13, 0.4], [14, 0.75], [15, 1.5], [16, 3], [17, 6], [18, 12], [19, 24], [20, 48]] + }, + "@country_label_size": { + "stops": [[0, 14], [11, 24]] + }, + "@poi_label_1-2_size": { + "stops": [[14, 10], [15, 11], [16, 12]] + }, + "@poi_label_3_size": { + "stops": [[15, 10], [16, 11]] + }, + "@hillshade_prerender": { + "stops": [[10, 0], [11, 1]] + }, + "@hillshade_prerender_size": { + "stops": [[10, 1056], [11, 512], [12, 256]] + } + }, + "sources": { + "mapbox": { + "type": "vector", + "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v6-dev", + "maxZoom": 15 + } + }, + "layers": [{ + "id": "background", + "style": { + "background-color": "@land" + }, + "style.night": { + "background-color": "@land_night" + }, + "type": "background" + }, { + "id": "landcover_snow", + "source": "mapbox", + "source-layer": "landcover", + "filter": { "class": "snow" }, + "style": { + "fill-color": "@snow" + }, + "style.night": { + "fill-color": "@snow_night" + }, + "type": "fill" + }, { + "id": "landcover_crop", + "source": "mapbox", + "source-layer": "landcover", + "filter": { "class": "crop" }, + "style": { + "fill-color": "@crop" + }, + "style.night": { + "fill-color": "@crop_night" + }, + "type": "fill" + }, { + "id": "landcover_grass", + "source": "mapbox", + "source-layer": "landcover", + "filter": { "class": "grass" }, + "style": { + "fill-color": "@grass", + "fill-opacity": { + "stops": [[12, 1], [13, 0.8], [16, 0.2]] + } + }, + "style.night": { + "fill-color": "@grass_night", + "fill-opacity": { + "stops": [[12, 1], [13, 0.8], [16, 0.2]] + } + }, + "type": "fill" + }, { + "id": "landcover_scrub", + "source": "mapbox", + "source-layer": "landcover", + "filter": { "class": "scrub" }, + "style": { + "fill-color": "@scrub", + "fill-opacity": { + "stops": [[12, 1], [13, 0.8], [16, 0.2]] + } + }, + "style.night": { + "fill-color": "@scrub_night", + "fill-opacity": { + "stops": [[12, 1], [13, 0.8], [16, 0.2]] + } + }, + "type": "fill" + }, { + "id": "landcover_wood", + "source": "mapbox", + "source-layer": "landcover", + "filter": { "class": "wood" }, + "style": { + "fill-color": "@wood", + "fill-opacity": { + "stops": [[12, 1], [13, 0.8], [16, 0.2]] + } + }, + "style.night": { + "fill-color": "@wood_night", + "fill-opacity": { + "stops": [[12, 1], [13, 0.8], [16, 0.2]] + } + }, + "type": "fill" + }, { + "id": "landuse_wood", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "wood" }, + "style": { + "fill-color": "@wood" + }, + "style.night": { + "fill-color": "@wood_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_school", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "school" }, + "style": { + "fill-color": "@school" + }, + "style.night": { + "fill-color": "@school_night" + }, + "type": "fill" + }, { + "id": "landuse_sand", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "sand" }, + "style": { + "fill-color": "@sand" + }, + "style.night": { + "fill-color": "@sand_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_pitch", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "pitch" }, + "style": { + "fill-color": "rgba(255,255,255,0.5)", + "fill-outline-color": "@pitch" + }, + "style.night": { + "fill-color": "@pitch_night", + "fill-outline-color": "@pitch" + }, + "type": "fill" + }, { + "id": "landuse_park", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "park" }, + "style": { + "fill-color": "@park" + }, + "style.night": { + "fill-color": "@park_night" + }, + "type": "fill" + }, { + "id": "landuse_industrial", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "industrial" }, + "style": { + "fill-color": "rgba(246,250,255,0.5)" + }, + "style.night": { + "fill-color": "@builtup_night" + }, + "type": "fill" + }, { + "id": "landuse_scrub", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "scrub" }, + "style": { + "fill-color": "@scrub" + }, + "style.night": { + "fill-color": "@scrub_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_grass", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "grass" }, + "style": { + "fill-color": "@grass" + }, + "style.night": { + "fill-color": "@grass_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_crop", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "crop" }, + "style": { + "fill-color": "@crop" + }, + "style.night": { + "fill-color": "@crop_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_rock", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "rock" }, + "style": { + "fill-color": "@rock" + }, + "style.night": { + "fill-color": "@rock_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_snow", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "snow" }, + "style": { + "fill-color": "@snow" + }, + "style.night": { + "fill-color": "@snow_night", + "fill-opacity": 0.8 + }, + "type": "fill" + }, { + "id": "landuse_hospital", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "hospital" }, + "style": { + "fill-color": "@hospital" + }, + "style.night": { + "fill-color": "@hospital_night" + }, + "type": "fill" + }, { + "id": "landuse_cemetery", + "source": "mapbox", + "source-layer": "landuse", + "filter": { "class": "cemetery" }, + "style": { + "fill-color": "@cemetery" + }, + "style.night": { + "fill-color": "@cemetery_night" + }, + "type": "fill" + }, { + "id": "overlay_breakwater_pier", + "source": "mapbox", + "source-layer": "landuse_overlay", + "filter": { "class": ["breakwater", "pier"] }, + "style": { + "fill-color": "@land" + }, + "style.night": { + "fill-color": "@land_night" + }, + "type": "fill" + }, { + "id": "waterway_river_canal", + "source": "mapbox", + "source-layer": "waterway", + "filter": { "type": ["river", "canal"] }, + "render": { + "line-cap": "round" + }, + "style": { + "line-color": "#87abaf", + "line-width": "@river_canal_width" + }, + "style.night": { + "line-color": "rgb(10,20,71)", + "line-width": "@river_canal_width" + }, + "type": "line" + }, { + "id": "waterway_stream", + "source": "mapbox", + "source-layer": "waterway", + "filter": { "type": "stream" }, + "render": { + "line-cap": "round" + }, + "style": { + "line-color": "#87abaf", + "line-width": "@stream_width" + }, + "style.night": { + "line-color": "rgb(10,20,71)", + "line-width": "@stream_width" + }, + "type": "line" + }, { + "id": "hillshade_rasters", + "type": "raster", + "source": "mapbox", + "render": { + "raster-size": 512, + "raster-blur": 1 + }, + "style": { + "raster-opacity": 1 + }, + "layers": [ + { + "id": "hillshade_full_highlight", + "source": "mapbox", + "source-layer": "hillshade", + "filter": { "class": "full_highlight" }, + "style": { + "fill-color": "#fffff3", + "fill-antialias": false, + "fill-opacity": { + "stops": [[14, 0.3], [15, 0.3], [16, 0.2], [17, 0.2], [18, 0.1]] + } + }, + "style.night": { + "fill-color": "#fdfdad", + "fill-antialias": false, + "fill-opacity": { + "stops": [[13, 0.4], [14, 0.3], [16, 0.2], [17, 0.1], [18, 0.05]] + } + }, + "type": "fill" + }, { + "id": "hillshade_medium_highlight", + "source": "mapbox", + "source-layer": "hillshade", + "filter": { "class": "medium_highlight" }, + "style": { + "fill-color": "#ffd", + "fill-antialias": false, + "fill-opacity": { + "stops": [[14, 0.3], [15, 0.3], [16, 0.2], [17, 0.2], [18, 0.1]] + } + }, + "style.night": { + "fill-color": "#ffe1b7", + "fill-antialias": false, + "fill-opacity": { + "stops": [[14, 0.3], [16, 0.2], [17, 0.15], [18, 0.05]] + } + }, + "type": "fill" + }, { + "id": "hillshade_medium_shadow", + "source": "mapbox", + "source-layer": "hillshade", + "filter": { "class": "medium_shadow" }, + "style": { + "fill-color": "#206", + "fill-antialias": false, + "fill-opacity": { + "stops": [[14, 0.08], [15, 0.075], [16, 0.05], [17, 0.05], [18, 0.025]] + } + }, + "style.night": { + "fill-color": "#206", + "fill-antialias": false, + "fill-opacity": { + "stops": [[15, 0.3], [16, 0.2], [17, 0.1], [18, 0.05]] + } + }, + "type": "fill" + }, { + "id": "hillshade_full_shadow", + "source": "mapbox", + "source-layer": "hillshade", + "filter": { "class": "full_shadow" }, + "style": { + "fill-color": "#103", + "fill-antialias": false, + "fill-opacity": { + "stops": [[14, 0.08], [15, 0.075], [16, 0.05], [17, 0.05], [18, 0.025]] + } + }, + "style.night": { + "fill-color": "#103", + "fill-antialias": false, + "fill-opacity": { + "stops": [[15, 0.3], [16, 0.2], [17, 0.1], [18, 0.05]] + } + }, + "type": "fill" + } + ] + }, { + "id": "overlay_wetland", + "source": "mapbox", + "source-layer": "landuse_overlay", + "filter": { "class": ["wetland", "wetland_noveg"] }, + "style": { + "fill-color": "rgba(210,225,225,0.2)", + "fill-image": "wetland_noveg_64" + }, + "style.night": { + "fill-color": "rgba(210,225,225,0.2)", + "fill-image": "wetland_noveg_64" + }, + "type": "fill" + }, { + "id": "building_shadow", + "source": "mapbox", + "source-layer": "building", + "style": { + "fill-color": "#d5d1c6", + "fill-translate": [1, 1], + "fill-opacity": { + "stops": [[15.5, 0], [16, 1]] + }, + "fill-outline-color": "#d5d1c6" + }, + "style.night": { + "fill-color": "#026688", + "fill-translate": [1, 1], + "fill-opacity": { + "stops": [[15.5, 0], [16, 1]] + }, + "fill-outline-color": "#026688" + }, + "type": "fill" + }, { + "id": "building", + "ref": "building_shadow", + "style": { + "fill-color": "#ebe7db" + }, + "style.night": { + "fill-color": "#027797" + } + }, { + "id": "building_wall", + "ref": "building_shadow", + "style": { + "fill-color": "#ebe7db", + "fill-opacity": { + "stops": [[15.5, 0], [16, 0.7]] + }, + "fill-outline-color": "#d5d1c6" + }, + "style.night": { + "fill-color": "#027797", + "fill-opacity": { + "stops": [[15.5, 0], [16, 0.7]] + }, + "fill-outline-color": "#026688" + } + }, { + "id": "contour_line_loud", + "source": "mapbox", + "source-layer": "contour", + "filter": { "index": 5 }, + "render": { + "line-join": "round" + }, + "style": { + "line-color": "#008", + "line-width": 0.9, + "line-opacity": { + "stops": [[11, 0.05], [12, 0.11]] + } + }, + "style.night": { + "line-color": "@contour_night", + "line-width": 0.9, + "line-opacity": { + "stops": [[11, 0.1], [12, 0.2]] + } + }, + "type": "line" + }, { + "id": "contour_line_regular", + "source": "mapbox", + "source-layer": "contour", + "render": { + "line-join": "round" + }, + "style": { + "line-color": "#008", + "line-width": 0.5, + "line-opacity": { + "stops": [[11, 0.05], [12, 0.11]] + } + }, + "style.night": { + "line-color": "@contour_night", + "line-width": 0.5, + "line-opacity": { + "stops": [[11, 0.1], [12, 0.4]] + } + }, + "type": "line" + }, { + "id": "barrier_line_gate", + "source": "mapbox", + "source-layer": "barrier_line", + "filter": { "class": "gate" }, + "style": { + "line-width": 2.5, + "line-color": "#aab" + }, + "style.night": { + "line-width": 2.5, + "line-color": "#59596f" + }, + "type": "line" + }, { + "id": "barrier_line_fence", + "source": "mapbox", + "source-layer": "barrier_line", + "filter": { "class": "fence" }, + "style": { + "line-color": "#aeada3", + "line-width": "@fence_width" + }, + "style.night": { + "line-color": "#014b61", + "line-width": "@fence_width" + }, + "type": "line" + }, { + "id": "barrier_line_hedge", + "source": "mapbox", + "source-layer": "barrier_line", + "filter": { "class": "hedge" }, + "style": { + "line-color": "#8de99b", + "line-width": "@hedge_width" + }, + "style.night": { + "line-color": "#2e7a57", + "line-width": "@hedge_width" + }, + "type": "line" + }, { + "id": "barrier_line_land", + "source": "mapbox", + "source-layer": "barrier_line", + "filter": { "class": "land" }, + "style": { + "line-color": "@land", + "line-width": "@barrier_line_land_width" + }, + "style.night": { + "line-color": "@land_night", + "line-width": "@barrier_line_land_width" + }, + "type": "line" + }, { + "id": "barrier_line_land_fill", + "source": "mapbox", + "source-layer": "barrier_line", + "filter": { "class": "land" }, + "style": { + "fill-color": "@land" + }, + "style.night": { + "fill-color": "@land_night" + }, + "type": "fill" + }, { + "id": "barrier_line_cliff", + "source": "mapbox", + "source-layer": "barrier_line", + "filter": { "class": "cliff" }, + "style": { + "line-color": "#987", + "line-width": 4 + }, + "style.night": { + "line-color": "#63574b", + "line-width": 4 + }, + "type": "line" + }, { + "id": "water", + "source": "mapbox", + "source-layer": "water", + "style": { + "fill-color": "@water", + "fill-outline-color": "#a2bdc0" + }, + "style.night": { + "fill-color": "@water_night", + "fill-outline-color": "@water_dark_night" + }, + "type": "fill" + }, { + "id": "aeroway_fill", + "source": "mapbox", + "source-layer": "aeroway", + "style": { + "fill-color": "#ddd" + }, + "style.night": { + "fill-color": "#367" + }, + "type": "fill" + }, { + "id": "aeroway_runway", + "source": "mapbox", + "source-layer": "aeroway", + "filter": { "type": "runway" }, + "style": { + "line-color": "#ddd", + "line-width": "@runway_width" + }, + "style.night": { + "line-color": "#367", + "line-width": "@runway_width" + }, + "type": "line" + }, { + "id": "aeroway_taxiway", + "source": "mapbox", + "source-layer": "aeroway", + "filter": { "type": "taxiway" }, + "style": { + "line-color": "#ddd", + "line-width": "@taxiway_width" + }, + "style.night": { + "line-color": "#367", + "line-width": "@taxiway_width" + }, + "type": "line" + }, { + "id": "tunnel_motorway_link_casing", + "source": "mapbox", + "source-layer": "tunnel", + "filter": { "class": "motorway_link" }, + "style": { + "line-color": "@case", + "line-dasharray": [6, 6], + "line-width": "@motorway_link_casing_width" + }, + "style.night": { + "line-color": "@case_night", + "line-dasharray": [6, 6], + "line-width": "@motorway_link_casing_width" + }, + "type": "line" + }, { + "id": "tunnel_service_casing", + "source": "mapbox", + "source-layer": "tunnel", + "filter": { "class": "service" }, + "style": { + "line-color": "#000", + "line-opacity": 0.04, + "line-dasharray": [6, 6], + "line-width": "@service_casing_width" + }, + "style.night": { + "line-color": "#000", + "line-opacity": 0.04, + "line-dasharray": [6, 6], + "line-width": "@service_casing_width" + }, + "type": "line" + }, { + "id": "tunnel_main_casing", + "source": "mapbox", + "source-layer": "tunnel", + "filter": { "class": "main" }, + "style": { + "line-color": "@case", + "line-dasharray": [6, 6], + "line-width": "@main_casing_width", + "line-opacity": { + "stops": [[8, 0], [9, 1]] + } + }, + "style.night": { + "line-color": "@case_night", + "line-dasharray": [6, 6], + "line-width": "@main_casing_width", + "line-opacity": { + "stops": [[8, 0], [9, 1]] + } + }, + "type": "line" + }, { + "id": "tunnel_street_casing", + "source": "mapbox", + "source-layer": "tunnel", + "filter": { "class": ["street", "street_limited"] }, + "style": { + "line-color": "#d9d5c6", + "line-width": "@street_casing_width", + "line-opacity": "@street_casing_opacity" + }, + "style.night": { + "line-color": "@street_case_night", + "line-width": "@street_casing_width", + "line-opacity": "@street_casing_opacity" + }, + "type": "line" + }, { + "id": "tunnel_motorway_link", + "ref": "tunnel_motorway_link_casing", + "style": { + "line-color": "#e6cec7", + "line-width": "@motorway_link_width" + }, + "style.night": { + "line-color": "#78b0c1", + "line-width": "@motorway_link_width" + } + }, { + "id": "tunnel_service", + "ref": "tunnel_service_casing", + "style": { + "line-color": "#e6cec7", + "line-width": 2 + }, + "style.night": { + "line-color": "#017ca0", + "line-width": 2 + } + }, { + "id": "tunnel_street", + "ref": "tunnel_street_casing", + "style": { + "line-color": "#d9d5c6", + "line-width": "@street_width" + }, + "style.night": { + "line-color": "@street_night", + "line-width": "@street_width" + } + }, { + "id": "tunnel_main", + "ref": "tunnel_main_casing", + "style": { + "line-color": "#e6cec7", + "line-width": "@main_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + }, + "style.night": { + "line-color": "#78b0c1", + "line-width": "@main_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + } + }, { + "id": "tunnel_motorway_casing", + "source": "mapbox", + "source-layer": "tunnel", + "filter": { "class": "motorway" }, + "style": { + "line-color": "@case", + "line-dasharray": [6, 6], + "line-width": "@motorway_casing_width", + "line-opacity": { + "stops": [[8.5, 0], [9, 1]] + } + }, + "style.night": { + "line-color": "@case_night", + "line-dasharray": [6, 6], + "line-width": "@motorway_casing_width", + "line-opacity": { + "stops": [[8.5, 0], [9, 1]] + } + }, + "type": "line" + }, { + "id": "tunnel_motorway", + "ref": "tunnel_motorway_casing", + "style": { + "line-color": "#e6cec7", + "line-width": "@motorway_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + }, + "style.night": { + "line-color": "#78b0c1", + "line-width": "@motorway_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + } + }, { + "id": "road_path_case", + "source": "mapbox", + "source-layer": "road", + "filter": { "class": "path" }, + "style": { + "line-color": "#ffd", + "line-opacity": 0.4, + "line-width": { + "stops": [[14, 3], [15, 4]] + } + }, + "style.night": { + "line-color": "@land_night", + "line-opacity": 0.2 + }, + "type": "line" + }, { + "id": "road_path_footway", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "type": "footway" }, + "style": { + "line-color": "#bba", + "line-dasharray": [10, 4], + "line-width": "@path_width" + }, + "style.night": { + "line-color": "#fff", + "line-dasharray": [10, 4], + "line-width": "@path_width" + }, + "type": "line" + }, { + "id": "road_path_path", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "type": "path" }, + "style": { + "line-color": "#987", + "line-dasharray": [10, 4], + "line-opacity": 0.8, + "line-width": { + "stops": [[13, 0.8], [14, 0.9], [15, 1.2]] + } + }, + "style.night": { + "line-color": "#fff", + "line-dasharray": [10, 4], + "line-opacity": 0.8, + "line-width": { + "stops": [[13, 0.8], [14, 0.9], [15, 1.2]] + } + }, + "type": "line" + }, { + "id": "road_path_cycleway", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "type": "cycleway" }, + "style": { + "line-color": "#488", + "line-dasharray": [10, 4], + "line-width": "@path_width" + }, + "style.night": { + "line-color": "#94e6ff", + "line-dasharray": [10, 4], + "line-width": "@path_width" + }, + "type": "line" + }, { + "id": "road_path_mtb", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "type": "mtb" }, + "style": { + "line-color": "#488", + "line-dasharray": [12, 4], + "line-width": "@path_width" + }, + "style.night": { + "line-color": "#94e6ff", + "line-dasharray": [12, 4], + "line-width": "@path_width" + }, + "type": "line" + }, { + "id": "road_path_piste", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "type": "piste" }, + "style": { + "line-color": "#87b", + "line-dasharray": [8, 4], + "line-width": "@path_width" + }, + "style.night": { + "line-color": "#715dae", + "line-dasharray": [8, 4], + "line-width": "@path_width" + }, + "type": "line" + }, { + "id": "road_path_steps", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "type": "steps" }, + "style": { + "line-color": "#bba", + "line-dasharray": [10, 4], + "line-width": 4 + }, + "style.night": { + "line-color": "#016684", + "line-dasharray": [10, 4], + "line-opacity": 0.3, + "line-width": 6 + }, + "type": "line" + }, { + "id": "road_major_rail", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": "major_rail" }, + "style": { + "line-color": "#c8c4c0", + "line-width": 0.8 + }, + "style.night": { + "line-color": "#c8c4c0", + "line-width": 0.8 + }, + "type": "line" + }, { + "id": "road_major_rail_hatching", + "ref": "road_major_rail", + "style": { + "line-color": "#c8c4c0", + "line-dasharray": [2, 31], + "line-width": 5 + }, + "style.night": { + "line-color": "#c8c4c0", + "line-dasharray": [2, 31], + "line-width": 5 + } + }, { + "id": "road_motorway_link_casing", + "source": "mapbox", + "source-layer": "road", + "filter": { "class": "motorway_link" }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "@case", + "line-width": "@motorway_link_casing_width" + }, + "style.night": { + "line-color": "@case_night", + "line-width": "@motorway_link_casing_width" + }, + "type": "line" + }, { + "id": "road_service_casing", + "source": "mapbox", + "source-layer": "road", + "filter": { "class": "service" }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "#000", + "line-opacity": 0.04, + "line-width": "@service_casing_width" + }, + "style.night": { + "line-color": "#000", + "line-opacity": 0.04, + "line-width": "@service_casing_width" + }, + "type": "line" + }, { + "id": "road_main_casing", + "source": "mapbox", + "source-layer": "road", + "filter": { "class": "main" }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "@case", + "line-width": "@main_casing_width", + "line-opacity": { + "stops": [[8, 0], [9, 1]] + } + }, + "style.night": { + "line-color": "@case_night", + "line-width": "@main_casing_width", + "line-opacity": { + "stops": [[8, 0], [9, 1]] + } + }, + "type": "line" + }, { + "id": "road_street_casing", + "source": "mapbox", + "source-layer": "road", + "filter": { "class": ["street", "street_limited"] }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "#d9d5c6", + "line-width": "@street_casing_width", + "line-opacity": "@street_casing_opacity" + }, + "style.night": { + "line-color": "@street_case_night", + "line-width": "@street_casing_width", + "line-opacity": "@street_casing_opacity" + }, + "type": "line" + }, { + "id": "road_motorway_link", + "ref": "road_motorway_link_casing", + "style": { + "line-color": "@motorway", + "line-width": "@motorway_link_width" + }, + "style.night": { + "line-color": "@motorway_night", + "line-width": "@motorway_link_width" + } + }, { + "id": "road_service", + "ref": "road_service_casing", + "style": { + "line-color": "@street", + "line-width": 2 + }, + "style.night": { + "line-color": "@street_night", + "line-width": 2 + } + }, { + "id": "road_street", + "ref": "road_street_casing", + "style": { + "line-color": "@street", + "line-width": "@street_width" + }, + "style.night": { + "line-color": "@street_night", + "line-width": "@street_width" + } + }, { + "id": "road_main", + "ref": "road_main_casing", + "style": { + "line-color": "@main", + "line-width": "@main_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + }, + "style.night": { + "line-color": "@main_night", + "line-width": "@main_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + } + }, { + "id": "road_motorway_casing", + "source": "mapbox", + "source-layer": "road", + "filter": { "class": "motorway" }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "@case", + "line-width": "@motorway_casing_width", + "line-opacity": { + "stops": [[8.5, 0], [9, 1]] + } + }, + "style.night": { + "line-color": "@case_night", + "line-width": "@motorway_casing_width", + "line-opacity": { + "stops": [[8.5, 0], [9, 1]] + } + }, + "type": "line" + }, { + "id": "road_motorway", + "ref": "road_motorway_casing", + "style": { + "line-color": "@motorway", + "line-width": "@motorway_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + }, + "style.night": { + "line-color": "@motorway_night", + "line-width": "@motorway_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + } + }, { + "id": "bridge_motorway_link_casing", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": "motorway_link" }, + "style": { + "line-color": "@case", + "line-width": "@motorway_link_casing_width" + }, + "style.night": { + "line-color": "@case_night", + "line-width": "@motorway_link_casing_width" + }, + "type": "line" + }, { + "id": "bridge_service_casing", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": "service" }, + "style": { + "line-color": "#000", + "line-opacity": 0.04, + "line-width": "@service_casing_width" + }, + "style.night": { + "line-color": "#000", + "line-opacity": 0.04, + "line-width": "@service_casing_width" + }, + "type": "line" + }, { + "id": "bridge_main_casing", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": "main" }, + "style": { + "line-color": "@case", + "line-width": "@main_casing_width", + "line-opacity": { + "stops": [[8, 0], [9, 1]] + } + }, + "style.night": { + "line-color": "@case_night", + "line-width": "@main_casing_width", + "line-opacity": { + "stops": [[8, 0], [9, 1]] + } + }, + "type": "line" + }, { + "id": "bridge_street_casing", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": ["street", "street_limited"] }, + "style": { + "line-color": "#d9d5c6", + "line-width": "@street_casing_width", + "line-opacity": "@street_casing_opacity" + }, + "style.night": { + "line-color": "@street_case_night", + "line-width": "@street_casing_width", + "line-opacity": "@street_casing_opacity" + }, + "type": "line" + }, { + "id": "bridge_motorway_link", + "ref": "bridge_motorway_link_casing", + "style": { + "line-color": "@motorway", + "line-width": "@motorway_link_width" + }, + "style.night": { + "line-color": "@motorway_night", + "line-width": "@motorway_link_width" + } + }, { + "id": "bridge_service", + "ref": "bridge_service_casing", + "style": { + "line-color": "@street", + "line-width": 2 + }, + "style.night": { + "line-color": "@street_night", + "line-width": 2 + } + }, { + "id": "bridge_street", + "ref": "bridge_street_casing", + "style": { + "line-color": "@street", + "line-width": "@street_width" + }, + "style.night": { + "line-color": "@street_night", + "line-width": "@street_width" + } + }, { + "id": "bridge_main", + "ref": "bridge_main_casing", + "style": { + "line-color": "@main", + "line-width": "@main_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + }, + "style.night": { + "line-color": "@main_night", + "line-width": "@main_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + } + }, { + "id": "bridge_motorway_casing", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": "motorway" }, + "style": { + "line-color": "@case", + "line-width": "@motorway_casing_width", + "line-opacity": { + "stops": [[8.5, 0], [9, 1]] + } + }, + "style.night": { + "line-color": "@case_night", + "line-width": "@motorway_casing_width", + "line-opacity": { + "stops": [[8.5, 0], [9, 1]] + } + }, + "type": "line" + }, { + "id": "bridge_motorway", + "ref": "bridge_motorway_casing", + "style": { + "line-color": "@motorway", + "line-width": "@motorway_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + }, + "style.night": { + "line-color": "@motorway_night", + "line-width": "@motorway_width", + "line-opacity": { + "stops": [[5.5, 0], [6, 1]] + } + } + }, { + "id": "bridge_aerialway_casing", + "source": "mapbox", + "source-layer": "bridge", + "filter": { "class": "aerialway" }, + "style": { + "line-color": "white", + "line-opacity": 0.5, + "line-width": "@aerialway_casing_width" + }, + "style.night": { + "line-color": "white", + "line-opacity": 0.5, + "line-width": "@aerialway_casing_width" + }, + "type": "line" + }, { + "id": "bridge_aerialway", + "ref": "bridge_aerialway_casing", + "style": { + "line-color": "#876", + "line-opacity": 0.5, + "line-width": "@aerialway_width" + }, + "style.night": { + "line-color": "#876", + "line-opacity": 0.5, + "line-width": "@aerialway_width" + } + }, { + "id": "admin_l3", + "source": "mapbox", + "source-layer": "admin", + "filter": { "admin_level": [3, 4, 5] }, + "render": { + "line-join": "round" + }, + "style": { + "line-color": "#88a", + "line-dasharray": [60, 20], + "line-opacity": { + "stops": [[3, 0], [5, 1]] + }, + "line-width": "@admin_l3_width" + }, + "style.night": { + "line-color": "@admin_night", + "line-dasharray": [60, 20], + "line-opacity": { + "stops": [[3, 0], [5, 1]] + }, + "line-width": "@admin_l3_width" + }, + "type": "line" + }, { + "id": "admin_l2", + "source": "mapbox", + "source-layer": "admin", + "filter": { "admin_level": 2 }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "#88a", + "line-width": "@admin_l2_width" + }, + "style.night": { + "line-color": "@admin_night", + "line-width": "@admin_l2_width" + }, + "type": "line" + }, { + "id": "admin_maritime_cover", + "source": "mapbox", + "source-layer": "admin", + "filter": { "maritime": 1 }, + "render": { + "line-join": "round", + "line-cap": "round" + }, + "style": { + "line-color": "@water", + "line-width": 5 + }, + "style.night": { + "line-color": "@water_night", + "line-width": 5 + }, + "type": "line" + }, { + "id": "admin_maritime", + "ref": "admin_maritime_cover", + "style": { + "line-color": "#c0d6d6", + "line-width": { + "stops": [[5, 1], [7, 2], [11, 3]] + } + }, + "style.night": { + "line-color": "#0a1347", + "line-width": { + "stops": [[5, 1], [7, 2], [11, 3]] + } + } + }, { + "id": "country_label_line", + "source": "mapbox", + "source-layer": "country_label_line", + "render": { + "text-max-width": 5 + }, + "style": { + "line-color": "@country_text", + "line-width": 0.5, + "line-opacity": 0.5 + }, + "style.night": { + "line-color": "@text_night", + "line-width": 0.5, + "line-opacity": 0.5 + }, + "type": "line" + }, { + "id": "country_label", + "source": "mapbox", + "source-layer": "country_label", + "filter": { "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 24, + "text-max-width": 5 + }, + "style": { + "text-color": "@country_text", + "text-halo-color": "rgba(255,255,255,0.5)", + "text-halo-width": { + "stops": [[0, 1.17], [11, 2]] + }, + "text-size": "@country_label_size" + }, + "style.night": { + "text-color": "@text_night", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[0, 1.63], [11, 2.8]] + }, + "text-size": "@country_label_size" + }, + "type": "symbol" + }, { + "id": "marine_label_line_1", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "LineString", "labelrank": 1 }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 30, + "text-max-angle": 28.65, + "text-letter-spacing": 0.4, + "symbol-placement": "line" + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[2, 20], [3, 25], [4, 30], [21, 30]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[2, 20], [3, 25], [4, 30], [21, 30]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_line_2", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "LineString", "labelrank": 2 }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 24, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[2, 13], [3, 14], [4, 20], [5, 24], [21, 24]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[2, 13], [3, 14], [4, 20], [5, 24], [21, 24]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_line_3", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "LineString", "labelrank": 3 }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 18, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[2, 12], [3, 13], [4, 15], [5, 18], [21, 18]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[2, 12], [3, 13], [4, 15], [5, 18], [21, 18]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_line_other", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "LineString", "labelrank": [4, 5, 6] }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 16, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[3, 12], [4, 14], [5, 16], [21, 16]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[3, 12], [4, 14], [5, 16], [21, 16]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_point_1", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "Point", "labelrank": 1 }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 30, + "text-max-width": 8, + "text-letter-spacing": 0.4, + "text-line-height": 2 + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[2, 20], [3, 25], [4, 30], [21, 30]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[2, 20], [3, 25], [4, 30], [21, 30]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_point_2", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "Point", "labelrank": 2 }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 24, + "text-max-width": 8, + "text-letter-spacing": 0.2, + "text-line-height": 1.5 + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[2, 13], [3, 14], [4, 20], [5, 24], [21, 24]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[2, 13], [3, 14], [4, 20], [5, 24], [21, 24]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_point_3", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "Point", "labelrank": 3 }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 18, + "text-max-width": 8, + "text-letter-spacing": 0.1, + "text-line-height": 1.3 + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[2, 12], [3, 13], [4, 15], [5, 18], [21, 18]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[2, 12], [3, 13], [4, 15], [5, 18], [21, 18]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "marine_label_point_other", + "source": "mapbox", + "source-layer": "marine_label", + "filter": { "$type": "Point", "labelrank": [4, 5, 6] }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 16, + "text-max-width": 8, + "text-letter-spacing": 0.1, + "text-line-height": 1.2 + }, + "style": { + "text-color": "@marine_text", + "text-size": { + "stops": [[3, 12], [4, 14], [5, 16], [21, 16]] + }, + "text-halo-color": "@water" + }, + "style.night": { + "text-color": "@water_dark_night", + "text-size": { + "stops": [[3, 12], [4, 14], [5, 16], [21, 16]] + }, + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "state_label", + "source": "mapbox", + "source-layer": "state_label", + "filter": { "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Regular, Arial Unicode MS Regular", + "text-max-size": 16, + "text-max-width": 8 + }, + "style": { + "text-color": "#333", + "text-halo-width": { + "stops": [[2.99, 0], [3, 1.17], [8.99, 1.87], [9, 0]] + }, + "text-halo-color": "rgba(244,239,225,0.8)", + "text-size": { + "stops": [[2.99, 0], [3, 10], [8.99, 16], [9, 0]] + } + }, + "style.night": { + "text-color": "#fff", + "text-halo-width": { + "stops": [[2.99, 0], [3, 1.17], [8.99, 1.87], [9, 0]] + }, + "text-halo-color": "@land_night", + "text-size": { + "stops": [[2.99, 0], [3, 10], [8.99, 16], [9, 0]] + } + }, + "type": "symbol" + }, { + "id": "place_label_city", + "source": "mapbox", + "source-layer": "place_label", + "filter": { "type": "city", "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 20, + "text-max-width": 8 + }, + "style": { + "text-color": "#444", + "text-halo-width": { + "stops": [[2.99, 0], [3, 1.17], [6, 1.63], [13.99, 2.33], [14, 0]] + }, + "text-halo-color": "@text_stroke", + "text-size": { + "stops": [[2.99, 0], [3, 10], [6, 14], [13.99, 20], [14, 0]] + } + }, + "style.night": { + "text-color": "#fff", + "text-halo-width": { + "stops": [[2.99, 0], [3, 1.17], [6, 1.63], [13.99, 2.33], [14, 0]] + }, + "text-halo-color": "@text2_stroke_night", + "text-size": { + "stops": [[2.99, 0], [3, 10], [6, 14], [13.99, 20], [14, 0]] + } + }, + "type": "symbol" + }, { + "id": "place_label_town", + "source": "mapbox", + "source-layer": "place_label", + "filter": { "type": "town", "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 24, + "text-max-width": 8 + }, + "style": { + "text-color": "#716656", + "text-halo-width": { + "stops": [[8, 1.5], [11, 1.95], [13, 2.55], [15, 3.3]] + }, + "text-halo-color": "@text_stroke", + "text-size": { + "stops": [[8, 10], [11, 13], [13, 17], [15, 22]] + } + }, + "style.night": { + "text-color": "@text_night", + "text-halo-width": { + "stops": [[8, 1.5], [11, 1.95], [13, 2.55], [15, 3.3]] + }, + "text-halo-color": "@text2_stroke_night", + "text-size": { + "stops": [[8, 10], [11, 13], [13, 17], [15, 22]] + } + }, + "type": "symbol" + }, { + "id": "place_label_village", + "source": "mapbox", + "source-layer": "place_label", + "filter": { "type": "village", "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 22, + "text-max-width": 8 + }, + "style": { + "text-color": "#635644", + "text-halo-width": { + "stops": [[8, 1.2], [11, 1.5], [13, 2.1], [15, 2.4], [16, 3]] + }, + "text-halo-color": "@text_stroke", + "text-size": { + "stops": [[8, 8], [11, 10], [13, 14], [15, 16], [16, 20]] + } + }, + "style.night": { + "text-color": "@text_night", + "text-halo-width": { + "stops": [[8, 1.2], [11, 1.5], [13, 2.1], [15, 2.4], [16, 3]] + }, + "text-halo-color": "@text2_stroke_night", + "text-size": { + "stops": [[8, 8], [11, 10], [13, 14], [15, 16], [16, 20]] + } + }, + "type": "symbol" + }, { + "id": "place_label_other", + "source": "mapbox", + "source-layer": "place_label", + "filter": { "type": ["hamlet", "suburb", "neighbourhood"], "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 18, + "text-max-width": 6 + }, + "style": { + "text-color": "#7d6c55", + "text-halo-color": "@text_stroke", + "text-size": { + "stops": [[12, 11], [13, 12], [15, 14], [17, 18]] + } + }, + "style.night": { + "text-color": "@text_night", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[12, 1.65], [13, 1.8], [15, 2.1], [17, 2.7]] + }, + "text-size": { + "stops": [[12, 11], [13, 12], [15, 14], [17, 18]] + } + }, + "type": "symbol" + }, { + "id": "road_label_1", + "source": "mapbox", + "source-layer": "road_label", + "filter": { "class": ["motorway", "main"], "$type": "LineString" }, + "render": { + "text-field": "{name_en}", + "text-padding": 2, + "text-font": "Open Sans Regular, Arial Unicode MS Regular", + "text-max-size": 18, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "#585042", + "text-halo-color": "@land", + "text-halo-width": { + "stops": [[12, 0.55], [13, 0.6], [14, 0.65], [15, 0.7], [16, 0.8], [17, 0.9]] + }, + "text-size": "@road_label_1_size" + }, + "style.night": { + "text-color": "@text_night", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[12, 0.92], [13, 1], [14, 1.08], [15, 1.17], [16, 1.33], [17, 1.5]] + }, + "text-size": "@road_label_1_size" + }, + "type": "symbol" + }, { + "id": "road_label_2", + "source": "mapbox", + "source-layer": "road_label", + "filter": { "class": ["street", "street_limited"], "$type": "LineString" }, + "render": { + "text-field": "{name_en}", + "text-padding": 2, + "text-font": "Open Sans Regular, Arial Unicode MS Regular", + "text-max-size": 16, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "#585042", + "text-halo-color": "@land", + "text-halo-width": { + "stops": [[12, 0.55], [13, 0.6], [15, 0.7], [17, 0.8]] + }, + "text-size": "@road_label_2_size" + }, + "style.night": { + "text-color": "@text_night", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[12, 0.92], [13, 1], [15, 1.17], [17, 1.33]] + }, + "text-size": "@road_label_2_size" + }, + "type": "symbol" + }, { + "id": "road_label_3", + "source": "mapbox", + "source-layer": "road_label", + "filter": { "class": ["service", "driveway", "path"], "$type": "LineString" }, + "render": { + "text-field": "{name_en}", + "text-padding": 2, + "text-font": "Open Sans Regular, Arial Unicode MS Regular", + "text-max-size": 14, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "#585042", + "text-halo-color": "@land", + "text-halo-width": { + "stops": [[14, 0.5], [15, 0.6], [17, 0.7]] + }, + "text-size": "@road_label_3_size" + }, + "style.night": { + "text-color": "@text_night", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[14, 0.83], [15, 1], [17, 1.17]] + }, + "text-size": "@road_label_3_size" + }, + "type": "symbol" + }, { + "id": "contour_label", + "source": "mapbox", + "source-layer": "contour", + "filter": { "index": [5, 10], "$type": "LineString" }, + "render": { + "text-field": "{ele} m", + "text-font": "Open Sans Regular, Arial Unicode MS Regular", + "text-max-size": 10, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "@text", + "text-halo-color": "@land", + "text-halo-width": 1.5, + "text-size": 10 + }, + "style.night": { + "text-color": "@contour_night", + "text-halo-color": "@land_night", + "text-halo-width": 1.5, + "text-size": 10 + }, + "type": "symbol" + }, { + "id": "water_label", + "source": "mapbox", + "source-layer": "water_label", + "filter": { "$type": "Point" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 12, + "text-max-width": 8 + }, + "style": { + "text-color": "@water_dark", + "text-halo-color": "rgba(255,255,255,0.75)" + }, + "style.night": { + "text-color": "@text_water_night", + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "waterway_label", + "source": "mapbox", + "source-layer": "waterway_label", + "filter": { "$type": "LineString" }, + "render": { + "text-field": "{name_en}", + "text-font": "Open Sans Semibold Italic, Arial Unicode MS Bold", + "text-max-size": 12, + "text-max-angle": 28.65, + "symbol-placement": "line" + }, + "style": { + "text-color": "@water_dark", + "text-halo-width": 1.4, + "text-halo-color": "@text_stroke" + }, + "style.night": { + "text-color": "@text_water_night", + "text-halo-color": "@water_night" + }, + "type": "symbol" + }, { + "id": "poi_label_1-2", + "source": "mapbox", + "source-layer": "poi_label", + "filter": { "scalerank": [1, 2], "$type": "Point" }, + "render": { + "icon-image": "{maki}-12", + "text-field": "{name_en}", + "text-padding": 2, + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 12, + "text-max-width": 10, + "text-offset": [0, 0.6], + "text-vertical-align": "top" + }, + "style": { + "text-color": "#444", + "text-size": "@poi_label_1-2_size", + "text-halo-color": "@land", + "text-halo-width": { + "stops": [[14, 1.5], [15, 1.65], [16, 1.8]] + } + }, + "style.night": { + "text-color": "#fff", + "text-size": "@poi_label_1-2_size", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[14, 1.5], [15, 1.65], [16, 1.8]] + } + }, + "type": "symbol" + }, { + "id": "poi_label_3", + "source": "mapbox", + "source-layer": "poi_label", + "filter": { "scalerank": 3, "$type": "Point" }, + "render": { + "icon-image": "{maki}-12", + "text-field": "{name_en}", + "text-padding": 2, + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 11, + "text-max-width": 10, + "text-offset": [0, 0.6], + "text-vertical-align": "top" + }, + "style": { + "icon-opacity": { + "stops": [[15.5, 0], [15.75, 1]] + }, + "text-color": "#444", + "text-size": "@poi_label_3_size", + "text-halo-color": "@land", + "text-halo-width": { + "stops": [[15, 1.5], [16, 1.65]] + }, + "text-opacity": { + "stops": [[15.5, 0], [15.75, 1]] + } + }, + "style.night": { + "text-color": "#fff", + "text-size": "@poi_label_3_size", + "text-halo-color": "@text2_stroke_night", + "text-halo-width": { + "stops": [[15, 1.5], [16, 1.65]] + }, + "text-opacity": { + "stops": [[15.5, 0], [15.75, 1]] + } + }, + "type": "symbol" + }, { + "id": "poi_label_4", + "source": "mapbox", + "source-layer": "poi_label", + "filter": { "scalerank": 4, "$type": "Point" }, + "render": { + "icon-image": "{maki}-12", + "text-field": "{name_en}", + "text-padding": 2, + "text-font": "Open Sans Semibold, Arial Unicode MS Bold", + "text-max-size": 10, + "text-max-width": 10, + "text-offset": [0, 0.6], + "text-vertical-align": "top" + }, + "style": { + "icon-opacity": { + "stops": [[17.5, 0], [17.75, 1]] + }, + "text-color": "#444", + "text-size": 10, + "text-opacity": { + "stops": [[17.5, 0], [17.75, 1]] + }, + "text-halo-color": "@land", + "text-halo-width": 1.5 + }, + "style.night": { + "text-color": "#fff", + "text-size": 10, + "text-opacity": { + "stops": [[17.5, 0], [17.75, 1]] + }, + "text-halo-color": "@text2_stroke_night", + "text-halo-width": 1.5 + }, + "type": "symbol" + }] +}
\ No newline at end of file |