diff options
author | Wilhelm Berg <wb@BergWerk-GIS.at> | 2018-08-22 16:56:32 +0200 |
---|---|---|
committer | Wilhelm Berg <wb@BergWerk-GIS.at> | 2018-08-22 16:56:32 +0200 |
commit | 797f622a26b34db5a30e7f1728d87c6700a2ec1e (patch) | |
tree | 75ea93979db2baf3eb2234c6fbb3d1a9c5b70329 /src/mbgl | |
parent | 86fc3f525e42d042f239876b93525ff411ad7182 (diff) | |
parent | 520df7f02049cdbbb9e68041e755d6c3a8d5b21f (diff) | |
download | qtlocation-mapboxgl-797f622a26b34db5a30e7f1728d87c6700a2ec1e.tar.gz |
Merge branch 'master' of github.com:mapbox/mapbox-gl-native into bwg-vs2017
Diffstat (limited to 'src/mbgl')
87 files changed, 3801 insertions, 673 deletions
diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index 41eedf17dc..1baf83179e 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -140,7 +140,13 @@ std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const Canonic auto pointLayer = tileData->addLayer(PointLayerID); LatLngBounds tileBounds(tileID); - + // Hack for https://github.com/mapbox/mapbox-gl-native/issues/12472 + // To handle precision issues, query a slightly larger area than the tile bounds + // Symbols at a border can be included in vector data for both tiles + // The rendering/querying logic will make sure the symbols show up in only one of the tiles + tileBounds.extend(LatLng(tileBounds.south() - 0.000000001, tileBounds.west() - 0.000000001)); + tileBounds.extend(LatLng(tileBounds.north() + 0.000000001, tileBounds.east() + 0.000000001)); + symbolTree.query(boost::geometry::index::intersects(tileBounds), boost::make_function_output_iterator([&](const auto& val){ val->updateLayer(tileID, *pointLayer); diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 41469f293d..ab718351ab 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -258,11 +258,6 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, const float textMaxBoxScale = tilePixelRatio * textMaxSize / glyphSize; const float iconBoxScale = tilePixelRatio * layoutIconSize; const float symbolSpacing = tilePixelRatio * layout.get<SymbolSpacing>(); - // CJL: I'm not sure why SymbolPlacementType::Line -> avoidEdges = false. It seems redundant since - // getAnchors will already avoid generating anchors outside the tile bounds. - // However, SymbolPlacementType::LineCenter allows anchors outside tile boundaries, so its behavior - // here should match SymbolPlacement::Point - const bool avoidEdges = layout.get<SymbolAvoidEdges>() && layout.get<SymbolPlacement>() != SymbolPlacementType::Line; const float textPadding = layout.get<TextPadding>() * tilePixelRatio; const float iconPadding = layout.get<IconPadding>() * tilePixelRatio; const float textMaxAngle = layout.get<TextMaxAngle>() * util::DEG2RAD; @@ -274,25 +269,14 @@ void SymbolLayout::addFeature(const std::size_t layoutFeatureIndex, IndexedSubfeature indexedFeature(feature.index, sourceLayer->getName(), bucketLeaderID, symbolInstances.size()); auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) { - // https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers - // +-------------------+ Symbols with anchors located on tile edges - // |(0,0) || are duplicated on neighbor tiles. - // | || - // | || In continuous mode, to avoid overdraw we - // | || skip symbols located on the extent edges. - // | Tile || In still mode, we include the features in - // | || the buffers for both tiles and clip them - // | || at draw time. - // | || - // +-------------------| In this scenario, the inner bounding box - // +-------------------+ is called 'withinPlus0', and the outer - // (extent,extent) is called 'inside'. - const bool withinPlus0 = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT; - const bool inside = withinPlus0 || anchor.point.x == util::EXTENT || anchor.point.y == util::EXTENT; - - if (avoidEdges && !inside) return; - - if (mode == MapMode::Tile || withinPlus0) { + const bool anchorInsideTile = anchor.point.x >= 0 && anchor.point.x < util::EXTENT && anchor.point.y >= 0 && anchor.point.y < util::EXTENT; + + if (mode == MapMode::Tile || anchorInsideTile) { + // For static/continuous rendering, only add symbols anchored within this tile: + // neighboring symbols will be added as part of the neighboring tiles. + // In tiled rendering mode, add all symbols in the buffers so that we can: + // (1) render symbols that overlap into this tile + // (2) approximate collision detection effects from neighboring symbols symbolInstances.emplace_back(anchor, line, shapedTextOrientations, shapedIcon, layout.evaluate(zoom, feature), layoutTextSize, textBoxScale, textPadding, textPlacement, textOffset, diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 0378cc0970..651f12828f 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -66,8 +66,8 @@ struct SymbolLayoutAttributes : gl::Attributes< {{ tx, ty, - static_cast<uint16_t>(sizeData.min * 10), - static_cast<uint16_t>(sizeData.max * 10) + static_cast<uint16_t>(sizeData.min * 256), + static_cast<uint16_t>(sizeData.max * 256) }} }; } diff --git a/src/mbgl/renderer/buckets/symbol_bucket.cpp b/src/mbgl/renderer/buckets/symbol_bucket.cpp index 027e864be5..a3f652fc6e 100644 --- a/src/mbgl/renderer/buckets/symbol_bucket.cpp +++ b/src/mbgl/renderer/buckets/symbol_bucket.cpp @@ -193,8 +193,8 @@ void SymbolBucket::sortFeatures(const float angle) { std::sort(symbolInstanceIndexes.begin(), symbolInstanceIndexes.end(), [sin, cos, this](size_t &aIndex, size_t &bIndex) { const SymbolInstance& a = symbolInstances[aIndex]; const SymbolInstance& b = symbolInstances[bIndex]; - const int32_t aRotated = static_cast<int32_t>(std::lround(sin * a.anchor.point.x + cos * a.anchor.point.y)); - const int32_t bRotated = static_cast<int32_t>(std::lround(sin * b.anchor.point.x + cos * b.anchor.point.y)); + const int32_t aRotated = static_cast<int32_t>(::lround(sin * a.anchor.point.x + cos * a.anchor.point.y)); + const int32_t bRotated = static_cast<int32_t>(::lround(sin * b.anchor.point.x + cos * b.anchor.point.y)); return aRotated != bRotated ? aRotated < bRotated : a.dataFeatureIndex > b.dataFeatureIndex; diff --git a/src/mbgl/renderer/layers/render_hillshade_layer.cpp b/src/mbgl/renderer/layers/render_hillshade_layer.cpp index 25eef98fcf..8bcd3f1837 100644 --- a/src/mbgl/renderer/layers/render_hillshade_layer.cpp +++ b/src/mbgl/renderer/layers/render_hillshade_layer.cpp @@ -59,8 +59,8 @@ bool RenderHillshadeLayer::hasTransition() const { void RenderHillshadeLayer::render(PaintParameters& parameters, RenderSource* src) { if (parameters.pass != RenderPass::Translucent && parameters.pass != RenderPass::Pass3D) return; - - RenderRasterDEMSource* demsrc = dynamic_cast<RenderRasterDEMSource*>(src); + + RenderRasterDEMSource* demsrc = static_cast<RenderRasterDEMSource*>(src); const uint8_t TERRAIN_RGB_MAXZOOM = 15; const uint8_t maxzoom = demsrc != nullptr ? demsrc->getMaxZoom() : TERRAIN_RGB_MAXZOOM; diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 63fcb6cfd5..f9e4e7c043 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -126,7 +126,7 @@ void RenderSymbolLayer::render(PaintParameters& parameters, RenderSource*) { ); }; - assert(dynamic_cast<GeometryTile*>(&tile.tile)); + assert(tile.tile.kind == Tile::Kind::Geometry); GeometryTile& geometryTile = static_cast<GeometryTile&>(tile.tile); if (bucket.hasIconData()) { diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index a667d5837e..4cd033da75 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -91,7 +91,7 @@ void RenderLayer::checkRenderability(const PaintParameters& parameters, activeBindingCount - parameters.context.minimumRequiredVertexBindingCount); hasRenderFailures = true; } else if (activeBindingCount > parameters.context.minimumRequiredVertexBindingCount) { - Log::Error(Event::OpenGL, + Log::Warning(Event::OpenGL, "The layer '%s' uses more data-driven properties than some devices may support. " "Though it will render correctly on this device, it may have rendering errors " "on other devices. To ensure compatibility with all devices, use %d fewer " diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index fea27403c9..d3f72b89b9 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -173,6 +173,10 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { renderLayers.at(entry.first)->setImpl(entry.second.after); } + if (!layerDiff.removed.empty() || !layerDiff.added.empty() || !layerDiff.changed.empty()) { + glyphManager->evict(fontStacks(*updateParameters.layers)); + } + // Update layers for class and zoom changes. for (const auto& entry : renderLayers) { RenderLayer& layer = *entry.second; diff --git a/src/mbgl/shaders/source.cpp b/src/mbgl/shaders/source.cpp index d5a4593ad9..242b726004 100644 --- a/src/mbgl/shaders/source.cpp +++ b/src/mbgl/shaders/source.cpp @@ -1272,193 +1272,193 @@ const char* source() { 0xaf, 0xea, 0x39, 0x92, 0x2d, 0xac, 0x48, 0x1c, 0xf1, 0x0c, 0x60, 0x84, 0xdf, 0x0e, 0xde, 0x75, 0x24, 0xee, 0x6f, 0x87, 0xef, 0x3a, 0x9a, 0x51, - 0xe1, 0xa1, 0x3b, 0x1c, 0xa8, 0x53, 0xf7, 0x0f, - 0x81, 0xb3, 0x4f, 0x48, 0xdc, 0x1a, 0x0e, 0xba, - 0xff, 0xba, 0x9e, 0x9a, 0x86, 0x7b, 0xad, 0x9e, - 0x24, 0x4b, 0xb4, 0xe1, 0x37, 0xd7, 0xa9, 0xba, - 0xdc, 0x79, 0x4d, 0xee, 0xfb, 0xdb, 0x68, 0xa0, - 0xf6, 0x82, 0x1b, 0xde, 0x09, 0x0c, 0x73, 0x91, - 0x18, 0xde, 0x09, 0x90, 0x5c, 0xd0, 0xbd, 0x8d, - 0xd6, 0x5f, 0xcf, 0x02, 0x72, 0x8b, 0x27, 0x17, - 0x55, 0x54, 0x16, 0x99, 0x65, 0xa2, 0xf1, 0xa1, - 0xc7, 0x97, 0x90, 0xa5, 0x6e, 0x14, 0x54, 0x66, - 0x9c, 0x84, 0xa5, 0xbb, 0xe9, 0xc5, 0x37, 0x46, - 0x5e, 0xad, 0x45, 0xa9, 0xdf, 0xc4, 0xec, 0xc5, - 0xb1, 0x86, 0xd0, 0x54, 0xab, 0x5f, 0x0f, 0xbf, - 0x3c, 0x3b, 0xd6, 0x9d, 0x8a, 0xc6, 0x9c, 0x0d, - 0x52, 0xba, 0x2f, 0xfc, 0x1f, 0x5b, 0x5f, 0xf8, - 0xf6, 0xcf, 0x1d, 0x69, 0xa7, 0x50, 0x0f, 0x56, - 0x01, 0xe6, 0xef, 0x75, 0x1a, 0x9c, 0xd3, 0xdc, - 0xa1, 0x13, 0x2e, 0x2e, 0xeb, 0x54, 0xc4, 0x81, - 0x97, 0x76, 0x67, 0x61, 0x10, 0xa9, 0xd7, 0x0a, - 0x19, 0xdb, 0x0d, 0xf1, 0x8a, 0x6b, 0xda, 0xc7, - 0x7a, 0x48, 0x62, 0x78, 0x2c, 0x6b, 0xfd, 0x44, - 0xfd, 0xef, 0xc0, 0x58, 0xb6, 0x88, 0x56, 0x40, - 0x12, 0x2f, 0xe1, 0xed, 0x6c, 0xda, 0x19, 0x48, - 0x92, 0x67, 0xf2, 0xba, 0x49, 0x33, 0x65, 0xf1, - 0x0d, 0xb7, 0xee, 0x8b, 0xd1, 0x01, 0x5d, 0x5f, - 0x4b, 0x8e, 0x5b, 0xe2, 0x10, 0xbc, 0xd6, 0x74, - 0x58, 0xb2, 0xc9, 0x43, 0x6f, 0x0d, 0xde, 0x7d, - 0xce, 0x31, 0x6a, 0x13, 0xfb, 0xd6, 0x84, 0xa3, - 0x69, 0x9b, 0x79, 0xdc, 0xeb, 0xad, 0x28, 0x5c, - 0xa5, 0xc8, 0x1b, 0xca, 0xd4, 0x7e, 0x56, 0x1e, - 0x58, 0xc3, 0x02, 0xcb, 0x44, 0x4d, 0xd7, 0x75, - 0xd5, 0x84, 0xae, 0x9b, 0xf9, 0xfa, 0x22, 0xf6, - 0x75, 0x45, 0xe3, 0xca, 0x92, 0x8d, 0xd5, 0x75, - 0x79, 0xc6, 0x28, 0x67, 0x4e, 0x0b, 0x2f, 0xb6, - 0xba, 0x02, 0x5f, 0x65, 0x10, 0x61, 0xdb, 0x92, - 0x45, 0x47, 0xe0, 0x0d, 0x19, 0x16, 0x5e, 0xb8, - 0x19, 0xc5, 0xed, 0x95, 0x20, 0x1e, 0x3d, 0xc6, - 0xfc, 0x47, 0xa7, 0x9c, 0xe1, 0xc0, 0xe1, 0xdd, - 0x4f, 0x8a, 0xfd, 0x56, 0x6c, 0x7e, 0x86, 0x30, - 0xa1, 0xa3, 0x87, 0xf2, 0x5e, 0x6c, 0x05, 0x01, - 0xef, 0x9a, 0x85, 0xfa, 0xa6, 0x96, 0xe2, 0x94, - 0xaf, 0xa0, 0x35, 0xc4, 0x8e, 0xf2, 0xda, 0xd0, - 0x58, 0x76, 0xca, 0xbf, 0x4e, 0x9c, 0x54, 0x51, - 0xf6, 0x45, 0x35, 0x1f, 0x87, 0x55, 0x52, 0x87, - 0xb5, 0xe8, 0x76, 0x6d, 0x58, 0x8b, 0xaa, 0xec, - 0x0d, 0x8e, 0x65, 0xae, 0x20, 0x9f, 0xe8, 0xdb, - 0xeb, 0x02, 0x1c, 0x9b, 0x20, 0xe8, 0xd3, 0x06, - 0xa6, 0xa2, 0x38, 0x5e, 0xb4, 0x96, 0xaa, 0x23, - 0x19, 0xb4, 0x3f, 0x4e, 0x73, 0xa4, 0x37, 0x56, - 0xbb, 0x6c, 0x74, 0x3e, 0xd7, 0x47, 0x33, 0xfe, - 0xdb, 0xb7, 0xa5, 0x1a, 0x4d, 0x68, 0xb6, 0xe4, - 0x62, 0x44, 0x0f, 0xf9, 0xa1, 0xe5, 0xaa, 0x05, - 0x6e, 0xd6, 0x4b, 0x23, 0x77, 0x42, 0x3b, 0xbb, - 0x1a, 0x9c, 0x99, 0x64, 0x11, 0xc0, 0x6c, 0x30, - 0x8e, 0x7c, 0x8a, 0xe9, 0x97, 0x0a, 0x02, 0x2b, - 0xa3, 0x59, 0x40, 0x62, 0xe9, 0x5d, 0xb4, 0x68, - 0x2c, 0x68, 0x82, 0xc7, 0xec, 0x6f, 0x2e, 0x78, - 0x38, 0x1d, 0x9f, 0xd8, 0xdd, 0x17, 0xf2, 0xd0, - 0xdb, 0xa6, 0x27, 0x69, 0x12, 0x39, 0xf9, 0x64, - 0x31, 0x0a, 0x6f, 0x2e, 0x2d, 0xde, 0xe2, 0x0b, - 0x4e, 0x5b, 0xda, 0x97, 0x57, 0x1c, 0xaa, 0xd1, - 0x5e, 0x09, 0x9d, 0x2b, 0xf2, 0x46, 0xcb, 0xdf, - 0xe5, 0xbd, 0x43, 0x5b, 0x3d, 0x1e, 0xfa, 0xc2, - 0xb5, 0x61, 0x69, 0x2e, 0xe1, 0x03, 0x74, 0xa6, - 0xe4, 0x5a, 0x5c, 0x57, 0x37, 0x37, 0x5c, 0x7e, - 0xb9, 0xa2, 0xbb, 0x2d, 0x9d, 0xbd, 0x8b, 0xd3, - 0xef, 0x28, 0xbd, 0x13, 0x0d, 0xc2, 0xff, 0x8b, - 0x33, 0xd8, 0x09, 0x01, 0xdc, 0x1f, 0x5d, 0x84, - 0x42, 0x4f, 0x5e, 0xbe, 0x47, 0xcf, 0x36, 0x29, - 0xac, 0x65, 0x4a, 0xf6, 0x44, 0xe5, 0x14, 0x8e, - 0x76, 0xcc, 0xdb, 0x39, 0xd5, 0xb5, 0xb2, 0x64, - 0x9d, 0x4e, 0x8c, 0xba, 0xcb, 0x89, 0x3b, 0xfd, - 0x30, 0x46, 0x14, 0xa2, 0x4b, 0xf8, 0x8f, 0xb2, - 0x65, 0xe3, 0x33, 0x49, 0x3e, 0xe0, 0x8e, 0x39, - 0x1b, 0x18, 0x7d, 0x05, 0xdc, 0x8a, 0x08, 0x88, - 0x00, 0x8b, 0xe8, 0xd1, 0x22, 0xdd, 0x08, 0xe0, - 0xfb, 0xc3, 0x75, 0x4a, 0x86, 0x49, 0x29, 0x47, - 0x5a, 0x28, 0x16, 0xd5, 0xed, 0xec, 0x18, 0xcb, - 0xde, 0x12, 0x89, 0x10, 0xb4, 0x16, 0xbd, 0xda, - 0xfc, 0x1f, 0x10, 0x1c, 0xce, 0x40, 0x61, 0xef, - 0x28, 0x10, 0xed, 0x0e, 0xd6, 0x13, 0x56, 0x3d, - 0x7a, 0xc8, 0x59, 0xae, 0x27, 0xde, 0xed, 0x4c, - 0x0f, 0xca, 0xf4, 0x50, 0x7b, 0xf9, 0x1f, 0x46, - 0x51, 0xd3, 0x43, 0x19, 0x53, 0xde, 0xf0, 0x5a, - 0xc6, 0x54, 0xaa, 0x7c, 0x32, 0x63, 0x17, 0x37, - 0x78, 0x76, 0xb8, 0xd5, 0x1a, 0x5d, 0x16, 0x16, - 0x5e, 0x94, 0x34, 0x61, 0x6d, 0xca, 0x1b, 0xb0, - 0x36, 0x95, 0x2a, 0xb1, 0xb6, 0x8b, 0x1b, 0xb0, - 0x76, 0xab, 0x7d, 0x01, 0x6f, 0x6b, 0x68, 0x40, - 0x0d, 0x8f, 0x33, 0x4c, 0x79, 0x3d, 0xae, 0xa6, - 0x4e, 0x25, 0xba, 0x76, 0x71, 0x03, 0xc6, 0x6e, - 0xb5, 0xab, 0x91, 0xae, 0x7f, 0x52, 0xa5, 0x8b, - 0xaf, 0x40, 0xb9, 0xf6, 0x71, 0x95, 0x55, 0x7a, - 0x15, 0xc2, 0x05, 0x0f, 0xa2, 0x87, 0x67, 0x9e, - 0xba, 0x27, 0xa3, 0xe2, 0xb5, 0x8d, 0x9c, 0xd5, - 0x56, 0xc8, 0x6d, 0x6d, 0x69, 0x78, 0x3a, 0xbb, - 0x77, 0x80, 0xfb, 0xf2, 0xeb, 0xf0, 0x3a, 0x56, - 0x34, 0x8b, 0x1f, 0x92, 0x7c, 0xaa, 0xff, 0xac, - 0x7c, 0xdc, 0x63, 0x8a, 0x3b, 0x05, 0x5e, 0x59, - 0xf7, 0xcc, 0xc7, 0x05, 0x58, 0xc9, 0xf3, 0x1a, - 0xb0, 0xb3, 0xf8, 0x1e, 0xc1, 0xd5, 0x7f, 0x56, - 0x62, 0x67, 0x8a, 0x3b, 0x05, 0x9e, 0x58, 0x87, - 0x9d, 0x0b, 0xb0, 0x92, 0xb7, 0x7d, 0x26, 0x8f, - 0x82, 0x2c, 0x2e, 0xa6, 0x67, 0xaa, 0xfe, 0x75, - 0x89, 0x29, 0xee, 0x14, 0x38, 0x5c, 0x1d, 0x5e, - 0x2e, 0xc0, 0x4a, 0x56, 0x75, 0x15, 0x76, 0xda, - 0x5b, 0x4d, 0xff, 0x55, 0x8f, 0x9b, 0x7a, 0xc7, - 0x65, 0x31, 0xb2, 0x46, 0xcc, 0xb4, 0xd7, 0x5b, - 0x15, 0x4b, 0xfa, 0x4c, 0xed, 0xb6, 0x45, 0xb3, - 0xed, 0xce, 0x6e, 0xfb, 0x27, 0xb3, 0xdb, 0xbe, - 0x92, 0xb1, 0x5d, 0xf0, 0xac, 0x44, 0x91, 0x57, - 0x9a, 0x17, 0x4d, 0xc6, 0xd5, 0x25, 0xbe, 0x6d, - 0x8a, 0xbc, 0xcb, 0x64, 0x4d, 0xaf, 0x3b, 0xa6, - 0x89, 0x72, 0x5f, 0xe4, 0x7a, 0x19, 0x6c, 0xad, - 0xa0, 0x63, 0xa5, 0x1c, 0x9d, 0x2c, 0x28, 0xb7, - 0x68, 0xc6, 0x20, 0xb5, 0xe3, 0x90, 0xc6, 0x45, - 0xc5, 0x09, 0x48, 0x83, 0x88, 0xdf, 0x18, 0x81, - 0x64, 0xaf, 0x33, 0x21, 0x13, 0x34, 0xfb, 0x89, - 0x08, 0x25, 0x56, 0x0e, 0xd0, 0x81, 0x09, 0x9d, - 0x31, 0x64, 0x28, 0x1a, 0xf4, 0xc6, 0xe7, 0xd4, - 0xa7, 0xfe, 0xa5, 0x4e, 0xc0, 0x8a, 0x07, 0x94, - 0x7c, 0x0f, 0x63, 0x3b, 0xc6, 0xd3, 0x01, 0xda, - 0xab, 0x19, 0x2d, 0x86, 0x89, 0xa9, 0x1e, 0x30, - 0x45, 0x91, 0xd1, 0xc3, 0x8e, 0x0b, 0x18, 0x5e, - 0x67, 0xbc, 0x91, 0x97, 0xce, 0x0b, 0xc3, 0xc5, - 0x72, 0x49, 0x4a, 0xa0, 0xa9, 0xd0, 0xfb, 0x14, - 0xcb, 0x11, 0x73, 0xd9, 0xdb, 0x6e, 0xe0, 0x94, - 0x17, 0xfd, 0xea, 0x51, 0xff, 0x39, 0x4c, 0xee, - 0xdb, 0x98, 0xdb, 0x6f, 0xdf, 0xd4, 0xfe, 0x19, - 0x99, 0xd9, 0x99, 0xa5, 0x48, 0x1a, 0x25, 0x5a, - 0x7f, 0xac, 0x00, 0x75, 0xbd, 0x28, 0x9c, 0xc7, - 0x78, 0x56, 0x1c, 0x23, 0xf1, 0x3f, 0x26, 0xaf, - 0x3a, 0x58, 0x91, 0xf0, 0x03, 0x60, 0xeb, 0x45, - 0x5c, 0x1b, 0xf3, 0x99, 0x53, 0xb2, 0xe1, 0x84, - 0x5d, 0xec, 0xe8, 0xe5, 0x8a, 0xdd, 0xc1, 0x9b, - 0x04, 0xe4, 0xb0, 0x39, 0xea, 0xc7, 0xb8, 0x65, - 0x88, 0x56, 0xf9, 0xe4, 0x09, 0x63, 0xc3, 0x7d, - 0xe4, 0xf6, 0xa1, 0xed, 0x95, 0x7a, 0x1b, 0x0c, - 0x1b, 0xb2, 0xc0, 0x5d, 0x65, 0xf5, 0xa6, 0xdc, - 0x90, 0xb1, 0x17, 0x1b, 0xbe, 0x6c, 0x29, 0x41, - 0x89, 0x30, 0xe7, 0xe7, 0x93, 0xcb, 0xc0, 0xa3, - 0xb0, 0x4f, 0x80, 0x4d, 0x6d, 0x7f, 0xbd, 0xdd, - 0x15, 0xc2, 0xee, 0x0a, 0xe1, 0x8b, 0xbb, 0x42, - 0x30, 0x5c, 0xc5, 0x7d, 0x2d, 0xe6, 0x3c, 0x34, - 0xb3, 0x25, 0xca, 0xcf, 0xe2, 0xb2, 0x41, 0x3d, - 0xe2, 0xd5, 0xa6, 0xbe, 0xe9, 0x2d, 0xdc, 0x3e, - 0xc8, 0x6b, 0x0c, 0x52, 0x67, 0xd5, 0xe3, 0x30, - 0x7c, 0x17, 0x7b, 0x41, 0xa1, 0xb9, 0x4c, 0x3c, - 0x32, 0x56, 0x6d, 0x95, 0x1f, 0x9b, 0x35, 0xad, - 0x1d, 0xc1, 0xa1, 0xc0, 0x6a, 0xf1, 0xe2, 0x2b, - 0x0e, 0x15, 0xdf, 0xe8, 0xec, 0xbb, 0xef, 0xc7, - 0xaf, 0xff, 0x29, 0x8e, 0xac, 0xd0, 0x51, 0x2f, - 0xbf, 0xfb, 0xe1, 0xe5, 0xf8, 0x87, 0x17, 0x7f, - 0xff, 0xfb, 0x0b, 0x98, 0x8c, 0xe1, 0xe0, 0xb0, - 0x5f, 0x7e, 0xfb, 0x50, 0x65, 0x7c, 0x40, 0x55, - 0xe3, 0x64, 0x0b, 0x3b, 0xe3, 0x7d, 0x5b, 0x08, - 0xef, 0xd5, 0xb6, 0x77, 0x7f, 0xc6, 0xb9, 0x7b, - 0xb6, 0xab, 0xdd, 0x89, 0x51, 0xac, 0xf2, 0x7e, - 0xad, 0xda, 0x80, 0xe4, 0xbc, 0xb3, 0xa9, 0xb3, - 0x7c, 0xdd, 0x86, 0x51, 0xe8, 0x4a, 0x9b, 0xd0, - 0xcd, 0xac, 0x39, 0x57, 0x1b, 0x73, 0x6e, 0x64, - 0x86, 0xb9, 0xeb, 0xf7, 0x6b, 0x05, 0x3b, 0xca, - 0xcd, 0x2c, 0x20, 0x57, 0x19, 0x40, 0x6e, 0x66, - 0xbd, 0xe0, 0x33, 0x42, 0x2e, 0xb2, 0x36, 0x3a, - 0x54, 0x1d, 0x33, 0x72, 0xc9, 0x7b, 0x17, 0x45, - 0x23, 0x82, 0x55, 0x76, 0x59, 0x3a, 0x23, 0xcc, - 0x8c, 0xc9, 0x3a, 0x45, 0xef, 0xb1, 0x6b, 0x4b, - 0xc8, 0xca, 0xde, 0x6c, 0x3c, 0xd4, 0x6d, 0x8a, - 0x29, 0xca, 0x26, 0xfc, 0x12, 0xea, 0xd4, 0x66, - 0xc7, 0x7d, 0xd1, 0x32, 0x9d, 0xee, 0xb9, 0xbb, - 0x42, 0x1e, 0x0c, 0xf6, 0xd3, 0xc7, 0xf5, 0x6c, - 0x86, 0x9e, 0xd8, 0xa3, 0xc3, 0xa7, 0xf4, 0x60, - 0x9f, 0xe3, 0x8a, 0x00, 0x62, 0xf8, 0xb7, 0x2d, - 0x8c, 0x4b, 0xe6, 0x5d, 0xf2, 0xba, 0x87, 0xc6, - 0x36, 0xed, 0xa9, 0x32, 0x85, 0x58, 0xcb, 0x2c, - 0xd6, 0x1e, 0x1c, 0xf4, 0xc3, 0xe7, 0x00, 0x5b, - 0x1e, 0x27, 0x4f, 0x2c, 0xac, 0xdb, 0xdb, 0xa0, - 0x4d, 0x51, 0x8c, 0x24, 0xbe, 0x8c, 0xad, 0x45, - 0x5f, 0x7d, 0x4b, 0xae, 0xd0, 0x7d, 0x38, 0x52, - 0xa1, 0x35, 0x6a, 0xf9, 0x56, 0xad, 0xf2, 0xa2, - 0x19, 0xaf, 0x99, 0xd5, 0x7b, 0x81, 0xd2, 0x54, - 0x33, 0x3e, 0x53, 0x0a, 0xa5, 0x81, 0x03, 0xdc, - 0x13, 0xa5, 0xb7, 0x7d, 0x8e, 0xe8, 0x28, 0xaf, - 0xbf, 0xad, 0x57, 0x6e, 0x34, 0x80, 0xae, 0x03, - 0xad, 0xc3, 0xa3, 0x7a, 0x52, 0xf8, 0x78, 0x83, - 0xe7, 0x6c, 0x28, 0x5d, 0xb9, 0xa7, 0xf8, 0x2d, - 0x5c, 0x93, 0xff, 0x7f, 0xc9, 0x73, 0xe5, 0xd5 + 0x91, 0xcf, 0x31, 0xa6, 0xa5, 0x93, 0xc2, 0x8b, + 0xc0, 0xe9, 0x27, 0x2c, 0x6e, 0x0d, 0x09, 0x8d, + 0x40, 0x6d, 0x57, 0x4d, 0x03, 0xbe, 0x56, 0x57, + 0x92, 0x29, 0xda, 0xf0, 0x9b, 0xeb, 0x54, 0x5d, + 0xef, 0xbc, 0x26, 0x07, 0xfe, 0x6d, 0x74, 0x50, + 0x7b, 0xc9, 0x0d, 0xf7, 0x04, 0x96, 0xb9, 0x48, + 0x0c, 0xf7, 0x04, 0x48, 0x2e, 0xe8, 0xde, 0x46, + 0x6b, 0xb0, 0x67, 0x01, 0x39, 0xc6, 0x93, 0x93, + 0x2a, 0xaa, 0x8b, 0xcc, 0x34, 0xd1, 0xfc, 0xd0, + 0xe3, 0x6b, 0xc8, 0x52, 0x37, 0x0a, 0x2a, 0xb3, + 0x4e, 0xc2, 0xd2, 0xdd, 0xf6, 0xe2, 0x1b, 0x23, + 0xb1, 0xd6, 0xa2, 0xd4, 0x6f, 0x62, 0xf7, 0xe2, + 0x58, 0x43, 0x68, 0xaa, 0xd5, 0xaf, 0x87, 0x5f, + 0x9e, 0x1d, 0xeb, 0x56, 0x45, 0x63, 0xce, 0x26, + 0x29, 0xdd, 0x17, 0xfe, 0x8f, 0xed, 0x2f, 0x7c, + 0xff, 0xe7, 0x8e, 0xb4, 0x53, 0xa8, 0x07, 0xab, + 0x00, 0xf3, 0xf7, 0x3a, 0x0d, 0xce, 0x69, 0xee, + 0xd0, 0x0d, 0x17, 0x97, 0x75, 0x2a, 0xe2, 0xc0, + 0x4b, 0xbb, 0xb3, 0x30, 0x88, 0xd4, 0x7b, 0x85, + 0x8c, 0x2d, 0x87, 0x78, 0xc9, 0x35, 0xed, 0x63, + 0x3d, 0x24, 0x31, 0x3c, 0x98, 0xb5, 0x86, 0xa2, + 0xfe, 0x77, 0x60, 0x6c, 0x5b, 0x44, 0x2b, 0x20, + 0x8b, 0x97, 0xf0, 0x76, 0xb6, 0xed, 0x0c, 0x64, + 0xc9, 0x33, 0x79, 0xe1, 0xa4, 0xd9, 0xb2, 0xf8, + 0x86, 0x5b, 0x03, 0xb1, 0x1f, 0xd0, 0x05, 0xb6, + 0xe4, 0xb9, 0x25, 0x1e, 0xc1, 0x6b, 0x4d, 0xc7, + 0x25, 0x1b, 0x3d, 0x06, 0x6a, 0x6b, 0xf0, 0xf6, + 0x73, 0x0e, 0x52, 0x9b, 0xd8, 0xb7, 0x26, 0x1c, + 0x4d, 0xdb, 0xcc, 0xe5, 0x5e, 0x6f, 0x45, 0xe1, + 0x2a, 0x49, 0xde, 0x50, 0x26, 0xf7, 0xb3, 0x32, + 0xc1, 0x1a, 0x26, 0x58, 0x26, 0x6a, 0xba, 0xb0, + 0xab, 0x26, 0x74, 0xdd, 0xcc, 0xd7, 0x57, 0xb1, + 0xaf, 0x2b, 0x1a, 0x57, 0x96, 0x6c, 0xac, 0xae, + 0xcb, 0x33, 0x46, 0x59, 0x73, 0x5a, 0x78, 0xb5, + 0xd5, 0x15, 0xf8, 0x2e, 0x83, 0x08, 0xdb, 0x96, + 0x2d, 0x3a, 0x02, 0xef, 0xc8, 0xb0, 0xf0, 0xc2, + 0xcd, 0x29, 0x6e, 0xaf, 0x04, 0x71, 0xe9, 0x31, + 0x66, 0x40, 0x3a, 0xe5, 0x1c, 0x07, 0x0e, 0xf7, + 0x7e, 0x52, 0xec, 0xb7, 0x62, 0xf3, 0x33, 0x84, + 0x09, 0x1d, 0x3e, 0x94, 0xf9, 0x62, 0x2b, 0x08, + 0x78, 0xdb, 0x2c, 0xd4, 0x37, 0xb5, 0x14, 0xa7, + 0x7c, 0x09, 0xad, 0x21, 0x76, 0x94, 0xdf, 0x86, + 0xc6, 0xb2, 0x53, 0xfe, 0x75, 0xe2, 0x24, 0x8b, + 0xb2, 0xaf, 0xaa, 0xf9, 0x40, 0xac, 0x92, 0x3b, + 0xac, 0x45, 0xb7, 0x6b, 0xc3, 0x5a, 0x54, 0xe5, + 0x6f, 0x70, 0x6c, 0x73, 0x05, 0x09, 0x45, 0xdf, + 0x5f, 0x17, 0xe0, 0xd8, 0x04, 0x41, 0x9f, 0x36, + 0x30, 0x15, 0xc5, 0xf1, 0xa2, 0xbd, 0x54, 0x1d, + 0xca, 0xa0, 0xff, 0x71, 0xa2, 0x23, 0xbd, 0xb1, + 0xda, 0x65, 0xb3, 0xf3, 0xb9, 0x3e, 0x9c, 0xf1, + 0xdf, 0xbe, 0x2d, 0xd7, 0x68, 0x42, 0xb3, 0x65, + 0x17, 0x23, 0x7c, 0xc8, 0x0f, 0x2d, 0x57, 0x31, + 0x70, 0xf3, 0x5e, 0x1a, 0xc9, 0x13, 0xda, 0xd9, + 0xd5, 0xe0, 0xd4, 0x24, 0x9b, 0x00, 0xe6, 0x83, + 0x71, 0x24, 0x54, 0x4c, 0xc0, 0x54, 0x10, 0x59, + 0x19, 0xcd, 0x02, 0x12, 0x4b, 0xef, 0xa2, 0x45, + 0x63, 0x41, 0x23, 0x3c, 0xe6, 0x7f, 0x73, 0xc1, + 0xc3, 0xf1, 0xf8, 0xc4, 0xee, 0xbe, 0x90, 0x89, + 0xde, 0x36, 0x3e, 0x49, 0xa3, 0xc8, 0xc9, 0x27, + 0x8b, 0x52, 0x78, 0x73, 0x79, 0xf1, 0x16, 0xdf, + 0x70, 0xda, 0xf2, 0xbe, 0xbc, 0xe4, 0x50, 0x8d, + 0xf6, 0x4a, 0xe8, 0x5c, 0x91, 0x39, 0x5a, 0xfe, + 0x2e, 0x6f, 0x1e, 0xda, 0xea, 0xf9, 0xd0, 0x17, + 0xae, 0x0f, 0x4b, 0x83, 0x09, 0x1f, 0xa0, 0x33, + 0x25, 0xd9, 0xe2, 0xba, 0xba, 0xd9, 0xe1, 0xf2, + 0xcb, 0x15, 0xdd, 0x6e, 0xe9, 0xfc, 0x5d, 0x9c, + 0x80, 0x47, 0x69, 0x9e, 0x68, 0x12, 0xfe, 0x5f, + 0x9c, 0xc1, 0x4e, 0x08, 0xe0, 0xfe, 0xe8, 0x22, + 0x14, 0x7a, 0xf4, 0xf2, 0x3d, 0xfa, 0xb6, 0x49, + 0x61, 0x2d, 0x53, 0xd2, 0x27, 0xaa, 0xa7, 0x70, + 0xb4, 0x63, 0xe6, 0xce, 0xa9, 0xae, 0x95, 0x25, + 0xeb, 0x74, 0x62, 0x14, 0x5e, 0x4e, 0xdd, 0xe9, + 0x87, 0x31, 0xa2, 0x10, 0x5d, 0xc2, 0x7f, 0x94, + 0x35, 0x1b, 0x1f, 0x4a, 0xf2, 0x01, 0x77, 0xcc, + 0xf9, 0xc0, 0xe8, 0x2b, 0xe0, 0x56, 0x44, 0x40, + 0x04, 0x58, 0x44, 0xcf, 0x16, 0xe9, 0x4e, 0x00, + 0x5f, 0x20, 0xae, 0x53, 0x32, 0x4d, 0x4a, 0x39, + 0xd2, 0x42, 0xb1, 0xa8, 0x70, 0x67, 0xc7, 0x58, + 0xf6, 0x96, 0x48, 0x84, 0xa0, 0xb5, 0xe8, 0xdd, + 0xe6, 0xff, 0x80, 0xe0, 0x70, 0x06, 0x2a, 0x7b, + 0x47, 0x81, 0x68, 0x77, 0xb0, 0x9e, 0xb0, 0xea, + 0xd1, 0x53, 0xce, 0x72, 0x3d, 0xf1, 0x6e, 0x67, + 0x7c, 0x50, 0xc6, 0x87, 0xda, 0xeb, 0xff, 0x30, + 0x8a, 0x9a, 0x9e, 0xca, 0x98, 0xf2, 0x86, 0xf7, + 0x32, 0xa6, 0x52, 0xe5, 0xa3, 0x19, 0xbb, 0xb8, + 0xc1, 0xb7, 0xc3, 0xad, 0xd6, 0xe8, 0xb4, 0xb0, + 0xf0, 0xa2, 0xa4, 0x09, 0x6b, 0x53, 0xde, 0x80, + 0xb5, 0xa9, 0x54, 0x89, 0xb5, 0x5d, 0xdc, 0x80, + 0xb5, 0x5b, 0xed, 0x0b, 0x78, 0x5d, 0x43, 0x03, + 0x6a, 0x78, 0x9e, 0x61, 0xca, 0xeb, 0x71, 0x35, + 0x75, 0x2a, 0xd1, 0xb5, 0x8b, 0x1b, 0x30, 0x76, + 0xab, 0x5d, 0x8d, 0x74, 0xfd, 0xa3, 0x2a, 0x5d, + 0x7c, 0x05, 0xca, 0xb5, 0xcf, 0xab, 0xac, 0xd2, + 0xab, 0x10, 0x2e, 0xf8, 0x10, 0x3d, 0x3c, 0x03, + 0xd5, 0x3d, 0x99, 0x15, 0xaf, 0x6d, 0xe6, 0xac, + 0xb6, 0x43, 0x6e, 0x6b, 0x4d, 0xc3, 0xd3, 0xd9, + 0xbd, 0x05, 0xdc, 0x97, 0x5f, 0x87, 0xd7, 0xb1, + 0xa3, 0x59, 0xfc, 0x90, 0xe4, 0x53, 0xfd, 0x67, + 0xe5, 0xf3, 0x1e, 0x53, 0xdc, 0x29, 0xf0, 0xca, + 0xba, 0x87, 0x3e, 0x2e, 0xc0, 0x4a, 0x9e, 0xd7, + 0x80, 0x9d, 0xc5, 0xf7, 0x08, 0xae, 0xfe, 0xb3, + 0x12, 0x3b, 0x53, 0xdc, 0x29, 0xf0, 0xc4, 0x3a, + 0xec, 0x5c, 0x80, 0x95, 0xbc, 0xed, 0x33, 0x79, + 0x16, 0x64, 0x71, 0x31, 0x3d, 0x53, 0xf5, 0xef, + 0x4b, 0x4c, 0x71, 0xa7, 0xc0, 0xe1, 0xea, 0xf0, + 0x72, 0x01, 0x56, 0xb2, 0xaa, 0xab, 0xb0, 0xd3, + 0xfe, 0x6a, 0xfa, 0xaf, 0x7a, 0xdc, 0xd4, 0x4b, + 0x2e, 0x8b, 0x91, 0x35, 0x62, 0xa6, 0xfd, 0xde, + 0xaa, 0x58, 0xd2, 0x67, 0x6a, 0xb9, 0x2d, 0x1a, + 0x6e, 0x77, 0x96, 0xdb, 0x3f, 0x9d, 0xe5, 0xf6, + 0x95, 0x8c, 0xef, 0x82, 0xa7, 0x25, 0x0a, 0xbd, + 0xd2, 0xc0, 0x68, 0xb2, 0xae, 0x2e, 0xf1, 0x7d, + 0x53, 0xe4, 0x5d, 0x26, 0x6b, 0x7a, 0xe1, 0x31, + 0x4d, 0x94, 0x0b, 0x23, 0xd7, 0xcb, 0x60, 0x73, + 0x05, 0x1d, 0x2b, 0xed, 0xe8, 0x64, 0x41, 0xf9, + 0x45, 0x33, 0x06, 0xa9, 0x9d, 0x87, 0x34, 0x2e, + 0x2a, 0x56, 0x40, 0x1a, 0x44, 0xfc, 0xce, 0x08, + 0x64, 0x7b, 0x9d, 0x0d, 0x99, 0xa0, 0xd9, 0xcf, + 0x44, 0x28, 0xb9, 0x72, 0x80, 0x4e, 0x4c, 0xe8, + 0x90, 0x21, 0xc3, 0xd1, 0xa0, 0x47, 0x3e, 0xa7, + 0x3f, 0xf5, 0x2f, 0x75, 0x12, 0x56, 0x3c, 0xa2, + 0xe4, 0x9b, 0x18, 0xdb, 0x39, 0x9e, 0x8e, 0xd0, + 0x5e, 0xcd, 0x68, 0x31, 0x54, 0x4c, 0xf5, 0x80, + 0x29, 0x92, 0x8c, 0x1e, 0x76, 0x5c, 0xc0, 0xf0, + 0x3a, 0xe3, 0x8d, 0xbc, 0x74, 0x5e, 0x18, 0x2e, + 0x96, 0x4b, 0x52, 0x02, 0x5d, 0x85, 0xde, 0xa8, + 0x58, 0xce, 0x98, 0xcb, 0xde, 0x76, 0x03, 0xa7, + 0xdc, 0xe8, 0x57, 0x8f, 0xfa, 0xcf, 0x61, 0x74, + 0xdf, 0xc6, 0xe0, 0x7e, 0xfb, 0xc6, 0xf6, 0xcf, + 0xc8, 0xd0, 0xce, 0x2c, 0x45, 0xd2, 0x28, 0xd1, + 0xfa, 0x63, 0x05, 0xa8, 0xeb, 0x45, 0xe1, 0x3c, + 0xc6, 0xd3, 0xe2, 0x18, 0x89, 0xff, 0x31, 0x79, + 0xd6, 0xc1, 0x8a, 0x84, 0x1f, 0x00, 0x5b, 0x2f, + 0xe2, 0xda, 0x98, 0xd3, 0x9c, 0x12, 0x0e, 0x27, + 0xec, 0x66, 0x47, 0xaf, 0x57, 0xec, 0x0e, 0xde, + 0x24, 0x20, 0x89, 0xcd, 0x51, 0x43, 0xc6, 0x2d, + 0x43, 0xb4, 0xca, 0x67, 0x4f, 0x18, 0x1b, 0xee, + 0x23, 0xb7, 0x0f, 0x6d, 0xaf, 0xd4, 0xdb, 0x60, + 0xe8, 0x90, 0x05, 0xee, 0x2a, 0xab, 0x37, 0xe5, + 0x8a, 0x8c, 0xbd, 0xd8, 0xf0, 0x65, 0x4b, 0x09, + 0x4a, 0x84, 0x39, 0x3f, 0xa1, 0x5c, 0x06, 0x1e, + 0x85, 0x7e, 0x02, 0x6c, 0x6a, 0xfb, 0xeb, 0xed, + 0x2e, 0x11, 0x76, 0x97, 0x08, 0x5f, 0xdc, 0x25, + 0x82, 0xe1, 0x2a, 0xee, 0x8b, 0x31, 0xe7, 0xb1, + 0x99, 0x2d, 0x53, 0x7e, 0x16, 0xd7, 0x0d, 0xea, + 0x21, 0xaf, 0x36, 0xf6, 0x4d, 0x6f, 0xe1, 0xfe, + 0x41, 0x5e, 0x64, 0x90, 0x42, 0xab, 0x1e, 0x88, + 0xe1, 0xdb, 0xd8, 0x0b, 0x0a, 0xcf, 0x65, 0x62, + 0x92, 0xb1, 0x72, 0xab, 0x7c, 0xd9, 0xac, 0x69, + 0xed, 0x08, 0x0e, 0x07, 0x56, 0x8b, 0x17, 0x5f, + 0x72, 0xa8, 0x18, 0x47, 0x67, 0xdf, 0x7d, 0x3f, + 0x7e, 0xfd, 0x4f, 0x71, 0x64, 0x85, 0x8f, 0x7a, + 0xf9, 0xdd, 0x0f, 0x2f, 0xc7, 0x3f, 0xbc, 0xf8, + 0xfb, 0xdf, 0x5f, 0xc0, 0x64, 0x0c, 0x07, 0x87, + 0xfd, 0xf2, 0xfb, 0x87, 0x2a, 0xf3, 0x03, 0x2a, + 0x1b, 0x27, 0x5b, 0x58, 0x1a, 0xef, 0xdb, 0x46, + 0x78, 0xaf, 0xd6, 0xbd, 0xfb, 0x33, 0xcf, 0xdd, + 0xb3, 0x65, 0xed, 0x4e, 0xcc, 0x62, 0x95, 0x37, + 0x6c, 0xd5, 0x26, 0x24, 0xe7, 0xad, 0x4d, 0x9d, + 0xed, 0xeb, 0x36, 0xcc, 0x42, 0x57, 0x5a, 0x85, + 0x6e, 0x66, 0xcf, 0xb9, 0xda, 0x9c, 0x73, 0x23, + 0x43, 0xcc, 0x5d, 0xbf, 0x61, 0x2b, 0x58, 0x52, + 0x6e, 0x66, 0x03, 0xb9, 0xca, 0x04, 0x72, 0x33, + 0xfb, 0x05, 0x9f, 0x11, 0x72, 0x91, 0xb5, 0xd9, + 0xa1, 0xea, 0x98, 0x91, 0x4b, 0xde, 0xbb, 0x28, + 0x9a, 0x11, 0xac, 0xb2, 0xcb, 0xd2, 0x19, 0x61, + 0x66, 0x4c, 0xd6, 0x29, 0x7a, 0x90, 0x5d, 0x5b, + 0x42, 0x56, 0x16, 0x67, 0xe3, 0xa5, 0x6e, 0x53, + 0x4c, 0x51, 0x36, 0xe1, 0xd7, 0x50, 0xa7, 0x36, + 0x3b, 0xee, 0x8b, 0x96, 0xe9, 0x74, 0xcf, 0xdd, + 0x15, 0xf2, 0x60, 0xb0, 0x9f, 0x3f, 0xae, 0x67, + 0x33, 0xf4, 0xc6, 0x26, 0x33, 0x02, 0xc8, 0x52, + 0x1c, 0x5b, 0xc4, 0x31, 0x2b, 0x68, 0xd3, 0x05, + 0xce, 0x74, 0xc9, 0xf3, 0x1e, 0x1a, 0xdb, 0xb4, + 0xa7, 0xca, 0x14, 0x62, 0x2d, 0xb3, 0x58, 0x7b, + 0x70, 0xd0, 0x0f, 0x9f, 0x03, 0x6c, 0x79, 0x9c, + 0x3c, 0xb1, 0xb0, 0x6e, 0x6f, 0x83, 0x36, 0x45, + 0x32, 0x92, 0xf8, 0x32, 0xb6, 0x16, 0x7d, 0xf5, + 0x2d, 0xb9, 0x42, 0xf7, 0xe1, 0x48, 0x85, 0xd6, + 0xa8, 0xe5, 0x7b, 0xb5, 0xca, 0xab, 0x66, 0xbc, + 0x68, 0x56, 0x6f, 0x06, 0x4a, 0x53, 0xcd, 0xf8, + 0x4c, 0x29, 0x9c, 0x06, 0x0e, 0x70, 0x4f, 0x94, + 0xde, 0xf7, 0x39, 0xa2, 0xa3, 0xbc, 0x00, 0xb7, + 0x5e, 0xba, 0xd1, 0x00, 0xba, 0x0e, 0xb4, 0x0e, + 0x8f, 0xea, 0x49, 0xe1, 0xe3, 0x0d, 0x9e, 0xb4, + 0xa1, 0x74, 0xe5, 0x9e, 0xe2, 0xb7, 0x70, 0x51, + 0xfe, 0xff, 0x01, 0x25, 0x68, 0xe6, 0xc5 }; static std::string decompressed = util::decompress(std::string(reinterpret_cast<const char*>(compressed), sizeof(compressed))); return decompressed.c_str(); diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index 9e33b99def..db758b656b 100644 --- a/src/mbgl/shaders/symbol_icon.cpp +++ b/src/mbgl/shaders/symbol_icon.cpp @@ -8,7 +8,7 @@ namespace shaders { const char* symbol_icon::name = "symbol_icon"; const char* symbol_icon::vertexSource = source() + 59607; -const char* symbol_icon::fragmentSource = source() + 63011; +const char* symbol_icon::fragmentSource = source() + 63013; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index 3443b4f21c..de9d3729a3 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -7,8 +7,8 @@ namespace mbgl { namespace shaders { const char* symbol_sdf::name = "symbol_sdf"; -const char* symbol_sdf::vertexSource = source() + 63461; -const char* symbol_sdf::fragmentSource = source() + 69382; +const char* symbol_sdf::vertexSource = source() + 63463; +const char* symbol_sdf::fragmentSource = source() + 69386; } // namespace shaders } // namespace mbgl diff --git a/src/mbgl/style/conversion/color_ramp_property_value.cpp b/src/mbgl/style/conversion/color_ramp_property_value.cpp index f29438b6a2..0da16c67ee 100644 --- a/src/mbgl/style/conversion/color_ramp_property_value.cpp +++ b/src/mbgl/style/conversion/color_ramp_property_value.cpp @@ -1,6 +1,6 @@ #include <mbgl/style/conversion/color_ramp_property_value.hpp> -#include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/expression/value.hpp> #include <mbgl/style/expression/is_constant.hpp> #include <mbgl/style/expression/is_expression.hpp> diff --git a/src/mbgl/style/conversion/constant.cpp b/src/mbgl/style/conversion/constant.cpp index d432b5f051..de4ab22269 100644 --- a/src/mbgl/style/conversion/constant.cpp +++ b/src/mbgl/style/conversion/constant.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { @@ -31,6 +32,38 @@ optional<std::string> Converter<std::string>::operator()(const Convertible& valu return *converted; } +template <class T> +optional<T> Converter<T, typename std::enable_if_t<std::is_enum<T>::value>>::operator()(const Convertible& value, Error& error) const { + optional<std::string> string = toString(value); + if (!string) { + error.message = "value must be a string"; + return nullopt; + } + + const auto result = Enum<T>::toEnum(*string); + if (!result) { + error.message = "value must be a valid enumeration value"; + return nullopt; + } + + return *result; +} + +template optional<AlignmentType> Converter<AlignmentType>::operator()(const Convertible&, Error&) const; +template optional<CirclePitchScaleType> Converter<CirclePitchScaleType>::operator()(const Convertible&, Error&) const; +template optional<HillshadeIlluminationAnchorType> Converter<HillshadeIlluminationAnchorType>::operator()(const Convertible&, Error&) const; +template optional<IconTextFitType> Converter<IconTextFitType>::operator()(const Convertible&, Error&) const; +template optional<LightAnchorType> Converter<LightAnchorType>::operator()(const Convertible&, Error&) const; +template optional<LineCapType> Converter<LineCapType>::operator()(const Convertible&, Error&) const; +template optional<LineJoinType> Converter<LineJoinType>::operator()(const Convertible&, Error&) const; +template optional<RasterResamplingType> Converter<RasterResamplingType>::operator()(const Convertible&, Error&) const; +template optional<SymbolAnchorType> Converter<SymbolAnchorType>::operator()(const Convertible&, Error&) const; +template optional<SymbolPlacementType> Converter<SymbolPlacementType>::operator()(const Convertible&, Error&) const; +template optional<TextJustifyType> Converter<TextJustifyType>::operator()(const Convertible&, Error&) const; +template optional<TextTransformType> Converter<TextTransformType>::operator()(const Convertible&, Error&) const; +template optional<TranslateAnchorType> Converter<TranslateAnchorType>::operator()(const Convertible&, Error&) const; +template optional<VisibilityType> Converter<VisibilityType>::operator()(const Convertible&, Error&) const; + optional<Color> Converter<Color>::operator()(const Convertible& value, Error& error) const { optional<std::string> string = toString(value); if (!string) { @@ -47,6 +80,29 @@ optional<Color> Converter<Color>::operator()(const Convertible& value, Error& er return *color; } +template <size_t N> +optional<std::array<float, N>> Converter<std::array<float, N>>::operator()(const Convertible& value, Error& error) const { + if (!isArray(value) || arrayLength(value) != N) { + error.message = "value must be an array of " + util::toString(N) + " numbers"; + return nullopt; + } + + std::array<float, N> result; + for (size_t i = 0; i < N; i++) { + optional<float> n = toNumber(arrayMember(value, i)); + if (!n) { + error.message = "value must be an array of " + util::toString(N) + " numbers"; + return nullopt; + } + result[i] = *n; + } + return result; +} + +template optional<std::array<float, 2>> Converter<std::array<float, 2>>::operator()(const Convertible&, Error&) const; +template optional<std::array<float, 3>> Converter<std::array<float, 3>>::operator()(const Convertible&, Error&) const; +template optional<std::array<float, 4>> Converter<std::array<float, 4>>::operator()(const Convertible&, Error&) const; + optional<std::vector<float>> Converter<std::vector<float>>::operator()(const Convertible& value, Error& error) const { if (!isArray(value)) { error.message = "value must be an array"; diff --git a/src/mbgl/style/conversion/coordinate.cpp b/src/mbgl/style/conversion/coordinate.cpp index 20abd45e26..ee03bffb30 100644 --- a/src/mbgl/style/conversion/coordinate.cpp +++ b/src/mbgl/style/conversion/coordinate.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/coordinate.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/conversion/custom_geometry_source_options.cpp b/src/mbgl/style/conversion/custom_geometry_source_options.cpp index 8983f9f479..491509c28f 100644 --- a/src/mbgl/style/conversion/custom_geometry_source_options.cpp +++ b/src/mbgl/style/conversion/custom_geometry_source_options.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/custom_geometry_source_options.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/conversion/filter.cpp b/src/mbgl/style/conversion/filter.cpp index 5114c61778..fc25ab0b0d 100644 --- a/src/mbgl/style/conversion/filter.cpp +++ b/src/mbgl/style/conversion/filter.cpp @@ -1,10 +1,11 @@ #include <mbgl/style/conversion/filter.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/expression/literal.hpp> -#include <mbgl/util/geometry.hpp> #include <mbgl/style/expression/expression.hpp> #include <mbgl/style/expression/type.hpp> #include <mbgl/style/expression/compound_expression.hpp> #include <mbgl/style/expression/boolean_operator.hpp> +#include <mbgl/util/geometry.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/conversion/function.cpp b/src/mbgl/style/conversion/function.cpp index 1cc49e483a..6aadaad3b3 100644 --- a/src/mbgl/style/conversion/function.cpp +++ b/src/mbgl/style/conversion/function.cpp @@ -1,4 +1,6 @@ #include <mbgl/style/conversion/function.hpp> +#include <mbgl/style/conversion/position.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/expression/dsl.hpp> #include <mbgl/style/expression/step.hpp> #include <mbgl/style/expression/interpolate.hpp> @@ -70,6 +72,72 @@ std::unique_ptr<Expression> convertTokenStringToExpression(const std::string& so } } +template <class T> +optional<PropertyExpression<T>> convertFunctionToExpression(const Convertible& value, Error& error, bool convertTokens) { + auto expression = convertFunctionToExpression(expression::valueTypeToExpressionType<T>(), value, error, convertTokens); + if (!expression) { + return nullopt; + } + + optional<T> defaultValue; + + auto defaultValueValue = objectMember(value, "default"); + if (defaultValueValue) { + defaultValue = convert<T>(*defaultValueValue, error); + if (!defaultValue) { + error.message = R"(wrong type for "default": )" + error.message; + return nullopt; + } + } + + return PropertyExpression<T>(std::move(*expression), defaultValue); +} + +template optional<PropertyExpression<AlignmentType>> + convertFunctionToExpression<AlignmentType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<bool>> + convertFunctionToExpression<bool>(const Convertible&, Error&, bool); +template optional<PropertyExpression<CirclePitchScaleType>> + convertFunctionToExpression<CirclePitchScaleType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<float>> + convertFunctionToExpression<float>(const Convertible&, Error&, bool); +template optional<PropertyExpression<HillshadeIlluminationAnchorType>> + convertFunctionToExpression<HillshadeIlluminationAnchorType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<IconTextFitType>> + convertFunctionToExpression<IconTextFitType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<LightAnchorType>> + convertFunctionToExpression<LightAnchorType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<LineCapType>> + convertFunctionToExpression<LineCapType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<LineJoinType>> + convertFunctionToExpression<LineJoinType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<Color>> + convertFunctionToExpression<Color>(const Convertible&, Error&, bool); +template optional<PropertyExpression<Position>> + convertFunctionToExpression<Position>(const Convertible&, Error&, bool); +template optional<PropertyExpression<RasterResamplingType>> + convertFunctionToExpression<RasterResamplingType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<std::array<float, 2>>> + convertFunctionToExpression<std::array<float, 2>>(const Convertible&, Error&, bool); +template optional<PropertyExpression<std::array<float, 4>>> + convertFunctionToExpression<std::array<float, 4>>(const Convertible&, Error&, bool); +template optional<PropertyExpression<std::string>> + convertFunctionToExpression<std::string>(const Convertible&, Error&, bool); +template optional<PropertyExpression<std::vector<float>>> + convertFunctionToExpression<std::vector<float>>(const Convertible&, Error&, bool); +template optional<PropertyExpression<std::vector<std::string>>> + convertFunctionToExpression<std::vector<std::string>>(const Convertible&, Error&, bool); +template optional<PropertyExpression<SymbolAnchorType>> + convertFunctionToExpression<SymbolAnchorType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<SymbolPlacementType>> + convertFunctionToExpression<SymbolPlacementType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<TextJustifyType>> + convertFunctionToExpression<TextJustifyType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<TextTransformType>> + convertFunctionToExpression<TextTransformType>(const Convertible&, Error&, bool); +template optional<PropertyExpression<TranslateAnchorType>> + convertFunctionToExpression<TranslateAnchorType>(const Convertible&, Error&, bool); + // Ad-hoc Converters for double and int64_t. We should replace float with double wholesale, // and promote the int64_t Converter to general use (and it should check that the input is // an integer). diff --git a/src/mbgl/style/conversion/geojson.cpp b/src/mbgl/style/conversion/geojson.cpp index e39a1a80eb..c2d34c5491 100644 --- a/src/mbgl/style/conversion/geojson.cpp +++ b/src/mbgl/style/conversion/geojson.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/conversion/geojson.hpp> #include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/conversion/geojson_options.cpp b/src/mbgl/style/conversion/geojson_options.cpp index 52a5030c34..11bd7cc507 100644 --- a/src/mbgl/style/conversion/geojson_options.cpp +++ b/src/mbgl/style/conversion/geojson_options.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/geojson_options.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { @@ -77,6 +78,16 @@ optional<GeoJSONOptions> Converter<GeoJSONOptions>::operator()(const Convertible } } + const auto lineMetricsValue = objectMember(value, "lineMetrics"); + if (lineMetricsValue) { + if (toBool(*lineMetricsValue)) { + options.lineMetrics = *toBool(*lineMetricsValue); + } else { + error = { "GeoJSON source lineMetrics value must be a boolean" }; + return nullopt; + } + } + return { options }; } diff --git a/src/mbgl/style/conversion/get_json_type.cpp b/src/mbgl/style/conversion/get_json_type.cpp index cd3b4608b1..2e9d35a957 100644 --- a/src/mbgl/style/conversion/get_json_type.cpp +++ b/src/mbgl/style/conversion/get_json_type.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/get_json_type.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/feature.hpp> namespace mbgl { diff --git a/src/mbgl/style/conversion/json.hpp b/src/mbgl/style/conversion/json.hpp index 7dd2378f6b..3a7bf2b557 100644 --- a/src/mbgl/style/conversion/json.hpp +++ b/src/mbgl/style/conversion/json.hpp @@ -1,4 +1,6 @@ -#include <mbgl/style/conversion.hpp> +#pragma once + +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/rapidjson_conversion.hpp> #include <string> diff --git a/src/mbgl/style/conversion/layer.cpp b/src/mbgl/style/conversion/layer.cpp index e18ad923f2..085d7ae4c6 100644 --- a/src/mbgl/style/conversion/layer.cpp +++ b/src/mbgl/style/conversion/layer.cpp @@ -1,7 +1,7 @@ #include <mbgl/style/conversion/layer.hpp> #include <mbgl/style/conversion/constant.hpp> #include <mbgl/style/conversion/filter.hpp> -#include <mbgl/style/conversion/make_property_setters.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/layers/background_layer.hpp> #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> @@ -16,24 +16,6 @@ namespace mbgl { namespace style { namespace conversion { -optional<Error> setLayoutProperty(Layer& layer, const std::string& name, const Convertible& value) { - static const auto setters = makeLayoutPropertySetters(); - auto it = setters.find(name); - if (it == setters.end()) { - return Error { "property not found" }; - } - return it->second(layer, value); -} - -optional<Error> setPaintProperty(Layer& layer, const std::string& name, const Convertible& value) { - static const auto setters = makePaintPropertySetters(); - auto it = setters.find(name); - if (it == setters.end()) { - return Error { "property not found" }; - } - return it->second(layer, value); -} - optional<Error> setPaintProperties(Layer& layer, const Convertible& value) { auto paintValue = objectMember(value, "paint"); if (!paintValue) { @@ -43,7 +25,7 @@ optional<Error> setPaintProperties(Layer& layer, const Convertible& value) { return { { "paint must be an object" } }; } return eachMember(*paintValue, [&] (const std::string& k, const Convertible& v) { - return setPaintProperty(layer, k, v); + return layer.setPaintProperty(k, v); }); } @@ -210,7 +192,7 @@ optional<std::unique_ptr<Layer>> Converter<std::unique_ptr<Layer>>::operator()(c return nullopt; } optional<Error> error_ = eachMember(*layoutValue, [&] (const std::string& k, const Convertible& v) { - return setLayoutProperty(*layer, k, v); + return layer->setLayoutProperty(k, v); }); if (error_) { error = *error_; diff --git a/src/mbgl/style/conversion/light.cpp b/src/mbgl/style/conversion/light.cpp index 7b96c89a1c..e8723216ee 100644 --- a/src/mbgl/style/conversion/light.cpp +++ b/src/mbgl/style/conversion/light.cpp @@ -2,6 +2,7 @@ #include <mbgl/style/conversion/position.hpp> #include <mbgl/style/conversion/property_value.hpp> #include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/conversion/make_property_setters.hpp b/src/mbgl/style/conversion/make_property_setters.hpp deleted file mode 100644 index ada0d53002..0000000000 --- a/src/mbgl/style/conversion/make_property_setters.hpp +++ /dev/null @@ -1,239 +0,0 @@ -#pragma once - -// This file is generated. Edit make_property_setters.hpp.ejs, then run `make style-code`. - -#include <mbgl/style/conversion/property_setter.hpp> - -#include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> -#include <mbgl/style/layers/circle_layer.hpp> -#include <mbgl/style/layers/heatmap_layer.hpp> -#include <mbgl/style/layers/fill_extrusion_layer.hpp> -#include <mbgl/style/layers/raster_layer.hpp> -#include <mbgl/style/layers/hillshade_layer.hpp> -#include <mbgl/style/layers/background_layer.hpp> - -#include <unordered_map> - -namespace mbgl { -namespace style { -namespace conversion { - -inline auto makeLayoutPropertySetters() { - std::unordered_map<std::string, PropertySetter> result; - - result["visibility"] = &setVisibility; - - - result["line-cap"] = &setProperty<LineLayer, PropertyValue<LineCapType>, &LineLayer::setLineCap, false, false>; - result["line-join"] = &setProperty<LineLayer, PropertyValue<LineJoinType>, &LineLayer::setLineJoin, true, false>; - result["line-miter-limit"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineMiterLimit, false, false>; - result["line-round-limit"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineRoundLimit, false, false>; - - result["symbol-placement"] = &setProperty<SymbolLayer, PropertyValue<SymbolPlacementType>, &SymbolLayer::setSymbolPlacement, false, false>; - result["symbol-spacing"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setSymbolSpacing, false, false>; - result["symbol-avoid-edges"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setSymbolAvoidEdges, false, false>; - result["icon-allow-overlap"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconAllowOverlap, false, false>; - result["icon-ignore-placement"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconIgnorePlacement, false, false>; - result["icon-optional"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconOptional, false, false>; - result["icon-rotation-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconRotationAlignment, false, false>; - result["icon-size"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconSize, true, false>; - result["icon-text-fit"] = &setProperty<SymbolLayer, PropertyValue<IconTextFitType>, &SymbolLayer::setIconTextFit, false, false>; - result["icon-text-fit-padding"] = &setProperty<SymbolLayer, PropertyValue<std::array<float, 4>>, &SymbolLayer::setIconTextFitPadding, false, false>; - result["icon-image"] = &setProperty<SymbolLayer, PropertyValue<std::string>, &SymbolLayer::setIconImage, true, true>; - result["icon-rotate"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconRotate, true, false>; - result["icon-padding"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconPadding, false, false>; - result["icon-keep-upright"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconKeepUpright, false, false>; - result["icon-offset"] = &setProperty<SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setIconOffset, true, false>; - result["icon-anchor"] = &setProperty<SymbolLayer, PropertyValue<SymbolAnchorType>, &SymbolLayer::setIconAnchor, true, false>; - result["icon-pitch-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconPitchAlignment, false, false>; - result["text-pitch-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextPitchAlignment, false, false>; - result["text-rotation-alignment"] = &setProperty<SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextRotationAlignment, false, false>; - result["text-field"] = &setProperty<SymbolLayer, PropertyValue<std::string>, &SymbolLayer::setTextField, true, true>; - result["text-font"] = &setProperty<SymbolLayer, PropertyValue<std::vector<std::string>>, &SymbolLayer::setTextFont, true, false>; - result["text-size"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextSize, true, false>; - result["text-max-width"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxWidth, true, false>; - result["text-line-height"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLineHeight, false, false>; - result["text-letter-spacing"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLetterSpacing, true, false>; - result["text-justify"] = &setProperty<SymbolLayer, PropertyValue<TextJustifyType>, &SymbolLayer::setTextJustify, true, false>; - result["text-anchor"] = &setProperty<SymbolLayer, PropertyValue<SymbolAnchorType>, &SymbolLayer::setTextAnchor, true, false>; - result["text-max-angle"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxAngle, false, false>; - result["text-rotate"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextRotate, true, false>; - result["text-padding"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextPadding, false, false>; - result["text-keep-upright"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextKeepUpright, false, false>; - result["text-transform"] = &setProperty<SymbolLayer, PropertyValue<TextTransformType>, &SymbolLayer::setTextTransform, true, false>; - result["text-offset"] = &setProperty<SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setTextOffset, true, false>; - result["text-allow-overlap"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextAllowOverlap, false, false>; - result["text-ignore-placement"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextIgnorePlacement, false, false>; - result["text-optional"] = &setProperty<SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextOptional, false, false>; - - - - - - - - return result; -} - -inline auto makePaintPropertySetters() { - std::unordered_map<std::string, PropertySetter> result; - - result["fill-antialias"] = &setProperty<FillLayer, PropertyValue<bool>, &FillLayer::setFillAntialias, false, false>; - result["fill-antialias-transition"] = &setTransition<FillLayer, &FillLayer::setFillAntialiasTransition>; - result["fill-opacity"] = &setProperty<FillLayer, PropertyValue<float>, &FillLayer::setFillOpacity, true, false>; - result["fill-opacity-transition"] = &setTransition<FillLayer, &FillLayer::setFillOpacityTransition>; - result["fill-color"] = &setProperty<FillLayer, PropertyValue<Color>, &FillLayer::setFillColor, true, false>; - result["fill-color-transition"] = &setTransition<FillLayer, &FillLayer::setFillColorTransition>; - result["fill-outline-color"] = &setProperty<FillLayer, PropertyValue<Color>, &FillLayer::setFillOutlineColor, true, false>; - result["fill-outline-color-transition"] = &setTransition<FillLayer, &FillLayer::setFillOutlineColorTransition>; - result["fill-translate"] = &setProperty<FillLayer, PropertyValue<std::array<float, 2>>, &FillLayer::setFillTranslate, false, false>; - result["fill-translate-transition"] = &setTransition<FillLayer, &FillLayer::setFillTranslateTransition>; - result["fill-translate-anchor"] = &setProperty<FillLayer, PropertyValue<TranslateAnchorType>, &FillLayer::setFillTranslateAnchor, false, false>; - result["fill-translate-anchor-transition"] = &setTransition<FillLayer, &FillLayer::setFillTranslateAnchorTransition>; - result["fill-pattern"] = &setProperty<FillLayer, PropertyValue<std::string>, &FillLayer::setFillPattern, false, false>; - result["fill-pattern-transition"] = &setTransition<FillLayer, &FillLayer::setFillPatternTransition>; - - result["line-opacity"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineOpacity, true, false>; - result["line-opacity-transition"] = &setTransition<LineLayer, &LineLayer::setLineOpacityTransition>; - result["line-color"] = &setProperty<LineLayer, PropertyValue<Color>, &LineLayer::setLineColor, true, false>; - result["line-color-transition"] = &setTransition<LineLayer, &LineLayer::setLineColorTransition>; - result["line-translate"] = &setProperty<LineLayer, PropertyValue<std::array<float, 2>>, &LineLayer::setLineTranslate, false, false>; - result["line-translate-transition"] = &setTransition<LineLayer, &LineLayer::setLineTranslateTransition>; - result["line-translate-anchor"] = &setProperty<LineLayer, PropertyValue<TranslateAnchorType>, &LineLayer::setLineTranslateAnchor, false, false>; - result["line-translate-anchor-transition"] = &setTransition<LineLayer, &LineLayer::setLineTranslateAnchorTransition>; - result["line-width"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineWidth, true, false>; - result["line-width-transition"] = &setTransition<LineLayer, &LineLayer::setLineWidthTransition>; - result["line-gap-width"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineGapWidth, true, false>; - result["line-gap-width-transition"] = &setTransition<LineLayer, &LineLayer::setLineGapWidthTransition>; - result["line-offset"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineOffset, true, false>; - result["line-offset-transition"] = &setTransition<LineLayer, &LineLayer::setLineOffsetTransition>; - result["line-blur"] = &setProperty<LineLayer, PropertyValue<float>, &LineLayer::setLineBlur, true, false>; - result["line-blur-transition"] = &setTransition<LineLayer, &LineLayer::setLineBlurTransition>; - result["line-dasharray"] = &setProperty<LineLayer, PropertyValue<std::vector<float>>, &LineLayer::setLineDasharray, false, false>; - result["line-dasharray-transition"] = &setTransition<LineLayer, &LineLayer::setLineDasharrayTransition>; - result["line-pattern"] = &setProperty<LineLayer, PropertyValue<std::string>, &LineLayer::setLinePattern, false, false>; - result["line-pattern-transition"] = &setTransition<LineLayer, &LineLayer::setLinePatternTransition>; - - result["icon-opacity"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconOpacity, true, false>; - result["icon-opacity-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconOpacityTransition>; - result["icon-color"] = &setProperty<SymbolLayer, PropertyValue<Color>, &SymbolLayer::setIconColor, true, false>; - result["icon-color-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconColorTransition>; - result["icon-halo-color"] = &setProperty<SymbolLayer, PropertyValue<Color>, &SymbolLayer::setIconHaloColor, true, false>; - result["icon-halo-color-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconHaloColorTransition>; - result["icon-halo-width"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconHaloWidth, true, false>; - result["icon-halo-width-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconHaloWidthTransition>; - result["icon-halo-blur"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconHaloBlur, true, false>; - result["icon-halo-blur-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconHaloBlurTransition>; - result["icon-translate"] = &setProperty<SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setIconTranslate, false, false>; - result["icon-translate-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconTranslateTransition>; - result["icon-translate-anchor"] = &setProperty<SymbolLayer, PropertyValue<TranslateAnchorType>, &SymbolLayer::setIconTranslateAnchor, false, false>; - result["icon-translate-anchor-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setIconTranslateAnchorTransition>; - result["text-opacity"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextOpacity, true, false>; - result["text-opacity-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextOpacityTransition>; - result["text-color"] = &setProperty<SymbolLayer, PropertyValue<Color>, &SymbolLayer::setTextColor, true, false>; - result["text-color-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextColorTransition>; - result["text-halo-color"] = &setProperty<SymbolLayer, PropertyValue<Color>, &SymbolLayer::setTextHaloColor, true, false>; - result["text-halo-color-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextHaloColorTransition>; - result["text-halo-width"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextHaloWidth, true, false>; - result["text-halo-width-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextHaloWidthTransition>; - result["text-halo-blur"] = &setProperty<SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextHaloBlur, true, false>; - result["text-halo-blur-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextHaloBlurTransition>; - result["text-translate"] = &setProperty<SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setTextTranslate, false, false>; - result["text-translate-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextTranslateTransition>; - result["text-translate-anchor"] = &setProperty<SymbolLayer, PropertyValue<TranslateAnchorType>, &SymbolLayer::setTextTranslateAnchor, false, false>; - result["text-translate-anchor-transition"] = &setTransition<SymbolLayer, &SymbolLayer::setTextTranslateAnchorTransition>; - - result["circle-radius"] = &setProperty<CircleLayer, PropertyValue<float>, &CircleLayer::setCircleRadius, true, false>; - result["circle-radius-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleRadiusTransition>; - result["circle-color"] = &setProperty<CircleLayer, PropertyValue<Color>, &CircleLayer::setCircleColor, true, false>; - result["circle-color-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleColorTransition>; - result["circle-blur"] = &setProperty<CircleLayer, PropertyValue<float>, &CircleLayer::setCircleBlur, true, false>; - result["circle-blur-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleBlurTransition>; - result["circle-opacity"] = &setProperty<CircleLayer, PropertyValue<float>, &CircleLayer::setCircleOpacity, true, false>; - result["circle-opacity-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleOpacityTransition>; - result["circle-translate"] = &setProperty<CircleLayer, PropertyValue<std::array<float, 2>>, &CircleLayer::setCircleTranslate, false, false>; - result["circle-translate-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleTranslateTransition>; - result["circle-translate-anchor"] = &setProperty<CircleLayer, PropertyValue<TranslateAnchorType>, &CircleLayer::setCircleTranslateAnchor, false, false>; - result["circle-translate-anchor-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleTranslateAnchorTransition>; - result["circle-pitch-scale"] = &setProperty<CircleLayer, PropertyValue<CirclePitchScaleType>, &CircleLayer::setCirclePitchScale, false, false>; - result["circle-pitch-scale-transition"] = &setTransition<CircleLayer, &CircleLayer::setCirclePitchScaleTransition>; - result["circle-pitch-alignment"] = &setProperty<CircleLayer, PropertyValue<AlignmentType>, &CircleLayer::setCirclePitchAlignment, false, false>; - result["circle-pitch-alignment-transition"] = &setTransition<CircleLayer, &CircleLayer::setCirclePitchAlignmentTransition>; - result["circle-stroke-width"] = &setProperty<CircleLayer, PropertyValue<float>, &CircleLayer::setCircleStrokeWidth, true, false>; - result["circle-stroke-width-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleStrokeWidthTransition>; - result["circle-stroke-color"] = &setProperty<CircleLayer, PropertyValue<Color>, &CircleLayer::setCircleStrokeColor, true, false>; - result["circle-stroke-color-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleStrokeColorTransition>; - result["circle-stroke-opacity"] = &setProperty<CircleLayer, PropertyValue<float>, &CircleLayer::setCircleStrokeOpacity, true, false>; - result["circle-stroke-opacity-transition"] = &setTransition<CircleLayer, &CircleLayer::setCircleStrokeOpacityTransition>; - - result["heatmap-radius"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapRadius, true, false>; - result["heatmap-radius-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapRadiusTransition>; - result["heatmap-weight"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapWeight, true, false>; - result["heatmap-weight-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapWeightTransition>; - result["heatmap-intensity"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapIntensity, false, false>; - result["heatmap-intensity-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapIntensityTransition>; - result["heatmap-color"] = &setProperty<HeatmapLayer, ColorRampPropertyValue, &HeatmapLayer::setHeatmapColor, false, false>; - result["heatmap-color-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapColorTransition>; - result["heatmap-opacity"] = &setProperty<HeatmapLayer, PropertyValue<float>, &HeatmapLayer::setHeatmapOpacity, false, false>; - result["heatmap-opacity-transition"] = &setTransition<HeatmapLayer, &HeatmapLayer::setHeatmapOpacityTransition>; - - result["fill-extrusion-opacity"] = &setProperty<FillExtrusionLayer, PropertyValue<float>, &FillExtrusionLayer::setFillExtrusionOpacity, false, false>; - result["fill-extrusion-opacity-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionOpacityTransition>; - result["fill-extrusion-color"] = &setProperty<FillExtrusionLayer, PropertyValue<Color>, &FillExtrusionLayer::setFillExtrusionColor, true, false>; - result["fill-extrusion-color-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionColorTransition>; - result["fill-extrusion-translate"] = &setProperty<FillExtrusionLayer, PropertyValue<std::array<float, 2>>, &FillExtrusionLayer::setFillExtrusionTranslate, false, false>; - result["fill-extrusion-translate-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionTranslateTransition>; - result["fill-extrusion-translate-anchor"] = &setProperty<FillExtrusionLayer, PropertyValue<TranslateAnchorType>, &FillExtrusionLayer::setFillExtrusionTranslateAnchor, false, false>; - result["fill-extrusion-translate-anchor-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionTranslateAnchorTransition>; - result["fill-extrusion-pattern"] = &setProperty<FillExtrusionLayer, PropertyValue<std::string>, &FillExtrusionLayer::setFillExtrusionPattern, false, false>; - result["fill-extrusion-pattern-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionPatternTransition>; - result["fill-extrusion-height"] = &setProperty<FillExtrusionLayer, PropertyValue<float>, &FillExtrusionLayer::setFillExtrusionHeight, true, false>; - result["fill-extrusion-height-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionHeightTransition>; - result["fill-extrusion-base"] = &setProperty<FillExtrusionLayer, PropertyValue<float>, &FillExtrusionLayer::setFillExtrusionBase, true, false>; - result["fill-extrusion-base-transition"] = &setTransition<FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionBaseTransition>; - - result["raster-opacity"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterOpacity, false, false>; - result["raster-opacity-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterOpacityTransition>; - result["raster-hue-rotate"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterHueRotate, false, false>; - result["raster-hue-rotate-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterHueRotateTransition>; - result["raster-brightness-min"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterBrightnessMin, false, false>; - result["raster-brightness-min-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterBrightnessMinTransition>; - result["raster-brightness-max"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterBrightnessMax, false, false>; - result["raster-brightness-max-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterBrightnessMaxTransition>; - result["raster-saturation"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterSaturation, false, false>; - result["raster-saturation-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterSaturationTransition>; - result["raster-contrast"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterContrast, false, false>; - result["raster-contrast-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterContrastTransition>; - result["raster-resampling"] = &setProperty<RasterLayer, PropertyValue<RasterResamplingType>, &RasterLayer::setRasterResampling, false, false>; - result["raster-resampling-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterResamplingTransition>; - result["raster-fade-duration"] = &setProperty<RasterLayer, PropertyValue<float>, &RasterLayer::setRasterFadeDuration, false, false>; - result["raster-fade-duration-transition"] = &setTransition<RasterLayer, &RasterLayer::setRasterFadeDurationTransition>; - - result["hillshade-illumination-direction"] = &setProperty<HillshadeLayer, PropertyValue<float>, &HillshadeLayer::setHillshadeIlluminationDirection, false, false>; - result["hillshade-illumination-direction-transition"] = &setTransition<HillshadeLayer, &HillshadeLayer::setHillshadeIlluminationDirectionTransition>; - result["hillshade-illumination-anchor"] = &setProperty<HillshadeLayer, PropertyValue<HillshadeIlluminationAnchorType>, &HillshadeLayer::setHillshadeIlluminationAnchor, false, false>; - result["hillshade-illumination-anchor-transition"] = &setTransition<HillshadeLayer, &HillshadeLayer::setHillshadeIlluminationAnchorTransition>; - result["hillshade-exaggeration"] = &setProperty<HillshadeLayer, PropertyValue<float>, &HillshadeLayer::setHillshadeExaggeration, false, false>; - result["hillshade-exaggeration-transition"] = &setTransition<HillshadeLayer, &HillshadeLayer::setHillshadeExaggerationTransition>; - result["hillshade-shadow-color"] = &setProperty<HillshadeLayer, PropertyValue<Color>, &HillshadeLayer::setHillshadeShadowColor, false, false>; - result["hillshade-shadow-color-transition"] = &setTransition<HillshadeLayer, &HillshadeLayer::setHillshadeShadowColorTransition>; - result["hillshade-highlight-color"] = &setProperty<HillshadeLayer, PropertyValue<Color>, &HillshadeLayer::setHillshadeHighlightColor, false, false>; - result["hillshade-highlight-color-transition"] = &setTransition<HillshadeLayer, &HillshadeLayer::setHillshadeHighlightColorTransition>; - result["hillshade-accent-color"] = &setProperty<HillshadeLayer, PropertyValue<Color>, &HillshadeLayer::setHillshadeAccentColor, false, false>; - result["hillshade-accent-color-transition"] = &setTransition<HillshadeLayer, &HillshadeLayer::setHillshadeAccentColorTransition>; - - result["background-color"] = &setProperty<BackgroundLayer, PropertyValue<Color>, &BackgroundLayer::setBackgroundColor, false, false>; - result["background-color-transition"] = &setTransition<BackgroundLayer, &BackgroundLayer::setBackgroundColorTransition>; - result["background-pattern"] = &setProperty<BackgroundLayer, PropertyValue<std::string>, &BackgroundLayer::setBackgroundPattern, false, false>; - result["background-pattern-transition"] = &setTransition<BackgroundLayer, &BackgroundLayer::setBackgroundPatternTransition>; - result["background-opacity"] = &setProperty<BackgroundLayer, PropertyValue<float>, &BackgroundLayer::setBackgroundOpacity, false, false>; - result["background-opacity-transition"] = &setTransition<BackgroundLayer, &BackgroundLayer::setBackgroundOpacityTransition>; - - return result; -} - -} // namespace conversion -} // namespace style -} // namespace mbgl diff --git a/src/mbgl/style/conversion/make_property_setters.hpp.ejs b/src/mbgl/style/conversion/make_property_setters.hpp.ejs deleted file mode 100644 index fbf2f93fd6..0000000000 --- a/src/mbgl/style/conversion/make_property_setters.hpp.ejs +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -// This file is generated. Edit make_property_setters.hpp.ejs, then run `make style-code`. - -#include <mbgl/style/conversion/property_setter.hpp> - -<% for (const layer of locals.layers) { -%> -#include <mbgl/style/layers/<%- layer.type.replace('-', '_') %>_layer.hpp> -<% } -%> - -#include <unordered_map> - -namespace mbgl { -namespace style { -namespace conversion { - -inline auto makeLayoutPropertySetters() { - std::unordered_map<std::string, PropertySetter> result; - - result["visibility"] = &setVisibility; - -<% for (const layer of locals.layers) { -%> -<% for (const property of layer.layoutProperties) { -%> - result["<%- property.name %>"] = &setProperty<<%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>, <%- property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven' %>, <%- property.name === 'icon-image' || property.name === 'text-field' %>>; -<% } -%> - -<% } -%> - return result; -} - -inline auto makePaintPropertySetters() { - std::unordered_map<std::string, PropertySetter> result; - -<% for (const layer of locals.layers) { -%> -<% for (const property of layer.paintProperties) { -%> - result["<%- property.name %>"] = &setProperty<<%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>, <%- property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven' %>, <%- property.name === 'icon-image' || property.name === 'text-field' %>>; - result["<%- property.name %>-transition"] = &setTransition<<%- camelize(layer.type) %>Layer, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>Transition>; -<% } -%> - -<% } -%> - return result; -} - -} // namespace conversion -} // namespace style -} // namespace mbgl diff --git a/src/mbgl/style/conversion/position.cpp b/src/mbgl/style/conversion/position.cpp index a19f57bff3..df6c868ee8 100644 --- a/src/mbgl/style/conversion/position.cpp +++ b/src/mbgl/style/conversion/position.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/conversion/position.hpp> #include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <array> diff --git a/src/mbgl/style/conversion/property_setter.hpp b/src/mbgl/style/conversion/property_setter.hpp deleted file mode 100644 index 3c5c65f96a..0000000000 --- a/src/mbgl/style/conversion/property_setter.hpp +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once - -#include <mbgl/style/layer.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> -#include <mbgl/style/conversion.hpp> -#include <mbgl/style/conversion/color_ramp_property_value.hpp> -#include <mbgl/style/conversion/constant.hpp> -#include <mbgl/style/conversion/property_value.hpp> -#include <mbgl/style/conversion/transition_options.hpp> - -#include <string> - -namespace mbgl { -namespace style { -namespace conversion { - -using PropertySetter = optional<Error> (*) (Layer&, const Convertible&); - -template <class L, class PropertyValue, void (L::*setter)(PropertyValue), bool allowDataExpressions, bool convertTokens> -optional<Error> setProperty(Layer& layer, const Convertible& value) { - auto* typedLayer = layer.as<L>(); - if (!typedLayer) { - return Error { "layer doesn't support this property" }; - } - - Error error; - optional<PropertyValue> typedValue = convert<PropertyValue>(value, error, allowDataExpressions, convertTokens); - if (!typedValue) { - return error; - } - - (typedLayer->*setter)(*typedValue); - return nullopt; -} - -template <class L, void (L::*setter)(const TransitionOptions&)> -optional<Error> setTransition(Layer& layer, const Convertible& value) { - auto* typedLayer = layer.as<L>(); - if (!typedLayer) { - return Error { "layer doesn't support this property" }; - } - - Error error; - optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); - if (!transition) { - return error; - } - - (typedLayer->*setter)(*transition); - return nullopt; -} - -inline optional<Error> setVisibility(Layer& layer, const Convertible& value) { - if (isUndefined(value)) { - layer.setVisibility(VisibilityType::Visible); - return nullopt; - } - - Error error; - optional<VisibilityType> visibility = convert<VisibilityType>(value, error); - if (!visibility) { - return error; - } - - layer.setVisibility(*visibility); - return nullopt; -} - -} // namespace conversion -} // namespace style -} // namespace mbgl diff --git a/src/mbgl/style/conversion/property_value.cpp b/src/mbgl/style/conversion/property_value.cpp new file mode 100644 index 0000000000..8a93c24767 --- /dev/null +++ b/src/mbgl/style/conversion/property_value.cpp @@ -0,0 +1,83 @@ +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/position.hpp> +#include <mbgl/style/conversion_impl.hpp> + +namespace mbgl { +namespace style { +namespace conversion { + +template <class T> +optional<PropertyValue<T>> Converter<PropertyValue<T>>::operator()(const Convertible& value, Error& error, bool allowDataExpressions, bool convertTokens) const { + using namespace mbgl::style::expression; + + if (isUndefined(value)) { + return PropertyValue<T>(); + } + + optional<PropertyExpression<T>> expression; + + if (isExpression(value)) { + ParsingContext ctx(valueTypeToExpressionType<T>()); + ParseResult parsed = ctx.parseLayerPropertyExpression(value); + if (!parsed) { + error.message = ctx.getCombinedErrors(); + return nullopt; + } + expression = PropertyExpression<T>(std::move(*parsed)); + } else if (isObject(value)) { + expression = convertFunctionToExpression<T>(value, error, convertTokens); + } else { + optional<T> constant = convert<T>(value, error); + if (!constant) { + return nullopt; + } + return convertTokens ? maybeConvertTokens(*constant) : PropertyValue<T>(*constant); + } + + if (!expression) { + return nullopt; + } else if (!allowDataExpressions && !(*expression).isFeatureConstant()) { + error.message = "data expressions not supported"; + return nullopt; + } else if (!(*expression).isFeatureConstant() || !(*expression).isZoomConstant()) { + return { std::move(*expression) }; + } else if ((*expression).getExpression().getKind() == Kind::Literal) { + optional<T> constant = fromExpressionValue<T>( + static_cast<const Literal&>((*expression).getExpression()).getValue()); + if (!constant) { + return nullopt; + } + return PropertyValue<T>(*constant); + } else { + assert(false); + error.message = "expected a literal expression"; + return nullopt; + } +} + +template optional<PropertyValue<bool>> Converter<PropertyValue<bool>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<float>> Converter<PropertyValue<float>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<std::array<float, 2>>> Converter<PropertyValue<std::array<float, 2>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<std::array<float, 4>>> Converter<PropertyValue<std::array<float, 4>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<std::vector<float>>> Converter<PropertyValue<std::vector<float>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<Color>> Converter<PropertyValue<Color>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<std::string>> Converter<PropertyValue<std::string>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<std::vector<std::string>>> Converter<PropertyValue<std::vector<std::string>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<AlignmentType>> Converter<PropertyValue<AlignmentType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<CirclePitchScaleType>> Converter<PropertyValue<CirclePitchScaleType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<HillshadeIlluminationAnchorType>> Converter<PropertyValue<HillshadeIlluminationAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<IconTextFitType>> Converter<PropertyValue<IconTextFitType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<LightAnchorType>> Converter<PropertyValue<LightAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<LineCapType>> Converter<PropertyValue<LineCapType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<LineJoinType>> Converter<PropertyValue<LineJoinType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<Position>> Converter<PropertyValue<Position>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<RasterResamplingType>> Converter<PropertyValue<RasterResamplingType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<SymbolAnchorType>> Converter<PropertyValue<SymbolAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<SymbolPlacementType>> Converter<PropertyValue<SymbolPlacementType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<TextJustifyType>> Converter<PropertyValue<TextJustifyType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<TextTransformType>> Converter<PropertyValue<TextTransformType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; +template optional<PropertyValue<TranslateAnchorType>> Converter<PropertyValue<TranslateAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const; + +} // namespace conversion +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/conversion/source.cpp b/src/mbgl/style/conversion/source.cpp index ce0cb24ce0..5ecbd3b474 100644 --- a/src/mbgl/style/conversion/source.cpp +++ b/src/mbgl/style/conversion/source.cpp @@ -3,6 +3,7 @@ #include <mbgl/style/conversion/geojson.hpp> #include <mbgl/style/conversion/geojson_options.hpp> #include <mbgl/style/conversion/tileset.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/sources/geojson_source.hpp> #include <mbgl/style/sources/raster_source.hpp> #include <mbgl/style/sources/raster_dem_source.hpp> diff --git a/src/mbgl/style/conversion/tileset.cpp b/src/mbgl/style/conversion/tileset.cpp index b566af0a18..40575838ea 100644 --- a/src/mbgl/style/conversion/tileset.cpp +++ b/src/mbgl/style/conversion/tileset.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/tileset.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/geo.hpp> #include <mbgl/math/clamp.hpp> diff --git a/src/mbgl/style/conversion/transition_options.cpp b/src/mbgl/style/conversion/transition_options.cpp index 924032a0c0..6e39dca24f 100644 --- a/src/mbgl/style/conversion/transition_options.cpp +++ b/src/mbgl/style/conversion/transition_options.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/expression/array_assertion.cpp b/src/mbgl/style/expression/array_assertion.cpp index 4049301b0b..9df586bdc3 100644 --- a/src/mbgl/style/expression/array_assertion.cpp +++ b/src/mbgl/style/expression/array_assertion.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/expression/array_assertion.hpp> #include <mbgl/style/expression/check_subtype.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/assertion.cpp b/src/mbgl/style/expression/assertion.cpp index 2434d7a2f8..7e93003ac3 100644 --- a/src/mbgl/style/expression/assertion.cpp +++ b/src/mbgl/style/expression/assertion.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/expression/assertion.hpp> #include <mbgl/style/expression/check_subtype.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/expression/at.cpp b/src/mbgl/style/expression/at.cpp index 725e5ddb51..648f247830 100644 --- a/src/mbgl/style/expression/at.cpp +++ b/src/mbgl/style/expression/at.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/expression/at.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> diff --git a/src/mbgl/style/expression/boolean_operator.cpp b/src/mbgl/style/expression/boolean_operator.cpp index 68e96129aa..fa472270ce 100644 --- a/src/mbgl/style/expression/boolean_operator.cpp +++ b/src/mbgl/style/expression/boolean_operator.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/expression/boolean_operator.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/expression/case.cpp b/src/mbgl/style/expression/case.cpp index e885c0ce6b..0c2ff0d7cd 100644 --- a/src/mbgl/style/expression/case.cpp +++ b/src/mbgl/style/expression/case.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/expression/case.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/coalesce.cpp b/src/mbgl/style/expression/coalesce.cpp index 0090f16009..cdbf452f7f 100644 --- a/src/mbgl/style/expression/coalesce.cpp +++ b/src/mbgl/style/expression/coalesce.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/expression/coalesce.hpp> #include <mbgl/style/expression/check_subtype.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/expression/coercion.cpp b/src/mbgl/style/expression/coercion.cpp index f5a4d70f66..486658ddda 100644 --- a/src/mbgl/style/expression/coercion.cpp +++ b/src/mbgl/style/expression/coercion.cpp @@ -1,6 +1,7 @@ #include <mbgl/style/expression/coercion.hpp> #include <mbgl/style/expression/check_subtype.hpp> #include <mbgl/style/expression/util.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/collator_expression.cpp b/src/mbgl/style/expression/collator_expression.cpp index b27eedbc76..07346633a2 100644 --- a/src/mbgl/style/expression/collator_expression.cpp +++ b/src/mbgl/style/expression/collator_expression.cpp @@ -1,6 +1,7 @@ #include <mbgl/style/expression/collator.hpp> #include <mbgl/style/expression/collator_expression.hpp> #include <mbgl/style/expression/literal.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/comparison.cpp b/src/mbgl/style/expression/comparison.cpp index 6179c3ce88..cdcdb5d59c 100644 --- a/src/mbgl/style/expression/comparison.cpp +++ b/src/mbgl/style/expression/comparison.cpp @@ -1,6 +1,7 @@ #include <mbgl/style/expression/collator.hpp> #include <mbgl/style/expression/comparison.hpp> #include <mbgl/style/expression/dsl.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index 4c476a3749..f8c2376cb3 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -3,6 +3,7 @@ #include <mbgl/style/expression/compound_expression.hpp> #include <mbgl/style/expression/check_subtype.hpp> #include <mbgl/style/expression/util.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/math/log2.hpp> #include <mbgl/util/i18n.hpp> diff --git a/src/mbgl/style/expression/interpolate.cpp b/src/mbgl/style/expression/interpolate.cpp index 54fbc6e1d7..8725e9e86d 100644 --- a/src/mbgl/style/expression/interpolate.cpp +++ b/src/mbgl/style/expression/interpolate.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/expression/interpolate.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/is_constant.cpp b/src/mbgl/style/expression/is_constant.cpp index 69f27f6fef..3b20f49a86 100644 --- a/src/mbgl/style/expression/is_constant.cpp +++ b/src/mbgl/style/expression/is_constant.cpp @@ -17,7 +17,7 @@ bool isFeatureConstant(const Expression& expression) { return false; } else if (name == "has" && parameterCount && *parameterCount == 1) { return false; - } else if (std::equal(std::begin(filter), std::end(filter) - 1, name.begin())) { + } else if (0 == name.rfind(filter, 0)) { // Legacy filters begin with "filter-" and are never constant. return false; } else if ( @@ -28,7 +28,7 @@ bool isFeatureConstant(const Expression& expression) { return false; } } - + if (expression.getKind() == Kind::CollatorExpression) { // Although the results of a Collator expression with fixed arguments // generally shouldn't change between executions, we can't serialize them diff --git a/src/mbgl/style/expression/is_expression.cpp b/src/mbgl/style/expression/is_expression.cpp index 77212f6a1e..acf074c25b 100644 --- a/src/mbgl/style/expression/is_expression.cpp +++ b/src/mbgl/style/expression/is_expression.cpp @@ -1,8 +1,7 @@ #include <mbgl/style/expression/is_expression.hpp> #include <mbgl/style/expression/compound_expression.hpp> #include <mbgl/style/expression/parsing_context.hpp> - -#include <mbgl/style/conversion.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <unordered_set> diff --git a/src/mbgl/style/expression/length.cpp b/src/mbgl/style/expression/length.cpp index ad7a15675a..f1b58d7952 100644 --- a/src/mbgl/style/expression/length.cpp +++ b/src/mbgl/style/expression/length.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/expression/length.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/let.cpp b/src/mbgl/style/expression/let.cpp index 242a995b0b..592ceed58a 100644 --- a/src/mbgl/style/expression/let.cpp +++ b/src/mbgl/style/expression/let.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/expression/let.hpp> #include <mbgl/style/conversion/get_json_type.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/literal.cpp b/src/mbgl/style/expression/literal.cpp index 345a52de9b..c69341d298 100644 --- a/src/mbgl/style/expression/literal.cpp +++ b/src/mbgl/style/expression/literal.cpp @@ -1,4 +1,5 @@ #include <mbgl/style/expression/literal.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/match.cpp b/src/mbgl/style/expression/match.cpp index 4b4984811f..0f05001a97 100644 --- a/src/mbgl/style/expression/match.cpp +++ b/src/mbgl/style/expression/match.cpp @@ -1,6 +1,7 @@ #include <mbgl/style/expression/match.hpp> #include <mbgl/style/expression/check_subtype.hpp> #include <mbgl/style/expression/parsing_context.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> namespace mbgl { diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp index b3f6b1acee..ef17caed33 100644 --- a/src/mbgl/style/expression/parsing_context.cpp +++ b/src/mbgl/style/expression/parsing_context.cpp @@ -24,6 +24,7 @@ #include <mbgl/style/expression/find_zoom_curve.hpp> #include <mbgl/style/conversion/get_json_type.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> diff --git a/src/mbgl/style/expression/step.cpp b/src/mbgl/style/expression/step.cpp index a1ca0a702e..39b04c04a0 100644 --- a/src/mbgl/style/expression/step.cpp +++ b/src/mbgl/style/expression/step.cpp @@ -1,5 +1,6 @@ #include <mbgl/style/expression/step.hpp> #include <mbgl/style/expression/get_covering_stops.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/string.hpp> #include <cmath> diff --git a/src/mbgl/style/layer.cpp b/src/mbgl/style/layer.cpp index 142fe313cf..e08b71e6b3 100644 --- a/src/mbgl/style/layer.cpp +++ b/src/mbgl/style/layer.cpp @@ -1,6 +1,8 @@ #include <mbgl/style/layer.hpp> #include <mbgl/style/layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion_impl.hpp> namespace mbgl { namespace style { @@ -38,5 +40,23 @@ void Layer::setObserver(LayerObserver* observer_) { observer = observer_ ? observer_ : &nullObserver; } +optional<conversion::Error> Layer::setVisibility(const conversion::Convertible& value) { + using namespace conversion; + + if (isUndefined(value)) { + setVisibility(VisibilityType::Visible); + return nullopt; + } + + Error error; + optional<VisibilityType> visibility = convert<VisibilityType>(value, error); + if (!visibility) { + return error; + } + + setVisibility(*visibility); + return nullopt; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/background_layer.cpp b/src/mbgl/style/layers/background_layer.cpp index 66ab46c078..f2e85ce7e7 100644 --- a/src/mbgl/style/layers/background_layer.cpp +++ b/src/mbgl/style/layers/background_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/background_layer.hpp> #include <mbgl/style/layers/background_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -149,5 +156,143 @@ TransitionOptions BackgroundLayer::getBackgroundOpacityTransition() const { return impl().paint.template get<BackgroundOpacity>().options; } +using namespace conversion; + +optional<Error> BackgroundLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + BackgroundColor, + BackgroundPattern, + BackgroundOpacity, + BackgroundColorTransition, + BackgroundPatternTransition, + BackgroundOpacityTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("background-color"): + if (name == "background-color") { + property = Property::BackgroundColor; + } + break; + case util::hashFNV1a("background-color-transition"): + if (name == "background-color-transition") { + property = Property::BackgroundColorTransition; + } + break; + case util::hashFNV1a("background-pattern"): + if (name == "background-pattern") { + property = Property::BackgroundPattern; + } + break; + case util::hashFNV1a("background-pattern-transition"): + if (name == "background-pattern-transition") { + property = Property::BackgroundPatternTransition; + } + break; + case util::hashFNV1a("background-opacity"): + if (name == "background-opacity") { + property = Property::BackgroundOpacity; + } + break; + case util::hashFNV1a("background-opacity-transition"): + if (name == "background-opacity-transition") { + property = Property::BackgroundOpacityTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::BackgroundColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setBackgroundColor(*typedValue); + return nullopt; + + } + + if (property == Property::BackgroundPattern) { + Error error; + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setBackgroundPattern(*typedValue); + return nullopt; + + } + + if (property == Property::BackgroundOpacity) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setBackgroundOpacity(*typedValue); + return nullopt; + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::BackgroundColorTransition) { + setBackgroundColorTransition(*transition); + return nullopt; + } + + if (property == Property::BackgroundPatternTransition) { + setBackgroundPatternTransition(*transition); + return nullopt; + } + + if (property == Property::BackgroundOpacityTransition) { + setBackgroundOpacityTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> BackgroundLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer.cpp b/src/mbgl/style/layers/circle_layer.cpp index d435ce89e1..c301a83c9e 100644 --- a/src/mbgl/style/layers/circle_layer.cpp +++ b/src/mbgl/style/layers/circle_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/circle_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -393,5 +400,344 @@ TransitionOptions CircleLayer::getCircleStrokeOpacityTransition() const { return impl().paint.template get<CircleStrokeOpacity>().options; } +using namespace conversion; + +optional<Error> CircleLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + CircleRadius, + CircleColor, + CircleBlur, + CircleOpacity, + CircleTranslate, + CircleTranslateAnchor, + CirclePitchScale, + CirclePitchAlignment, + CircleStrokeWidth, + CircleStrokeColor, + CircleStrokeOpacity, + CircleRadiusTransition, + CircleColorTransition, + CircleBlurTransition, + CircleOpacityTransition, + CircleTranslateTransition, + CircleTranslateAnchorTransition, + CirclePitchScaleTransition, + CirclePitchAlignmentTransition, + CircleStrokeWidthTransition, + CircleStrokeColorTransition, + CircleStrokeOpacityTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("circle-radius"): + if (name == "circle-radius") { + property = Property::CircleRadius; + } + break; + case util::hashFNV1a("circle-radius-transition"): + if (name == "circle-radius-transition") { + property = Property::CircleRadiusTransition; + } + break; + case util::hashFNV1a("circle-color"): + if (name == "circle-color") { + property = Property::CircleColor; + } + break; + case util::hashFNV1a("circle-color-transition"): + if (name == "circle-color-transition") { + property = Property::CircleColorTransition; + } + break; + case util::hashFNV1a("circle-blur"): + if (name == "circle-blur") { + property = Property::CircleBlur; + } + break; + case util::hashFNV1a("circle-blur-transition"): + if (name == "circle-blur-transition") { + property = Property::CircleBlurTransition; + } + break; + case util::hashFNV1a("circle-opacity"): + if (name == "circle-opacity") { + property = Property::CircleOpacity; + } + break; + case util::hashFNV1a("circle-opacity-transition"): + if (name == "circle-opacity-transition") { + property = Property::CircleOpacityTransition; + } + break; + case util::hashFNV1a("circle-translate"): + if (name == "circle-translate") { + property = Property::CircleTranslate; + } + break; + case util::hashFNV1a("circle-translate-transition"): + if (name == "circle-translate-transition") { + property = Property::CircleTranslateTransition; + } + break; + case util::hashFNV1a("circle-translate-anchor"): + if (name == "circle-translate-anchor") { + property = Property::CircleTranslateAnchor; + } + break; + case util::hashFNV1a("circle-translate-anchor-transition"): + if (name == "circle-translate-anchor-transition") { + property = Property::CircleTranslateAnchorTransition; + } + break; + case util::hashFNV1a("circle-pitch-scale"): + if (name == "circle-pitch-scale") { + property = Property::CirclePitchScale; + } + break; + case util::hashFNV1a("circle-pitch-scale-transition"): + if (name == "circle-pitch-scale-transition") { + property = Property::CirclePitchScaleTransition; + } + break; + case util::hashFNV1a("circle-pitch-alignment"): + if (name == "circle-pitch-alignment") { + property = Property::CirclePitchAlignment; + } + break; + case util::hashFNV1a("circle-pitch-alignment-transition"): + if (name == "circle-pitch-alignment-transition") { + property = Property::CirclePitchAlignmentTransition; + } + break; + case util::hashFNV1a("circle-stroke-width"): + if (name == "circle-stroke-width") { + property = Property::CircleStrokeWidth; + } + break; + case util::hashFNV1a("circle-stroke-width-transition"): + if (name == "circle-stroke-width-transition") { + property = Property::CircleStrokeWidthTransition; + } + break; + case util::hashFNV1a("circle-stroke-color"): + if (name == "circle-stroke-color") { + property = Property::CircleStrokeColor; + } + break; + case util::hashFNV1a("circle-stroke-color-transition"): + if (name == "circle-stroke-color-transition") { + property = Property::CircleStrokeColorTransition; + } + break; + case util::hashFNV1a("circle-stroke-opacity"): + if (name == "circle-stroke-opacity") { + property = Property::CircleStrokeOpacity; + } + break; + case util::hashFNV1a("circle-stroke-opacity-transition"): + if (name == "circle-stroke-opacity-transition") { + property = Property::CircleStrokeOpacityTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::CircleRadius || property == Property::CircleBlur || property == Property::CircleOpacity || property == Property::CircleStrokeWidth || property == Property::CircleStrokeOpacity) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::CircleRadius) { + setCircleRadius(*typedValue); + return nullopt; + } + + if (property == Property::CircleBlur) { + setCircleBlur(*typedValue); + return nullopt; + } + + if (property == Property::CircleOpacity) { + setCircleOpacity(*typedValue); + return nullopt; + } + + if (property == Property::CircleStrokeWidth) { + setCircleStrokeWidth(*typedValue); + return nullopt; + } + + if (property == Property::CircleStrokeOpacity) { + setCircleStrokeOpacity(*typedValue); + return nullopt; + } + + } + + if (property == Property::CircleColor || property == Property::CircleStrokeColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::CircleColor) { + setCircleColor(*typedValue); + return nullopt; + } + + if (property == Property::CircleStrokeColor) { + setCircleStrokeColor(*typedValue); + return nullopt; + } + + } + + if (property == Property::CircleTranslate) { + Error error; + optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setCircleTranslate(*typedValue); + return nullopt; + + } + + if (property == Property::CircleTranslateAnchor) { + Error error; + optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setCircleTranslateAnchor(*typedValue); + return nullopt; + + } + + if (property == Property::CirclePitchScale) { + Error error; + optional<PropertyValue<CirclePitchScaleType>> typedValue = convert<PropertyValue<CirclePitchScaleType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setCirclePitchScale(*typedValue); + return nullopt; + + } + + if (property == Property::CirclePitchAlignment) { + Error error; + optional<PropertyValue<AlignmentType>> typedValue = convert<PropertyValue<AlignmentType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setCirclePitchAlignment(*typedValue); + return nullopt; + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::CircleRadiusTransition) { + setCircleRadiusTransition(*transition); + return nullopt; + } + + if (property == Property::CircleColorTransition) { + setCircleColorTransition(*transition); + return nullopt; + } + + if (property == Property::CircleBlurTransition) { + setCircleBlurTransition(*transition); + return nullopt; + } + + if (property == Property::CircleOpacityTransition) { + setCircleOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::CircleTranslateTransition) { + setCircleTranslateTransition(*transition); + return nullopt; + } + + if (property == Property::CircleTranslateAnchorTransition) { + setCircleTranslateAnchorTransition(*transition); + return nullopt; + } + + if (property == Property::CirclePitchScaleTransition) { + setCirclePitchScaleTransition(*transition); + return nullopt; + } + + if (property == Property::CirclePitchAlignmentTransition) { + setCirclePitchAlignmentTransition(*transition); + return nullopt; + } + + if (property == Property::CircleStrokeWidthTransition) { + setCircleStrokeWidthTransition(*transition); + return nullopt; + } + + if (property == Property::CircleStrokeColorTransition) { + setCircleStrokeColorTransition(*transition); + return nullopt; + } + + if (property == Property::CircleStrokeOpacityTransition) { + setCircleStrokeOpacityTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> CircleLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/circle_layer_impl.cpp b/src/mbgl/style/layers/circle_layer_impl.cpp index 69f574cd6b..358598e09c 100644 --- a/src/mbgl/style/layers/circle_layer_impl.cpp +++ b/src/mbgl/style/layers/circle_layer_impl.cpp @@ -4,7 +4,7 @@ namespace mbgl { namespace style { bool CircleLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const { - assert(dynamic_cast<const CircleLayer::Impl*>(&other)); + assert(other.type == LayerType::Circle); const auto& impl = static_cast<const style::CircleLayer::Impl&>(other); return filter != impl.filter || visibility != impl.visibility || diff --git a/src/mbgl/style/layers/custom_layer.cpp b/src/mbgl/style/layers/custom_layer.cpp index 0e51a70e50..d1ac1a705c 100644 --- a/src/mbgl/style/layers/custom_layer.cpp +++ b/src/mbgl/style/layers/custom_layer.cpp @@ -50,6 +50,16 @@ void CustomLayer::setMaxZoom(float maxZoom) { baseImpl = std::move(impl_); } +using namespace conversion; + +optional<Error> CustomLayer::setPaintProperty(const std::string&, const Convertible&) { + return Error { "layer doesn't support this property" }; +} + +optional<Error> CustomLayer::setLayoutProperty(const std::string&, const Convertible&) { + return Error { "layer doesn't support this property" }; +} + template <> bool Layer::is<CustomLayer>() const { return getType() == LayerType::Custom; diff --git a/src/mbgl/style/layers/fill_extrusion_layer.cpp b/src/mbgl/style/layers/fill_extrusion_layer.cpp index 829a24f354..74cdb9abe6 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/fill_extrusion_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -285,5 +292,254 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionBaseTransition() const { return impl().paint.template get<FillExtrusionBase>().options; } +using namespace conversion; + +optional<Error> FillExtrusionLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + FillExtrusionOpacity, + FillExtrusionColor, + FillExtrusionTranslate, + FillExtrusionTranslateAnchor, + FillExtrusionPattern, + FillExtrusionHeight, + FillExtrusionBase, + FillExtrusionOpacityTransition, + FillExtrusionColorTransition, + FillExtrusionTranslateTransition, + FillExtrusionTranslateAnchorTransition, + FillExtrusionPatternTransition, + FillExtrusionHeightTransition, + FillExtrusionBaseTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("fill-extrusion-opacity"): + if (name == "fill-extrusion-opacity") { + property = Property::FillExtrusionOpacity; + } + break; + case util::hashFNV1a("fill-extrusion-opacity-transition"): + if (name == "fill-extrusion-opacity-transition") { + property = Property::FillExtrusionOpacityTransition; + } + break; + case util::hashFNV1a("fill-extrusion-color"): + if (name == "fill-extrusion-color") { + property = Property::FillExtrusionColor; + } + break; + case util::hashFNV1a("fill-extrusion-color-transition"): + if (name == "fill-extrusion-color-transition") { + property = Property::FillExtrusionColorTransition; + } + break; + case util::hashFNV1a("fill-extrusion-translate"): + if (name == "fill-extrusion-translate") { + property = Property::FillExtrusionTranslate; + } + break; + case util::hashFNV1a("fill-extrusion-translate-transition"): + if (name == "fill-extrusion-translate-transition") { + property = Property::FillExtrusionTranslateTransition; + } + break; + case util::hashFNV1a("fill-extrusion-translate-anchor"): + if (name == "fill-extrusion-translate-anchor") { + property = Property::FillExtrusionTranslateAnchor; + } + break; + case util::hashFNV1a("fill-extrusion-translate-anchor-transition"): + if (name == "fill-extrusion-translate-anchor-transition") { + property = Property::FillExtrusionTranslateAnchorTransition; + } + break; + case util::hashFNV1a("fill-extrusion-pattern"): + if (name == "fill-extrusion-pattern") { + property = Property::FillExtrusionPattern; + } + break; + case util::hashFNV1a("fill-extrusion-pattern-transition"): + if (name == "fill-extrusion-pattern-transition") { + property = Property::FillExtrusionPatternTransition; + } + break; + case util::hashFNV1a("fill-extrusion-height"): + if (name == "fill-extrusion-height") { + property = Property::FillExtrusionHeight; + } + break; + case util::hashFNV1a("fill-extrusion-height-transition"): + if (name == "fill-extrusion-height-transition") { + property = Property::FillExtrusionHeightTransition; + } + break; + case util::hashFNV1a("fill-extrusion-base"): + if (name == "fill-extrusion-base") { + property = Property::FillExtrusionBase; + } + break; + case util::hashFNV1a("fill-extrusion-base-transition"): + if (name == "fill-extrusion-base-transition") { + property = Property::FillExtrusionBaseTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::FillExtrusionOpacity) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillExtrusionOpacity(*typedValue); + return nullopt; + + } + + if (property == Property::FillExtrusionColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setFillExtrusionColor(*typedValue); + return nullopt; + + } + + if (property == Property::FillExtrusionTranslate) { + Error error; + optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillExtrusionTranslate(*typedValue); + return nullopt; + + } + + if (property == Property::FillExtrusionTranslateAnchor) { + Error error; + optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillExtrusionTranslateAnchor(*typedValue); + return nullopt; + + } + + if (property == Property::FillExtrusionPattern) { + Error error; + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillExtrusionPattern(*typedValue); + return nullopt; + + } + + if (property == Property::FillExtrusionHeight || property == Property::FillExtrusionBase) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::FillExtrusionHeight) { + setFillExtrusionHeight(*typedValue); + return nullopt; + } + + if (property == Property::FillExtrusionBase) { + setFillExtrusionBase(*typedValue); + return nullopt; + } + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::FillExtrusionOpacityTransition) { + setFillExtrusionOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::FillExtrusionColorTransition) { + setFillExtrusionColorTransition(*transition); + return nullopt; + } + + if (property == Property::FillExtrusionTranslateTransition) { + setFillExtrusionTranslateTransition(*transition); + return nullopt; + } + + if (property == Property::FillExtrusionTranslateAnchorTransition) { + setFillExtrusionTranslateAnchorTransition(*transition); + return nullopt; + } + + if (property == Property::FillExtrusionPatternTransition) { + setFillExtrusionPatternTransition(*transition); + return nullopt; + } + + if (property == Property::FillExtrusionHeightTransition) { + setFillExtrusionHeightTransition(*transition); + return nullopt; + } + + if (property == Property::FillExtrusionBaseTransition) { + setFillExtrusionBaseTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> FillExtrusionLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp index d37c2ad29b..357ea3e973 100644 --- a/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp +++ b/src/mbgl/style/layers/fill_extrusion_layer_impl.cpp @@ -4,7 +4,7 @@ namespace mbgl { namespace style { bool FillExtrusionLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const { - assert(dynamic_cast<const FillExtrusionLayer::Impl*>(&other)); + assert(other.type == LayerType::FillExtrusion); const auto& impl = static_cast<const style::FillExtrusionLayer::Impl&>(other); return filter != impl.filter || visibility != impl.visibility || diff --git a/src/mbgl/style/layers/fill_layer.cpp b/src/mbgl/style/layers/fill_layer.cpp index 8eebd54e3c..bdfc000736 100644 --- a/src/mbgl/style/layers/fill_layer.cpp +++ b/src/mbgl/style/layers/fill_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/fill_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -285,5 +292,254 @@ TransitionOptions FillLayer::getFillPatternTransition() const { return impl().paint.template get<FillPattern>().options; } +using namespace conversion; + +optional<Error> FillLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + FillAntialias, + FillOpacity, + FillColor, + FillOutlineColor, + FillTranslate, + FillTranslateAnchor, + FillPattern, + FillAntialiasTransition, + FillOpacityTransition, + FillColorTransition, + FillOutlineColorTransition, + FillTranslateTransition, + FillTranslateAnchorTransition, + FillPatternTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("fill-antialias"): + if (name == "fill-antialias") { + property = Property::FillAntialias; + } + break; + case util::hashFNV1a("fill-antialias-transition"): + if (name == "fill-antialias-transition") { + property = Property::FillAntialiasTransition; + } + break; + case util::hashFNV1a("fill-opacity"): + if (name == "fill-opacity") { + property = Property::FillOpacity; + } + break; + case util::hashFNV1a("fill-opacity-transition"): + if (name == "fill-opacity-transition") { + property = Property::FillOpacityTransition; + } + break; + case util::hashFNV1a("fill-color"): + if (name == "fill-color") { + property = Property::FillColor; + } + break; + case util::hashFNV1a("fill-color-transition"): + if (name == "fill-color-transition") { + property = Property::FillColorTransition; + } + break; + case util::hashFNV1a("fill-outline-color"): + if (name == "fill-outline-color") { + property = Property::FillOutlineColor; + } + break; + case util::hashFNV1a("fill-outline-color-transition"): + if (name == "fill-outline-color-transition") { + property = Property::FillOutlineColorTransition; + } + break; + case util::hashFNV1a("fill-translate"): + if (name == "fill-translate") { + property = Property::FillTranslate; + } + break; + case util::hashFNV1a("fill-translate-transition"): + if (name == "fill-translate-transition") { + property = Property::FillTranslateTransition; + } + break; + case util::hashFNV1a("fill-translate-anchor"): + if (name == "fill-translate-anchor") { + property = Property::FillTranslateAnchor; + } + break; + case util::hashFNV1a("fill-translate-anchor-transition"): + if (name == "fill-translate-anchor-transition") { + property = Property::FillTranslateAnchorTransition; + } + break; + case util::hashFNV1a("fill-pattern"): + if (name == "fill-pattern") { + property = Property::FillPattern; + } + break; + case util::hashFNV1a("fill-pattern-transition"): + if (name == "fill-pattern-transition") { + property = Property::FillPatternTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::FillAntialias) { + Error error; + optional<PropertyValue<bool>> typedValue = convert<PropertyValue<bool>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillAntialias(*typedValue); + return nullopt; + + } + + if (property == Property::FillOpacity) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setFillOpacity(*typedValue); + return nullopt; + + } + + if (property == Property::FillColor || property == Property::FillOutlineColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::FillColor) { + setFillColor(*typedValue); + return nullopt; + } + + if (property == Property::FillOutlineColor) { + setFillOutlineColor(*typedValue); + return nullopt; + } + + } + + if (property == Property::FillTranslate) { + Error error; + optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillTranslate(*typedValue); + return nullopt; + + } + + if (property == Property::FillTranslateAnchor) { + Error error; + optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillTranslateAnchor(*typedValue); + return nullopt; + + } + + if (property == Property::FillPattern) { + Error error; + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setFillPattern(*typedValue); + return nullopt; + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::FillAntialiasTransition) { + setFillAntialiasTransition(*transition); + return nullopt; + } + + if (property == Property::FillOpacityTransition) { + setFillOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::FillColorTransition) { + setFillColorTransition(*transition); + return nullopt; + } + + if (property == Property::FillOutlineColorTransition) { + setFillOutlineColorTransition(*transition); + return nullopt; + } + + if (property == Property::FillTranslateTransition) { + setFillTranslateTransition(*transition); + return nullopt; + } + + if (property == Property::FillTranslateAnchorTransition) { + setFillTranslateAnchorTransition(*transition); + return nullopt; + } + + if (property == Property::FillPatternTransition) { + setFillPatternTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> FillLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/fill_layer_impl.cpp b/src/mbgl/style/layers/fill_layer_impl.cpp index 0dc7ed14d5..a8ba1b693b 100644 --- a/src/mbgl/style/layers/fill_layer_impl.cpp +++ b/src/mbgl/style/layers/fill_layer_impl.cpp @@ -4,7 +4,7 @@ namespace mbgl { namespace style { bool FillLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const { - assert(dynamic_cast<const FillLayer::Impl*>(&other)); + assert(other.type == LayerType::Fill); const auto& impl = static_cast<const style::FillLayer::Impl&>(other); return filter != impl.filter || visibility != impl.visibility || diff --git a/src/mbgl/style/layers/heatmap_layer.cpp b/src/mbgl/style/layers/heatmap_layer.cpp index 21016ee509..a90aab7009 100644 --- a/src/mbgl/style/layers/heatmap_layer.cpp +++ b/src/mbgl/style/layers/heatmap_layer.cpp @@ -3,10 +3,13 @@ #include <mbgl/style/layers/heatmap_layer.hpp> #include <mbgl/style/layers/heatmap_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> -// for constructing default heatmap-color ramp expression from style JSON -#include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> #include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -237,5 +240,191 @@ TransitionOptions HeatmapLayer::getHeatmapOpacityTransition() const { return impl().paint.template get<HeatmapOpacity>().options; } +using namespace conversion; + +optional<Error> HeatmapLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + HeatmapRadius, + HeatmapWeight, + HeatmapIntensity, + HeatmapColor, + HeatmapOpacity, + HeatmapRadiusTransition, + HeatmapWeightTransition, + HeatmapIntensityTransition, + HeatmapColorTransition, + HeatmapOpacityTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("heatmap-radius"): + if (name == "heatmap-radius") { + property = Property::HeatmapRadius; + } + break; + case util::hashFNV1a("heatmap-radius-transition"): + if (name == "heatmap-radius-transition") { + property = Property::HeatmapRadiusTransition; + } + break; + case util::hashFNV1a("heatmap-weight"): + if (name == "heatmap-weight") { + property = Property::HeatmapWeight; + } + break; + case util::hashFNV1a("heatmap-weight-transition"): + if (name == "heatmap-weight-transition") { + property = Property::HeatmapWeightTransition; + } + break; + case util::hashFNV1a("heatmap-intensity"): + if (name == "heatmap-intensity") { + property = Property::HeatmapIntensity; + } + break; + case util::hashFNV1a("heatmap-intensity-transition"): + if (name == "heatmap-intensity-transition") { + property = Property::HeatmapIntensityTransition; + } + break; + case util::hashFNV1a("heatmap-color"): + if (name == "heatmap-color") { + property = Property::HeatmapColor; + } + break; + case util::hashFNV1a("heatmap-color-transition"): + if (name == "heatmap-color-transition") { + property = Property::HeatmapColorTransition; + } + break; + case util::hashFNV1a("heatmap-opacity"): + if (name == "heatmap-opacity") { + property = Property::HeatmapOpacity; + } + break; + case util::hashFNV1a("heatmap-opacity-transition"): + if (name == "heatmap-opacity-transition") { + property = Property::HeatmapOpacityTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::HeatmapRadius || property == Property::HeatmapWeight) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::HeatmapRadius) { + setHeatmapRadius(*typedValue); + return nullopt; + } + + if (property == Property::HeatmapWeight) { + setHeatmapWeight(*typedValue); + return nullopt; + } + + } + + if (property == Property::HeatmapIntensity || property == Property::HeatmapOpacity) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::HeatmapIntensity) { + setHeatmapIntensity(*typedValue); + return nullopt; + } + + if (property == Property::HeatmapOpacity) { + setHeatmapOpacity(*typedValue); + return nullopt; + } + + } + + if (property == Property::HeatmapColor) { + Error error; + optional<ColorRampPropertyValue> typedValue = convert<ColorRampPropertyValue>(value, error, false, false); + if (!typedValue) { + return error; + } + + setHeatmapColor(*typedValue); + return nullopt; + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::HeatmapRadiusTransition) { + setHeatmapRadiusTransition(*transition); + return nullopt; + } + + if (property == Property::HeatmapWeightTransition) { + setHeatmapWeightTransition(*transition); + return nullopt; + } + + if (property == Property::HeatmapIntensityTransition) { + setHeatmapIntensityTransition(*transition); + return nullopt; + } + + if (property == Property::HeatmapColorTransition) { + setHeatmapColorTransition(*transition); + return nullopt; + } + + if (property == Property::HeatmapOpacityTransition) { + setHeatmapOpacityTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> HeatmapLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/heatmap_layer_impl.cpp b/src/mbgl/style/layers/heatmap_layer_impl.cpp index af20888d9d..8fd0cf72b2 100644 --- a/src/mbgl/style/layers/heatmap_layer_impl.cpp +++ b/src/mbgl/style/layers/heatmap_layer_impl.cpp @@ -4,7 +4,7 @@ namespace mbgl { namespace style { bool HeatmapLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const { - assert(dynamic_cast<const HeatmapLayer::Impl*>(&other)); + assert(other.type == LayerType::Heatmap); const auto& impl = static_cast<const style::HeatmapLayer::Impl&>(other); return filter != impl.filter || visibility != impl.visibility || diff --git a/src/mbgl/style/layers/heatmap_layer_properties.hpp b/src/mbgl/style/layers/heatmap_layer_properties.hpp index fe7257a78a..4d49a52c72 100644 --- a/src/mbgl/style/layers/heatmap_layer_properties.hpp +++ b/src/mbgl/style/layers/heatmap_layer_properties.hpp @@ -24,7 +24,8 @@ struct HeatmapIntensity : PaintProperty<float> { static float defaultValue() { return 1; } }; -using HeatmapColor = ColorRampProperty; +struct HeatmapColor : ColorRampProperty { +}; struct HeatmapOpacity : PaintProperty<float> { static float defaultValue() { return 1; } diff --git a/src/mbgl/style/layers/hillshade_layer.cpp b/src/mbgl/style/layers/hillshade_layer.cpp index e352ae090c..aed49f6441 100644 --- a/src/mbgl/style/layers/hillshade_layer.cpp +++ b/src/mbgl/style/layers/hillshade_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/hillshade_layer.hpp> #include <mbgl/style/layers/hillshade_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -236,5 +243,213 @@ TransitionOptions HillshadeLayer::getHillshadeAccentColorTransition() const { return impl().paint.template get<HillshadeAccentColor>().options; } +using namespace conversion; + +optional<Error> HillshadeLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + HillshadeIlluminationDirection, + HillshadeIlluminationAnchor, + HillshadeExaggeration, + HillshadeShadowColor, + HillshadeHighlightColor, + HillshadeAccentColor, + HillshadeIlluminationDirectionTransition, + HillshadeIlluminationAnchorTransition, + HillshadeExaggerationTransition, + HillshadeShadowColorTransition, + HillshadeHighlightColorTransition, + HillshadeAccentColorTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("hillshade-illumination-direction"): + if (name == "hillshade-illumination-direction") { + property = Property::HillshadeIlluminationDirection; + } + break; + case util::hashFNV1a("hillshade-illumination-direction-transition"): + if (name == "hillshade-illumination-direction-transition") { + property = Property::HillshadeIlluminationDirectionTransition; + } + break; + case util::hashFNV1a("hillshade-illumination-anchor"): + if (name == "hillshade-illumination-anchor") { + property = Property::HillshadeIlluminationAnchor; + } + break; + case util::hashFNV1a("hillshade-illumination-anchor-transition"): + if (name == "hillshade-illumination-anchor-transition") { + property = Property::HillshadeIlluminationAnchorTransition; + } + break; + case util::hashFNV1a("hillshade-exaggeration"): + if (name == "hillshade-exaggeration") { + property = Property::HillshadeExaggeration; + } + break; + case util::hashFNV1a("hillshade-exaggeration-transition"): + if (name == "hillshade-exaggeration-transition") { + property = Property::HillshadeExaggerationTransition; + } + break; + case util::hashFNV1a("hillshade-shadow-color"): + if (name == "hillshade-shadow-color") { + property = Property::HillshadeShadowColor; + } + break; + case util::hashFNV1a("hillshade-shadow-color-transition"): + if (name == "hillshade-shadow-color-transition") { + property = Property::HillshadeShadowColorTransition; + } + break; + case util::hashFNV1a("hillshade-highlight-color"): + if (name == "hillshade-highlight-color") { + property = Property::HillshadeHighlightColor; + } + break; + case util::hashFNV1a("hillshade-highlight-color-transition"): + if (name == "hillshade-highlight-color-transition") { + property = Property::HillshadeHighlightColorTransition; + } + break; + case util::hashFNV1a("hillshade-accent-color"): + if (name == "hillshade-accent-color") { + property = Property::HillshadeAccentColor; + } + break; + case util::hashFNV1a("hillshade-accent-color-transition"): + if (name == "hillshade-accent-color-transition") { + property = Property::HillshadeAccentColorTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::HillshadeIlluminationDirection || property == Property::HillshadeExaggeration) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::HillshadeIlluminationDirection) { + setHillshadeIlluminationDirection(*typedValue); + return nullopt; + } + + if (property == Property::HillshadeExaggeration) { + setHillshadeExaggeration(*typedValue); + return nullopt; + } + + } + + if (property == Property::HillshadeIlluminationAnchor) { + Error error; + optional<PropertyValue<HillshadeIlluminationAnchorType>> typedValue = convert<PropertyValue<HillshadeIlluminationAnchorType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setHillshadeIlluminationAnchor(*typedValue); + return nullopt; + + } + + if (property == Property::HillshadeShadowColor || property == Property::HillshadeHighlightColor || property == Property::HillshadeAccentColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::HillshadeShadowColor) { + setHillshadeShadowColor(*typedValue); + return nullopt; + } + + if (property == Property::HillshadeHighlightColor) { + setHillshadeHighlightColor(*typedValue); + return nullopt; + } + + if (property == Property::HillshadeAccentColor) { + setHillshadeAccentColor(*typedValue); + return nullopt; + } + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::HillshadeIlluminationDirectionTransition) { + setHillshadeIlluminationDirectionTransition(*transition); + return nullopt; + } + + if (property == Property::HillshadeIlluminationAnchorTransition) { + setHillshadeIlluminationAnchorTransition(*transition); + return nullopt; + } + + if (property == Property::HillshadeExaggerationTransition) { + setHillshadeExaggerationTransition(*transition); + return nullopt; + } + + if (property == Property::HillshadeShadowColorTransition) { + setHillshadeShadowColorTransition(*transition); + return nullopt; + } + + if (property == Property::HillshadeHighlightColorTransition) { + setHillshadeHighlightColorTransition(*transition); + return nullopt; + } + + if (property == Property::HillshadeAccentColorTransition) { + setHillshadeAccentColorTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> HillshadeLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer.cpp.ejs b/src/mbgl/style/layers/layer.cpp.ejs index a9b6d9d02d..b5fb1a97a4 100644 --- a/src/mbgl/style/layers/layer.cpp.ejs +++ b/src/mbgl/style/layers/layer.cpp.ejs @@ -8,12 +8,13 @@ #include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp> #include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> -<% if (type === 'heatmap') { -%> -// for constructing default heatmap-color ramp expression from style JSON -#include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> #include <mbgl/style/conversion/json.hpp> -<% } -%> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -175,5 +176,145 @@ TransitionOptions <%- camelize(type) %>Layer::get<%- camelize(property.name) %>T } <% } -%> +using namespace conversion; + +optional<Error> <%- camelize(type) %>Layer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, +<% for (const property of paintProperties) { -%> + <%- camelize(property.name) %>, +<% } -%> +<% for (const property of paintProperties) { -%> + <%- camelize(property.name) %>Transition, +<% } -%> + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + <% for (const property of paintProperties) { -%> +case util::hashFNV1a("<%- property.name %>"): + if (name == "<%- property.name %>") { + property = Property::<%- camelize(property.name) %>; + } + break; + case util::hashFNV1a("<%- property.name %>-transition"): + if (name == "<%- property.name %>-transition") { + property = Property::<%- camelize(property.name) %>Transition; + } + break; + <% } %> + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + <% + const paintConversions = {}; + for (const property of paintProperties) { + const dataDriven = property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven'; + const convertTokens = property.name === 'icon-image' || property.name === 'text-field'; + const conversion = `optional<${propertyValueType(property)}> typedValue = convert<${propertyValueType(property)}>(value, error, ${dataDriven}, ${convertTokens})`; + paintConversions[conversion] = paintConversions[conversion] || []; + paintConversions[conversion].push(property); + } + -%> + <% for (const key in paintConversions) { + const properties = paintConversions[key]; + %> + if (<%- properties.map(p => `property == Property::${camelize(p.name)}`).join(' || ') %>) { + Error error; + <%- key %>; + if (!typedValue) { + return error; + } + <% if (properties.length == 1) { %> + set<%- camelize(properties[0].name) %>(*typedValue); + return nullopt; + <% } else for (const property of properties) { %> + if (property == Property::<%- camelize(property.name) %>) { + set<%- camelize(property.name) %>(*typedValue); + return nullopt; + } + <% } %> + } + <% } %> + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + <% for (const property of paintProperties) { %> + if (property == Property::<%- camelize(property.name) %>Transition) { + set<%- camelize(property.name) %>Transition(*transition); + return nullopt; + } + <% } %> + + return Error { "layer doesn't support this property" }; +} + +optional<Error> <%- camelize(type) %>Layer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, +<% for (const property of layoutProperties) { -%> + <%- camelize(property.name) %>, +<% } -%> + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + <% for (const property of layoutProperties) { %> + case util::hashFNV1a("<%- property.name %>"): + if (name == "<%- property.name %>") { + property = Property::<%- camelize(property.name) %>; + } + break; + <% } %> + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + <% + const layoutConversions = {}; + for (const property of layoutProperties) { + const dataDriven = property['property-type'] === 'data-driven' || property['property-type'] === 'cross-faded-data-driven'; + const convertTokens = property.name === 'icon-image' || property.name === 'text-field'; + const conversion = `optional<${propertyValueType(property)}> typedValue = convert<${propertyValueType(property)}>(value, error, ${dataDriven}, ${convertTokens})`; + layoutConversions[conversion] = layoutConversions[conversion] || []; + layoutConversions[conversion].push(property); + } + -%> + <% for (const key in layoutConversions) { + const properties = layoutConversions[key]; + %> + if (<%- properties.map(p => `property == Property::${camelize(p.name)}`).join(' || ') %>) { + Error error; + <%- key %>; + if (!typedValue) { + return error; + } + <% if (properties.length == 1) { %> + set<%- camelize(properties[0].name) %>(*typedValue); + return nullopt; + <% } else for (const property of properties) { %> + if (property == Property::<%- camelize(property.name) %>) { + set<%- camelize(property.name) %>(*typedValue); + return nullopt; + } + <% } %> + } + <% } %> + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/layer_properties.hpp.ejs b/src/mbgl/style/layers/layer_properties.hpp.ejs index 5b774933a6..694d9a62b7 100644 --- a/src/mbgl/style/layers/layer_properties.hpp.ejs +++ b/src/mbgl/style/layers/layer_properties.hpp.ejs @@ -26,7 +26,8 @@ struct <%- camelize(property.name) %> : <%- layoutPropertyType(property, type) % <% } -%> <% for (const property of paintProperties) { -%> <% if (property['property-type'] === 'color-ramp') { -%> -using <%- camelize(property.name) %> = ColorRampProperty; +struct <%- camelize(property.name) %> : ColorRampProperty { +}; <% } else { -%> struct <%- camelize(property.name) %> : <%- paintPropertyType(property, type) %> { static <%- evaluatedType(property) %> defaultValue() { return <%- defaultValue(property) %>; } diff --git a/src/mbgl/style/layers/line_layer.cpp b/src/mbgl/style/layers/line_layer.cpp index 0cda849c0f..1b84c2d73e 100644 --- a/src/mbgl/style/layers/line_layer.cpp +++ b/src/mbgl/style/layers/line_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/line_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -431,5 +438,391 @@ TransitionOptions LineLayer::getLinePatternTransition() const { return impl().paint.template get<LinePattern>().options; } +using namespace conversion; + +optional<Error> LineLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + LineOpacity, + LineColor, + LineTranslate, + LineTranslateAnchor, + LineWidth, + LineGapWidth, + LineOffset, + LineBlur, + LineDasharray, + LinePattern, + LineOpacityTransition, + LineColorTransition, + LineTranslateTransition, + LineTranslateAnchorTransition, + LineWidthTransition, + LineGapWidthTransition, + LineOffsetTransition, + LineBlurTransition, + LineDasharrayTransition, + LinePatternTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("line-opacity"): + if (name == "line-opacity") { + property = Property::LineOpacity; + } + break; + case util::hashFNV1a("line-opacity-transition"): + if (name == "line-opacity-transition") { + property = Property::LineOpacityTransition; + } + break; + case util::hashFNV1a("line-color"): + if (name == "line-color") { + property = Property::LineColor; + } + break; + case util::hashFNV1a("line-color-transition"): + if (name == "line-color-transition") { + property = Property::LineColorTransition; + } + break; + case util::hashFNV1a("line-translate"): + if (name == "line-translate") { + property = Property::LineTranslate; + } + break; + case util::hashFNV1a("line-translate-transition"): + if (name == "line-translate-transition") { + property = Property::LineTranslateTransition; + } + break; + case util::hashFNV1a("line-translate-anchor"): + if (name == "line-translate-anchor") { + property = Property::LineTranslateAnchor; + } + break; + case util::hashFNV1a("line-translate-anchor-transition"): + if (name == "line-translate-anchor-transition") { + property = Property::LineTranslateAnchorTransition; + } + break; + case util::hashFNV1a("line-width"): + if (name == "line-width") { + property = Property::LineWidth; + } + break; + case util::hashFNV1a("line-width-transition"): + if (name == "line-width-transition") { + property = Property::LineWidthTransition; + } + break; + case util::hashFNV1a("line-gap-width"): + if (name == "line-gap-width") { + property = Property::LineGapWidth; + } + break; + case util::hashFNV1a("line-gap-width-transition"): + if (name == "line-gap-width-transition") { + property = Property::LineGapWidthTransition; + } + break; + case util::hashFNV1a("line-offset"): + if (name == "line-offset") { + property = Property::LineOffset; + } + break; + case util::hashFNV1a("line-offset-transition"): + if (name == "line-offset-transition") { + property = Property::LineOffsetTransition; + } + break; + case util::hashFNV1a("line-blur"): + if (name == "line-blur") { + property = Property::LineBlur; + } + break; + case util::hashFNV1a("line-blur-transition"): + if (name == "line-blur-transition") { + property = Property::LineBlurTransition; + } + break; + case util::hashFNV1a("line-dasharray"): + if (name == "line-dasharray") { + property = Property::LineDasharray; + } + break; + case util::hashFNV1a("line-dasharray-transition"): + if (name == "line-dasharray-transition") { + property = Property::LineDasharrayTransition; + } + break; + case util::hashFNV1a("line-pattern"): + if (name == "line-pattern") { + property = Property::LinePattern; + } + break; + case util::hashFNV1a("line-pattern-transition"): + if (name == "line-pattern-transition") { + property = Property::LinePatternTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::LineOpacity || property == Property::LineWidth || property == Property::LineGapWidth || property == Property::LineOffset || property == Property::LineBlur) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::LineOpacity) { + setLineOpacity(*typedValue); + return nullopt; + } + + if (property == Property::LineWidth) { + setLineWidth(*typedValue); + return nullopt; + } + + if (property == Property::LineGapWidth) { + setLineGapWidth(*typedValue); + return nullopt; + } + + if (property == Property::LineOffset) { + setLineOffset(*typedValue); + return nullopt; + } + + if (property == Property::LineBlur) { + setLineBlur(*typedValue); + return nullopt; + } + + } + + if (property == Property::LineColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setLineColor(*typedValue); + return nullopt; + + } + + if (property == Property::LineTranslate) { + Error error; + optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setLineTranslate(*typedValue); + return nullopt; + + } + + if (property == Property::LineTranslateAnchor) { + Error error; + optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setLineTranslateAnchor(*typedValue); + return nullopt; + + } + + if (property == Property::LineDasharray) { + Error error; + optional<PropertyValue<std::vector<float>>> typedValue = convert<PropertyValue<std::vector<float>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setLineDasharray(*typedValue); + return nullopt; + + } + + if (property == Property::LinePattern) { + Error error; + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setLinePattern(*typedValue); + return nullopt; + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::LineOpacityTransition) { + setLineOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::LineColorTransition) { + setLineColorTransition(*transition); + return nullopt; + } + + if (property == Property::LineTranslateTransition) { + setLineTranslateTransition(*transition); + return nullopt; + } + + if (property == Property::LineTranslateAnchorTransition) { + setLineTranslateAnchorTransition(*transition); + return nullopt; + } + + if (property == Property::LineWidthTransition) { + setLineWidthTransition(*transition); + return nullopt; + } + + if (property == Property::LineGapWidthTransition) { + setLineGapWidthTransition(*transition); + return nullopt; + } + + if (property == Property::LineOffsetTransition) { + setLineOffsetTransition(*transition); + return nullopt; + } + + if (property == Property::LineBlurTransition) { + setLineBlurTransition(*transition); + return nullopt; + } + + if (property == Property::LineDasharrayTransition) { + setLineDasharrayTransition(*transition); + return nullopt; + } + + if (property == Property::LinePatternTransition) { + setLinePatternTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> LineLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + LineCap, + LineJoin, + LineMiterLimit, + LineRoundLimit, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + case util::hashFNV1a("line-cap"): + if (name == "line-cap") { + property = Property::LineCap; + } + break; + + case util::hashFNV1a("line-join"): + if (name == "line-join") { + property = Property::LineJoin; + } + break; + + case util::hashFNV1a("line-miter-limit"): + if (name == "line-miter-limit") { + property = Property::LineMiterLimit; + } + break; + + case util::hashFNV1a("line-round-limit"): + if (name == "line-round-limit") { + property = Property::LineRoundLimit; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::LineCap) { + Error error; + optional<PropertyValue<LineCapType>> typedValue = convert<PropertyValue<LineCapType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setLineCap(*typedValue); + return nullopt; + + } + + if (property == Property::LineJoin) { + Error error; + optional<PropertyValue<LineJoinType>> typedValue = convert<PropertyValue<LineJoinType>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setLineJoin(*typedValue); + return nullopt; + + } + + if (property == Property::LineMiterLimit || property == Property::LineRoundLimit) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::LineMiterLimit) { + setLineMiterLimit(*typedValue); + return nullopt; + } + + if (property == Property::LineRoundLimit) { + setLineRoundLimit(*typedValue); + return nullopt; + } + + } + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/line_layer_impl.cpp b/src/mbgl/style/layers/line_layer_impl.cpp index bee88d6a47..68cd3a8f49 100644 --- a/src/mbgl/style/layers/line_layer_impl.cpp +++ b/src/mbgl/style/layers/line_layer_impl.cpp @@ -4,7 +4,7 @@ namespace mbgl { namespace style { bool LineLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const { - assert(dynamic_cast<const LineLayer::Impl*>(&other)); + assert(other.type == LayerType::Line); const auto& impl = static_cast<const style::LineLayer::Impl&>(other); return filter != impl.filter || visibility != impl.visibility || diff --git a/src/mbgl/style/layers/raster_layer.cpp b/src/mbgl/style/layers/raster_layer.cpp index e5b03df0f6..7bd01c92e1 100644 --- a/src/mbgl/style/layers/raster_layer.cpp +++ b/src/mbgl/style/layers/raster_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/raster_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -290,5 +297,248 @@ TransitionOptions RasterLayer::getRasterFadeDurationTransition() const { return impl().paint.template get<RasterFadeDuration>().options; } +using namespace conversion; + +optional<Error> RasterLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + RasterOpacity, + RasterHueRotate, + RasterBrightnessMin, + RasterBrightnessMax, + RasterSaturation, + RasterContrast, + RasterResampling, + RasterFadeDuration, + RasterOpacityTransition, + RasterHueRotateTransition, + RasterBrightnessMinTransition, + RasterBrightnessMaxTransition, + RasterSaturationTransition, + RasterContrastTransition, + RasterResamplingTransition, + RasterFadeDurationTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("raster-opacity"): + if (name == "raster-opacity") { + property = Property::RasterOpacity; + } + break; + case util::hashFNV1a("raster-opacity-transition"): + if (name == "raster-opacity-transition") { + property = Property::RasterOpacityTransition; + } + break; + case util::hashFNV1a("raster-hue-rotate"): + if (name == "raster-hue-rotate") { + property = Property::RasterHueRotate; + } + break; + case util::hashFNV1a("raster-hue-rotate-transition"): + if (name == "raster-hue-rotate-transition") { + property = Property::RasterHueRotateTransition; + } + break; + case util::hashFNV1a("raster-brightness-min"): + if (name == "raster-brightness-min") { + property = Property::RasterBrightnessMin; + } + break; + case util::hashFNV1a("raster-brightness-min-transition"): + if (name == "raster-brightness-min-transition") { + property = Property::RasterBrightnessMinTransition; + } + break; + case util::hashFNV1a("raster-brightness-max"): + if (name == "raster-brightness-max") { + property = Property::RasterBrightnessMax; + } + break; + case util::hashFNV1a("raster-brightness-max-transition"): + if (name == "raster-brightness-max-transition") { + property = Property::RasterBrightnessMaxTransition; + } + break; + case util::hashFNV1a("raster-saturation"): + if (name == "raster-saturation") { + property = Property::RasterSaturation; + } + break; + case util::hashFNV1a("raster-saturation-transition"): + if (name == "raster-saturation-transition") { + property = Property::RasterSaturationTransition; + } + break; + case util::hashFNV1a("raster-contrast"): + if (name == "raster-contrast") { + property = Property::RasterContrast; + } + break; + case util::hashFNV1a("raster-contrast-transition"): + if (name == "raster-contrast-transition") { + property = Property::RasterContrastTransition; + } + break; + case util::hashFNV1a("raster-resampling"): + if (name == "raster-resampling") { + property = Property::RasterResampling; + } + break; + case util::hashFNV1a("raster-resampling-transition"): + if (name == "raster-resampling-transition") { + property = Property::RasterResamplingTransition; + } + break; + case util::hashFNV1a("raster-fade-duration"): + if (name == "raster-fade-duration") { + property = Property::RasterFadeDuration; + } + break; + case util::hashFNV1a("raster-fade-duration-transition"): + if (name == "raster-fade-duration-transition") { + property = Property::RasterFadeDurationTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::RasterOpacity || property == Property::RasterHueRotate || property == Property::RasterBrightnessMin || property == Property::RasterBrightnessMax || property == Property::RasterSaturation || property == Property::RasterContrast || property == Property::RasterFadeDuration) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::RasterOpacity) { + setRasterOpacity(*typedValue); + return nullopt; + } + + if (property == Property::RasterHueRotate) { + setRasterHueRotate(*typedValue); + return nullopt; + } + + if (property == Property::RasterBrightnessMin) { + setRasterBrightnessMin(*typedValue); + return nullopt; + } + + if (property == Property::RasterBrightnessMax) { + setRasterBrightnessMax(*typedValue); + return nullopt; + } + + if (property == Property::RasterSaturation) { + setRasterSaturation(*typedValue); + return nullopt; + } + + if (property == Property::RasterContrast) { + setRasterContrast(*typedValue); + return nullopt; + } + + if (property == Property::RasterFadeDuration) { + setRasterFadeDuration(*typedValue); + return nullopt; + } + + } + + if (property == Property::RasterResampling) { + Error error; + optional<PropertyValue<RasterResamplingType>> typedValue = convert<PropertyValue<RasterResamplingType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setRasterResampling(*typedValue); + return nullopt; + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::RasterOpacityTransition) { + setRasterOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::RasterHueRotateTransition) { + setRasterHueRotateTransition(*transition); + return nullopt; + } + + if (property == Property::RasterBrightnessMinTransition) { + setRasterBrightnessMinTransition(*transition); + return nullopt; + } + + if (property == Property::RasterBrightnessMaxTransition) { + setRasterBrightnessMaxTransition(*transition); + return nullopt; + } + + if (property == Property::RasterSaturationTransition) { + setRasterSaturationTransition(*transition); + return nullopt; + } + + if (property == Property::RasterContrastTransition) { + setRasterContrastTransition(*transition); + return nullopt; + } + + if (property == Property::RasterResamplingTransition) { + setRasterResamplingTransition(*transition); + return nullopt; + } + + if (property == Property::RasterFadeDurationTransition) { + setRasterFadeDurationTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> RasterLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer.cpp b/src/mbgl/style/layers/symbol_layer.cpp index c416c6a6c5..4ea138a7f5 100644 --- a/src/mbgl/style/layers/symbol_layer.cpp +++ b/src/mbgl/style/layers/symbol_layer.cpp @@ -3,6 +3,13 @@ #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> #include <mbgl/style/layer_observer.hpp> +#include <mbgl/style/conversion/color_ramp_property_value.hpp> +#include <mbgl/style/conversion/constant.hpp> +#include <mbgl/style/conversion/property_value.hpp> +#include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion/json.hpp> +#include <mbgl/style/conversion_impl.hpp> +#include <mbgl/util/fnv_hash.hpp> namespace mbgl { namespace style { @@ -1051,5 +1058,937 @@ TransitionOptions SymbolLayer::getTextTranslateAnchorTransition() const { return impl().paint.template get<TextTranslateAnchor>().options; } +using namespace conversion; + +optional<Error> SymbolLayer::setPaintProperty(const std::string& name, const Convertible& value) { + enum class Property { + Unknown, + IconOpacity, + IconColor, + IconHaloColor, + IconHaloWidth, + IconHaloBlur, + IconTranslate, + IconTranslateAnchor, + TextOpacity, + TextColor, + TextHaloColor, + TextHaloWidth, + TextHaloBlur, + TextTranslate, + TextTranslateAnchor, + IconOpacityTransition, + IconColorTransition, + IconHaloColorTransition, + IconHaloWidthTransition, + IconHaloBlurTransition, + IconTranslateTransition, + IconTranslateAnchorTransition, + TextOpacityTransition, + TextColorTransition, + TextHaloColorTransition, + TextHaloWidthTransition, + TextHaloBlurTransition, + TextTranslateTransition, + TextTranslateAnchorTransition, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + case util::hashFNV1a("icon-opacity"): + if (name == "icon-opacity") { + property = Property::IconOpacity; + } + break; + case util::hashFNV1a("icon-opacity-transition"): + if (name == "icon-opacity-transition") { + property = Property::IconOpacityTransition; + } + break; + case util::hashFNV1a("icon-color"): + if (name == "icon-color") { + property = Property::IconColor; + } + break; + case util::hashFNV1a("icon-color-transition"): + if (name == "icon-color-transition") { + property = Property::IconColorTransition; + } + break; + case util::hashFNV1a("icon-halo-color"): + if (name == "icon-halo-color") { + property = Property::IconHaloColor; + } + break; + case util::hashFNV1a("icon-halo-color-transition"): + if (name == "icon-halo-color-transition") { + property = Property::IconHaloColorTransition; + } + break; + case util::hashFNV1a("icon-halo-width"): + if (name == "icon-halo-width") { + property = Property::IconHaloWidth; + } + break; + case util::hashFNV1a("icon-halo-width-transition"): + if (name == "icon-halo-width-transition") { + property = Property::IconHaloWidthTransition; + } + break; + case util::hashFNV1a("icon-halo-blur"): + if (name == "icon-halo-blur") { + property = Property::IconHaloBlur; + } + break; + case util::hashFNV1a("icon-halo-blur-transition"): + if (name == "icon-halo-blur-transition") { + property = Property::IconHaloBlurTransition; + } + break; + case util::hashFNV1a("icon-translate"): + if (name == "icon-translate") { + property = Property::IconTranslate; + } + break; + case util::hashFNV1a("icon-translate-transition"): + if (name == "icon-translate-transition") { + property = Property::IconTranslateTransition; + } + break; + case util::hashFNV1a("icon-translate-anchor"): + if (name == "icon-translate-anchor") { + property = Property::IconTranslateAnchor; + } + break; + case util::hashFNV1a("icon-translate-anchor-transition"): + if (name == "icon-translate-anchor-transition") { + property = Property::IconTranslateAnchorTransition; + } + break; + case util::hashFNV1a("text-opacity"): + if (name == "text-opacity") { + property = Property::TextOpacity; + } + break; + case util::hashFNV1a("text-opacity-transition"): + if (name == "text-opacity-transition") { + property = Property::TextOpacityTransition; + } + break; + case util::hashFNV1a("text-color"): + if (name == "text-color") { + property = Property::TextColor; + } + break; + case util::hashFNV1a("text-color-transition"): + if (name == "text-color-transition") { + property = Property::TextColorTransition; + } + break; + case util::hashFNV1a("text-halo-color"): + if (name == "text-halo-color") { + property = Property::TextHaloColor; + } + break; + case util::hashFNV1a("text-halo-color-transition"): + if (name == "text-halo-color-transition") { + property = Property::TextHaloColorTransition; + } + break; + case util::hashFNV1a("text-halo-width"): + if (name == "text-halo-width") { + property = Property::TextHaloWidth; + } + break; + case util::hashFNV1a("text-halo-width-transition"): + if (name == "text-halo-width-transition") { + property = Property::TextHaloWidthTransition; + } + break; + case util::hashFNV1a("text-halo-blur"): + if (name == "text-halo-blur") { + property = Property::TextHaloBlur; + } + break; + case util::hashFNV1a("text-halo-blur-transition"): + if (name == "text-halo-blur-transition") { + property = Property::TextHaloBlurTransition; + } + break; + case util::hashFNV1a("text-translate"): + if (name == "text-translate") { + property = Property::TextTranslate; + } + break; + case util::hashFNV1a("text-translate-transition"): + if (name == "text-translate-transition") { + property = Property::TextTranslateTransition; + } + break; + case util::hashFNV1a("text-translate-anchor"): + if (name == "text-translate-anchor") { + property = Property::TextTranslateAnchor; + } + break; + case util::hashFNV1a("text-translate-anchor-transition"): + if (name == "text-translate-anchor-transition") { + property = Property::TextTranslateAnchorTransition; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::IconOpacity || property == Property::IconHaloWidth || property == Property::IconHaloBlur || property == Property::TextOpacity || property == Property::TextHaloWidth || property == Property::TextHaloBlur) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconOpacity) { + setIconOpacity(*typedValue); + return nullopt; + } + + if (property == Property::IconHaloWidth) { + setIconHaloWidth(*typedValue); + return nullopt; + } + + if (property == Property::IconHaloBlur) { + setIconHaloBlur(*typedValue); + return nullopt; + } + + if (property == Property::TextOpacity) { + setTextOpacity(*typedValue); + return nullopt; + } + + if (property == Property::TextHaloWidth) { + setTextHaloWidth(*typedValue); + return nullopt; + } + + if (property == Property::TextHaloBlur) { + setTextHaloBlur(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconColor || property == Property::IconHaloColor || property == Property::TextColor || property == Property::TextHaloColor) { + Error error; + optional<PropertyValue<Color>> typedValue = convert<PropertyValue<Color>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconColor) { + setIconColor(*typedValue); + return nullopt; + } + + if (property == Property::IconHaloColor) { + setIconHaloColor(*typedValue); + return nullopt; + } + + if (property == Property::TextColor) { + setTextColor(*typedValue); + return nullopt; + } + + if (property == Property::TextHaloColor) { + setTextHaloColor(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconTranslate || property == Property::TextTranslate) { + Error error; + optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconTranslate) { + setIconTranslate(*typedValue); + return nullopt; + } + + if (property == Property::TextTranslate) { + setTextTranslate(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconTranslateAnchor || property == Property::TextTranslateAnchor) { + Error error; + optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconTranslateAnchor) { + setIconTranslateAnchor(*typedValue); + return nullopt; + } + + if (property == Property::TextTranslateAnchor) { + setTextTranslateAnchor(*typedValue); + return nullopt; + } + + } + + + Error error; + optional<TransitionOptions> transition = convert<TransitionOptions>(value, error); + if (!transition) { + return error; + } + + if (property == Property::IconOpacityTransition) { + setIconOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::IconColorTransition) { + setIconColorTransition(*transition); + return nullopt; + } + + if (property == Property::IconHaloColorTransition) { + setIconHaloColorTransition(*transition); + return nullopt; + } + + if (property == Property::IconHaloWidthTransition) { + setIconHaloWidthTransition(*transition); + return nullopt; + } + + if (property == Property::IconHaloBlurTransition) { + setIconHaloBlurTransition(*transition); + return nullopt; + } + + if (property == Property::IconTranslateTransition) { + setIconTranslateTransition(*transition); + return nullopt; + } + + if (property == Property::IconTranslateAnchorTransition) { + setIconTranslateAnchorTransition(*transition); + return nullopt; + } + + if (property == Property::TextOpacityTransition) { + setTextOpacityTransition(*transition); + return nullopt; + } + + if (property == Property::TextColorTransition) { + setTextColorTransition(*transition); + return nullopt; + } + + if (property == Property::TextHaloColorTransition) { + setTextHaloColorTransition(*transition); + return nullopt; + } + + if (property == Property::TextHaloWidthTransition) { + setTextHaloWidthTransition(*transition); + return nullopt; + } + + if (property == Property::TextHaloBlurTransition) { + setTextHaloBlurTransition(*transition); + return nullopt; + } + + if (property == Property::TextTranslateTransition) { + setTextTranslateTransition(*transition); + return nullopt; + } + + if (property == Property::TextTranslateAnchorTransition) { + setTextTranslateAnchorTransition(*transition); + return nullopt; + } + + + return Error { "layer doesn't support this property" }; +} + +optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Convertible& value) { + if (name == "visibility") { + return Layer::setVisibility(value); + } + + enum class Property { + Unknown, + SymbolPlacement, + SymbolSpacing, + SymbolAvoidEdges, + IconAllowOverlap, + IconIgnorePlacement, + IconOptional, + IconRotationAlignment, + IconSize, + IconTextFit, + IconTextFitPadding, + IconImage, + IconRotate, + IconPadding, + IconKeepUpright, + IconOffset, + IconAnchor, + IconPitchAlignment, + TextPitchAlignment, + TextRotationAlignment, + TextField, + TextFont, + TextSize, + TextMaxWidth, + TextLineHeight, + TextLetterSpacing, + TextJustify, + TextAnchor, + TextMaxAngle, + TextRotate, + TextPadding, + TextKeepUpright, + TextTransform, + TextOffset, + TextAllowOverlap, + TextIgnorePlacement, + TextOptional, + }; + + Property property = Property::Unknown; + switch (util::hashFNV1a(name.c_str())) { + + case util::hashFNV1a("symbol-placement"): + if (name == "symbol-placement") { + property = Property::SymbolPlacement; + } + break; + + case util::hashFNV1a("symbol-spacing"): + if (name == "symbol-spacing") { + property = Property::SymbolSpacing; + } + break; + + case util::hashFNV1a("symbol-avoid-edges"): + if (name == "symbol-avoid-edges") { + property = Property::SymbolAvoidEdges; + } + break; + + case util::hashFNV1a("icon-allow-overlap"): + if (name == "icon-allow-overlap") { + property = Property::IconAllowOverlap; + } + break; + + case util::hashFNV1a("icon-ignore-placement"): + if (name == "icon-ignore-placement") { + property = Property::IconIgnorePlacement; + } + break; + + case util::hashFNV1a("icon-optional"): + if (name == "icon-optional") { + property = Property::IconOptional; + } + break; + + case util::hashFNV1a("icon-rotation-alignment"): + if (name == "icon-rotation-alignment") { + property = Property::IconRotationAlignment; + } + break; + + case util::hashFNV1a("icon-size"): + if (name == "icon-size") { + property = Property::IconSize; + } + break; + + case util::hashFNV1a("icon-text-fit"): + if (name == "icon-text-fit") { + property = Property::IconTextFit; + } + break; + + case util::hashFNV1a("icon-text-fit-padding"): + if (name == "icon-text-fit-padding") { + property = Property::IconTextFitPadding; + } + break; + + case util::hashFNV1a("icon-image"): + if (name == "icon-image") { + property = Property::IconImage; + } + break; + + case util::hashFNV1a("icon-rotate"): + if (name == "icon-rotate") { + property = Property::IconRotate; + } + break; + + case util::hashFNV1a("icon-padding"): + if (name == "icon-padding") { + property = Property::IconPadding; + } + break; + + case util::hashFNV1a("icon-keep-upright"): + if (name == "icon-keep-upright") { + property = Property::IconKeepUpright; + } + break; + + case util::hashFNV1a("icon-offset"): + if (name == "icon-offset") { + property = Property::IconOffset; + } + break; + + case util::hashFNV1a("icon-anchor"): + if (name == "icon-anchor") { + property = Property::IconAnchor; + } + break; + + case util::hashFNV1a("icon-pitch-alignment"): + if (name == "icon-pitch-alignment") { + property = Property::IconPitchAlignment; + } + break; + + case util::hashFNV1a("text-pitch-alignment"): + if (name == "text-pitch-alignment") { + property = Property::TextPitchAlignment; + } + break; + + case util::hashFNV1a("text-rotation-alignment"): + if (name == "text-rotation-alignment") { + property = Property::TextRotationAlignment; + } + break; + + case util::hashFNV1a("text-field"): + if (name == "text-field") { + property = Property::TextField; + } + break; + + case util::hashFNV1a("text-font"): + if (name == "text-font") { + property = Property::TextFont; + } + break; + + case util::hashFNV1a("text-size"): + if (name == "text-size") { + property = Property::TextSize; + } + break; + + case util::hashFNV1a("text-max-width"): + if (name == "text-max-width") { + property = Property::TextMaxWidth; + } + break; + + case util::hashFNV1a("text-line-height"): + if (name == "text-line-height") { + property = Property::TextLineHeight; + } + break; + + case util::hashFNV1a("text-letter-spacing"): + if (name == "text-letter-spacing") { + property = Property::TextLetterSpacing; + } + break; + + case util::hashFNV1a("text-justify"): + if (name == "text-justify") { + property = Property::TextJustify; + } + break; + + case util::hashFNV1a("text-anchor"): + if (name == "text-anchor") { + property = Property::TextAnchor; + } + break; + + case util::hashFNV1a("text-max-angle"): + if (name == "text-max-angle") { + property = Property::TextMaxAngle; + } + break; + + case util::hashFNV1a("text-rotate"): + if (name == "text-rotate") { + property = Property::TextRotate; + } + break; + + case util::hashFNV1a("text-padding"): + if (name == "text-padding") { + property = Property::TextPadding; + } + break; + + case util::hashFNV1a("text-keep-upright"): + if (name == "text-keep-upright") { + property = Property::TextKeepUpright; + } + break; + + case util::hashFNV1a("text-transform"): + if (name == "text-transform") { + property = Property::TextTransform; + } + break; + + case util::hashFNV1a("text-offset"): + if (name == "text-offset") { + property = Property::TextOffset; + } + break; + + case util::hashFNV1a("text-allow-overlap"): + if (name == "text-allow-overlap") { + property = Property::TextAllowOverlap; + } + break; + + case util::hashFNV1a("text-ignore-placement"): + if (name == "text-ignore-placement") { + property = Property::TextIgnorePlacement; + } + break; + + case util::hashFNV1a("text-optional"): + if (name == "text-optional") { + property = Property::TextOptional; + } + break; + + } + + if (property == Property::Unknown) { + return Error { "layer doesn't support this property" }; + } + + + if (property == Property::SymbolPlacement) { + Error error; + optional<PropertyValue<SymbolPlacementType>> typedValue = convert<PropertyValue<SymbolPlacementType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setSymbolPlacement(*typedValue); + return nullopt; + + } + + if (property == Property::SymbolSpacing || property == Property::IconPadding || property == Property::TextLineHeight || property == Property::TextMaxAngle || property == Property::TextPadding) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::SymbolSpacing) { + setSymbolSpacing(*typedValue); + return nullopt; + } + + if (property == Property::IconPadding) { + setIconPadding(*typedValue); + return nullopt; + } + + if (property == Property::TextLineHeight) { + setTextLineHeight(*typedValue); + return nullopt; + } + + if (property == Property::TextMaxAngle) { + setTextMaxAngle(*typedValue); + return nullopt; + } + + if (property == Property::TextPadding) { + setTextPadding(*typedValue); + return nullopt; + } + + } + + if (property == Property::SymbolAvoidEdges || property == Property::IconAllowOverlap || property == Property::IconIgnorePlacement || property == Property::IconOptional || property == Property::IconKeepUpright || property == Property::TextKeepUpright || property == Property::TextAllowOverlap || property == Property::TextIgnorePlacement || property == Property::TextOptional) { + Error error; + optional<PropertyValue<bool>> typedValue = convert<PropertyValue<bool>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::SymbolAvoidEdges) { + setSymbolAvoidEdges(*typedValue); + return nullopt; + } + + if (property == Property::IconAllowOverlap) { + setIconAllowOverlap(*typedValue); + return nullopt; + } + + if (property == Property::IconIgnorePlacement) { + setIconIgnorePlacement(*typedValue); + return nullopt; + } + + if (property == Property::IconOptional) { + setIconOptional(*typedValue); + return nullopt; + } + + if (property == Property::IconKeepUpright) { + setIconKeepUpright(*typedValue); + return nullopt; + } + + if (property == Property::TextKeepUpright) { + setTextKeepUpright(*typedValue); + return nullopt; + } + + if (property == Property::TextAllowOverlap) { + setTextAllowOverlap(*typedValue); + return nullopt; + } + + if (property == Property::TextIgnorePlacement) { + setTextIgnorePlacement(*typedValue); + return nullopt; + } + + if (property == Property::TextOptional) { + setTextOptional(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconRotationAlignment || property == Property::IconPitchAlignment || property == Property::TextPitchAlignment || property == Property::TextRotationAlignment) { + Error error; + optional<PropertyValue<AlignmentType>> typedValue = convert<PropertyValue<AlignmentType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconRotationAlignment) { + setIconRotationAlignment(*typedValue); + return nullopt; + } + + if (property == Property::IconPitchAlignment) { + setIconPitchAlignment(*typedValue); + return nullopt; + } + + if (property == Property::TextPitchAlignment) { + setTextPitchAlignment(*typedValue); + return nullopt; + } + + if (property == Property::TextRotationAlignment) { + setTextRotationAlignment(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconSize || property == Property::IconRotate || property == Property::TextSize || property == Property::TextMaxWidth || property == Property::TextLetterSpacing || property == Property::TextRotate) { + Error error; + optional<PropertyValue<float>> typedValue = convert<PropertyValue<float>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconSize) { + setIconSize(*typedValue); + return nullopt; + } + + if (property == Property::IconRotate) { + setIconRotate(*typedValue); + return nullopt; + } + + if (property == Property::TextSize) { + setTextSize(*typedValue); + return nullopt; + } + + if (property == Property::TextMaxWidth) { + setTextMaxWidth(*typedValue); + return nullopt; + } + + if (property == Property::TextLetterSpacing) { + setTextLetterSpacing(*typedValue); + return nullopt; + } + + if (property == Property::TextRotate) { + setTextRotate(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconTextFit) { + Error error; + optional<PropertyValue<IconTextFitType>> typedValue = convert<PropertyValue<IconTextFitType>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setIconTextFit(*typedValue); + return nullopt; + + } + + if (property == Property::IconTextFitPadding) { + Error error; + optional<PropertyValue<std::array<float, 4>>> typedValue = convert<PropertyValue<std::array<float, 4>>>(value, error, false, false); + if (!typedValue) { + return error; + } + + setIconTextFitPadding(*typedValue); + return nullopt; + + } + + if (property == Property::IconImage || property == Property::TextField) { + Error error; + optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, true); + if (!typedValue) { + return error; + } + + if (property == Property::IconImage) { + setIconImage(*typedValue); + return nullopt; + } + + if (property == Property::TextField) { + setTextField(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconOffset || property == Property::TextOffset) { + Error error; + optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconOffset) { + setIconOffset(*typedValue); + return nullopt; + } + + if (property == Property::TextOffset) { + setTextOffset(*typedValue); + return nullopt; + } + + } + + if (property == Property::IconAnchor || property == Property::TextAnchor) { + Error error; + optional<PropertyValue<SymbolAnchorType>> typedValue = convert<PropertyValue<SymbolAnchorType>>(value, error, true, false); + if (!typedValue) { + return error; + } + + if (property == Property::IconAnchor) { + setIconAnchor(*typedValue); + return nullopt; + } + + if (property == Property::TextAnchor) { + setTextAnchor(*typedValue); + return nullopt; + } + + } + + if (property == Property::TextFont) { + Error error; + optional<PropertyValue<std::vector<std::string>>> typedValue = convert<PropertyValue<std::vector<std::string>>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setTextFont(*typedValue); + return nullopt; + + } + + if (property == Property::TextJustify) { + Error error; + optional<PropertyValue<TextJustifyType>> typedValue = convert<PropertyValue<TextJustifyType>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setTextJustify(*typedValue); + return nullopt; + + } + + if (property == Property::TextTransform) { + Error error; + optional<PropertyValue<TextTransformType>> typedValue = convert<PropertyValue<TextTransformType>>(value, error, true, false); + if (!typedValue) { + return error; + } + + setTextTransform(*typedValue); + return nullopt; + + } + + + return Error { "layer doesn't support this property" }; +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/layers/symbol_layer_impl.cpp b/src/mbgl/style/layers/symbol_layer_impl.cpp index b59768725d..753b2fa184 100644 --- a/src/mbgl/style/layers/symbol_layer_impl.cpp +++ b/src/mbgl/style/layers/symbol_layer_impl.cpp @@ -4,7 +4,7 @@ namespace mbgl { namespace style { bool SymbolLayer::Impl::hasLayoutDifference(const Layer::Impl& other) const { - assert(dynamic_cast<const SymbolLayer::Impl*>(&other)); + assert(other.type == LayerType::Symbol); const auto& impl = static_cast<const style::SymbolLayer::Impl&>(other); return filter != impl.filter || visibility != impl.visibility || diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp index 8d14d7972c..114a666f08 100644 --- a/src/mbgl/style/parser.cpp +++ b/src/mbgl/style/parser.cpp @@ -1,13 +1,12 @@ #include <mbgl/style/parser.hpp> #include <mbgl/style/layer_impl.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/rapidjson_conversion.hpp> -#include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/coordinate.hpp> #include <mbgl/style/conversion/source.hpp> #include <mbgl/style/conversion/layer.hpp> #include <mbgl/style/conversion/light.hpp> #include <mbgl/style/conversion/transition_options.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/util/string.hpp> @@ -274,31 +273,12 @@ void Parser::parseLayer(const std::string& id, const JSValue& value, std::unique } std::vector<FontStack> Parser::fontStacks() const { - std::set<FontStack> result; - + std::vector<Immutable<Layer::Impl>> impls; + impls.reserve(layers.size()); for (const auto& layer : layers) { - if (layer->is<SymbolLayer>() && !layer->as<SymbolLayer>()->getTextField().isUndefined()) { - layer->as<SymbolLayer>()->getTextFont().match( - [&] (Undefined) { - result.insert({"Open Sans Regular", "Arial Unicode MS Regular"}); - }, - [&] (const FontStack& constant) { - result.insert(constant); - }, - [&] (const auto& function) { - for (const auto& value : function.possibleOutputs()) { - if (value) { - result.insert(*value); - } else { - Log::Warning(Event::ParseStyle, "Layer '%s' has an invalid value for text-font and will not work offline. Output values must be contained as literals within the expression.", layer->getID().c_str()); - break; - } - } - } - ); - } + impls.emplace_back(layer->baseImpl); } - + std::set<FontStack> result = mbgl::fontStacks(impls); return std::vector<FontStack>(result.begin(), result.end()); } diff --git a/src/mbgl/style/rapidjson_conversion.hpp b/src/mbgl/style/rapidjson_conversion.hpp index 79bd9c928b..be335101e9 100644 --- a/src/mbgl/style/rapidjson_conversion.hpp +++ b/src/mbgl/style/rapidjson_conversion.hpp @@ -1,7 +1,7 @@ #pragma once #include <mbgl/util/rapidjson.hpp> -#include <mbgl/style/conversion.hpp> +#include <mbgl/style/conversion_impl.hpp> #include <mapbox/geojson.hpp> #include <mapbox/geojson/rapidjson.hpp> diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp index fd6d7d3013..5ec3909d3e 100644 --- a/src/mbgl/style/sources/geojson_source_impl.cpp +++ b/src/mbgl/style/sources/geojson_source_impl.cpp @@ -64,6 +64,7 @@ GeoJSONSource::Impl::Impl(const Impl& other, const GeoJSON& geoJSON) vtOptions.extent = util::EXTENT; vtOptions.buffer = ::round(scale * options.buffer); vtOptions.tolerance = scale * options.tolerance; + vtOptions.lineMetrics = options.lineMetrics; data = std::make_unique<GeoJSONVTData>(geoJSON, vtOptions); } } diff --git a/src/mbgl/text/collision_index.cpp b/src/mbgl/text/collision_index.cpp index 091840a371..dae789a196 100644 --- a/src/mbgl/text/collision_index.cpp +++ b/src/mbgl/text/collision_index.cpp @@ -62,6 +62,21 @@ bool CollisionIndex::isOffscreen(const CollisionBox& box) const { bool CollisionIndex::isInsideGrid(const CollisionBox& box) const { return box.px2 >= 0 && box.px1 < gridRightBoundary && box.py2 >= 0 && box.py1 < gridBottomBoundary; } + +CollisionTileBoundaries CollisionIndex::projectTileBoundaries(const mat4& posMatrix) const { + Point<float> topLeft = projectPoint(posMatrix, { 0, 0 }); + Point<float> bottomRight = projectPoint(posMatrix, { util::EXTENT, util::EXTENT }); + + return {{ topLeft.x, topLeft.y, bottomRight.x, bottomRight.y }}; + +} + +bool CollisionIndex::isInsideTile(const CollisionBox& box, const CollisionTileBoundaries& tileBoundaries) const { + // This check is only well defined when the tile boundaries are axis-aligned + // We are relying on it only being used in MapMode::Tile, where that is always the case + + return box.px1 >= tileBoundaries[0] && box.py1 >= tileBoundaries[1] && box.px2 < tileBoundaries[2] && box.py2 < tileBoundaries[3]; +} std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature, @@ -73,7 +88,8 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature, const float fontSize, const bool allowOverlap, const bool pitchWithMap, - const bool collisionDebug) { + const bool collisionDebug, + const optional<CollisionTileBoundaries>& avoidEdges) { if (!feature.alongLine) { CollisionBox& box = feature.boxes.front(); const auto projectedPoint = projectAndGetPerspectiveRatio(posMatrix, box.anchor); @@ -82,15 +98,17 @@ std::pair<bool,bool> CollisionIndex::placeFeature(CollisionFeature& feature, box.py1 = box.y1 * tileToViewport + projectedPoint.first.y; box.px2 = box.x2 * tileToViewport + projectedPoint.first.x; box.py2 = box.y2 * tileToViewport + projectedPoint.first.y; + - if (!isInsideGrid(box) || + if ((avoidEdges && !isInsideTile(box, *avoidEdges)) || + !isInsideGrid(box) || (!allowOverlap && collisionGrid.hitTest({{ box.px1, box.py1 }, { box.px2, box.py2 }}))) { return { false, false }; } return {true, isOffscreen(box)}; } else { - return placeLineFeature(feature, posMatrix, labelPlaneMatrix, textPixelRatio, symbol, scale, fontSize, allowOverlap, pitchWithMap, collisionDebug); + return placeLineFeature(feature, posMatrix, labelPlaneMatrix, textPixelRatio, symbol, scale, fontSize, allowOverlap, pitchWithMap, collisionDebug, avoidEdges); } } @@ -103,7 +121,8 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature, const float fontSize, const bool allowOverlap, const bool pitchWithMap, - const bool collisionDebug) { + const bool collisionDebug, + const optional<CollisionTileBoundaries>& avoidEdges) { const auto tileUnitAnchorPoint = symbol.anchorPoint; const auto projectedAnchor = projectAnchor(posMatrix, tileUnitAnchorPoint); @@ -202,15 +221,14 @@ std::pair<bool,bool> CollisionIndex::placeLineFeature(CollisionFeature& feature, entirelyOffscreen &= isOffscreen(circle); inGrid |= isInsideGrid(circle); - if (!allowOverlap) { - if (collisionGrid.hitTest({{circle.px, circle.py}, circle.radius})) { - if (!collisionDebug) { - return {false, false}; - } else { - // Don't early exit if we're showing the debug circles because we still want to calculate - // which circles are in use - collisionDetected = true; - } + if ((avoidEdges && !isInsideTile(circle, *avoidEdges)) || + (!allowOverlap && collisionGrid.hitTest({{circle.px, circle.py}, circle.radius}))) { + if (!collisionDebug) { + return {false, false}; + } else { + // Don't early exit if we're showing the debug circles because we still want to calculate + // which circles are in use + collisionDetected = true; } } } diff --git a/src/mbgl/text/collision_index.hpp b/src/mbgl/text/collision_index.hpp index b2be4c6ade..78782fe61c 100644 --- a/src/mbgl/text/collision_index.hpp +++ b/src/mbgl/text/collision_index.hpp @@ -3,13 +3,18 @@ #include <mbgl/geometry/feature_index.hpp> #include <mbgl/text/collision_feature.hpp> #include <mbgl/util/grid_index.hpp> +#include <mbgl/util/optional.hpp> #include <mbgl/map/transform_state.hpp> +#include <array> + namespace mbgl { class PlacedSymbol; struct TileDistance; + +using CollisionTileBoundaries = std::array<float,4>; class CollisionIndex { public: @@ -26,15 +31,19 @@ public: const float fontSize, const bool allowOverlap, const bool pitchWithMap, - const bool collisionDebug); + const bool collisionDebug, + const optional<CollisionTileBoundaries>& avoidEdges); void insertFeature(CollisionFeature& feature, bool ignorePlacement, uint32_t bucketInstanceId); std::unordered_map<uint32_t, std::vector<IndexedSubfeature>> queryRenderedSymbols(const ScreenLineString&) const; + + CollisionTileBoundaries projectTileBoundaries(const mat4& posMatrix) const; private: bool isOffscreen(const CollisionBox&) const; bool isInsideGrid(const CollisionBox&) const; + bool isInsideTile(const CollisionBox&, const CollisionTileBoundaries& tileBoundaries) const; std::pair<bool,bool> placeLineFeature(CollisionFeature& feature, const mat4& posMatrix, @@ -45,7 +54,8 @@ private: const float fontSize, const bool allowOverlap, const bool pitchWithMap, - const bool collisionDebug); + const bool collisionDebug, + const optional<CollisionTileBoundaries>& avoidEdges); float approximateTileDistance(const TileDistance& tileDistance, const float lastSegmentAngle, const float pixelsToTileUnits, const float cameraToAnchorDistance, const bool pitchWithMap); diff --git a/src/mbgl/text/glyph_manager.cpp b/src/mbgl/text/glyph_manager.cpp index 3130418908..8e7cfe5ba7 100644 --- a/src/mbgl/text/glyph_manager.cpp +++ b/src/mbgl/text/glyph_manager.cpp @@ -5,6 +5,7 @@ #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> #include <mbgl/util/tiny_sdf.hpp> +#include <mbgl/util/std.hpp> namespace mbgl { @@ -153,4 +154,10 @@ void GlyphManager::removeRequestor(GlyphRequestor& requestor) { } } +void GlyphManager::evict(const std::set<FontStack>& keep) { + util::erase_if(entries, [&] (const auto& entry) { + return keep.count(entry.first) == 0; + }); +} + } // namespace mbgl diff --git a/src/mbgl/text/glyph_manager.hpp b/src/mbgl/text/glyph_manager.hpp index 84db2c4be5..642471bbf2 100644 --- a/src/mbgl/text/glyph_manager.hpp +++ b/src/mbgl/text/glyph_manager.hpp @@ -42,6 +42,9 @@ public: void setObserver(GlyphManagerObserver*); + // Remove glyphs for all but the supplied font stacks. + void evict(const std::set<FontStack>&); + private: Glyph generateLocalSDF(const FontStack& fontStack, GlyphID glyphID); diff --git a/src/mbgl/text/placement.cpp b/src/mbgl/text/placement.cpp index 16dd94b374..0747133bd2 100644 --- a/src/mbgl/text/placement.cpp +++ b/src/mbgl/text/placement.cpp @@ -48,7 +48,7 @@ void Placement::placeLayer(RenderSymbolLayer& symbolLayer, const mat4& projMatri if (!renderTile.tile.isRenderable()) { continue; } - assert(dynamic_cast<GeometryTile*>(&renderTile.tile)); + assert(renderTile.tile.kind == Tile::Kind::Geometry); GeometryTile& geometryTile = static_cast<GeometryTile&>(renderTile.tile); auto bucket = renderTile.tile.getBucket<SymbolBucket>(*symbolLayer.baseImpl); @@ -110,6 +110,13 @@ void Placement::placeLayerBucket( auto partiallyEvaluatedTextSize = bucket.textSizeBinder->evaluateForZoom(state.getZoom()); auto partiallyEvaluatedIconSize = bucket.iconSizeBinder->evaluateForZoom(state.getZoom()); + optional<CollisionTileBoundaries> avoidEdges; + if (mapMode == MapMode::Tile && + (bucket.layout.get<style::SymbolAvoidEdges>() || + bucket.layout.get<style::SymbolPlacement>() == style::SymbolPlacementType::Line)) { + avoidEdges = collisionIndex.projectTileBoundaries(posMatrix); + } + for (auto& symbolInstance : bucket.symbolInstances) { if (seenCrossTileIDs.count(symbolInstance.crossTileID) == 0) { @@ -133,7 +140,7 @@ void Placement::placeLayerBucket( placedSymbol, scale, fontSize, bucket.layout.get<style::TextAllowOverlap>(), bucket.layout.get<style::TextPitchAlignment>() == style::AlignmentType::Map, - showCollisionBoxes); + showCollisionBoxes, avoidEdges); placeText = placed.first; offscreen &= placed.second; } @@ -147,7 +154,7 @@ void Placement::placeLayerBucket( placedSymbol, scale, fontSize, bucket.layout.get<style::IconAllowOverlap>(), bucket.layout.get<style::IconPitchAlignment>() == style::AlignmentType::Map, - showCollisionBoxes); + showCollisionBoxes, avoidEdges); placeIcon = placed.first; offscreen &= placed.second; } @@ -254,9 +261,16 @@ void Placement::updateBucketOpacities(SymbolBucket& bucket, std::set<uint32_t>& JointOpacityState duplicateOpacityState(false, false, true); + const bool textAllowOverlap = bucket.layout.get<style::TextAllowOverlap>(); + const bool iconAllowOverlap = bucket.layout.get<style::IconAllowOverlap>(); + + // If allow-overlap is true, we can show symbols before placement runs on them + // But we have to wait for placement if we potentially depend on a paired icon/text + // with allow-overlap: false. + // See https://github.com/mapbox/mapbox-gl-native/issues/12483 JointOpacityState defaultOpacityState( - bucket.layout.get<style::TextAllowOverlap>(), - bucket.layout.get<style::IconAllowOverlap>(), + textAllowOverlap && (iconAllowOverlap || !bucket.hasIconData() || bucket.layout.get<style::IconOptional>()), + iconAllowOverlap && (textAllowOverlap || !bucket.hasTextData() || bucket.layout.get<style::TextOptional>()), true); for (SymbolInstance& symbolInstance : bucket.symbolInstances) { diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index d686d8440b..90d4d07895 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -44,7 +44,7 @@ using namespace style; GeometryTile::GeometryTile(const OverscaledTileID& id_, std::string sourceID_, const TileParameters& parameters) - : Tile(id_), + : Tile(Kind::Geometry, id_), sourceID(std::move(sourceID_)), mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())), worker(parameters.workerScheduler, diff --git a/src/mbgl/tile/raster_dem_tile.cpp b/src/mbgl/tile/raster_dem_tile.cpp index f29861ee71..751f69bad9 100644 --- a/src/mbgl/tile/raster_dem_tile.cpp +++ b/src/mbgl/tile/raster_dem_tile.cpp @@ -15,7 +15,7 @@ namespace mbgl { RasterDEMTile::RasterDEMTile(const OverscaledTileID& id_, const TileParameters& parameters, const Tileset& tileset) - : Tile(id_), + : Tile(Kind::RasterDEM, id_), loader(*this, id_, parameters, tileset), mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())), worker(parameters.workerScheduler, diff --git a/src/mbgl/tile/raster_tile.cpp b/src/mbgl/tile/raster_tile.cpp index cc71c04ba1..1346f87ae5 100644 --- a/src/mbgl/tile/raster_tile.cpp +++ b/src/mbgl/tile/raster_tile.cpp @@ -15,7 +15,7 @@ namespace mbgl { RasterTile::RasterTile(const OverscaledTileID& id_, const TileParameters& parameters, const Tileset& tileset) - : Tile(id_), + : Tile(Kind::Raster, id_), loader(*this, id_, parameters, tileset), mailbox(std::make_shared<Mailbox>(*Scheduler::GetCurrent())), worker(parameters.workerScheduler, diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp index b95944f10e..5a69df5b43 100644 --- a/src/mbgl/tile/tile.cpp +++ b/src/mbgl/tile/tile.cpp @@ -9,7 +9,7 @@ namespace mbgl { static TileObserver nullObserver; -Tile::Tile(OverscaledTileID id_) : id(std::move(id_)), observer(&nullObserver) { +Tile::Tile(Kind kind_, OverscaledTileID id_) : kind(kind_), id(std::move(id_)), observer(&nullObserver) { } Tile::~Tile() = default; @@ -27,6 +27,14 @@ void Tile::setTriedCache() { } void Tile::dumpDebugLogs() const { + std::string kindString; + switch (kind) { + case Kind::Geometry: kindString = "Geometry"; break; + case Kind::Raster: kindString = "Raster"; break; + case Kind::RasterDEM: kindString = "RasterDEM"; break; + default: kindString = "Unknown"; break; + } + Log::Info(Event::General, "Tile::Kind: %s", kindString.c_str()); Log::Info(Event::General, "Tile::id: %s", util::toString(id).c_str()); Log::Info(Event::General, "Tile::renderable: %s", isRenderable() ? "yes" : "no"); Log::Info(Event::General, "Tile::complete: %s", isComplete() ? "yes" : "no"); diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 5cf74abff5..70b2aa0371 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -35,7 +35,13 @@ class Context; class Tile : private util::noncopyable { public: - Tile(OverscaledTileID); + enum class Kind : uint8_t { + Geometry, + Raster, + RasterDEM + }; + + Tile(Kind, OverscaledTileID); virtual ~Tile(); void setObserver(TileObserver* observer); @@ -119,6 +125,7 @@ public: void dumpDebugLogs() const; + const Kind kind; OverscaledTileID id; optional<Timestamp> modified; optional<Timestamp> expires; diff --git a/src/mbgl/util/fnv_hash.hpp b/src/mbgl/util/fnv_hash.hpp new file mode 100644 index 0000000000..87d4661c56 --- /dev/null +++ b/src/mbgl/util/fnv_hash.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace mbgl { +namespace util { + +inline constexpr uint64_t hashFNV1a(const char * str, uint64_t value = 0xcbf29ce484222325) { + return str[0] ? hashFNV1a(str + 1, (value ^ uint64_t(str[0])) * 0x100000001b3) : value; +} + +} // end namespace util +} // end namespace mbgl diff --git a/src/mbgl/util/font_stack.cpp b/src/mbgl/util/font_stack.cpp index fb3b1b60a2..177d5e6f31 100644 --- a/src/mbgl/util/font_stack.cpp +++ b/src/mbgl/util/font_stack.cpp @@ -1,10 +1,14 @@ #include <mbgl/util/font_stack.hpp> +#include <mbgl/util/logging.hpp> +#include <mbgl/style/layers/symbol_layer_impl.hpp> #include <boost/functional/hash.hpp> #include <boost/algorithm/string/join.hpp> namespace mbgl { +using namespace style; + std::string fontStackToString(const FontStack& fontStack) { return boost::algorithm::join(fontStack, ","); } @@ -13,4 +17,40 @@ std::size_t FontStackHash::operator()(const FontStack& fontStack) const { return boost::hash_range(fontStack.begin(), fontStack.end()); } +std::set<FontStack> fontStacks(const std::vector<Immutable<style::Layer::Impl>>& layers) { + std::set<FontStack> result; + + for (const auto& layer : layers) { + if (layer->type != LayerType::Symbol) { + continue; + } + + const SymbolLayer::Impl& impl = dynamic_cast<const SymbolLayer::Impl&>(*layer); + if (impl.layout.get<TextField>().isUndefined()) { + continue; + } + + impl.layout.get<TextFont>().match( + [&] (Undefined) { + result.insert({"Open Sans Regular", "Arial Unicode MS Regular"}); + }, + [&] (const FontStack& constant) { + result.insert(constant); + }, + [&] (const auto& function) { + for (const auto& value : function.possibleOutputs()) { + if (value) { + result.insert(*value); + } else { + Log::Warning(Event::ParseStyle, "Layer '%s' has an invalid value for text-font and will not render text. Output values must be contained as literals within the expression.", impl.id.c_str()); + break; + } + } + } + ); + } + + return result; +} + } // namespace mbgl diff --git a/src/mbgl/util/logging.cpp b/src/mbgl/util/logging.cpp index d322bd3670..fd3f14825d 100644 --- a/src/mbgl/util/logging.cpp +++ b/src/mbgl/util/logging.cpp @@ -35,7 +35,7 @@ void Log::record(EventSeverity severity, Event event, const char* format, ...) { vsnprintf(msg, sizeof(msg), format, args); va_end(args); - record(severity, event, -1, msg); + record(severity, event, -1, std::string{ msg }); } void Log::record(EventSeverity severity, Event event, int64_t code, const char* format, ...) { diff --git a/src/mbgl/util/tile_cover.cpp b/src/mbgl/util/tile_cover.cpp index 3f39e53d40..f58d1270bd 100644 --- a/src/mbgl/util/tile_cover.cpp +++ b/src/mbgl/util/tile_cover.cpp @@ -4,6 +4,7 @@ #include <mbgl/map/transform_state.hpp> #include <mbgl/util/tile_cover_impl.hpp> #include <mbgl/util/tile_coordinate.hpp> +#include <mbgl/math/log2.hpp> #include <functional> #include <list> |