[core] Implement image expression (#15877)
* [core] Bump gl-js version * [core] Implement image expression * [core] Use new image expression * [core] Coerce image expression to / from string * [core] Serialize evaluated image * [core] Pass available images to layout * [core] Pass images to evaluation context * [core] Set available flag value based on image availability * [core] Allow image coercion to boolean to indicate image availability * [core] Coalesce image expression * [core] Add image expression to next build system * [core] Align serialization format and evaluated type with gl-js * [core] Add images to expression evaluation method * [core] Add support for Image expression to expression test runner * [core] Unskip image expression tests * [core] Update unit tests * [core] Use image expression in annotation manager * [core] Add string to ImageExpression conversion * [core] Add image expression to expression dsl * [core] Convert tokens for implicitly created Image literal * [core] Fix clang format * [core] Split generated style code lines that are over 120 characters * [core] Add unit test for image expression equality * [core] Add image property expression evaluation unit test * [core] Unskip image expression render test * [core] Skip 'in' expression tests * [core] Ignore fill-pattern/update-feature-state render test * [core] Rename Image::serialize to Image::toValue
This commit is contained in:
@@ -104,8 +104,7 @@ optional<Value> toValue(const JSValue& jsvalue) {
|
||||
|
||||
style::expression::type::Type stringToType(const std::string& type) {
|
||||
using namespace style::expression;
|
||||
if (type == "string"s || type == "number-format"s ||
|
||||
type == "image"s) { // TODO: replace once we implement image expressions
|
||||
if (type == "string"s || type == "number-format"s) {
|
||||
return type::String;
|
||||
} else if (type == "number"s) {
|
||||
return type::Number;
|
||||
@@ -119,6 +118,8 @@ style::expression::type::Type stringToType(const std::string& type) {
|
||||
return type::Value;
|
||||
} else if (type == "formatted"s) {
|
||||
return type::Formatted;
|
||||
} else if (type == "resolvedImage"s) {
|
||||
return type::Image;
|
||||
}
|
||||
|
||||
// Should not reach.
|
||||
@@ -253,6 +254,16 @@ bool parseInputs(const JSValue& inputsValue, TestData& data) {
|
||||
heatmapDensity = evaluationContext["heatmapDensity"].GetDouble();
|
||||
}
|
||||
|
||||
// Parse availableImages
|
||||
std::set<std::string> availableImages;
|
||||
if (evaluationContext.HasMember("availableImages")) {
|
||||
assert(evaluationContext["availableImages"].IsArray());
|
||||
for (const auto& image : evaluationContext["availableImages"].GetArray()) {
|
||||
assert(image.IsString());
|
||||
availableImages.emplace(toString(image));
|
||||
}
|
||||
}
|
||||
|
||||
// Parse feature properties
|
||||
Feature feature(mapbox::geometry::point<double>(0.0, 0.0));
|
||||
const auto& featureObject = input[1].GetObject();
|
||||
@@ -271,7 +282,8 @@ bool parseInputs(const JSValue& inputsValue, TestData& data) {
|
||||
feature.id = mapbox::geojson::convert<mapbox::feature::identifier>(featureObject["id"]);
|
||||
}
|
||||
|
||||
data.inputs.emplace_back(std::move(zoom), std::move(heatmapDensity), std::move(feature));
|
||||
data.inputs.emplace_back(
|
||||
std::move(zoom), std::move(heatmapDensity), std::move(availableImages), std::move(feature));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -7,18 +7,24 @@
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace mbgl;
|
||||
|
||||
struct Input {
|
||||
Input(optional<float> zoom_, optional<double> heatmapDensity_, Feature feature_)
|
||||
Input(optional<float> zoom_,
|
||||
optional<double> heatmapDensity_,
|
||||
std::set<std::string> availableImages_,
|
||||
Feature feature_)
|
||||
: zoom(std::move(zoom_)),
|
||||
heatmapDensity(std::move(heatmapDensity_)),
|
||||
availableImages(std::move(availableImages_)),
|
||||
feature(std::move(feature_)) {}
|
||||
optional<float> zoom;
|
||||
optional<double> heatmapDensity;
|
||||
std::set<std::string> availableImages;
|
||||
Feature feature;
|
||||
};
|
||||
|
||||
|
||||
@@ -104,7 +104,8 @@ TestRunOutput runExpressionTest(TestData& data, const std::string& rootPath, con
|
||||
std::vector<Value> outputs;
|
||||
if (!data.inputs.empty()) {
|
||||
for (const auto& input : data.inputs) {
|
||||
auto evaluationResult = expression->evaluate(input.zoom, input.feature, input.heatmapDensity);
|
||||
auto evaluationResult =
|
||||
expression->evaluate(input.zoom, input.feature, input.heatmapDensity, input.availableImages);
|
||||
if (!evaluationResult) {
|
||||
std::unordered_map<std::string, Value> error{{"error", Value{evaluationResult.error().message}}};
|
||||
outputs.emplace_back(Value{std::move(error)});
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace conversion {
|
||||
|
||||
bool hasTokens(const std::string&);
|
||||
std::unique_ptr<expression::Expression> convertTokenStringToFormatExpression(const std::string&);
|
||||
std::unique_ptr<expression::Expression> convertTokenStringToImageExpression(const std::string&);
|
||||
std::unique_ptr<expression::Expression> convertTokenStringToExpression(const std::string&);
|
||||
|
||||
optional<std::unique_ptr<expression::Expression>> convertFunctionToExpression(expression::type::Type, const Convertible&, Error&, bool convertTokens);
|
||||
|
||||
@@ -39,6 +39,12 @@ struct Converter<PropertyValue<T>> {
|
||||
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToFormatExpression(firstUnformattedSection)))
|
||||
: PropertyValue<T>(t);
|
||||
}
|
||||
|
||||
PropertyValue<T> maybeConvertTokens(const expression::Image& image) const {
|
||||
return hasTokens(image.id())
|
||||
? PropertyValue<T>(PropertyExpression<T>(convertTokenStringToImageExpression(image.id())))
|
||||
: PropertyValue<T>(image);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/color_ramp_property_value.hpp>
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
#include <mbgl/style/property_value.hpp>
|
||||
#include <mbgl/style/transition_options.hpp>
|
||||
|
||||
@@ -49,6 +49,7 @@ std::unique_ptr<Expression> toString(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> toFormatted(std::unique_ptr<Expression>,
|
||||
std::unique_ptr<Expression> def = nullptr);
|
||||
std::unique_ptr<Expression> toImage(std::unique_ptr<Expression>, std::unique_ptr<Expression> def = nullptr);
|
||||
|
||||
std::unique_ptr<Expression> get(const char* value);
|
||||
std::unique_ptr<Expression> get(std::unique_ptr<Expression>);
|
||||
@@ -89,6 +90,9 @@ std::unique_ptr<Expression> concat(std::vector<std::unique_ptr<Expression>> inpu
|
||||
std::unique_ptr<Expression> format(const char* value);
|
||||
std::unique_ptr<Expression> format(std::unique_ptr<Expression>);
|
||||
|
||||
std::unique_ptr<Expression> image(const char* value);
|
||||
std::unique_ptr<Expression> image(std::unique_ptr<Expression>);
|
||||
|
||||
} // namespace dsl
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
|
||||
@@ -28,9 +28,7 @@ public:
|
||||
EvaluationContext() = default;
|
||||
explicit EvaluationContext(float zoom_) : zoom(zoom_) {}
|
||||
explicit EvaluationContext(GeometryTileFeature const * feature_) : feature(feature_) {}
|
||||
EvaluationContext(float zoom_, GeometryTileFeature const * feature_) :
|
||||
zoom(zoom_), feature(feature_)
|
||||
{}
|
||||
EvaluationContext(float zoom_, GeometryTileFeature const* feature_) : zoom(zoom_), feature(feature_) {}
|
||||
EvaluationContext(optional<mbgl::Value> accumulated_, GeometryTileFeature const * feature_) :
|
||||
accumulated(std::move(accumulated_)), feature(feature_)
|
||||
{}
|
||||
@@ -50,6 +48,11 @@ public:
|
||||
return *this;
|
||||
};
|
||||
|
||||
EvaluationContext& withAvailableImages(const std::set<std::string>* availableImages_) noexcept {
|
||||
availableImages = availableImages_;
|
||||
return *this;
|
||||
};
|
||||
|
||||
optional<float> zoom;
|
||||
optional<mbgl::Value> accumulated;
|
||||
GeometryTileFeature const * feature = nullptr;
|
||||
@@ -57,6 +60,7 @@ public:
|
||||
// Contains formatted section object, std::unordered_map<std::string, Value>.
|
||||
const Value* formattedSection = nullptr;
|
||||
const FeatureState* featureState = nullptr;
|
||||
const std::set<std::string>* availableImages = nullptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -155,7 +159,8 @@ enum class Kind : int32_t {
|
||||
Comparison,
|
||||
FormatExpression,
|
||||
FormatSectionOverride,
|
||||
NumberFormat
|
||||
NumberFormat,
|
||||
ImageExpression
|
||||
};
|
||||
|
||||
class Expression {
|
||||
@@ -172,9 +177,14 @@ public:
|
||||
|
||||
Kind getKind() const { return kind; };
|
||||
type::Type getType() const { return type; };
|
||||
|
||||
|
||||
EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> colorRampParameter) const;
|
||||
EvaluationResult evaluate(optional<float> zoom,
|
||||
const Feature& feature,
|
||||
optional<double> colorRampParameter,
|
||||
const std::set<std::string>& availableImages) const;
|
||||
EvaluationResult evaluate(optional<mbgl::Value> accumulated, const Feature& feature) const;
|
||||
|
||||
/**
|
||||
* Statically analyze the expression, attempting to enumerate possible outputs. Returns
|
||||
* an array of values plus the sentinel null optional value, used to indicate that the
|
||||
|
||||
@@ -36,7 +36,7 @@ struct FormattedSection {
|
||||
class Formatted {
|
||||
public:
|
||||
Formatted() = default;
|
||||
|
||||
|
||||
Formatted(const char* plainU8String) {
|
||||
sections.emplace_back(std::string(plainU8String), nullopt, nullopt, nullopt);
|
||||
}
|
||||
|
||||
49
include/mbgl/style/expression/image.hpp
Normal file
49
include/mbgl/style/expression/image.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/conversion.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class Image {
|
||||
public:
|
||||
Image() = default;
|
||||
Image(const char* imageID);
|
||||
Image(std::string imageID);
|
||||
explicit Image(std::string imageID, bool available);
|
||||
bool operator==(const Image&) const;
|
||||
mbgl::Value toValue() const;
|
||||
const std::string& id() const;
|
||||
bool isAvailable() const;
|
||||
bool empty() const;
|
||||
|
||||
private:
|
||||
std::string imageID;
|
||||
bool available;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
|
||||
namespace conversion {
|
||||
|
||||
template <>
|
||||
struct Converter<expression::Image> {
|
||||
public:
|
||||
optional<expression::Image> operator()(const Convertible& value, Error& error) const;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ValueFactory<expression::Image> {
|
||||
static Value make(const expression::Image& image) { return image.toValue(); }
|
||||
};
|
||||
|
||||
} // namespace conversion
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
33
include/mbgl/style/expression/image_expression.hpp
Normal file
33
include/mbgl/style/expression/image_expression.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
class ParsingContext;
|
||||
|
||||
class ImageExpression final : public Expression {
|
||||
public:
|
||||
explicit ImageExpression(std::unique_ptr<Expression> imageID);
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override;
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible&, ParsingContext&);
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override;
|
||||
|
||||
std::vector<optional<Value>> possibleOutputs() const override { return {nullopt}; }
|
||||
|
||||
mbgl::Value serialize() const override;
|
||||
std::string getOperator() const override { return "image"; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<Expression> imageID;
|
||||
};
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -30,6 +30,8 @@ bool isGlobalPropertyConstant(const Expression& expression, const T& properties)
|
||||
bool isFeatureConstant(const Expression& expression);
|
||||
bool isZoomConstant(const Expression& e);
|
||||
|
||||
// Returns true if expression does not depend on information provided by the runtime.
|
||||
bool isRuntimeConstant(const Expression& e);
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
|
||||
@@ -14,65 +14,70 @@ template <class T>
|
||||
std::string toString(const T& t);
|
||||
|
||||
struct NullType {
|
||||
constexpr NullType() {};
|
||||
constexpr NullType() = default;
|
||||
std::string getName() const { return "null"; }
|
||||
bool operator==(const NullType&) const { return true; }
|
||||
};
|
||||
|
||||
struct NumberType {
|
||||
constexpr NumberType() {};
|
||||
constexpr NumberType() = default;
|
||||
std::string getName() const { return "number"; }
|
||||
bool operator==(const NumberType&) const { return true; }
|
||||
};
|
||||
|
||||
struct BooleanType {
|
||||
constexpr BooleanType() {};
|
||||
constexpr BooleanType() = default;
|
||||
std::string getName() const { return "boolean"; }
|
||||
bool operator==(const BooleanType&) const { return true; }
|
||||
};
|
||||
|
||||
struct StringType {
|
||||
constexpr StringType() {};
|
||||
constexpr StringType() = default;
|
||||
std::string getName() const { return "string"; }
|
||||
bool operator==(const StringType&) const { return true; }
|
||||
};
|
||||
|
||||
struct ColorType {
|
||||
constexpr ColorType() {};
|
||||
constexpr ColorType() = default;
|
||||
std::string getName() const { return "color"; }
|
||||
bool operator==(const ColorType&) const { return true; }
|
||||
};
|
||||
|
||||
struct ObjectType {
|
||||
constexpr ObjectType() {};
|
||||
constexpr ObjectType() = default;
|
||||
std::string getName() const { return "object"; }
|
||||
bool operator==(const ObjectType&) const { return true; }
|
||||
};
|
||||
|
||||
struct ErrorType {
|
||||
constexpr ErrorType() {};
|
||||
constexpr ErrorType() = default;
|
||||
std::string getName() const { return "error"; }
|
||||
bool operator==(const ErrorType&) const { return true; }
|
||||
};
|
||||
|
||||
struct ValueType {
|
||||
constexpr ValueType() {};
|
||||
constexpr ValueType() = default;
|
||||
std::string getName() const { return "value"; }
|
||||
bool operator==(const ValueType&) const { return true; }
|
||||
};
|
||||
|
||||
struct CollatorType {
|
||||
constexpr CollatorType() {}; // NOLINT
|
||||
constexpr CollatorType() = default;
|
||||
std::string getName() const { return "collator"; }
|
||||
bool operator==(const CollatorType&) const { return true; }
|
||||
};
|
||||
|
||||
struct FormattedType {
|
||||
constexpr FormattedType() {}; // NOLINT
|
||||
constexpr FormattedType() = default;
|
||||
std::string getName() const { return "formatted"; }
|
||||
bool operator==(const FormattedType&) const { return true; }
|
||||
};
|
||||
|
||||
struct ImageType {
|
||||
constexpr ImageType() = default;
|
||||
std::string getName() const { return "resolvedImage"; }
|
||||
bool operator==(const ImageType&) const { return true; }
|
||||
};
|
||||
|
||||
constexpr NullType Null;
|
||||
constexpr NumberType Number;
|
||||
@@ -84,21 +89,22 @@ constexpr ObjectType Object;
|
||||
constexpr CollatorType Collator;
|
||||
constexpr FormattedType Formatted;
|
||||
constexpr ErrorType Error;
|
||||
constexpr ImageType Image;
|
||||
|
||||
struct Array;
|
||||
|
||||
using Type = variant<
|
||||
NullType,
|
||||
NumberType,
|
||||
BooleanType,
|
||||
StringType,
|
||||
ColorType,
|
||||
ObjectType,
|
||||
ValueType,
|
||||
mapbox::util::recursive_wrapper<Array>,
|
||||
CollatorType,
|
||||
FormattedType,
|
||||
ErrorType>;
|
||||
using Type = variant<NullType,
|
||||
NumberType,
|
||||
BooleanType,
|
||||
StringType,
|
||||
ColorType,
|
||||
ObjectType,
|
||||
ValueType,
|
||||
mapbox::util::recursive_wrapper<Array>,
|
||||
CollatorType,
|
||||
FormattedType,
|
||||
ErrorType,
|
||||
ImageType>;
|
||||
|
||||
struct Array {
|
||||
explicit Array(Type itemType_) : itemType(std::move(itemType_)) {}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/expression/collator.hpp>
|
||||
#include <mbgl/style/expression/formatted.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/expression/type.hpp>
|
||||
#include <mbgl/style/position.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
@@ -19,16 +20,16 @@ namespace expression {
|
||||
|
||||
struct Value;
|
||||
|
||||
using ValueBase = variant<
|
||||
NullValue,
|
||||
bool,
|
||||
double,
|
||||
std::string,
|
||||
Color,
|
||||
Collator,
|
||||
Formatted,
|
||||
mapbox::util::recursive_wrapper<std::vector<Value>>,
|
||||
mapbox::util::recursive_wrapper<std::unordered_map<std::string, Value>>>;
|
||||
using ValueBase = variant<NullValue,
|
||||
bool,
|
||||
double,
|
||||
std::string,
|
||||
Color,
|
||||
Collator,
|
||||
Formatted,
|
||||
Image,
|
||||
mapbox::util::recursive_wrapper<std::vector<Value>>,
|
||||
mapbox::util::recursive_wrapper<std::unordered_map<std::string, Value>>>;
|
||||
struct Value : ValueBase {
|
||||
using ValueBase::ValueBase;
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ public:
|
||||
void setBackgroundOpacityTransition(const TransitionOptions&);
|
||||
TransitionOptions getBackgroundOpacityTransition() const;
|
||||
|
||||
static PropertyValue<std::string> getDefaultBackgroundPattern();
|
||||
const PropertyValue<std::string>& getBackgroundPattern() const;
|
||||
void setBackgroundPattern(const PropertyValue<std::string>&);
|
||||
static PropertyValue<expression::Image> getDefaultBackgroundPattern();
|
||||
const PropertyValue<expression::Image>& getBackgroundPattern() const;
|
||||
void setBackgroundPattern(const PropertyValue<expression::Image>&);
|
||||
void setBackgroundPatternTransition(const TransitionOptions&);
|
||||
TransitionOptions getBackgroundPatternTransition() const;
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ public:
|
||||
void setFillExtrusionOpacityTransition(const TransitionOptions&);
|
||||
TransitionOptions getFillExtrusionOpacityTransition() const;
|
||||
|
||||
static PropertyValue<std::string> getDefaultFillExtrusionPattern();
|
||||
const PropertyValue<std::string>& getFillExtrusionPattern() const;
|
||||
void setFillExtrusionPattern(const PropertyValue<std::string>&);
|
||||
static PropertyValue<expression::Image> getDefaultFillExtrusionPattern();
|
||||
const PropertyValue<expression::Image>& getFillExtrusionPattern() const;
|
||||
void setFillExtrusionPattern(const PropertyValue<expression::Image>&);
|
||||
void setFillExtrusionPatternTransition(const TransitionOptions&);
|
||||
TransitionOptions getFillExtrusionPatternTransition() const;
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ public:
|
||||
void setFillOutlineColorTransition(const TransitionOptions&);
|
||||
TransitionOptions getFillOutlineColorTransition() const;
|
||||
|
||||
static PropertyValue<std::string> getDefaultFillPattern();
|
||||
const PropertyValue<std::string>& getFillPattern() const;
|
||||
void setFillPattern(const PropertyValue<std::string>&);
|
||||
static PropertyValue<expression::Image> getDefaultFillPattern();
|
||||
const PropertyValue<expression::Image>& getFillPattern() const;
|
||||
void setFillPattern(const PropertyValue<expression::Image>&);
|
||||
void setFillPatternTransition(const TransitionOptions&);
|
||||
TransitionOptions getFillPatternTransition() const;
|
||||
|
||||
|
||||
@@ -91,9 +91,9 @@ public:
|
||||
void setLineOpacityTransition(const TransitionOptions&);
|
||||
TransitionOptions getLineOpacityTransition() const;
|
||||
|
||||
static PropertyValue<std::string> getDefaultLinePattern();
|
||||
const PropertyValue<std::string>& getLinePattern() const;
|
||||
void setLinePattern(const PropertyValue<std::string>&);
|
||||
static PropertyValue<expression::Image> getDefaultLinePattern();
|
||||
const PropertyValue<expression::Image>& getLinePattern() const;
|
||||
void setLinePattern(const PropertyValue<expression::Image>&);
|
||||
void setLinePatternTransition(const TransitionOptions&);
|
||||
TransitionOptions getLinePatternTransition() const;
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ public:
|
||||
const PropertyValue<bool>& getIconIgnorePlacement() const;
|
||||
void setIconIgnorePlacement(const PropertyValue<bool>&);
|
||||
|
||||
static PropertyValue<std::string> getDefaultIconImage();
|
||||
const PropertyValue<std::string>& getIconImage() const;
|
||||
void setIconImage(const PropertyValue<std::string>&);
|
||||
static PropertyValue<expression::Image> getDefaultIconImage();
|
||||
const PropertyValue<expression::Image>& getIconImage() const;
|
||||
void setIconImage(const PropertyValue<expression::Image>&);
|
||||
|
||||
static PropertyValue<bool> getDefaultIconKeepUpright();
|
||||
const PropertyValue<bool>& getIconKeepUpright() const;
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
|
||||
bool isZoomConstant() const noexcept;
|
||||
bool isFeatureConstant() const noexcept;
|
||||
bool canEvaluateWith(const expression::EvaluationContext&) const noexcept;
|
||||
bool isRuntimeConstant() const noexcept;
|
||||
float interpolationFactor(const Range<float>&, const float) const noexcept;
|
||||
Range<float> getCoveringStops(const float, const float) const noexcept;
|
||||
const expression::Expression& getExpression() const noexcept;
|
||||
@@ -28,6 +28,7 @@ protected:
|
||||
variant<std::nullptr_t, const expression::Interpolate*, const expression::Step*> zoomCurve;
|
||||
bool isZoomConstant_;
|
||||
bool isFeatureConstant_;
|
||||
bool isRuntimeConstant_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -40,7 +41,6 @@ public:
|
||||
}
|
||||
|
||||
T evaluate(const expression::EvaluationContext& context, T finalDefaultValue = T()) const {
|
||||
assert(canEvaluateWith(context));
|
||||
const expression::EvaluationResult result = expression->evaluate(context);
|
||||
if (result) {
|
||||
const optional<T> typed = expression::fromExpressionValue<T>(*result);
|
||||
@@ -50,18 +50,38 @@ public:
|
||||
}
|
||||
|
||||
T evaluate(float zoom) const {
|
||||
assert(!isZoomConstant());
|
||||
assert(isFeatureConstant());
|
||||
return evaluate(expression::EvaluationContext(zoom));
|
||||
}
|
||||
|
||||
T evaluate(const GeometryTileFeature& feature, T finalDefaultValue) const {
|
||||
assert(isZoomConstant());
|
||||
assert(!isFeatureConstant());
|
||||
return evaluate(expression::EvaluationContext(&feature), finalDefaultValue);
|
||||
}
|
||||
|
||||
T evaluate(const GeometryTileFeature& feature,
|
||||
const std::set<std::string>& availableImages,
|
||||
T finalDefaultValue) const {
|
||||
return evaluate(expression::EvaluationContext(&feature).withAvailableImages(&availableImages),
|
||||
finalDefaultValue);
|
||||
}
|
||||
|
||||
T evaluate(float zoom, const GeometryTileFeature& feature, T finalDefaultValue) const {
|
||||
return evaluate(expression::EvaluationContext(zoom, &feature), finalDefaultValue);
|
||||
}
|
||||
|
||||
T evaluate(float zoom,
|
||||
const GeometryTileFeature& feature,
|
||||
const std::set<std::string>& availableImages,
|
||||
T finalDefaultValue) const {
|
||||
return evaluate(expression::EvaluationContext(zoom, &feature).withAvailableImages(&availableImages),
|
||||
finalDefaultValue);
|
||||
}
|
||||
|
||||
T evaluate(float zoom, const GeometryTileFeature& feature, const FeatureState& state, T finalDefaultValue) const {
|
||||
assert(!isFeatureConstant());
|
||||
return evaluate(expression::EvaluationContext(zoom, &feature, &state), finalDefaultValue);
|
||||
}
|
||||
|
||||
|
||||
Submodule mapbox-gl-js updated: 6453c38a51...cbbbbfc523
@@ -151,6 +151,8 @@ add_library(
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/format_section_override.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/formatted.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/get_covering_stops.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/image.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/image_expression.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/interpolate.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/interpolator.hpp
|
||||
${MBGL_ROOT}/include/mbgl/style/expression/is_constant.hpp
|
||||
@@ -613,6 +615,8 @@ add_library(
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/format_expression.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/formatted.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/get_covering_stops.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/image.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/image_expression.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/interpolate.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/is_constant.cpp
|
||||
${MBGL_ROOT}/src/mbgl/style/expression/is_expression.cpp
|
||||
|
||||
@@ -35,16 +35,14 @@ void NodeExpression::Init(v8::Local<v8::Object> target) {
|
||||
}
|
||||
|
||||
type::Type parseType(v8::Local<v8::Object> type) {
|
||||
static std::unordered_map<std::string, type::Type> types = {
|
||||
{"string", type::String},
|
||||
{"number", type::Number},
|
||||
{"boolean", type::Boolean},
|
||||
{"object", type::Object},
|
||||
{"color", type::Color},
|
||||
{"value", type::Value},
|
||||
{"formatted", type::Formatted},
|
||||
{"number-format", type::String}
|
||||
};
|
||||
static std::unordered_map<std::string, type::Type> types = {{"string", type::String},
|
||||
{"number", type::Number},
|
||||
{"boolean", type::Boolean},
|
||||
{"object", type::Object},
|
||||
{"color", type::Color},
|
||||
{"value", type::Value},
|
||||
{"formatted", type::Formatted},
|
||||
{"number-format", type::String}};
|
||||
|
||||
v8::Local<v8::Value> v8kind = Nan::Get(type, Nan::New("kind").ToLocalChecked()).ToLocalChecked();
|
||||
std::string kind(*v8::String::Utf8Value(v8kind));
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
"expression-tests/legacy/interval/composite": "https://github.com/mapbox/mapbox-gl-native/issues/12747",
|
||||
"expression-tests/legacy/interval/composite-default": "https://github.com/mapbox/mapbox-gl-native/issues/12747",
|
||||
"expression-tests/legacy/interval/tokens-zoom": "https://github.com/mapbox/mapbox-gl-native/issues/12747",
|
||||
"expression-tests/image/basic": "https://github.com/mapbox/mapbox-gl-native/issues/15800",
|
||||
"expression-tests/image/compound": "https://github.com/mapbox/mapbox-gl-native/issues/15800",
|
||||
"expression-tests/image/coalesce": "https://github.com/mapbox/mapbox-gl-native/issues/15800",
|
||||
"expression-tests/image/implicit-assert": "https://github.com/mapbox/mapbox-gl-native/issues/15800",
|
||||
"expression-tests/in/assert-array": "https://github.com/mapbox/mapbox-gl-native/issues/15893",
|
||||
"expression-tests/in/assert-string": "https://github.com/mapbox/mapbox-gl-native/issues/15893",
|
||||
"expression-tests/in/basic-array": "https://github.com/mapbox/mapbox-gl-native/issues/15893",
|
||||
"expression-tests/in/basic-string": "https://github.com/mapbox/mapbox-gl-native/issues/15893",
|
||||
"expression-tests/in/invalid-haystack": "https://github.com/mapbox/mapbox-gl-native/issues/15893",
|
||||
"expression-tests/in/invalid-needle": "https://github.com/mapbox/mapbox-gl-native/issues/15893",
|
||||
"query-tests/geometry/multilinestring": "needs investigation",
|
||||
"query-tests/geometry/multipolygon": "needs investigation",
|
||||
"query-tests/geometry/polygon": "needs investigation",
|
||||
@@ -77,7 +79,6 @@
|
||||
"render-tests/line-sort-key/literal": "https://github.com/mapbox/mapbox-gl-native/issues/15008",
|
||||
"render-tests/regressions/mapbox-gl-js#8817": "skip - https://github.com/mapbox/mapbox-gl-native/issues/15737",
|
||||
"render-tests/text-max-width/zero-width-point-placement": "https://github.com/mapbox/mapbox-gl-native/issues/15648",
|
||||
"render-tests/icon-image/image-expression": "https://github.com/mapbox/mapbox-gl-native/issues/15800",
|
||||
"render-tests/icon-text-fit/text-variable-anchor-overlap": "https://github.com/mapbox/mapbox-gl-native/issues/15809",
|
||||
"query-tests/fill-extrusion/base-in": "https://github.com/mapbox/mapbox-gl-native/issues/13139",
|
||||
"query-tests/fill-extrusion/box-in": "https://github.com/mapbox/mapbox-gl-native/issues/13139",
|
||||
@@ -87,5 +88,6 @@
|
||||
"query-tests/fill-extrusion/sort-rotated": "https://github.com/mapbox/mapbox-gl-native/issues/13139",
|
||||
"query-tests/fill-extrusion/sort": "https://github.com/mapbox/mapbox-gl-native/issues/13139",
|
||||
"query-tests/fill-extrusion/top-in": "https://github.com/mapbox/mapbox-gl-native/issues/13139",
|
||||
"query-tests/regressions/mapbox-gl-js#7883": "https://github.com/mapbox/mapbox-gl-native/issues/14585"
|
||||
"query-tests/regressions/mapbox-gl-js#7883": "https://github.com/mapbox/mapbox-gl-native/issues/14585",
|
||||
"render-tests/fill-pattern/update-feature-state": "https://github.com/mapbox/mapbox-gl-native/issues/15895"
|
||||
}
|
||||
|
||||
@@ -35,8 +35,9 @@ global.expressionType = function (property) {
|
||||
case 'number':
|
||||
case 'enum':
|
||||
return 'NumberType';
|
||||
case 'image':
|
||||
return 'ImageType';
|
||||
case 'string':
|
||||
case 'image': // TODO: replace once we implement image expressions
|
||||
return 'StringType';
|
||||
case 'color':
|
||||
return `ColorType`;
|
||||
@@ -66,10 +67,11 @@ global.evaluatedType = function (property) {
|
||||
return 'bool';
|
||||
case 'number':
|
||||
return 'float';
|
||||
case 'resolvedImage':
|
||||
return 'expression::Image';
|
||||
case 'formatted':
|
||||
return 'expression::Formatted';
|
||||
case 'string':
|
||||
case 'image': // TODO: replace once we implement image expressions
|
||||
return 'std::string';
|
||||
case 'enum':
|
||||
return (isLightProperty(property) ? 'Light' : '') + `${camelize(property.name)}Type`;
|
||||
@@ -168,8 +170,8 @@ global.defaultValue = function (property) {
|
||||
}
|
||||
case 'formatted':
|
||||
case 'string':
|
||||
case 'image': // TODO: replace once we implement image expressions
|
||||
return JSON.stringify(property.default || "");
|
||||
case 'resolvedImage':
|
||||
return property.default ? `{${JSON.stringify(property.default)}}` : '{}';
|
||||
case 'enum':
|
||||
if (property.default === undefined) {
|
||||
return `${evaluatedType(property)}::Undefined`;
|
||||
@@ -191,9 +193,9 @@ global.defaultValue = function (property) {
|
||||
case 'array':
|
||||
const defaults = (property.default || []).map((e) => defaultValue({ type: property.value, default: e }));
|
||||
if (property.length) {
|
||||
return `{{ ${defaults.join(', ')} }}`;
|
||||
return `{{${defaults.join(', ')}}}`;
|
||||
} else {
|
||||
return `{ ${defaults.join(', ')} }`;
|
||||
return `{${defaults.join(', ')}}`;
|
||||
}
|
||||
default:
|
||||
return property.default;
|
||||
|
||||
@@ -192,6 +192,8 @@
|
||||
"src/mbgl/style/expression/format_expression.cpp",
|
||||
"src/mbgl/style/expression/formatted.cpp",
|
||||
"src/mbgl/style/expression/get_covering_stops.cpp",
|
||||
"src/mbgl/style/expression/image.cpp",
|
||||
"src/mbgl/style/expression/image_expression.cpp",
|
||||
"src/mbgl/style/expression/interpolate.cpp",
|
||||
"src/mbgl/style/expression/is_constant.cpp",
|
||||
"src/mbgl/style/expression/is_expression.cpp",
|
||||
@@ -418,6 +420,8 @@
|
||||
"mbgl/style/expression/format_section_override.hpp": "include/mbgl/style/expression/format_section_override.hpp",
|
||||
"mbgl/style/expression/formatted.hpp": "include/mbgl/style/expression/formatted.hpp",
|
||||
"mbgl/style/expression/get_covering_stops.hpp": "include/mbgl/style/expression/get_covering_stops.hpp",
|
||||
"mbgl/style/expression/image.hpp": "include/mbgl/style/expression/image.hpp",
|
||||
"mbgl/style/expression/image_expression.hpp": "include/mbgl/style/expression/image_expression.hpp",
|
||||
"mbgl/style/expression/interpolate.hpp": "include/mbgl/style/expression/interpolate.hpp",
|
||||
"mbgl/style/expression/interpolator.hpp": "include/mbgl/style/expression/interpolator.hpp",
|
||||
"mbgl/style/expression/is_constant.hpp": "include/mbgl/style/expression/is_constant.hpp",
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#include <mbgl/annotation/annotation_manager.hpp>
|
||||
#include <mbgl/annotation/annotation_source.hpp>
|
||||
#include <mbgl/annotation/annotation_tile.hpp>
|
||||
#include <mbgl/annotation/symbol_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/line_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/fill_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/line_annotation_impl.hpp>
|
||||
#include <mbgl/annotation/symbol_annotation_impl.hpp>
|
||||
#include <mbgl/layermanager/layer_manager.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_impl.hpp>
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/style/style_impl.hpp>
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
|
||||
@@ -184,7 +185,8 @@ void AnnotationManager::updateStyle() {
|
||||
|
||||
using namespace expression::dsl;
|
||||
layer->setSourceLayer(PointLayerID);
|
||||
layer->setIconImage(PropertyExpression<std::string>(concat(vec(literal(SourceID + "."), toString(get("sprite"))))));
|
||||
layer->setIconImage(PropertyExpression<expression::Image>(
|
||||
image(concat(vec(literal(SourceID + "."), toString(get("sprite")))))));
|
||||
layer->setIconAllowOverlap(true);
|
||||
layer->setIconIgnorePlacement(true);
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ std::unique_ptr<Layout> FillExtrusionLayerFactory::createLayout(const LayoutPara
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
|
||||
using namespace style;
|
||||
using LayoutType = PatternLayout<FillExtrusionBucket, FillExtrusionLayerProperties, FillExtrusionPattern>;
|
||||
return std::make_unique<LayoutType>(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies);
|
||||
return std::make_unique<LayoutType>(parameters.bucketParameters, group, std::move(layer), parameters);
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderLayer> FillExtrusionLayerFactory::createRenderLayer(Immutable<style::Layer::Impl> impl) noexcept {
|
||||
|
||||
@@ -30,7 +30,7 @@ FillLayerFactory::createLayout(const LayoutParameters& parameters,
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
|
||||
using namespace style;
|
||||
using LayoutType = PatternLayout<FillBucket, FillLayerProperties, FillPattern>;
|
||||
return std::make_unique<LayoutType>(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies);
|
||||
return std::make_unique<LayoutType>(parameters.bucketParameters, group, std::move(layer), parameters);
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderLayer> FillLayerFactory::createRenderLayer(Immutable<style::Layer::Impl> impl) noexcept {
|
||||
|
||||
@@ -29,7 +29,7 @@ std::unique_ptr<Layout> LineLayerFactory::createLayout(const LayoutParameters& p
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
|
||||
using namespace style;
|
||||
using LayoutType = PatternLayout<LineBucket, LineLayerProperties, LinePattern, LineLayoutProperties::PossiblyEvaluated>;
|
||||
return std::make_unique<LayoutType>(parameters.bucketParameters, group, std::move(layer), parameters.imageDependencies);
|
||||
return std::make_unique<LayoutType>(parameters.bucketParameters, group, std::move(layer), parameters);
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderLayer> LineLayerFactory::createRenderLayer(Immutable<style::Layer::Impl> impl) noexcept {
|
||||
|
||||
@@ -27,11 +27,7 @@ std::unique_ptr<style::Layer> SymbolLayerFactory::createLayer(const std::string&
|
||||
std::unique_ptr<Layout> SymbolLayerFactory::createLayout(const LayoutParameters& parameters,
|
||||
std::unique_ptr<GeometryTileLayer> tileLayer,
|
||||
const std::vector<Immutable<style::LayerProperties>>& group) noexcept {
|
||||
return std::make_unique<SymbolLayout>(parameters.bucketParameters,
|
||||
group,
|
||||
std::move(tileLayer),
|
||||
parameters.imageDependencies,
|
||||
parameters.glyphDependencies);
|
||||
return std::make_unique<SymbolLayout>(parameters.bucketParameters, group, std::move(tileLayer), parameters);
|
||||
}
|
||||
|
||||
std::unique_ptr<RenderLayer> SymbolLayerFactory::createRenderLayer(Immutable<style::Layer::Impl> impl) noexcept {
|
||||
|
||||
@@ -38,6 +38,7 @@ public:
|
||||
const BucketParameters& bucketParameters;
|
||||
GlyphDependencies& glyphDependencies;
|
||||
ImageDependencies& imageDependencies;
|
||||
std::set<std::string>& availableImages;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/layout/layout.hpp>
|
||||
#include <mbgl/renderer/bucket_parameters.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/renderer/render_layer.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layer_properties.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -32,11 +33,11 @@ public:
|
||||
PatternLayout(const BucketParameters& parameters,
|
||||
const std::vector<Immutable<style::LayerProperties>>& group,
|
||||
std::unique_ptr<GeometryTileLayer> sourceLayer_,
|
||||
ImageDependencies& patternDependencies)
|
||||
: sourceLayer(std::move(sourceLayer_)),
|
||||
zoom(parameters.tileID.overscaledZ),
|
||||
overscaling(parameters.tileID.overscaleFactor()),
|
||||
hasPattern(false) {
|
||||
const LayoutParameters& layoutParameters)
|
||||
: sourceLayer(std::move(sourceLayer_)),
|
||||
zoom(parameters.tileID.overscaledZ),
|
||||
overscaling(parameters.tileID.overscaleFactor()),
|
||||
hasPattern(false) {
|
||||
assert(!group.empty());
|
||||
auto leaderLayerProperties = staticImmutableCast<LayerPropertiesType>(group.front());
|
||||
layout = leaderLayerProperties->layerImpl().layout.evaluate(PropertyEvaluationParameters(zoom));
|
||||
@@ -47,15 +48,15 @@ public:
|
||||
const std::string& layerId = layerProperties->baseImpl->id;
|
||||
const auto& evaluated = style::getEvaluated<LayerPropertiesType>(layerProperties);
|
||||
const auto patternProperty = evaluated.template get<PatternPropertyType>();
|
||||
const auto constantPattern = patternProperty.constantOr(Faded<std::basic_string<char> >{ "", ""});
|
||||
const auto constantPattern = patternProperty.constantOr(Faded<style::expression::Image>{"", ""});
|
||||
// determine if layer group has any layers that use *-pattern property and add
|
||||
// constant pattern dependencies.
|
||||
if (!patternProperty.isConstant()) {
|
||||
hasPattern = true;
|
||||
} else if (!constantPattern.to.empty()){
|
||||
} else if (!constantPattern.to.id().empty()) {
|
||||
hasPattern = true;
|
||||
patternDependencies.emplace(constantPattern.to, ImageType::Pattern);
|
||||
patternDependencies.emplace(constantPattern.from, ImageType::Pattern);
|
||||
layoutParameters.imageDependencies.emplace(constantPattern.to.id(), ImageType::Pattern);
|
||||
layoutParameters.imageDependencies.emplace(constantPattern.from.id(), ImageType::Pattern);
|
||||
}
|
||||
layerPropertiesMap.emplace(layerId, layerProperties);
|
||||
}
|
||||
@@ -77,15 +78,22 @@ public:
|
||||
if (!patternProperty.isConstant()) {
|
||||
// For layers with non-data-constant pattern properties, evaluate their expression and add
|
||||
// the patterns to the dependency vector
|
||||
const auto min = patternProperty.evaluate(*feature, zoom - 1, PatternPropertyType::defaultValue());
|
||||
const auto mid = patternProperty.evaluate(*feature, zoom, PatternPropertyType::defaultValue());
|
||||
const auto max = patternProperty.evaluate(*feature, zoom + 1, PatternPropertyType::defaultValue());
|
||||
|
||||
patternDependencies.emplace(min.to, ImageType::Pattern);
|
||||
patternDependencies.emplace(mid.to, ImageType::Pattern);
|
||||
patternDependencies.emplace(max.to, ImageType::Pattern);
|
||||
patternDependencyMap.emplace(layerId, PatternDependency {min.to, mid.to, max.to});
|
||||
const auto min = patternProperty.evaluate(*feature,
|
||||
zoom - 1,
|
||||
layoutParameters.availableImages,
|
||||
PatternPropertyType::defaultValue());
|
||||
const auto mid = patternProperty.evaluate(
|
||||
*feature, zoom, layoutParameters.availableImages, PatternPropertyType::defaultValue());
|
||||
const auto max = patternProperty.evaluate(*feature,
|
||||
zoom + 1,
|
||||
layoutParameters.availableImages,
|
||||
PatternPropertyType::defaultValue());
|
||||
|
||||
layoutParameters.imageDependencies.emplace(min.to.id(), ImageType::Pattern);
|
||||
layoutParameters.imageDependencies.emplace(mid.to.id(), ImageType::Pattern);
|
||||
layoutParameters.imageDependencies.emplace(max.to.id(), ImageType::Pattern);
|
||||
patternDependencyMap.emplace(layerId,
|
||||
PatternDependency{min.to.id(), mid.to.id(), max.to.id()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/text/tagged_string.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/optional.hpp>
|
||||
#include <mbgl/text/tagged_string.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
std::unique_ptr<GeometryTileFeature> feature;
|
||||
GeometryCollection geometry;
|
||||
optional<TaggedString> formattedText;
|
||||
optional<std::string> icon;
|
||||
optional<style::expression::Image> icon;
|
||||
float sortKey = 0.0f;
|
||||
std::size_t index;
|
||||
bool allowsVerticalWritingMode = false;
|
||||
|
||||
@@ -81,8 +81,7 @@ inline Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> createLayout(
|
||||
SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
const std::vector<Immutable<style::LayerProperties>>& layers,
|
||||
std::unique_ptr<GeometryTileLayer> sourceLayer_,
|
||||
ImageDependencies& imageDependencies,
|
||||
GlyphDependencies& glyphDependencies)
|
||||
const LayoutParameters& layoutParameters)
|
||||
: bucketLeaderID(layers.front()->baseImpl->id),
|
||||
sourceLayer(std::move(sourceLayer_)),
|
||||
overscaling(parameters.tileID.overscaleFactor()),
|
||||
@@ -141,7 +140,7 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
ft.index = i;
|
||||
|
||||
if (hasText) {
|
||||
auto formatted = layout->evaluate<TextField>(zoom, ft);
|
||||
auto formatted = layout->evaluate<TextField>(zoom, ft, layoutParameters.availableImages);
|
||||
auto textTransform = layout->evaluate<TextTransform>(zoom, ft);
|
||||
FontStack baseFontStack = layout->evaluate<TextFont>(zoom, ft);
|
||||
|
||||
@@ -168,7 +167,8 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
// Loop through all characters of this text and collect unique codepoints.
|
||||
for (std::size_t j = 0; j < ft.formattedText->length(); j++) {
|
||||
const auto& sectionFontStack = formatted.sections[ft.formattedText->getSectionIndex(j)].fontStack;
|
||||
GlyphIDs& dependencies = glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack];
|
||||
GlyphIDs& dependencies =
|
||||
layoutParameters.glyphDependencies[sectionFontStack ? *sectionFontStack : baseFontStack];
|
||||
char16_t codePoint = ft.formattedText->getCharCodeAt(j);
|
||||
dependencies.insert(codePoint);
|
||||
if (canVerticalizeText || (allowVerticalPlacement && ft.formattedText->allowsVerticalWritingMode())) {
|
||||
@@ -180,8 +180,8 @@ SymbolLayout::SymbolLayout(const BucketParameters& parameters,
|
||||
}
|
||||
|
||||
if (hasIcon) {
|
||||
ft.icon = layout->evaluate<IconImage>(zoom, ft);
|
||||
imageDependencies.emplace(*ft.icon, ImageType::Icon);
|
||||
ft.icon = layout->evaluate<IconImage>(zoom, ft, layoutParameters.availableImages);
|
||||
layoutParameters.imageDependencies.emplace(ft.icon->id(), ImageType::Icon);
|
||||
}
|
||||
|
||||
if (ft.formattedText || ft.icon) {
|
||||
@@ -448,14 +448,13 @@ void SymbolLayout::prepareSymbols(const GlyphMap& glyphMap, const GlyphPositions
|
||||
// if feature has icon, get sprite atlas position
|
||||
SymbolContent iconType{SymbolContent::None};
|
||||
if (feature.icon) {
|
||||
auto image = imageMap.find(*feature.icon);
|
||||
auto image = imageMap.find(feature.icon->id());
|
||||
if (image != imageMap.end()) {
|
||||
iconType = SymbolContent::IconRGBA;
|
||||
shapedIcon = PositionedIcon::shapeIcon(
|
||||
imagePositions.at(*feature.icon),
|
||||
layout->evaluate<IconOffset>(zoom, feature),
|
||||
layout->evaluate<IconAnchor>(zoom, feature),
|
||||
layout->evaluate<IconRotate>(zoom, feature) * util::DEG2RAD);
|
||||
shapedIcon = PositionedIcon::shapeIcon(imagePositions.at(feature.icon->id()),
|
||||
layout->evaluate<IconOffset>(zoom, feature),
|
||||
layout->evaluate<IconAnchor>(zoom, feature),
|
||||
layout->evaluate<IconRotate>(zoom, feature) * util::DEG2RAD);
|
||||
if (image->second->sdf) {
|
||||
iconType = SymbolContent::IconSDF;
|
||||
}
|
||||
|
||||
@@ -27,9 +27,8 @@ public:
|
||||
SymbolLayout(const BucketParameters&,
|
||||
const std::vector<Immutable<style::LayerProperties>>&,
|
||||
std::unique_ptr<GeometryTileLayer>,
|
||||
ImageDependencies&,
|
||||
GlyphDependencies&);
|
||||
|
||||
const LayoutParameters& parameters);
|
||||
|
||||
~SymbolLayout() final = default;
|
||||
|
||||
void prepareSymbols(const GlyphMap&, const GlyphPositions&,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/renderer/cross_faded_property_evaluator.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/util/chrono.hpp>
|
||||
|
||||
#include <cmath>
|
||||
@@ -30,7 +31,7 @@ Faded<T> CrossFadedPropertyEvaluator<T>::calculate(const T& min, const T& mid, c
|
||||
: Faded<T> { max, mid };
|
||||
}
|
||||
|
||||
template class CrossFadedPropertyEvaluator<std::string>;
|
||||
template class CrossFadedPropertyEvaluator<style::expression::Image>;
|
||||
template class CrossFadedPropertyEvaluator<std::vector<float>>;
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -26,14 +26,14 @@ public:
|
||||
|
||||
ResultType operator()(const style::PropertyExpression<T>& expression) const {
|
||||
if (useIntegerZoom) { // Compiler will optimize out the unused branch.
|
||||
if (!expression.isFeatureConstant()) {
|
||||
if (!expression.isFeatureConstant() || !expression.isRuntimeConstant()) {
|
||||
auto returnExpression = expression;
|
||||
returnExpression.useIntegerZoom = true;
|
||||
return ResultType(returnExpression);
|
||||
}
|
||||
}
|
||||
return ResultType(expression.evaluate(floor(parameters.z)));
|
||||
} else {
|
||||
if (!expression.isFeatureConstant()) {
|
||||
if (!expression.isFeatureConstant() || !expression.isRuntimeConstant()) {
|
||||
return ResultType(expression);
|
||||
}
|
||||
return ResultType(expression.evaluate(parameters.z));
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
}
|
||||
|
||||
ResultType operator()(const style::PropertyExpression<T>& expression) const {
|
||||
if (!expression.isFeatureConstant()) {
|
||||
if (!expression.isFeatureConstant() || !expression.isRuntimeConstant()) {
|
||||
return ResultType(expression);
|
||||
} else {
|
||||
const T evaluated = expression.evaluate(floor(parameters.z));
|
||||
|
||||
@@ -43,6 +43,7 @@ void ImageManager::addImage(Immutable<style::Image::Impl> image_) {
|
||||
if (requestedImages.find(image_->id) != requestedImages.end()) {
|
||||
requestedImagesCacheSize += image_->image.bytes();
|
||||
}
|
||||
availableImages.emplace(image_->id);
|
||||
images.emplace(image_->id, std::move(image_));
|
||||
}
|
||||
|
||||
@@ -81,6 +82,7 @@ void ImageManager::removeImage(const std::string& id) {
|
||||
requestedImages.erase(requestedIt);
|
||||
}
|
||||
images.erase(it);
|
||||
availableImages.erase(id);
|
||||
updatedImageVersions.erase(id);
|
||||
}
|
||||
|
||||
@@ -169,6 +171,10 @@ void ImageManager::reduceMemoryUseIfCacheSizeExceedsLimit() {
|
||||
}
|
||||
}
|
||||
|
||||
const std::set<std::string>& ImageManager::getAvailableImages() const {
|
||||
return availableImages;
|
||||
}
|
||||
|
||||
void ImageManager::checkMissingAndNotify(ImageRequestor& requestor, const ImageRequestPair& pair) {
|
||||
ImageDependencies missingDependencies;
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ public:
|
||||
void notifyIfMissingImageAdded();
|
||||
void reduceMemoryUse();
|
||||
void reduceMemoryUseIfCacheSizeExceedsLimit();
|
||||
const std::set<std::string>& getAvailableImages() const;
|
||||
|
||||
ImageVersionMap updatedImageVersions;
|
||||
|
||||
@@ -62,6 +63,8 @@ private:
|
||||
std::map<std::string, std::set<ImageRequestor*>> requestedImages;
|
||||
std::size_t requestedImagesCacheSize = 0ul;
|
||||
ImageMap images;
|
||||
// Mirror of 'ImageMap images;' keys.
|
||||
std::set<std::string> availableImages;
|
||||
|
||||
ImageManagerObserver* observer = nullptr;
|
||||
};
|
||||
|
||||
@@ -105,8 +105,10 @@ void RenderBackgroundLayer::render(PaintParameters& parameters) {
|
||||
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& crossfade = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).crossfade;
|
||||
if (!evaluated.get<BackgroundPattern>().to.empty()) {
|
||||
optional<ImagePosition> imagePosA = parameters.patternAtlas.getPattern(evaluated.get<BackgroundPattern>().from);
|
||||
optional<ImagePosition> imagePosB = parameters.patternAtlas.getPattern(evaluated.get<BackgroundPattern>().to);
|
||||
optional<ImagePosition> imagePosA =
|
||||
parameters.patternAtlas.getPattern(evaluated.get<BackgroundPattern>().from.id());
|
||||
optional<ImagePosition> imagePosB =
|
||||
parameters.patternAtlas.getPattern(evaluated.get<BackgroundPattern>().to.id());
|
||||
|
||||
if (!imagePosA || !imagePosB)
|
||||
return;
|
||||
@@ -176,8 +178,8 @@ void RenderBackgroundLayer::prepare(const LayerPrepareParameters& params) {
|
||||
if (!evaluated.get<BackgroundPattern>().to.empty()) {
|
||||
// Ensures that the pattern bitmap gets copied to atlas bitmap.
|
||||
// Atlas bitmap is uploaded to atlas texture in upload.
|
||||
addPatternIfNeeded(evaluated.get<BackgroundPattern>().from, params);
|
||||
addPatternIfNeeded(evaluated.get<BackgroundPattern>().to, params);
|
||||
addPatternIfNeeded(evaluated.get<BackgroundPattern>().from.id(), params);
|
||||
addPatternIfNeeded(evaluated.get<BackgroundPattern>().to.id(), params);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
|
||||
#include <mbgl/renderer/buckets/fill_extrusion_bucket.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/programs/fill_extrusion_program.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/gfx/render_pass.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/gfx/render_pass.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/programs/fill_extrusion_program.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/renderer/buckets/fill_extrusion_bucket.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/layers/render_fill_extrusion_layer.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -171,7 +172,8 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
}
|
||||
} else {
|
||||
// Draw textured extrusions
|
||||
const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<std::basic_string<char> >{"", ""});
|
||||
const auto fillPatternValue =
|
||||
evaluated.get<FillExtrusionPattern>().constantOr(mbgl::Faded<expression::Image>{"", ""});
|
||||
auto drawTiles = [&](const gfx::StencilMode& stencilMode_, const gfx::ColorMode& colorMode_, const std::string& name) {
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const LayerRenderData* renderData = getRenderDataForPass(tile, parameters.pass);
|
||||
@@ -179,8 +181,8 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
continue;
|
||||
}
|
||||
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
||||
optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from);
|
||||
optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to);
|
||||
optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from.id());
|
||||
optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
|
||||
|
||||
draw(
|
||||
parameters.programs.getFillExtrusionLayerPrograms().fillExtrusionPattern,
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
#include <mbgl/renderer/layers/render_fill_layer.hpp>
|
||||
#include <mbgl/renderer/buckets/fill_bucket.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/programs/fill_program.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/style/layers/fill_layer_impl.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/gfx/renderable.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/programs/fill_program.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/renderer/buckets/fill_bucket.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/layers/render_fill_layer.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layers/fill_layer_impl.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -171,9 +172,9 @@ void RenderFillLayer::render(PaintParameters& parameters) {
|
||||
const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
|
||||
const auto& crossfade = getCrossfade<FillLayerProperties>(renderData->layerProperties);
|
||||
|
||||
const auto& fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<std::basic_string<char>>{"", ""});
|
||||
optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from);
|
||||
optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to);
|
||||
const auto& fillPatternValue = evaluated.get<FillPattern>().constantOr(Faded<expression::Image>{"", ""});
|
||||
optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from.id());
|
||||
optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
|
||||
|
||||
auto draw = [&] (auto& programInstance,
|
||||
const auto& drawMode,
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
#include <mbgl/renderer/layers/render_line_layer.hpp>
|
||||
#include <mbgl/renderer/buckets/line_bucket.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/programs/line_program.hpp>
|
||||
#include <mbgl/geometry/line_atlas.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/style/layers/line_layer_impl.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/geometry/line_atlas.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/programs/line_program.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/renderer/buckets/line_bucket.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/layers/render_line_layer.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layers/line_layer_impl.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -168,11 +169,11 @@ void RenderLineLayer::render(PaintParameters& parameters) {
|
||||
});
|
||||
|
||||
} else if (!unevaluated.get<LinePattern>().isUndefined()) {
|
||||
const auto& linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<std::basic_string<char>>{ "", ""});
|
||||
const auto& linePatternValue = evaluated.get<LinePattern>().constantOr(Faded<expression::Image>{"", ""});
|
||||
const Size& texsize = tile.getIconAtlasTexture().size;
|
||||
|
||||
optional<ImagePosition> posA = tile.getPattern(linePatternValue.from);
|
||||
optional<ImagePosition> posB = tile.getPattern(linePatternValue.to);
|
||||
optional<ImagePosition> posA = tile.getPattern(linePatternValue.from.id());
|
||||
optional<ImagePosition> posB = tile.getPattern(linePatternValue.to.id());
|
||||
|
||||
draw(parameters.programs.getLineLayerPrograms().linePattern,
|
||||
LinePatternProgram::layoutUniformValues(
|
||||
|
||||
@@ -93,16 +93,19 @@ public:
|
||||
}
|
||||
|
||||
template <class Feature>
|
||||
Faded<T> evaluate(const Feature& feature, float zoom, T defaultValue) const {
|
||||
Faded<T> evaluate(const Feature& feature,
|
||||
float zoom,
|
||||
const std::set<std::string>& availableImages,
|
||||
T defaultValue) const {
|
||||
return this->match(
|
||||
[&] (const Faded<T>& constant_) { return constant_; },
|
||||
[&] (const style::PropertyExpression<T>& expression) {
|
||||
if (!expression.isZoomConstant()) {
|
||||
const T min = expression.evaluate(floor(zoom), feature, defaultValue);
|
||||
const T max = expression.evaluate(floor(zoom) + 1, feature, defaultValue);
|
||||
const T min = expression.evaluate(floor(zoom), feature, availableImages, defaultValue);
|
||||
const T max = expression.evaluate(floor(zoom) + 1, feature, availableImages, defaultValue);
|
||||
return Faded<T> {min, max};
|
||||
} else {
|
||||
const T evaluated = expression.evaluate(feature, defaultValue);
|
||||
const T evaluated = expression.evaluate(feature, availableImages, defaultValue);
|
||||
return Faded<T> {evaluated, evaluated};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include <mbgl/style/conversion/function.hpp>
|
||||
#include <mbgl/style/conversion/position.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/expression/case.hpp>
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
#include <mbgl/style/expression/dsl_impl.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
#include <mbgl/style/expression/format_expression.hpp>
|
||||
#include <mbgl/style/expression/image_expression.hpp>
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/match.hpp>
|
||||
#include <mbgl/style/expression/case.hpp>
|
||||
#include <mbgl/style/expression/format_expression.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <cassert>
|
||||
@@ -46,6 +47,10 @@ std::unique_ptr<Expression> convertTokenStringToFormatExpression(const std::stri
|
||||
return std::make_unique<FormatExpression>(sections);
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> convertTokenStringToImageExpression(const std::string& source) {
|
||||
return std::make_unique<ImageExpression>(convertTokenStringToExpression(source));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> convertTokenStringToExpression(const std::string& source) {
|
||||
std::vector<std::unique_ptr<Expression>> inputs;
|
||||
|
||||
@@ -149,11 +154,11 @@ template optional<PropertyExpression<TextTransformType>>
|
||||
convertFunctionToExpression<TextTransformType>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<TranslateAnchorType>>
|
||||
convertFunctionToExpression<TranslateAnchorType>(const Convertible&, Error&, bool);
|
||||
|
||||
template optional<PropertyExpression<Formatted>>
|
||||
convertFunctionToExpression<Formatted>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<std::vector<TextWritingModeType>>>
|
||||
convertFunctionToExpression<std::vector<TextWritingModeType>>(const Convertible&, Error&, bool);
|
||||
template optional<PropertyExpression<Image>> convertFunctionToExpression<Image>(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
|
||||
@@ -207,35 +212,35 @@ static bool interpolatable(type::Type type) {
|
||||
|
||||
static optional<std::unique_ptr<Expression>> convertLiteral(type::Type type, const Convertible& value, Error& error, bool convertTokens = false) {
|
||||
return type.match(
|
||||
[&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
|
||||
auto result = convert<float>(value, error);
|
||||
if (!result) {
|
||||
return nullopt;
|
||||
}
|
||||
return literal(double(*result));
|
||||
},
|
||||
[&] (const type::BooleanType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::BooleanType&) -> optional<std::unique_ptr<Expression>> {
|
||||
auto result = convert<bool>(value, error);
|
||||
if (!result) {
|
||||
return nullopt;
|
||||
}
|
||||
return literal(*result);
|
||||
},
|
||||
[&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::StringType&) -> optional<std::unique_ptr<Expression>> {
|
||||
auto result = convert<std::string>(value, error);
|
||||
if (!result) {
|
||||
return nullopt;
|
||||
}
|
||||
return convertTokens ? convertTokenStringToExpression(*result) : literal(*result);
|
||||
},
|
||||
[&] (const type::ColorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::ColorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
auto result = convert<Color>(value, error);
|
||||
if (!result) {
|
||||
return nullopt;
|
||||
}
|
||||
return literal(*result);
|
||||
},
|
||||
[&] (const type::Array& array) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::Array& array) -> optional<std::unique_ptr<Expression>> {
|
||||
if (!isArray(value)) {
|
||||
error.message = "value must be an array";
|
||||
return nullopt;
|
||||
@@ -277,27 +282,27 @@ static optional<std::unique_ptr<Expression>> convertLiteral(type::Type type, con
|
||||
}
|
||||
);
|
||||
},
|
||||
[&] (const type::NullType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::NullType&) -> optional<std::unique_ptr<Expression>> {
|
||||
assert(false); // No properties use this type.
|
||||
return nullopt;
|
||||
},
|
||||
[&] (const type::ObjectType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::ObjectType&) -> optional<std::unique_ptr<Expression>> {
|
||||
assert(false); // No properties use this type.
|
||||
return nullopt;
|
||||
},
|
||||
[&] (const type::ErrorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::ErrorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
assert(false); // No properties use this type.
|
||||
return nullopt;
|
||||
},
|
||||
[&] (const type::ValueType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::ValueType&) -> optional<std::unique_ptr<Expression>> {
|
||||
assert(false); // No properties use this type.
|
||||
return nullopt;
|
||||
},
|
||||
[&] (const type::CollatorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::CollatorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
assert(false); // No properties use this type.
|
||||
return nullopt;
|
||||
},
|
||||
[&] (const type::FormattedType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::FormattedType&) -> optional<std::unique_ptr<Expression>> {
|
||||
auto result = convert<std::string>(value, error);
|
||||
if (!result) {
|
||||
return nullopt;
|
||||
@@ -305,8 +310,15 @@ static optional<std::unique_ptr<Expression>> convertLiteral(type::Type type, con
|
||||
return convertTokens ?
|
||||
convertTokenStringToFormatExpression(*result) :
|
||||
literal(Formatted(result->c_str()));
|
||||
}
|
||||
);
|
||||
},
|
||||
[&](const type::ImageType&) -> optional<std::unique_ptr<Expression>> {
|
||||
auto result = convert<std::string>(value, error);
|
||||
if (!result) {
|
||||
return nullopt;
|
||||
}
|
||||
return convertTokens ? std::make_unique<ImageExpression>(convertTokenStringToImageExpression(*result))
|
||||
: literal(Image(result->c_str()));
|
||||
});
|
||||
}
|
||||
|
||||
static optional<std::map<double, std::unique_ptr<Expression>>> convertStops(type::Type type,
|
||||
@@ -749,29 +761,31 @@ optional<std::unique_ptr<Expression>> convertFunctionToExpression(type::Type typ
|
||||
|
||||
if (functionType == FunctionType::Identity) {
|
||||
return type.match(
|
||||
[&] (const type::StringType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::StringType&) -> optional<std::unique_ptr<Expression>> {
|
||||
return string(get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&] (const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::NumberType&) -> optional<std::unique_ptr<Expression>> {
|
||||
return number(get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&] (const type::BooleanType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::BooleanType&) -> optional<std::unique_ptr<Expression>> {
|
||||
return boolean(get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&] (const type::ColorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::ColorType&) -> optional<std::unique_ptr<Expression>> {
|
||||
return toColor(get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&] (const type::Array& array) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::Array& array) -> optional<std::unique_ptr<Expression>> {
|
||||
return assertion(array, get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&] (const type::FormattedType&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::FormattedType&) -> optional<std::unique_ptr<Expression>> {
|
||||
return toFormatted(get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&] (const auto&) -> optional<std::unique_ptr<Expression>> {
|
||||
[&](const type::ImageType&) -> optional<std::unique_ptr<Expression>> {
|
||||
return toImage(get(literal(*property)), defaultExpr());
|
||||
},
|
||||
[&](const auto&) -> optional<std::unique_ptr<Expression>> {
|
||||
assert(false); // No properties use this type.
|
||||
return nullopt;
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
auto stopsValue = objectMember(value, "stops");
|
||||
|
||||
@@ -39,7 +39,8 @@ optional<PropertyValue<T>> Converter<PropertyValue<T>>::operator()(const Convert
|
||||
} else if (!allowDataExpressions && !(*expression).isFeatureConstant()) {
|
||||
error.message = "data expressions not supported";
|
||||
return nullopt;
|
||||
} else if (!(*expression).isFeatureConstant() || !(*expression).isZoomConstant()) {
|
||||
} else if (!(*expression).isFeatureConstant() || !(*expression).isZoomConstant() ||
|
||||
!(*expression).isRuntimeConstant()) {
|
||||
return { std::move(*expression) };
|
||||
} else if ((*expression).getExpression().getKind() == Kind::Literal) {
|
||||
optional<T> constant = fromExpressionValue<T>(
|
||||
@@ -81,6 +82,11 @@ template optional<PropertyValue<TextTransformType>> Converter<PropertyValue<Text
|
||||
template optional<PropertyValue<TranslateAnchorType>> Converter<PropertyValue<TranslateAnchorType>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<mbgl::style::expression::Formatted>> Converter<PropertyValue<mbgl::style::expression::Formatted>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<std::vector<TextWritingModeType>>> Converter<PropertyValue<std::vector<TextWritingModeType>>>::operator()(conversion::Convertible const&, conversion::Error&, bool, bool) const;
|
||||
template optional<PropertyValue<mbgl::style::expression::Image>>
|
||||
Converter<PropertyValue<mbgl::style::expression::Image>>::operator()(conversion::Convertible const&,
|
||||
conversion::Error&,
|
||||
bool,
|
||||
bool) const;
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
|
||||
@@ -141,6 +141,11 @@ void stringify(Writer& writer, const expression::Formatted& v) {
|
||||
stringify(writer, expression::ValueConverter<mbgl::Value>::fromExpressionValue(v));
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const expression::Image& v) {
|
||||
stringify(writer, expression::ValueConverter<mbgl::Value>::fromExpressionValue(v));
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const Undefined&) {
|
||||
assert(false); // Should be omitted entirely instead.
|
||||
|
||||
@@ -32,18 +32,9 @@ optional<std::string> checkSubtype(const Type& expected, const Type& t) {
|
||||
},
|
||||
[&] (const ValueType&) -> optional<std::string> {
|
||||
if (t.is<ValueType>()) return {};
|
||||
|
||||
const Type members[] = {
|
||||
Null,
|
||||
Boolean,
|
||||
Number,
|
||||
String,
|
||||
Object,
|
||||
Color,
|
||||
Formatted,
|
||||
Array(Value)
|
||||
};
|
||||
|
||||
|
||||
const Type members[] = {Null, Boolean, Number, String, Object, Color, Formatted, Image, Array(Value)};
|
||||
|
||||
for (const auto& member : members) {
|
||||
const auto err = checkSubtype(member, t);
|
||||
if (!err) {
|
||||
|
||||
@@ -8,8 +8,22 @@ namespace expression {
|
||||
|
||||
EvaluationResult Coalesce::evaluate(const EvaluationContext& params) const {
|
||||
EvaluationResult result = Null;
|
||||
std::size_t argsCount = args.size();
|
||||
optional<Image> requestedImage;
|
||||
for (const auto& arg : args) {
|
||||
--argsCount;
|
||||
result = arg->evaluate(params);
|
||||
// We need to keep track of the first requested image in a coalesce statement.
|
||||
// If coalesce can't find a valid image, we return the first requested image.
|
||||
if (getType() == type::Image && result) {
|
||||
const auto image = fromExpressionValue<Image>(*result);
|
||||
if (image && !image->isAvailable()) {
|
||||
if (!requestedImage) requestedImage = Image(image->id());
|
||||
if (!argsCount) result = *requestedImage;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!result || *result != Null) break;
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -9,13 +9,12 @@ namespace style {
|
||||
namespace expression {
|
||||
|
||||
EvaluationResult toBoolean(const Value& v) {
|
||||
return v.match(
|
||||
[&] (double f) { return static_cast<bool>(f); },
|
||||
[&] (const std::string& s) { return s.length() > 0; },
|
||||
[&] (bool b) { return b; },
|
||||
[&] (const NullValue&) { return false; },
|
||||
[&] (const auto&) { return true; }
|
||||
);
|
||||
return v.match([&](double f) { return static_cast<bool>(f); },
|
||||
[&](const std::string& s) { return s.length() > 0; },
|
||||
[&](bool b) { return b; },
|
||||
[&](const NullValue&) { return false; },
|
||||
[&](const Image& i) { return i.isAvailable(); },
|
||||
[&](const auto&) { return true; });
|
||||
}
|
||||
|
||||
EvaluationResult toNumber(const Value& v) {
|
||||
@@ -86,6 +85,10 @@ EvaluationResult toFormatted(const Value& formattedValue) {
|
||||
return Formatted(toString(formattedValue).c_str());
|
||||
}
|
||||
|
||||
EvaluationResult toImage(const Value& imageValue) {
|
||||
return Image(toString(imageValue).c_str());
|
||||
}
|
||||
|
||||
Coercion::Coercion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(Kind::Coercion, std::move(type_)),
|
||||
inputs(std::move(inputs_))
|
||||
@@ -102,6 +105,8 @@ Coercion::Coercion(type::Type type_, std::vector<std::unique_ptr<Expression>> in
|
||||
coerceSingleValue = [] (const Value& v) -> EvaluationResult { return toString(v); };
|
||||
} else if (t.is<type::FormattedType>()) {
|
||||
coerceSingleValue = toFormatted;
|
||||
} else if (t.is<type::ImageType>()) {
|
||||
coerceSingleValue = toImage;
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
@@ -115,6 +120,8 @@ mbgl::Value Coercion::serialize() const {
|
||||
serialized.push_back(inputs[0]->serialize());
|
||||
serialized.emplace_back(std::unordered_map<std::string, mbgl::Value>());
|
||||
return serialized;
|
||||
} else if (getType().is<type::ImageType>()) {
|
||||
return std::vector<mbgl::Value>{{std::string("image")}, inputs[0]->serialize()};
|
||||
} else {
|
||||
return Expression::serialize();
|
||||
}
|
||||
@@ -148,11 +155,13 @@ ParseResult Coercion::parse(const Convertible& value, ParsingContext& ctx) {
|
||||
auto it = types.find(*toString(arrayMember(value, 0)));
|
||||
assert(it != types.end());
|
||||
|
||||
if ((it->second == type::Boolean || it->second == type::String || it->second == type::Formatted) && length != 2) {
|
||||
if ((it->second == type::Boolean || it->second == type::String || it->second == type::Formatted ||
|
||||
it->second == type::Image) &&
|
||||
length != 2) {
|
||||
ctx.error("Expected one argument.");
|
||||
return ParseResult();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Special form for error-coalescing coercion expressions "to-number",
|
||||
* "to-color". Since these coercions can fail at runtime, they accept multiple
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
#include <mbgl/style/expression/dsl_impl.hpp>
|
||||
#include <mbgl/style/expression/error.hpp>
|
||||
#include <mbgl/style/expression/literal.hpp>
|
||||
#include <mbgl/style/expression/assertion.hpp>
|
||||
#include <mbgl/style/expression/coercion.hpp>
|
||||
#include <mbgl/style/expression/comparison.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/compound_expression.hpp>
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
#include <mbgl/style/expression/dsl_impl.hpp>
|
||||
#include <mbgl/style/expression/error.hpp>
|
||||
#include <mbgl/style/expression/format_expression.hpp>
|
||||
#include <mbgl/style/expression/image_expression.hpp>
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/literal.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
#include <mbgl/style/conversion/json.hpp>
|
||||
@@ -122,7 +123,11 @@ std::unique_ptr<Expression> toFormatted(std::unique_ptr<Expression> value,
|
||||
std::unique_ptr<Expression> def) {
|
||||
return coercion(type::Formatted, std::move(value), std::move(def));
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<Expression> toImage(std::unique_ptr<Expression> value, std::unique_ptr<Expression> def) {
|
||||
return coercion(type::Image, std::move(value), std::move(def));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> get(const char* value) {
|
||||
return get(literal(value));
|
||||
}
|
||||
@@ -237,6 +242,14 @@ std::unique_ptr<Expression> format(std::unique_ptr<Expression> input) {
|
||||
return std::make_unique<FormatExpression>(sections);
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> image(const char* value) {
|
||||
return std::make_unique<Literal>(Image(value));
|
||||
}
|
||||
|
||||
std::unique_ptr<Expression> image(std::unique_ptr<Expression> expression) {
|
||||
return std::make_unique<ImageExpression>(std::move(expression));
|
||||
}
|
||||
|
||||
} // namespace dsl
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
|
||||
@@ -25,12 +25,22 @@ public:
|
||||
return optional<mbgl::Value>();
|
||||
}
|
||||
};
|
||||
|
||||
EvaluationResult Expression::evaluate(optional<float> zoom, const Feature& feature, optional<double> colorRampParameter) const {
|
||||
|
||||
EvaluationResult Expression::evaluate(optional<float> zoom,
|
||||
const Feature& feature,
|
||||
optional<double> colorRampParameter) const {
|
||||
GeoJSONFeature f(feature);
|
||||
return this->evaluate(EvaluationContext(zoom, &f, colorRampParameter));
|
||||
}
|
||||
|
||||
EvaluationResult Expression::evaluate(optional<float> zoom,
|
||||
const Feature& feature,
|
||||
optional<double> colorRampParameter,
|
||||
const std::set<std::string>& availableImages) const {
|
||||
GeoJSONFeature f(feature);
|
||||
return this->evaluate(EvaluationContext(zoom, &f, colorRampParameter).withAvailableImages(&availableImages));
|
||||
}
|
||||
|
||||
EvaluationResult Expression::evaluate(optional<mbgl::Value> accumulated, const Feature& feature) const {
|
||||
GeoJSONFeature f(feature);
|
||||
return this->evaluate(EvaluationContext(accumulated, &f));
|
||||
|
||||
67
src/mbgl/style/expression/image.cpp
Normal file
67
src/mbgl/style/expression/image.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
#include <mbgl/style/conversion/constant.hpp>
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
Image::Image(std::string imageID_, bool available_) : imageID(std::move(imageID_)), available(available_) {}
|
||||
|
||||
Image::Image(std::string imageID_) : Image(std::move(imageID_), false) {}
|
||||
|
||||
Image::Image(const char* imageID_) : Image(std::string(imageID_)) {
|
||||
assert(imageID_);
|
||||
}
|
||||
|
||||
bool Image::operator==(const Image& other) const {
|
||||
return imageID == other.imageID && available == other.available;
|
||||
}
|
||||
|
||||
mbgl::Value Image::toValue() const {
|
||||
return mapbox::base::ValueObject{{"name", imageID}, {"available", available}};
|
||||
}
|
||||
|
||||
const std::string& Image::id() const {
|
||||
return imageID;
|
||||
}
|
||||
|
||||
bool Image::isAvailable() const {
|
||||
return available;
|
||||
}
|
||||
|
||||
bool Image::empty() const {
|
||||
return imageID.empty();
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
|
||||
namespace conversion {
|
||||
using namespace mbgl::style::expression;
|
||||
optional<Image> Converter<Image>::operator()(const Convertible& value, Error& error) const {
|
||||
if (isArray(value)) {
|
||||
Convertible imageParameters = arrayMember(value, 0);
|
||||
std::size_t imageParametersLength = arrayLength(imageParameters);
|
||||
if (imageParametersLength < 1) {
|
||||
error.message = "Image has to contain an ID.";
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<std::string> imageID = toString(arrayMember(imageParameters, 0));
|
||||
if (!imageID) {
|
||||
error.message = "Image has to contain an ID.";
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
return Image(*imageID, false);
|
||||
} else if (optional<std::string> result = toString(value)) {
|
||||
return Image(*result, false);
|
||||
} else {
|
||||
error.message = "Image must be plain string or array type.";
|
||||
return nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
68
src/mbgl/style/expression/image_expression.cpp
Normal file
68
src/mbgl/style/expression/image_expression.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <mbgl/style/conversion_impl.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/expression/image_expression.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace expression {
|
||||
|
||||
ImageExpression::ImageExpression(std::unique_ptr<Expression> imageID_)
|
||||
: Expression(Kind::ImageExpression, type::Image), imageID(std::move(imageID_)) {
|
||||
assert(imageID);
|
||||
}
|
||||
|
||||
using namespace mbgl::style::conversion;
|
||||
|
||||
ParseResult ImageExpression::parse(const Convertible& value, ParsingContext& ctx) {
|
||||
std::size_t argsLength = arrayLength(value);
|
||||
if (argsLength < 2) {
|
||||
ctx.error("Invalid number of arguments for 'image' expression.");
|
||||
return ParseResult();
|
||||
}
|
||||
|
||||
// Parse expression that evaluates to image id.
|
||||
auto imageIDArg = arrayMember(value, 1);
|
||||
ParseResult imageIDExpr = ctx.parse(imageIDArg, 1, {type::String});
|
||||
if (!imageIDExpr) {
|
||||
return ParseResult();
|
||||
}
|
||||
|
||||
return ParseResult(std::make_unique<ImageExpression>(std::move(*imageIDExpr)));
|
||||
}
|
||||
|
||||
void ImageExpression::eachChild(const std::function<void(const Expression&)>& fn) const {
|
||||
fn(*imageID);
|
||||
}
|
||||
|
||||
bool ImageExpression::operator==(const Expression& e) const {
|
||||
if (e.getKind() == Kind::ImageExpression) {
|
||||
auto rhs = static_cast<const ImageExpression*>(&e);
|
||||
return *imageID == *rhs->imageID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
mbgl::Value ImageExpression::serialize() const {
|
||||
std::vector<mbgl::Value> serialized{{getOperator()}};
|
||||
serialized.push_back(imageID->serialize());
|
||||
return serialized;
|
||||
}
|
||||
|
||||
EvaluationResult ImageExpression::evaluate(const EvaluationContext& ctx) const {
|
||||
auto imageIDResult = imageID->evaluate(ctx);
|
||||
if (!imageIDResult) {
|
||||
return imageIDResult.error();
|
||||
}
|
||||
|
||||
optional<std::string> evaluatedImageID = toString(*imageIDResult);
|
||||
if (!evaluatedImageID) {
|
||||
return EvaluationError({"Could not evaluate ID for 'image' expression."});
|
||||
}
|
||||
|
||||
bool available = ctx.availableImages && ctx.availableImages->count(*evaluatedImageID);
|
||||
return Image(*evaluatedImageID, available);
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -49,6 +49,19 @@ bool isZoomConstant(const Expression& e) {
|
||||
return isGlobalPropertyConstant(e, std::array<std::string, 1>{{"zoom"}});
|
||||
}
|
||||
|
||||
bool isRuntimeConstant(const Expression& expression) {
|
||||
if (expression.getKind() == Kind::ImageExpression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool runtimeConstant = true;
|
||||
expression.eachChild([&](const Expression& e) {
|
||||
if (runtimeConstant && !isRuntimeConstant(e)) {
|
||||
runtimeConstant = false;
|
||||
}
|
||||
});
|
||||
return runtimeConstant;
|
||||
}
|
||||
|
||||
} // namespace expression
|
||||
} // namespace style
|
||||
|
||||
@@ -4,22 +4,23 @@
|
||||
#include <mbgl/style/expression/is_constant.hpp>
|
||||
#include <mbgl/style/expression/type.hpp>
|
||||
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/at.hpp>
|
||||
#include <mbgl/style/expression/assertion.hpp>
|
||||
#include <mbgl/style/expression/at.hpp>
|
||||
#include <mbgl/style/expression/boolean_operator.hpp>
|
||||
#include <mbgl/style/expression/case.hpp>
|
||||
#include <mbgl/style/expression/coalesce.hpp>
|
||||
#include <mbgl/style/expression/coercion.hpp>
|
||||
#include <mbgl/style/expression/compound_expression.hpp>
|
||||
#include <mbgl/style/expression/comparison.hpp>
|
||||
#include <mbgl/style/expression/number_format.hpp>
|
||||
#include <mbgl/style/expression/compound_expression.hpp>
|
||||
#include <mbgl/style/expression/expression.hpp>
|
||||
#include <mbgl/style/expression/format_expression.hpp>
|
||||
#include <mbgl/style/expression/image_expression.hpp>
|
||||
#include <mbgl/style/expression/interpolate.hpp>
|
||||
#include <mbgl/style/expression/length.hpp>
|
||||
#include <mbgl/style/expression/let.hpp>
|
||||
#include <mbgl/style/expression/literal.hpp>
|
||||
#include <mbgl/style/expression/match.hpp>
|
||||
#include <mbgl/style/expression/number_format.hpp>
|
||||
#include <mbgl/style/expression/step.hpp>
|
||||
|
||||
#include <mbgl/style/expression/find_zoom_curve.hpp>
|
||||
@@ -117,7 +118,7 @@ MAPBOX_ETERNAL_CONSTEXPR const auto expressionRegistry =
|
||||
{"coalesce", Coalesce::parse},
|
||||
{"collator", CollatorExpression::parse},
|
||||
{"format", FormatExpression::parse},
|
||||
{"image", Assertion::parse}, // TODO: replace once we implement image expressions
|
||||
{"image", ImageExpression::parse},
|
||||
{"interpolate", parseInterpolate},
|
||||
{"length", Length::parse},
|
||||
{"let", Let::parse},
|
||||
@@ -193,7 +194,8 @@ ParseResult ParsingContext::parse(const Convertible& value, optional<TypeAnnotat
|
||||
const type::Type actual = (*parsed)->getType();
|
||||
if ((*expected == type::String || *expected == type::Number || *expected == type::Boolean || *expected == type::Object || expected->is<type::Array>()) && actual == type::Value) {
|
||||
parsed = { annotate(std::move(*parsed), *expected, typeAnnotationOption.value_or(TypeAnnotationOption::assert)) };
|
||||
} else if ((*expected == type::Color || *expected == type::Formatted) && (actual == type::Value || actual == type::String)) {
|
||||
} else if ((*expected == type::Color || *expected == type::Formatted || *expected == type::Image) &&
|
||||
(actual == type::Value || actual == type::String)) {
|
||||
parsed = { annotate(std::move(*parsed), *expected, typeAnnotationOption.value_or(TypeAnnotationOption::coerce)) };
|
||||
} else {
|
||||
checkType((*parsed)->getType());
|
||||
@@ -205,8 +207,9 @@ ParseResult ParsingContext::parse(const Convertible& value, optional<TypeAnnotat
|
||||
|
||||
// If an expression's arguments are all constant, we can evaluate
|
||||
// it immediately and replace it with a literal value in the
|
||||
// parsed result.
|
||||
if ((*parsed)->getKind() != Kind::Literal && isConstant(**parsed)) {
|
||||
// parsed/compiled result. Expressions that expect an image should
|
||||
// not be resolved here so we can later get the available images.
|
||||
if ((*parsed)->getKind() != Kind::Literal && (*parsed)->getType() != type::Image && isConstant(**parsed)) {
|
||||
EvaluationContext params(nullptr);
|
||||
EvaluationResult evaluated((*parsed)->evaluate(params));
|
||||
if (!evaluated) {
|
||||
|
||||
@@ -8,81 +8,78 @@ namespace style {
|
||||
namespace expression {
|
||||
|
||||
type::Type typeOf(const Value& value) {
|
||||
return value.match(
|
||||
[&](bool) -> type::Type { return type::Boolean; },
|
||||
[&](double) -> type::Type { return type::Number; },
|
||||
[&](const std::string&) -> type::Type { return type::String; },
|
||||
[&](const Color&) -> type::Type { return type::Color; },
|
||||
[&](const Collator&) -> type::Type { return type::Collator; },
|
||||
[&](const Formatted&) -> type::Type { return type::Formatted; },
|
||||
[&](const NullValue&) -> type::Type { return type::Null; },
|
||||
[&](const std::unordered_map<std::string, Value>&) -> type::Type { return type::Object; },
|
||||
[&](const std::vector<Value>& arr) -> type::Type {
|
||||
optional<type::Type> itemType;
|
||||
for (const auto& item : arr) {
|
||||
const type::Type t = typeOf(item);
|
||||
if (!itemType) {
|
||||
itemType = {t};
|
||||
} else if (*itemType == t) {
|
||||
continue;
|
||||
} else {
|
||||
itemType = {type::Value};
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value.match([&](bool) -> type::Type { return type::Boolean; },
|
||||
[&](double) -> type::Type { return type::Number; },
|
||||
[&](const std::string&) -> type::Type { return type::String; },
|
||||
[&](const Color&) -> type::Type { return type::Color; },
|
||||
[&](const Collator&) -> type::Type { return type::Collator; },
|
||||
[&](const Formatted&) -> type::Type { return type::Formatted; },
|
||||
[&](const Image&) -> type::Type { return type::Image; },
|
||||
[&](const NullValue&) -> type::Type { return type::Null; },
|
||||
[&](const std::unordered_map<std::string, Value>&) -> type::Type { return type::Object; },
|
||||
[&](const std::vector<Value>& arr) -> type::Type {
|
||||
optional<type::Type> itemType;
|
||||
for (const auto& item : arr) {
|
||||
const type::Type t = typeOf(item);
|
||||
if (!itemType) {
|
||||
itemType = {t};
|
||||
} else if (*itemType == t) {
|
||||
continue;
|
||||
} else {
|
||||
itemType = {type::Value};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return type::Array(itemType.value_or(type::Value), arr.size());
|
||||
}
|
||||
);
|
||||
return type::Array(itemType.value_or(type::Value), arr.size());
|
||||
});
|
||||
}
|
||||
|
||||
std::string toString(const Value& value) {
|
||||
return value.match(
|
||||
[](const NullValue&) { return std::string(); },
|
||||
[](const Color& c) { return c.stringify(); }, // avoid quoting
|
||||
[](const Formatted& f) { return f.toString(); },
|
||||
[](const std::string& s) { return s; }, // avoid quoting
|
||||
[](const auto& v_) { return stringify(v_); }
|
||||
);
|
||||
return value.match([](const NullValue&) { return std::string(); },
|
||||
[](const Color& c) { return c.stringify(); }, // avoid quoting
|
||||
[](const Formatted& f) { return f.toString(); },
|
||||
[](const Image& i) { return i.id(); },
|
||||
[](const std::string& s) { return s; }, // avoid quoting
|
||||
[](const auto& v_) { return stringify(v_); });
|
||||
}
|
||||
|
||||
void writeJSON(rapidjson::Writer<rapidjson::StringBuffer>& writer, const Value& value) {
|
||||
value.match(
|
||||
[&] (const NullValue&) { writer.Null(); },
|
||||
[&] (bool b) { writer.Bool(b); },
|
||||
[&] (double f) {
|
||||
// make sure integer values are stringified without trailing ".0".
|
||||
f == std::floor(f) ? writer.Int(f) : writer.Double(f);
|
||||
},
|
||||
[&] (const std::string& s) { writer.String(s); },
|
||||
[&] (const Color& c) { writer.String(c.stringify()); },
|
||||
[&] (const Collator&) {
|
||||
// Collators are excluded from constant folding and there's no Literal parser
|
||||
// for them so there shouldn't be any way to serialize this value.
|
||||
assert(false);
|
||||
},
|
||||
[&] (const Formatted& f) {
|
||||
// `stringify` in turns calls ValueConverter::fromExpressionValue below
|
||||
// Serialization strategy for Formatted objects is to return the constant
|
||||
// expression that would generate them.
|
||||
mbgl::style::conversion::stringify(writer, f);
|
||||
},
|
||||
[&] (const std::vector<Value>& arr) {
|
||||
writer.StartArray();
|
||||
for(const auto& item : arr) {
|
||||
writeJSON(writer, item);
|
||||
}
|
||||
writer.EndArray();
|
||||
},
|
||||
[&] (const std::unordered_map<std::string, Value>& obj) {
|
||||
writer.StartObject();
|
||||
for(const auto& entry : obj) {
|
||||
writer.Key(entry.first.c_str());
|
||||
writeJSON(writer, entry.second);
|
||||
}
|
||||
writer.EndObject();
|
||||
}
|
||||
);
|
||||
value.match([&](const NullValue&) { writer.Null(); },
|
||||
[&](bool b) { writer.Bool(b); },
|
||||
[&](double f) {
|
||||
// make sure integer values are stringified without trailing ".0".
|
||||
f == std::floor(f) ? writer.Int(f) : writer.Double(f);
|
||||
},
|
||||
[&](const std::string& s) { writer.String(s); },
|
||||
[&](const Color& c) { writer.String(c.stringify()); },
|
||||
[&](const Collator&) {
|
||||
// Collators are excluded from constant folding and there's no Literal parser
|
||||
// for them so there shouldn't be any way to serialize this value.
|
||||
assert(false);
|
||||
},
|
||||
[&](const Formatted& f) {
|
||||
// `stringify` in turns calls ValueConverter::fromExpressionValue below
|
||||
// Serialization strategy for Formatted objects is to return the constant
|
||||
// expression that would generate them.
|
||||
mbgl::style::conversion::stringify(writer, f);
|
||||
},
|
||||
[&](const Image& i) { mbgl::style::conversion::stringify(writer, i); },
|
||||
[&](const std::vector<Value>& arr) {
|
||||
writer.StartArray();
|
||||
for (const auto& item : arr) {
|
||||
writeJSON(writer, item);
|
||||
}
|
||||
writer.EndArray();
|
||||
},
|
||||
[&](const std::unordered_map<std::string, Value>& obj) {
|
||||
writer.StartObject();
|
||||
for (const auto& entry : obj) {
|
||||
writer.Key(entry.first.c_str());
|
||||
writeJSON(writer, entry.second);
|
||||
}
|
||||
writer.EndObject();
|
||||
});
|
||||
}
|
||||
|
||||
std::string stringify(const Value& value) {
|
||||
@@ -129,7 +126,7 @@ Value ValueConverter<mbgl::Value>::toExpressionValue(const mbgl::Value& value) {
|
||||
|
||||
mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value) {
|
||||
return value.match(
|
||||
[&](const Color& color)->mbgl::Value {
|
||||
[&](const Color& color) -> mbgl::Value {
|
||||
std::array<double, 4> array = color.toArray();
|
||||
return std::vector<mbgl::Value>{
|
||||
std::string("rgba"),
|
||||
@@ -139,13 +136,13 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value)
|
||||
array[3],
|
||||
};
|
||||
},
|
||||
[&](const Collator&)->mbgl::Value {
|
||||
[&](const Collator&) -> mbgl::Value {
|
||||
// fromExpressionValue can't be used for Collator values,
|
||||
// because they have no meaningful representation as an mbgl::Value
|
||||
assert(false);
|
||||
return mbgl::Value();
|
||||
},
|
||||
[&](const Formatted& formatted)->mbgl::Value {
|
||||
[&](const Formatted& formatted) -> mbgl::Value {
|
||||
// Serialization strategy for Formatted objects is to return the constant
|
||||
// expression that would generate them.
|
||||
std::vector<mbgl::Value> serialized;
|
||||
@@ -175,7 +172,8 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value)
|
||||
}
|
||||
return serialized;
|
||||
},
|
||||
[&](const std::vector<Value>& values)->mbgl::Value {
|
||||
[&](const Image& i) -> mbgl::Value { return i.toValue(); },
|
||||
[&](const std::vector<Value>& values) -> mbgl::Value {
|
||||
std::vector<mbgl::Value> converted;
|
||||
converted.reserve(values.size());
|
||||
for (const Value& v : values) {
|
||||
@@ -183,7 +181,7 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value)
|
||||
}
|
||||
return converted;
|
||||
},
|
||||
[&](const std::unordered_map<std::string, Value>& values)->mbgl::Value {
|
||||
[&](const std::unordered_map<std::string, Value>& values) -> mbgl::Value {
|
||||
std::unordered_map<std::string, mbgl::Value> converted;
|
||||
converted.reserve(values.size());
|
||||
for(const auto& entry : values) {
|
||||
@@ -191,8 +189,7 @@ mbgl::Value ValueConverter<mbgl::Value>::fromExpressionValue(const Value& value)
|
||||
}
|
||||
return converted;
|
||||
},
|
||||
[&](const auto& a)->mbgl::Value { return a; }
|
||||
);
|
||||
[&](const auto& a) -> mbgl::Value { return a; });
|
||||
}
|
||||
|
||||
Value ValueConverter<float>::toExpressionValue(const float value) {
|
||||
@@ -302,6 +299,10 @@ template <> type::Type valueTypeToExpressionType<std::string>() { return type::S
|
||||
template <> type::Type valueTypeToExpressionType<Color>() { return type::Color; }
|
||||
template <> type::Type valueTypeToExpressionType<Collator>() { return type::Collator; }
|
||||
template <> type::Type valueTypeToExpressionType<Formatted>() { return type::Formatted; }
|
||||
template <>
|
||||
type::Type valueTypeToExpressionType<Image>() {
|
||||
return type::Image;
|
||||
}
|
||||
template <> type::Type valueTypeToExpressionType<std::unordered_map<std::string, Value>>() { return type::Object; }
|
||||
template <> type::Type valueTypeToExpressionType<std::vector<Value>>() { return type::Array(type::Value); }
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ void BackgroundLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringB
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<Color> BackgroundLayer::getDefaultBackgroundColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& BackgroundLayer::getBackgroundColor() const {
|
||||
@@ -91,7 +91,7 @@ TransitionOptions BackgroundLayer::getBackgroundColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> BackgroundLayer::getDefaultBackgroundOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& BackgroundLayer::getBackgroundOpacity() const {
|
||||
@@ -117,15 +117,15 @@ TransitionOptions BackgroundLayer::getBackgroundOpacityTransition() const {
|
||||
return impl().paint.template get<BackgroundOpacity>().options;
|
||||
}
|
||||
|
||||
PropertyValue<std::string> BackgroundLayer::getDefaultBackgroundPattern() {
|
||||
return { "" };
|
||||
PropertyValue<expression::Image> BackgroundLayer::getDefaultBackgroundPattern() {
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::string>& BackgroundLayer::getBackgroundPattern() const {
|
||||
const PropertyValue<expression::Image>& BackgroundLayer::getBackgroundPattern() const {
|
||||
return impl().paint.template get<BackgroundPattern>().value;
|
||||
}
|
||||
|
||||
void BackgroundLayer::setBackgroundPattern(const PropertyValue<std::string>& value) {
|
||||
void BackgroundLayer::setBackgroundPattern(const PropertyValue<expression::Image>& value) {
|
||||
if (value == getBackgroundPattern())
|
||||
return;
|
||||
auto impl_ = mutableImpl();
|
||||
@@ -208,7 +208,8 @@ optional<Error> BackgroundLayer::setPaintProperty(const std::string& name, const
|
||||
|
||||
if (property == Property::BackgroundPattern) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, false, false);
|
||||
optional<PropertyValue<expression::Image>> typedValue =
|
||||
convert<PropertyValue<expression::Image>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ struct BackgroundOpacity : PaintProperty<float> {
|
||||
static float defaultValue() { return 1; }
|
||||
};
|
||||
|
||||
struct BackgroundPattern : CrossFadedPaintProperty<std::string> {
|
||||
static std::string defaultValue() { return ""; }
|
||||
struct BackgroundPattern : CrossFadedPaintProperty<expression::Image> {
|
||||
static expression::Image defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
class BackgroundPaintProperties : public Properties<
|
||||
|
||||
@@ -64,7 +64,7 @@ void CircleLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffe
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<float> CircleLayer::getDefaultCircleBlur() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& CircleLayer::getCircleBlur() const {
|
||||
@@ -91,7 +91,7 @@ TransitionOptions CircleLayer::getCircleBlurTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> CircleLayer::getDefaultCircleColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& CircleLayer::getCircleColor() const {
|
||||
@@ -118,7 +118,7 @@ TransitionOptions CircleLayer::getCircleColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> CircleLayer::getDefaultCircleOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& CircleLayer::getCircleOpacity() const {
|
||||
@@ -145,7 +145,7 @@ TransitionOptions CircleLayer::getCircleOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<AlignmentType> CircleLayer::getDefaultCirclePitchAlignment() {
|
||||
return { AlignmentType::Viewport };
|
||||
return {AlignmentType::Viewport};
|
||||
}
|
||||
|
||||
const PropertyValue<AlignmentType>& CircleLayer::getCirclePitchAlignment() const {
|
||||
@@ -172,7 +172,7 @@ TransitionOptions CircleLayer::getCirclePitchAlignmentTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<CirclePitchScaleType> CircleLayer::getDefaultCirclePitchScale() {
|
||||
return { CirclePitchScaleType::Map };
|
||||
return {CirclePitchScaleType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<CirclePitchScaleType>& CircleLayer::getCirclePitchScale() const {
|
||||
@@ -199,7 +199,7 @@ TransitionOptions CircleLayer::getCirclePitchScaleTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> CircleLayer::getDefaultCircleRadius() {
|
||||
return { 5 };
|
||||
return {5};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& CircleLayer::getCircleRadius() const {
|
||||
@@ -226,7 +226,7 @@ TransitionOptions CircleLayer::getCircleRadiusTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> CircleLayer::getDefaultCircleStrokeColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& CircleLayer::getCircleStrokeColor() const {
|
||||
@@ -253,7 +253,7 @@ TransitionOptions CircleLayer::getCircleStrokeColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> CircleLayer::getDefaultCircleStrokeOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& CircleLayer::getCircleStrokeOpacity() const {
|
||||
@@ -280,7 +280,7 @@ TransitionOptions CircleLayer::getCircleStrokeOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> CircleLayer::getDefaultCircleStrokeWidth() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& CircleLayer::getCircleStrokeWidth() const {
|
||||
@@ -307,7 +307,7 @@ TransitionOptions CircleLayer::getCircleStrokeWidthTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<std::array<float, 2>> CircleLayer::getDefaultCircleTranslate() {
|
||||
return { {{ 0, 0 }} };
|
||||
return {{{0, 0}}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::array<float, 2>>& CircleLayer::getCircleTranslate() const {
|
||||
@@ -334,7 +334,7 @@ TransitionOptions CircleLayer::getCircleTranslateTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<TranslateAnchorType> CircleLayer::getDefaultCircleTranslateAnchor() {
|
||||
return { TranslateAnchorType::Map };
|
||||
return {TranslateAnchorType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<TranslateAnchorType>& CircleLayer::getCircleTranslateAnchor() const {
|
||||
@@ -497,7 +497,8 @@ optional<Error> CircleLayer::setPaintProperty(const std::string& name, const Con
|
||||
|
||||
if (property == Property::CirclePitchScale) {
|
||||
Error error;
|
||||
optional<PropertyValue<CirclePitchScaleType>> typedValue = convert<PropertyValue<CirclePitchScaleType>>(value, error, false, false);
|
||||
optional<PropertyValue<CirclePitchScaleType>> typedValue =
|
||||
convert<PropertyValue<CirclePitchScaleType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -509,7 +510,8 @@ optional<Error> CircleLayer::setPaintProperty(const std::string& name, const Con
|
||||
|
||||
if (property == Property::CircleTranslate) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -521,7 +523,8 @@ optional<Error> CircleLayer::setPaintProperty(const std::string& name, const Con
|
||||
|
||||
if (property == Property::CircleTranslateAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue =
|
||||
convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ struct CircleStrokeWidth : DataDrivenPaintProperty<float, attributes::stroke_wid
|
||||
};
|
||||
|
||||
struct CircleTranslate : PaintProperty<std::array<float, 2>> {
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct CircleTranslateAnchor : PaintProperty<TranslateAnchorType> {
|
||||
|
||||
@@ -64,7 +64,7 @@ void FillExtrusionLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::Stri
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionBase() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& FillExtrusionLayer::getFillExtrusionBase() const {
|
||||
@@ -91,7 +91,7 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionBaseTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> FillExtrusionLayer::getDefaultFillExtrusionColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& FillExtrusionLayer::getFillExtrusionColor() const {
|
||||
@@ -118,7 +118,7 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionHeight() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& FillExtrusionLayer::getFillExtrusionHeight() const {
|
||||
@@ -145,7 +145,7 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionHeightTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> FillExtrusionLayer::getDefaultFillExtrusionOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& FillExtrusionLayer::getFillExtrusionOpacity() const {
|
||||
@@ -171,15 +171,15 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionOpacityTransition() const
|
||||
return impl().paint.template get<FillExtrusionOpacity>().options;
|
||||
}
|
||||
|
||||
PropertyValue<std::string> FillExtrusionLayer::getDefaultFillExtrusionPattern() {
|
||||
return { "" };
|
||||
PropertyValue<expression::Image> FillExtrusionLayer::getDefaultFillExtrusionPattern() {
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::string>& FillExtrusionLayer::getFillExtrusionPattern() const {
|
||||
const PropertyValue<expression::Image>& FillExtrusionLayer::getFillExtrusionPattern() const {
|
||||
return impl().paint.template get<FillExtrusionPattern>().value;
|
||||
}
|
||||
|
||||
void FillExtrusionLayer::setFillExtrusionPattern(const PropertyValue<std::string>& value) {
|
||||
void FillExtrusionLayer::setFillExtrusionPattern(const PropertyValue<expression::Image>& value) {
|
||||
if (value == getFillExtrusionPattern())
|
||||
return;
|
||||
auto impl_ = mutableImpl();
|
||||
@@ -199,7 +199,7 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionPatternTransition() const
|
||||
}
|
||||
|
||||
PropertyValue<std::array<float, 2>> FillExtrusionLayer::getDefaultFillExtrusionTranslate() {
|
||||
return { {{ 0, 0 }} };
|
||||
return {{{0, 0}}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::array<float, 2>>& FillExtrusionLayer::getFillExtrusionTranslate() const {
|
||||
@@ -226,7 +226,7 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateTransition() cons
|
||||
}
|
||||
|
||||
PropertyValue<TranslateAnchorType> FillExtrusionLayer::getDefaultFillExtrusionTranslateAnchor() {
|
||||
return { TranslateAnchorType::Map };
|
||||
return {TranslateAnchorType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<TranslateAnchorType>& FillExtrusionLayer::getFillExtrusionTranslateAnchor() const {
|
||||
@@ -253,7 +253,7 @@ TransitionOptions FillExtrusionLayer::getFillExtrusionTranslateAnchorTransition(
|
||||
}
|
||||
|
||||
PropertyValue<bool> FillExtrusionLayer::getDefaultFillExtrusionVerticalGradient() {
|
||||
return { true };
|
||||
return {true};
|
||||
}
|
||||
|
||||
const PropertyValue<bool>& FillExtrusionLayer::getFillExtrusionVerticalGradient() const {
|
||||
@@ -382,7 +382,8 @@ optional<Error> FillExtrusionLayer::setPaintProperty(const std::string& name, co
|
||||
|
||||
if (property == Property::FillExtrusionPattern) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, false);
|
||||
optional<PropertyValue<expression::Image>> typedValue =
|
||||
convert<PropertyValue<expression::Image>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -394,7 +395,8 @@ optional<Error> FillExtrusionLayer::setPaintProperty(const std::string& name, co
|
||||
|
||||
if (property == Property::FillExtrusionTranslate) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -406,7 +408,8 @@ optional<Error> FillExtrusionLayer::setPaintProperty(const std::string& name, co
|
||||
|
||||
if (property == Property::FillExtrusionTranslateAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue =
|
||||
convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ struct FillExtrusionOpacity : PaintProperty<float> {
|
||||
static float defaultValue() { return 1; }
|
||||
};
|
||||
|
||||
struct FillExtrusionPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> {
|
||||
static std::string defaultValue() { return ""; }
|
||||
struct FillExtrusionPattern : CrossFadedDataDrivenPaintProperty<expression::Image, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> {
|
||||
static expression::Image defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct FillExtrusionTranslate : PaintProperty<std::array<float, 2>> {
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct FillExtrusionTranslateAnchor : PaintProperty<TranslateAnchorType> {
|
||||
|
||||
@@ -64,7 +64,7 @@ void FillLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<bool> FillLayer::getDefaultFillAntialias() {
|
||||
return { true };
|
||||
return {true};
|
||||
}
|
||||
|
||||
const PropertyValue<bool>& FillLayer::getFillAntialias() const {
|
||||
@@ -91,7 +91,7 @@ TransitionOptions FillLayer::getFillAntialiasTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> FillLayer::getDefaultFillColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& FillLayer::getFillColor() const {
|
||||
@@ -118,7 +118,7 @@ TransitionOptions FillLayer::getFillColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> FillLayer::getDefaultFillOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& FillLayer::getFillOpacity() const {
|
||||
@@ -145,7 +145,7 @@ TransitionOptions FillLayer::getFillOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> FillLayer::getDefaultFillOutlineColor() {
|
||||
return { {} };
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& FillLayer::getFillOutlineColor() const {
|
||||
@@ -171,15 +171,15 @@ TransitionOptions FillLayer::getFillOutlineColorTransition() const {
|
||||
return impl().paint.template get<FillOutlineColor>().options;
|
||||
}
|
||||
|
||||
PropertyValue<std::string> FillLayer::getDefaultFillPattern() {
|
||||
return { "" };
|
||||
PropertyValue<expression::Image> FillLayer::getDefaultFillPattern() {
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::string>& FillLayer::getFillPattern() const {
|
||||
const PropertyValue<expression::Image>& FillLayer::getFillPattern() const {
|
||||
return impl().paint.template get<FillPattern>().value;
|
||||
}
|
||||
|
||||
void FillLayer::setFillPattern(const PropertyValue<std::string>& value) {
|
||||
void FillLayer::setFillPattern(const PropertyValue<expression::Image>& value) {
|
||||
if (value == getFillPattern())
|
||||
return;
|
||||
auto impl_ = mutableImpl();
|
||||
@@ -199,7 +199,7 @@ TransitionOptions FillLayer::getFillPatternTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<std::array<float, 2>> FillLayer::getDefaultFillTranslate() {
|
||||
return { {{ 0, 0 }} };
|
||||
return {{{0, 0}}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::array<float, 2>>& FillLayer::getFillTranslate() const {
|
||||
@@ -226,7 +226,7 @@ TransitionOptions FillLayer::getFillTranslateTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<TranslateAnchorType> FillLayer::getDefaultFillTranslateAnchor() {
|
||||
return { TranslateAnchorType::Map };
|
||||
return {TranslateAnchorType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<TranslateAnchorType>& FillLayer::getFillTranslateAnchor() const {
|
||||
@@ -351,7 +351,8 @@ optional<Error> FillLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::FillPattern) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, false);
|
||||
optional<PropertyValue<expression::Image>> typedValue =
|
||||
convert<PropertyValue<expression::Image>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -363,7 +364,8 @@ optional<Error> FillLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::FillTranslate) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -375,7 +377,8 @@ optional<Error> FillLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::FillTranslateAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue =
|
||||
convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -32,12 +32,12 @@ struct FillOutlineColor : DataDrivenPaintProperty<Color, attributes::outline_col
|
||||
static Color defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct FillPattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> {
|
||||
static std::string defaultValue() { return ""; }
|
||||
struct FillPattern : CrossFadedDataDrivenPaintProperty<expression::Image, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> {
|
||||
static expression::Image defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct FillTranslate : PaintProperty<std::array<float, 2>> {
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct FillTranslateAnchor : PaintProperty<TranslateAnchorType> {
|
||||
|
||||
@@ -93,7 +93,7 @@ TransitionOptions HeatmapLayer::getHeatmapColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> HeatmapLayer::getDefaultHeatmapIntensity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& HeatmapLayer::getHeatmapIntensity() const {
|
||||
@@ -120,7 +120,7 @@ TransitionOptions HeatmapLayer::getHeatmapIntensityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> HeatmapLayer::getDefaultHeatmapOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& HeatmapLayer::getHeatmapOpacity() const {
|
||||
@@ -147,7 +147,7 @@ TransitionOptions HeatmapLayer::getHeatmapOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> HeatmapLayer::getDefaultHeatmapRadius() {
|
||||
return { 30 };
|
||||
return {30};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& HeatmapLayer::getHeatmapRadius() const {
|
||||
@@ -174,7 +174,7 @@ TransitionOptions HeatmapLayer::getHeatmapRadiusTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> HeatmapLayer::getDefaultHeatmapWeight() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& HeatmapLayer::getHeatmapWeight() const {
|
||||
|
||||
@@ -64,7 +64,7 @@ void HillshadeLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBu
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<Color> HillshadeLayer::getDefaultHillshadeAccentColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& HillshadeLayer::getHillshadeAccentColor() const {
|
||||
@@ -91,7 +91,7 @@ TransitionOptions HillshadeLayer::getHillshadeAccentColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> HillshadeLayer::getDefaultHillshadeExaggeration() {
|
||||
return { 0.5 };
|
||||
return {0.5};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& HillshadeLayer::getHillshadeExaggeration() const {
|
||||
@@ -118,7 +118,7 @@ TransitionOptions HillshadeLayer::getHillshadeExaggerationTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> HillshadeLayer::getDefaultHillshadeHighlightColor() {
|
||||
return { Color::white() };
|
||||
return {Color::white()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& HillshadeLayer::getHillshadeHighlightColor() const {
|
||||
@@ -145,7 +145,7 @@ TransitionOptions HillshadeLayer::getHillshadeHighlightColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<HillshadeIlluminationAnchorType> HillshadeLayer::getDefaultHillshadeIlluminationAnchor() {
|
||||
return { HillshadeIlluminationAnchorType::Viewport };
|
||||
return {HillshadeIlluminationAnchorType::Viewport};
|
||||
}
|
||||
|
||||
const PropertyValue<HillshadeIlluminationAnchorType>& HillshadeLayer::getHillshadeIlluminationAnchor() const {
|
||||
@@ -172,7 +172,7 @@ TransitionOptions HillshadeLayer::getHillshadeIlluminationAnchorTransition() con
|
||||
}
|
||||
|
||||
PropertyValue<float> HillshadeLayer::getDefaultHillshadeIlluminationDirection() {
|
||||
return { 335 };
|
||||
return {335};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& HillshadeLayer::getHillshadeIlluminationDirection() const {
|
||||
@@ -199,7 +199,7 @@ TransitionOptions HillshadeLayer::getHillshadeIlluminationDirectionTransition()
|
||||
}
|
||||
|
||||
PropertyValue<Color> HillshadeLayer::getDefaultHillshadeShadowColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& HillshadeLayer::getHillshadeShadowColor() const {
|
||||
@@ -320,7 +320,8 @@ optional<Error> HillshadeLayer::setPaintProperty(const std::string& name, const
|
||||
|
||||
if (property == Property::HillshadeIlluminationAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<HillshadeIlluminationAnchorType>> typedValue = convert<PropertyValue<HillshadeIlluminationAnchorType>>(value, error, false, false);
|
||||
optional<PropertyValue<HillshadeIlluminationAnchorType>> typedValue =
|
||||
convert<PropertyValue<HillshadeIlluminationAnchorType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,15 @@ layerCapabilities['heatmap'] = defaults.require('Source')
|
||||
.set('TileKind', 'Geometry')
|
||||
.finalize();
|
||||
layerCapabilities['raster'] = defaults.require('Source').set('TileKind', 'Raster').finalize();
|
||||
|
||||
// Splits lines that are over 120 characters at the firts occurance of '='.
|
||||
const split120Line = line => {
|
||||
if (line.length > 120) {
|
||||
return line.replace('=', '=\n ');
|
||||
}
|
||||
return line;
|
||||
};
|
||||
|
||||
%>
|
||||
// static
|
||||
const LayerTypeInfo* <%- camelize(type) %>Layer::Impl::staticTypeInfo() noexcept {
|
||||
@@ -155,7 +164,7 @@ void <%- camelize(type) %>Layer::set<%- camelize(property.name) %>(const <%- pro
|
||||
std::string rawValue = R"JSON(<%- JSON.stringify(property.default) %>)JSON";
|
||||
return *conversion::convertJSON<<%- propertyValueType(property)%>>(rawValue, error);
|
||||
<% } else { -%>
|
||||
return { <%- defaultValue(property) %> };
|
||||
return {<%- defaultValue(property) %>};
|
||||
<% } -%>
|
||||
}
|
||||
|
||||
@@ -243,7 +252,7 @@ optional<Error> <%- camelize(type) %>Layer::setPaintProperty(const std::string&
|
||||
%>
|
||||
if (<%- properties.map(p => `property == Property::${camelize(p.name)}`).join(' || ') %>) {
|
||||
Error error;
|
||||
<%- key %>;
|
||||
<%- split120Line(key) %>;
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -323,7 +332,7 @@ optional<Error> <%- camelize(type) %>Layer::setLayoutProperty(const std::string&
|
||||
%>
|
||||
if (<%- properties.map(p => `property == Property::${camelize(p.name)}`).join(' || ') %>) {
|
||||
Error error;
|
||||
<%- key %>;
|
||||
<%- split120Line(key) %>;
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ void LineLayer::setLineRoundLimit(const PropertyValue<float>& value) {
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<float> LineLayer::getDefaultLineBlur() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& LineLayer::getLineBlur() const {
|
||||
@@ -156,7 +156,7 @@ TransitionOptions LineLayer::getLineBlurTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> LineLayer::getDefaultLineColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& LineLayer::getLineColor() const {
|
||||
@@ -183,7 +183,7 @@ TransitionOptions LineLayer::getLineColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<std::vector<float>> LineLayer::getDefaultLineDasharray() {
|
||||
return { { } };
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::vector<float>>& LineLayer::getLineDasharray() const {
|
||||
@@ -210,7 +210,7 @@ TransitionOptions LineLayer::getLineDasharrayTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> LineLayer::getDefaultLineGapWidth() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& LineLayer::getLineGapWidth() const {
|
||||
@@ -237,7 +237,7 @@ TransitionOptions LineLayer::getLineGapWidthTransition() const {
|
||||
}
|
||||
|
||||
ColorRampPropertyValue LineLayer::getDefaultLineGradient() {
|
||||
return { {} };
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const ColorRampPropertyValue& LineLayer::getLineGradient() const {
|
||||
@@ -264,7 +264,7 @@ TransitionOptions LineLayer::getLineGradientTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> LineLayer::getDefaultLineOffset() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& LineLayer::getLineOffset() const {
|
||||
@@ -291,7 +291,7 @@ TransitionOptions LineLayer::getLineOffsetTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> LineLayer::getDefaultLineOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& LineLayer::getLineOpacity() const {
|
||||
@@ -317,15 +317,15 @@ TransitionOptions LineLayer::getLineOpacityTransition() const {
|
||||
return impl().paint.template get<LineOpacity>().options;
|
||||
}
|
||||
|
||||
PropertyValue<std::string> LineLayer::getDefaultLinePattern() {
|
||||
return { "" };
|
||||
PropertyValue<expression::Image> LineLayer::getDefaultLinePattern() {
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::string>& LineLayer::getLinePattern() const {
|
||||
const PropertyValue<expression::Image>& LineLayer::getLinePattern() const {
|
||||
return impl().paint.template get<LinePattern>().value;
|
||||
}
|
||||
|
||||
void LineLayer::setLinePattern(const PropertyValue<std::string>& value) {
|
||||
void LineLayer::setLinePattern(const PropertyValue<expression::Image>& value) {
|
||||
if (value == getLinePattern())
|
||||
return;
|
||||
auto impl_ = mutableImpl();
|
||||
@@ -345,7 +345,7 @@ TransitionOptions LineLayer::getLinePatternTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<std::array<float, 2>> LineLayer::getDefaultLineTranslate() {
|
||||
return { {{ 0, 0 }} };
|
||||
return {{{0, 0}}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::array<float, 2>>& LineLayer::getLineTranslate() const {
|
||||
@@ -372,7 +372,7 @@ TransitionOptions LineLayer::getLineTranslateTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<TranslateAnchorType> LineLayer::getDefaultLineTranslateAnchor() {
|
||||
return { TranslateAnchorType::Map };
|
||||
return {TranslateAnchorType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<TranslateAnchorType>& LineLayer::getLineTranslateAnchor() const {
|
||||
@@ -399,7 +399,7 @@ TransitionOptions LineLayer::getLineTranslateAnchorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> LineLayer::getDefaultLineWidth() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& LineLayer::getLineWidth() const {
|
||||
@@ -552,7 +552,8 @@ optional<Error> LineLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::LineDasharray) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::vector<float>>> typedValue = convert<PropertyValue<std::vector<float>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::vector<float>>> typedValue =
|
||||
convert<PropertyValue<std::vector<float>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -576,7 +577,8 @@ optional<Error> LineLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::LinePattern) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, false);
|
||||
optional<PropertyValue<expression::Image>> typedValue =
|
||||
convert<PropertyValue<expression::Image>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -588,7 +590,8 @@ optional<Error> LineLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::LineTranslate) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue = convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -600,7 +603,8 @@ optional<Error> LineLayer::setPaintProperty(const std::string& name, const Conve
|
||||
|
||||
if (property == Property::LineTranslateAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue =
|
||||
convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ struct LineColor : DataDrivenPaintProperty<Color, attributes::color, uniforms::c
|
||||
};
|
||||
|
||||
struct LineDasharray : CrossFadedPaintProperty<std::vector<float>> {
|
||||
static std::vector<float> defaultValue() { return { }; }
|
||||
static std::vector<float> defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct LineFloorWidth : DataDrivenPaintProperty<float, attributes::floorwidth, uniforms::floorwidth> {
|
||||
@@ -68,12 +68,12 @@ struct LineOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniform
|
||||
static float defaultValue() { return 1; }
|
||||
};
|
||||
|
||||
struct LinePattern : CrossFadedDataDrivenPaintProperty<std::string, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> {
|
||||
static std::string defaultValue() { return ""; }
|
||||
struct LinePattern : CrossFadedDataDrivenPaintProperty<expression::Image, attributes::pattern_to, uniforms::pattern_to, attributes::pattern_from, uniforms::pattern_from> {
|
||||
static expression::Image defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct LineTranslate : PaintProperty<std::array<float, 2>> {
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct LineTranslateAnchor : PaintProperty<TranslateAnchorType> {
|
||||
|
||||
@@ -64,7 +64,7 @@ void RasterLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffe
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMax() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterBrightnessMax() const {
|
||||
@@ -91,7 +91,7 @@ TransitionOptions RasterLayer::getRasterBrightnessMaxTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterBrightnessMin() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterBrightnessMin() const {
|
||||
@@ -118,7 +118,7 @@ TransitionOptions RasterLayer::getRasterBrightnessMinTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterContrast() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterContrast() const {
|
||||
@@ -145,7 +145,7 @@ TransitionOptions RasterLayer::getRasterContrastTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterFadeDuration() {
|
||||
return { 300 };
|
||||
return {300};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterFadeDuration() const {
|
||||
@@ -172,7 +172,7 @@ TransitionOptions RasterLayer::getRasterFadeDurationTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterHueRotate() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterHueRotate() const {
|
||||
@@ -199,7 +199,7 @@ TransitionOptions RasterLayer::getRasterHueRotateTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterOpacity() const {
|
||||
@@ -226,7 +226,7 @@ TransitionOptions RasterLayer::getRasterOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<RasterResamplingType> RasterLayer::getDefaultRasterResampling() {
|
||||
return { RasterResamplingType::Linear };
|
||||
return {RasterResamplingType::Linear};
|
||||
}
|
||||
|
||||
const PropertyValue<RasterResamplingType>& RasterLayer::getRasterResampling() const {
|
||||
@@ -253,7 +253,7 @@ TransitionOptions RasterLayer::getRasterResamplingTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> RasterLayer::getDefaultRasterSaturation() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& RasterLayer::getRasterSaturation() const {
|
||||
@@ -383,7 +383,8 @@ optional<Error> RasterLayer::setPaintProperty(const std::string& name, const Con
|
||||
|
||||
if (property == Property::RasterResampling) {
|
||||
Error error;
|
||||
optional<PropertyValue<RasterResamplingType>> typedValue = convert<PropertyValue<RasterResamplingType>>(value, error, false, false);
|
||||
optional<PropertyValue<RasterResamplingType>> typedValue =
|
||||
convert<PropertyValue<RasterResamplingType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -109,15 +109,15 @@ void SymbolLayer::setIconIgnorePlacement(const PropertyValue<bool>& value) {
|
||||
baseImpl = std::move(impl_);
|
||||
observer->onLayerChanged(*this);
|
||||
}
|
||||
PropertyValue<std::string> SymbolLayer::getDefaultIconImage() {
|
||||
PropertyValue<expression::Image> SymbolLayer::getDefaultIconImage() {
|
||||
return IconImage::defaultValue();
|
||||
}
|
||||
|
||||
const PropertyValue<std::string>& SymbolLayer::getIconImage() const {
|
||||
const PropertyValue<expression::Image>& SymbolLayer::getIconImage() const {
|
||||
return impl().layout.get<IconImage>();
|
||||
}
|
||||
|
||||
void SymbolLayer::setIconImage(const PropertyValue<std::string>& value) {
|
||||
void SymbolLayer::setIconImage(const PropertyValue<expression::Image>& value) {
|
||||
if (value == getIconImage())
|
||||
return;
|
||||
auto impl_ = mutableImpl();
|
||||
@@ -721,7 +721,7 @@ void SymbolLayer::setTextWritingMode(const PropertyValue<std::vector<TextWriting
|
||||
// Paint properties
|
||||
|
||||
PropertyValue<Color> SymbolLayer::getDefaultIconColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& SymbolLayer::getIconColor() const {
|
||||
@@ -748,7 +748,7 @@ TransitionOptions SymbolLayer::getIconColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> SymbolLayer::getDefaultIconHaloBlur() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& SymbolLayer::getIconHaloBlur() const {
|
||||
@@ -775,7 +775,7 @@ TransitionOptions SymbolLayer::getIconHaloBlurTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> SymbolLayer::getDefaultIconHaloColor() {
|
||||
return { {} };
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& SymbolLayer::getIconHaloColor() const {
|
||||
@@ -802,7 +802,7 @@ TransitionOptions SymbolLayer::getIconHaloColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> SymbolLayer::getDefaultIconHaloWidth() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& SymbolLayer::getIconHaloWidth() const {
|
||||
@@ -829,7 +829,7 @@ TransitionOptions SymbolLayer::getIconHaloWidthTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> SymbolLayer::getDefaultIconOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& SymbolLayer::getIconOpacity() const {
|
||||
@@ -856,7 +856,7 @@ TransitionOptions SymbolLayer::getIconOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultIconTranslate() {
|
||||
return { {{ 0, 0 }} };
|
||||
return {{{0, 0}}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::array<float, 2>>& SymbolLayer::getIconTranslate() const {
|
||||
@@ -883,7 +883,7 @@ TransitionOptions SymbolLayer::getIconTranslateTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultIconTranslateAnchor() {
|
||||
return { TranslateAnchorType::Map };
|
||||
return {TranslateAnchorType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<TranslateAnchorType>& SymbolLayer::getIconTranslateAnchor() const {
|
||||
@@ -910,7 +910,7 @@ TransitionOptions SymbolLayer::getIconTranslateAnchorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> SymbolLayer::getDefaultTextColor() {
|
||||
return { Color::black() };
|
||||
return {Color::black()};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& SymbolLayer::getTextColor() const {
|
||||
@@ -937,7 +937,7 @@ TransitionOptions SymbolLayer::getTextColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> SymbolLayer::getDefaultTextHaloBlur() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& SymbolLayer::getTextHaloBlur() const {
|
||||
@@ -964,7 +964,7 @@ TransitionOptions SymbolLayer::getTextHaloBlurTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<Color> SymbolLayer::getDefaultTextHaloColor() {
|
||||
return { {} };
|
||||
return {{}};
|
||||
}
|
||||
|
||||
const PropertyValue<Color>& SymbolLayer::getTextHaloColor() const {
|
||||
@@ -991,7 +991,7 @@ TransitionOptions SymbolLayer::getTextHaloColorTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> SymbolLayer::getDefaultTextHaloWidth() {
|
||||
return { 0 };
|
||||
return {0};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& SymbolLayer::getTextHaloWidth() const {
|
||||
@@ -1018,7 +1018,7 @@ TransitionOptions SymbolLayer::getTextHaloWidthTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<float> SymbolLayer::getDefaultTextOpacity() {
|
||||
return { 1 };
|
||||
return {1};
|
||||
}
|
||||
|
||||
const PropertyValue<float>& SymbolLayer::getTextOpacity() const {
|
||||
@@ -1045,7 +1045,7 @@ TransitionOptions SymbolLayer::getTextOpacityTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<std::array<float, 2>> SymbolLayer::getDefaultTextTranslate() {
|
||||
return { {{ 0, 0 }} };
|
||||
return {{{0, 0}}};
|
||||
}
|
||||
|
||||
const PropertyValue<std::array<float, 2>>& SymbolLayer::getTextTranslate() const {
|
||||
@@ -1072,7 +1072,7 @@ TransitionOptions SymbolLayer::getTextTranslateTransition() const {
|
||||
}
|
||||
|
||||
PropertyValue<TranslateAnchorType> SymbolLayer::getDefaultTextTranslateAnchor() {
|
||||
return { TranslateAnchorType::Map };
|
||||
return {TranslateAnchorType::Map};
|
||||
}
|
||||
|
||||
const PropertyValue<TranslateAnchorType>& SymbolLayer::getTextTranslateAnchor() const {
|
||||
@@ -1332,7 +1332,8 @@ optional<Error> SymbolLayer::setPaintProperty(const std::string& name, const Con
|
||||
|
||||
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);
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 2>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1351,7 +1352,8 @@ optional<Error> SymbolLayer::setPaintProperty(const std::string& name, const Con
|
||||
|
||||
if (property == Property::IconTranslateAnchor || property == Property::TextTranslateAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue = convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
optional<PropertyValue<TranslateAnchorType>> typedValue =
|
||||
convert<PropertyValue<TranslateAnchorType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1665,7 +1667,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::IconAnchor || property == Property::TextAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<SymbolAnchorType>> typedValue = convert<PropertyValue<SymbolAnchorType>>(value, error, true, false);
|
||||
optional<PropertyValue<SymbolAnchorType>> typedValue =
|
||||
convert<PropertyValue<SymbolAnchorType>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1684,7 +1687,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::IconImage) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::string>> typedValue = convert<PropertyValue<std::string>>(value, error, true, true);
|
||||
optional<PropertyValue<expression::Image>> typedValue =
|
||||
convert<PropertyValue<expression::Image>>(value, error, true, true);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1696,7 +1700,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
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);
|
||||
optional<PropertyValue<std::array<float, 2>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 2>>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1827,7 +1832,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::IconTextFit) {
|
||||
Error error;
|
||||
optional<PropertyValue<IconTextFitType>> typedValue = convert<PropertyValue<IconTextFitType>>(value, error, false, false);
|
||||
optional<PropertyValue<IconTextFitType>> typedValue =
|
||||
convert<PropertyValue<IconTextFitType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1839,7 +1845,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::IconTextFitPadding) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::array<float, 4>>> typedValue = convert<PropertyValue<std::array<float, 4>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::array<float, 4>>> typedValue =
|
||||
convert<PropertyValue<std::array<float, 4>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1851,7 +1858,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::SymbolPlacement) {
|
||||
Error error;
|
||||
optional<PropertyValue<SymbolPlacementType>> typedValue = convert<PropertyValue<SymbolPlacementType>>(value, error, false, false);
|
||||
optional<PropertyValue<SymbolPlacementType>> typedValue =
|
||||
convert<PropertyValue<SymbolPlacementType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1863,7 +1871,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::SymbolZOrder) {
|
||||
Error error;
|
||||
optional<PropertyValue<SymbolZOrderType>> typedValue = convert<PropertyValue<SymbolZOrderType>>(value, error, false, false);
|
||||
optional<PropertyValue<SymbolZOrderType>> typedValue =
|
||||
convert<PropertyValue<SymbolZOrderType>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1875,7 +1884,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::TextField) {
|
||||
Error error;
|
||||
optional<PropertyValue<expression::Formatted>> typedValue = convert<PropertyValue<expression::Formatted>>(value, error, true, true);
|
||||
optional<PropertyValue<expression::Formatted>> typedValue =
|
||||
convert<PropertyValue<expression::Formatted>>(value, error, true, true);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1887,7 +1897,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::TextFont) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::vector<std::string>>> typedValue = convert<PropertyValue<std::vector<std::string>>>(value, error, true, false);
|
||||
optional<PropertyValue<std::vector<std::string>>> typedValue =
|
||||
convert<PropertyValue<std::vector<std::string>>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1911,7 +1922,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::TextTransform) {
|
||||
Error error;
|
||||
optional<PropertyValue<TextTransformType>> typedValue = convert<PropertyValue<TextTransformType>>(value, error, true, false);
|
||||
optional<PropertyValue<TextTransformType>> typedValue =
|
||||
convert<PropertyValue<TextTransformType>>(value, error, true, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1923,7 +1935,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::TextVariableAnchor) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::vector<TextVariableAnchorType>>> typedValue = convert<PropertyValue<std::vector<TextVariableAnchorType>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::vector<TextVariableAnchorType>>> typedValue =
|
||||
convert<PropertyValue<std::vector<TextVariableAnchorType>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
@@ -1935,7 +1948,8 @@ optional<Error> SymbolLayer::setLayoutProperty(const std::string& name, const Co
|
||||
|
||||
if (property == Property::TextWritingMode) {
|
||||
Error error;
|
||||
optional<PropertyValue<std::vector<TextWritingModeType>>> typedValue = convert<PropertyValue<std::vector<TextWritingModeType>>>(value, error, false, false);
|
||||
optional<PropertyValue<std::vector<TextWritingModeType>>> typedValue =
|
||||
convert<PropertyValue<std::vector<TextWritingModeType>>>(value, error, false, false);
|
||||
if (!typedValue) {
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -31,9 +31,9 @@ struct IconIgnorePlacement : LayoutProperty<bool> {
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct IconImage : DataDrivenLayoutProperty<std::string> {
|
||||
struct IconImage : DataDrivenLayoutProperty<expression::Image> {
|
||||
static constexpr const char *name() { return "icon-image"; }
|
||||
static std::string defaultValue() { return ""; }
|
||||
static expression::Image defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct IconKeepUpright : LayoutProperty<bool> {
|
||||
@@ -43,7 +43,7 @@ struct IconKeepUpright : LayoutProperty<bool> {
|
||||
|
||||
struct IconOffset : DataDrivenLayoutProperty<std::array<float, 2>> {
|
||||
static constexpr const char *name() { return "icon-offset"; }
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct IconOptional : LayoutProperty<bool> {
|
||||
@@ -83,7 +83,7 @@ struct IconTextFit : LayoutProperty<IconTextFitType> {
|
||||
|
||||
struct IconTextFitPadding : LayoutProperty<std::array<float, 4>> {
|
||||
static constexpr const char *name() { return "icon-text-fit-padding"; }
|
||||
static std::array<float, 4> defaultValue() { return {{ 0, 0, 0, 0 }}; }
|
||||
static std::array<float, 4> defaultValue() { return {{0, 0, 0, 0}}; }
|
||||
};
|
||||
|
||||
struct SymbolAvoidEdges : LayoutProperty<bool> {
|
||||
@@ -123,12 +123,12 @@ struct TextAnchor : DataDrivenLayoutProperty<SymbolAnchorType> {
|
||||
|
||||
struct TextField : DataDrivenLayoutProperty<expression::Formatted> {
|
||||
static constexpr const char *name() { return "text-field"; }
|
||||
static expression::Formatted defaultValue() { return ""; }
|
||||
static expression::Formatted defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct TextFont : DataDrivenLayoutProperty<std::vector<std::string>> {
|
||||
static constexpr const char *name() { return "text-font"; }
|
||||
static std::vector<std::string> defaultValue() { return { "Open Sans Regular", "Arial Unicode MS Regular" }; }
|
||||
static std::vector<std::string> defaultValue() { return {{"Open Sans Regular"}, {"Arial Unicode MS Regular"}}; }
|
||||
};
|
||||
|
||||
struct TextIgnorePlacement : LayoutProperty<bool> {
|
||||
@@ -168,7 +168,7 @@ struct TextMaxWidth : DataDrivenLayoutProperty<float> {
|
||||
|
||||
struct TextOffset : DataDrivenLayoutProperty<std::array<float, 2>> {
|
||||
static constexpr const char *name() { return "text-offset"; }
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct TextOptional : LayoutProperty<bool> {
|
||||
@@ -213,12 +213,12 @@ struct TextTransform : DataDrivenLayoutProperty<TextTransformType> {
|
||||
|
||||
struct TextVariableAnchor : LayoutProperty<std::vector<TextVariableAnchorType>> {
|
||||
static constexpr const char *name() { return "text-variable-anchor"; }
|
||||
static std::vector<TextVariableAnchorType> defaultValue() { return { }; }
|
||||
static std::vector<TextVariableAnchorType> defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct TextWritingMode : LayoutProperty<std::vector<TextWritingModeType>> {
|
||||
static constexpr const char *name() { return "text-writing-mode"; }
|
||||
static std::vector<TextWritingModeType> defaultValue() { return { }; }
|
||||
static std::vector<TextWritingModeType> defaultValue() { return {}; }
|
||||
};
|
||||
|
||||
struct IconColor : DataDrivenPaintProperty<Color, attributes::fill_color, uniforms::fill_color> {
|
||||
@@ -242,7 +242,7 @@ struct IconOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniform
|
||||
};
|
||||
|
||||
struct IconTranslate : PaintProperty<std::array<float, 2>> {
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct IconTranslateAnchor : PaintProperty<TranslateAnchorType> {
|
||||
@@ -273,7 +273,7 @@ struct TextOpacity : DataDrivenPaintProperty<float, attributes::opacity, uniform
|
||||
};
|
||||
|
||||
struct TextTranslate : PaintProperty<std::array<float, 2>> {
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
static std::array<float, 2> defaultValue() { return {{0, 0}}; }
|
||||
};
|
||||
|
||||
struct TextTranslateAnchor : PaintProperty<TranslateAnchorType> {
|
||||
|
||||
@@ -169,8 +169,10 @@ public:
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static T evaluate(float z, const GeometryTileFeature& feature,
|
||||
const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) {
|
||||
static T evaluate(float z,
|
||||
const GeometryTileFeature& feature,
|
||||
const PossiblyEvaluatedPropertyValue<T>& v,
|
||||
const T& defaultValue) {
|
||||
return v.match(
|
||||
[&] (const T& t) {
|
||||
return t;
|
||||
@@ -180,6 +182,17 @@ public:
|
||||
});
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static T evaluate(float z,
|
||||
const GeometryTileFeature& feature,
|
||||
const PossiblyEvaluatedPropertyValue<T>& v,
|
||||
const T& defaultValue,
|
||||
const std::set<std::string>& availableImages) {
|
||||
return v.match(
|
||||
[&](const T& t) { return t; },
|
||||
[&](const PropertyExpression<T>& t) { return t.evaluate(z, feature, availableImages, defaultValue); });
|
||||
}
|
||||
|
||||
template <class T>
|
||||
static T evaluate(float z, const GeometryTileFeature& feature, const FeatureState& state,
|
||||
const PossiblyEvaluatedPropertyValue<T>& v, const T& defaultValue) {
|
||||
@@ -197,6 +210,11 @@ public:
|
||||
return evaluate(z, feature, state, this->template get<P>(), P::defaultValue());
|
||||
}
|
||||
|
||||
template <class P>
|
||||
auto evaluate(float z, const GeometryTileFeature& feature, const std::set<std::string>& availableImages) const {
|
||||
return evaluate(z, feature, this->template get<P>(), P::defaultValue(), availableImages);
|
||||
}
|
||||
|
||||
Evaluated evaluate(float z, const GeometryTileFeature& feature) const {
|
||||
return Evaluated {
|
||||
evaluate<Ps>(z, feature)...
|
||||
|
||||
@@ -8,6 +8,7 @@ PropertyExpressionBase::PropertyExpressionBase(std::unique_ptr<expression::Expre
|
||||
zoomCurve(expression::findZoomCurveChecked(expression.get())) {
|
||||
isZoomConstant_ = expression::isZoomConstant(*expression);
|
||||
isFeatureConstant_ = expression::isFeatureConstant(*expression);
|
||||
isRuntimeConstant_ = expression::isRuntimeConstant(*expression);
|
||||
}
|
||||
|
||||
bool PropertyExpressionBase::isZoomConstant() const noexcept {
|
||||
@@ -18,19 +19,8 @@ bool PropertyExpressionBase::isFeatureConstant() const noexcept {
|
||||
return isFeatureConstant_;
|
||||
}
|
||||
|
||||
bool PropertyExpressionBase::canEvaluateWith(const expression::EvaluationContext& context) const noexcept {
|
||||
if (context.zoom) {
|
||||
if (context.feature != nullptr) {
|
||||
return !isFeatureConstant();
|
||||
}
|
||||
return !isZoomConstant() && isFeatureConstant();
|
||||
}
|
||||
|
||||
if (context.feature != nullptr) {
|
||||
return isZoomConstant() && !isFeatureConstant();
|
||||
}
|
||||
|
||||
return true;
|
||||
bool PropertyExpressionBase::isRuntimeConstant() const noexcept {
|
||||
return isRuntimeConstant_;
|
||||
}
|
||||
|
||||
float PropertyExpressionBase::interpolationFactor(const Range<float>& inputLevels, const float inputValue) const noexcept {
|
||||
|
||||
@@ -182,7 +182,8 @@ void GeometryTile::setData(std::unique_ptr<const GeometryTileData> data_, bool r
|
||||
pending = true;
|
||||
|
||||
++correlationID;
|
||||
worker.self().invoke(&GeometryTileWorker::setData, std::move(data_), resetLayers, correlationID);
|
||||
worker.self().invoke(
|
||||
&GeometryTileWorker::setData, std::move(data_), imageManager.getAvailableImages(), resetLayers, correlationID);
|
||||
}
|
||||
|
||||
std::unique_ptr<TileRenderData> GeometryTile::createRenderData() {
|
||||
@@ -212,7 +213,8 @@ void GeometryTile::setLayers(const std::vector<Immutable<LayerProperties>>& laye
|
||||
}
|
||||
|
||||
++correlationID;
|
||||
worker.self().invoke(&GeometryTileWorker::setLayers, std::move(impls), correlationID);
|
||||
worker.self().invoke(
|
||||
&GeometryTileWorker::setLayers, std::move(impls), imageManager.getAvailableImages(), correlationID);
|
||||
}
|
||||
|
||||
void GeometryTile::setShowCollisionBoxes(const bool showCollisionBoxes_) {
|
||||
|
||||
@@ -116,10 +116,14 @@ GeometryTileWorker::~GeometryTileWorker() = default;
|
||||
completed parse.
|
||||
*/
|
||||
|
||||
void GeometryTileWorker::setData(std::unique_ptr<const GeometryTileData> data_, bool resetLayers_, uint64_t correlationID_) {
|
||||
void GeometryTileWorker::setData(std::unique_ptr<const GeometryTileData> data_,
|
||||
std::set<std::string> availableImages_,
|
||||
bool resetLayers_,
|
||||
uint64_t correlationID_) {
|
||||
try {
|
||||
data = std::move(data_);
|
||||
correlationID = correlationID_;
|
||||
availableImages = std::move(availableImages_);
|
||||
if (resetLayers_) layers = nullopt;
|
||||
|
||||
switch (state) {
|
||||
@@ -139,10 +143,13 @@ void GeometryTileWorker::setData(std::unique_ptr<const GeometryTileData> data_,
|
||||
}
|
||||
}
|
||||
|
||||
void GeometryTileWorker::setLayers(std::vector<Immutable<LayerProperties>> layers_, uint64_t correlationID_) {
|
||||
void GeometryTileWorker::setLayers(std::vector<Immutable<LayerProperties>> layers_,
|
||||
std::set<std::string> availableImages_,
|
||||
uint64_t correlationID_) {
|
||||
try {
|
||||
layers = std::move(layers_);
|
||||
correlationID = correlationID_;
|
||||
availableImages = std::move(availableImages_);
|
||||
|
||||
switch (state) {
|
||||
case Idle:
|
||||
@@ -365,7 +372,8 @@ void GeometryTileWorker::parse() {
|
||||
// and either immediately create a bucket if no images/glyphs are used, or the Layout is stored until
|
||||
// the images/glyphs are available to add the features to the buckets.
|
||||
if (leaderImpl.getTypeInfo()->layout == LayerTypeInfo::Layout::Required) {
|
||||
std::unique_ptr<Layout> layout = LayerManager::get()->createLayout({parameters, glyphDependencies, imageDependencies}, std::move(geometryLayer), group);
|
||||
std::unique_ptr<Layout> layout = LayerManager::get()->createLayout(
|
||||
{parameters, glyphDependencies, imageDependencies, availableImages}, std::move(geometryLayer), group);
|
||||
if (layout->hasDependencies()) {
|
||||
layouts.push_back(std::move(layout));
|
||||
} else {
|
||||
|
||||
@@ -38,8 +38,13 @@ public:
|
||||
const bool showCollisionBoxes_);
|
||||
~GeometryTileWorker();
|
||||
|
||||
void setLayers(std::vector<Immutable<style::LayerProperties>>, uint64_t correlationID);
|
||||
void setData(std::unique_ptr<const GeometryTileData>, bool resetLayers, uint64_t correlationID);
|
||||
void setLayers(std::vector<Immutable<style::LayerProperties>>,
|
||||
std::set<std::string> availableImages,
|
||||
uint64_t correlationID);
|
||||
void setData(std::unique_ptr<const GeometryTileData>,
|
||||
std::set<std::string> availableImages,
|
||||
bool resetLayers,
|
||||
uint64_t correlationID);
|
||||
void setShowCollisionBoxes(bool showCollisionBoxes_, uint64_t correlationID_);
|
||||
|
||||
void onGlyphsAvailable(GlyphMap glyphs);
|
||||
@@ -96,7 +101,8 @@ private:
|
||||
ImageMap imageMap;
|
||||
ImageMap patternMap;
|
||||
ImageVersionMap versionMap;
|
||||
|
||||
std::set<std::string> availableImages;
|
||||
|
||||
bool showCollisionBoxes;
|
||||
bool firstLoad = true;
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ std::vector<Feature> getTopClusterFeature(QueryTest& test) {
|
||||
source->loadDescription(*test.fileSource);
|
||||
|
||||
auto clusterLayer = std::make_unique<SymbolLayer>("cluster_layer"s, "cluster_source"s);
|
||||
clusterLayer->setIconImage("test-icon"s);
|
||||
clusterLayer->setIconImage({"test-icon"s});
|
||||
clusterLayer->setIconSize(12.0f);
|
||||
|
||||
test.map.jumpTo(CameraOptions().withCenter(coordinate).withZoom(0.0));
|
||||
|
||||
4
test/fixtures/expression_equality/image.a.json
vendored
Normal file
4
test/fixtures/expression_equality/image.a.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[
|
||||
"image",
|
||||
"maki-11"
|
||||
]
|
||||
4
test/fixtures/expression_equality/image.b.json
vendored
Normal file
4
test/fixtures/expression_equality/image.b.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
[
|
||||
"image",
|
||||
"bicycle-15"
|
||||
]
|
||||
@@ -35,7 +35,8 @@ TEST(Expression, IsExpression) {
|
||||
|
||||
// TODO: "interpolate-hcl": https://github.com/mapbox/mapbox-gl-native/issues/8720
|
||||
// TODO: "interpolate-lab": https://github.com/mapbox/mapbox-gl-native/issues/8720
|
||||
if (name == "interpolate-hcl" || name == "interpolate-lab") {
|
||||
// TODO: "in": https://github.com/mapbox/mapbox-gl-native/issues/15893
|
||||
if (name == "interpolate-hcl" || name == "interpolate-lab" || name == "in") {
|
||||
if (expression::isExpression(conversion::Convertible(expression))) {
|
||||
ASSERT_TRUE(false) << "Expression name" << name << "is implemented - please update Expression.IsExpression test.";
|
||||
}
|
||||
|
||||
@@ -14,21 +14,17 @@ using namespace mbgl::style::expression::dsl;
|
||||
|
||||
using namespace std::string_literals;
|
||||
|
||||
static StubGeometryTileFeature oneInteger {
|
||||
PropertyMap {{ "property", uint64_t(1) }}
|
||||
};
|
||||
static const StubGeometryTileFeature oneInteger{PropertyMap{{"property", uint64_t(1)}}};
|
||||
|
||||
static StubGeometryTileFeature oneDouble {
|
||||
PropertyMap {{ "property", 1.0 }}
|
||||
};
|
||||
static const StubGeometryTileFeature oneDouble{PropertyMap{{"property", 1.0}}};
|
||||
|
||||
static StubGeometryTileFeature oneString {
|
||||
PropertyMap {{ "property", "1"s }}
|
||||
};
|
||||
static const StubGeometryTileFeature oneString{PropertyMap{{"property", "1"s}}};
|
||||
|
||||
static StubGeometryTileFeature oneColor {
|
||||
PropertyMap {{ "color", "red"s }}
|
||||
};
|
||||
static const StubGeometryTileFeature oneColor{PropertyMap{{"color", "red"s}}};
|
||||
|
||||
static const StubGeometryTileFeature oneImage{PropertyMap{{"image_name", "maki-11"s}}};
|
||||
|
||||
static const StubGeometryTileFeature emptyTileFeature{PropertyMap{}};
|
||||
|
||||
float evaluate(PropertyValue<float> value, float zoom) {
|
||||
return value.evaluate(PropertyEvaluator<float>(PropertyEvaluationParameters(zoom), 0));
|
||||
@@ -171,3 +167,54 @@ TEST(PropertyExpression, FormatSectionOverride) {
|
||||
EXPECT_TRUE(*override1 != *override4);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(PropertyExpression, ImageExpression) {
|
||||
const std::set<std::string> emptySet;
|
||||
const std::set<std::string> availableImages = {"maki-11", "airport-11", "bicycle-15"};
|
||||
|
||||
// evaluation test without available images
|
||||
{
|
||||
PropertyExpression<expression::Image> propExpr(image(literal("airport-11")));
|
||||
auto evaluatedImage = propExpr.evaluate(emptyTileFeature, emptySet, expression::Image());
|
||||
EXPECT_FALSE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), "airport-11"s);
|
||||
|
||||
PropertyExpression<expression::Image> ddPropExpr(image(get(literal("image_name"s))));
|
||||
evaluatedImage = ddPropExpr.evaluate(oneImage, emptySet, expression::Image());
|
||||
EXPECT_FALSE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), "maki-11"s);
|
||||
|
||||
evaluatedImage = ddPropExpr.evaluate(emptyTileFeature, emptySet, expression::Image());
|
||||
EXPECT_FALSE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), ""s);
|
||||
}
|
||||
|
||||
// evaluation test with available images
|
||||
{
|
||||
PropertyExpression<expression::Image> propExpr(image(literal("airport-11")));
|
||||
auto evaluatedImage = propExpr.evaluate(emptyTileFeature, availableImages, expression::Image());
|
||||
EXPECT_TRUE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), "airport-11"s);
|
||||
|
||||
PropertyExpression<expression::Image> ddPropExpr(image(get(literal("image_name"s))));
|
||||
evaluatedImage = ddPropExpr.evaluate(oneImage, availableImages, expression::Image());
|
||||
EXPECT_TRUE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), "maki-11"s);
|
||||
|
||||
evaluatedImage = ddPropExpr.evaluate(emptyTileFeature, availableImages, expression::Image());
|
||||
EXPECT_FALSE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), ""s);
|
||||
}
|
||||
|
||||
// evaluation with zoom
|
||||
{
|
||||
auto expr = step(zoom(), image(literal("airport-11")), 18.0, image(literal("bicycle-15")));
|
||||
PropertyExpression<expression::Image> propExpr(std::move(expr));
|
||||
auto evaluatedImage = propExpr.evaluate(0.0, emptyTileFeature, availableImages, expression::Image());
|
||||
EXPECT_TRUE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), "airport-11"s);
|
||||
evaluatedImage = propExpr.evaluate(18.0, emptyTileFeature, availableImages, expression::Image());
|
||||
EXPECT_TRUE(evaluatedImage.isAvailable());
|
||||
EXPECT_EQ(evaluatedImage.id(), "bicycle-15"s);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <mbgl/style/expression/dsl.hpp>
|
||||
#include <mbgl/style/expression/match.hpp>
|
||||
#include <mbgl/style/expression/format_expression.hpp>
|
||||
#include <mbgl/style/style_impl.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/expression/match.hpp>
|
||||
#include <mbgl/style/layers/background_layer.hpp>
|
||||
#include <mbgl/style/layers/background_layer_impl.hpp>
|
||||
#include <mbgl/style/layers/circle_layer.hpp>
|
||||
@@ -16,12 +16,13 @@
|
||||
#include <mbgl/style/layers/raster_layer_impl.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/test/stub_layer_observer.hpp>
|
||||
#include <mbgl/style/style_impl.hpp>
|
||||
#include <mbgl/test/stub_file_source.hpp>
|
||||
#include <mbgl/test/stub_layer_observer.hpp>
|
||||
#include <mbgl/test/util.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
#include <mbgl/util/io.hpp>
|
||||
#include <mbgl/util/run_loop.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@@ -37,7 +38,7 @@ const auto color = Color { 1, 0, 0, 1 };
|
||||
const auto opacity = 1.0f;
|
||||
const auto radius = 1.0f;
|
||||
const auto blur = 1.0f;
|
||||
const auto pattern = std::string { "foo" };
|
||||
const auto pattern = PropertyValue<expression::Image>{"foo"};
|
||||
const auto antialias = false;
|
||||
const auto translate = std::array<float, 2> {{ 0, 0 }};
|
||||
const auto translateAnchor = TranslateAnchorType::Map;
|
||||
|
||||
@@ -19,11 +19,15 @@ LineString<int16_t> emptyLine;
|
||||
|
||||
class SymbolFeatureStub : public SymbolFeature {
|
||||
public:
|
||||
SymbolFeatureStub(FeatureIdentifier id_, FeatureType type_, GeometryCollection geometry_,
|
||||
PropertyMap properties_, optional<std::u16string> text_,
|
||||
optional<std::string> icon_, std::size_t index_) :
|
||||
SymbolFeature(std::make_unique<StubGeometryTileFeature>(std::move(id_), type_, std::move(geometry_), std::move(properties_)))
|
||||
{
|
||||
SymbolFeatureStub(FeatureIdentifier id_,
|
||||
FeatureType type_,
|
||||
GeometryCollection geometry_,
|
||||
PropertyMap properties_,
|
||||
optional<std::u16string> text_,
|
||||
optional<style::expression::Image> icon_,
|
||||
std::size_t index_)
|
||||
: SymbolFeature(std::make_unique<StubGeometryTileFeature>(
|
||||
std::move(id_), type_, std::move(geometry_), std::move(properties_))) {
|
||||
if (text_) {
|
||||
formattedText = TaggedString(*text_, SectionOptions(1.0, {}));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user