[core] Get rid of user-specified refs
This commit is contained in:
@@ -60,6 +60,8 @@ mason_use(pixelmatch VERSION 0.10.0 HEADER_ONLY)
|
||||
mason_use(geojson VERSION 0.4.0 HEADER_ONLY)
|
||||
mason_use(polylabel VERSION 1.0.2 HEADER_ONLY)
|
||||
|
||||
add_definitions(-DRAPIDJSON_HAS_STDSTRING=1)
|
||||
|
||||
if(WITH_COVERAGE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} --coverage")
|
||||
|
||||
@@ -221,6 +221,8 @@ set(MBGL_CORE_FILES
|
||||
src/mbgl/style/cross_faded_property_evaluator.cpp
|
||||
src/mbgl/style/cross_faded_property_evaluator.hpp
|
||||
src/mbgl/style/function.cpp
|
||||
src/mbgl/style/group_by_layout.cpp
|
||||
src/mbgl/style/group_by_layout.hpp
|
||||
src/mbgl/style/layer.cpp
|
||||
src/mbgl/style/layer_impl.cpp
|
||||
src/mbgl/style/layer_impl.hpp
|
||||
@@ -260,6 +262,7 @@ set(MBGL_CORE_FILES
|
||||
include/mbgl/style/conversion/property_value.hpp
|
||||
include/mbgl/style/conversion/source.hpp
|
||||
include/mbgl/style/conversion/tileset.hpp
|
||||
src/mbgl/style/conversion/stringify.hpp
|
||||
|
||||
# style/layers
|
||||
include/mbgl/style/layers/background_layer.hpp
|
||||
|
||||
@@ -73,10 +73,12 @@ set(MBGL_TEST_FILES
|
||||
|
||||
# style/conversion
|
||||
test/style/conversion/geojson_options.test.cpp
|
||||
test/style/conversion/stringify.test.cpp
|
||||
|
||||
# style
|
||||
test/style/filter.test.cpp
|
||||
test/style/functions.test.cpp
|
||||
test/style/group_by_layout.test.cpp
|
||||
test/style/source.test.cpp
|
||||
test/style/style.test.cpp
|
||||
test/style/style_layer.test.cpp
|
||||
|
||||
@@ -116,6 +116,8 @@ public:
|
||||
|
||||
// Private implementation
|
||||
const std::unique_ptr<Impl> baseImpl;
|
||||
|
||||
friend std::string layoutKey(const Layer&);
|
||||
};
|
||||
|
||||
} // namespace style
|
||||
|
||||
@@ -36,6 +36,7 @@ public:
|
||||
static Color blue() { return { 0.0f, 0.0f, 1.0f, 1.0f }; };
|
||||
|
||||
static optional<Color> parse(const std::string&);
|
||||
std::string stringify() const;
|
||||
};
|
||||
|
||||
inline bool operator==(const Color& colorA, const Color& colorB) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"express": "^4.11.1",
|
||||
"lodash": "^4.16.4",
|
||||
"mapbox-gl-style-spec": "mapbox/mapbox-gl-style-spec#49e8b407bdbbe6f7c92dbcb56d3d51f425fc2653",
|
||||
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#2bdca923fc4190156b5a22af71be29442451db54",
|
||||
"mapbox-gl-test-suite": "mapbox/mapbox-gl-test-suite#7bf5725a2dfe848463db85ff2c85a0f9551d18bf",
|
||||
"mkdirp": "^0.5.1",
|
||||
"node-cmake": "^1.2.1",
|
||||
"pixelmatch": "^4.0.2",
|
||||
|
||||
@@ -24,12 +24,12 @@ void StyleSourcedAnnotationImpl::updateStyle(Style& style) const {
|
||||
return;
|
||||
|
||||
if (sourceLayer->is<LineLayer>()) {
|
||||
std::unique_ptr<Layer> layer = sourceLayer->baseImpl->copy(layerID, "", AnnotationManager::SourceID);
|
||||
std::unique_ptr<Layer> layer = sourceLayer->baseImpl->copy(layerID, AnnotationManager::SourceID);
|
||||
layer->as<LineLayer>()->setSourceLayer(layerID);
|
||||
layer->as<LineLayer>()->setVisibility(VisibilityType::Visible);
|
||||
style.addLayer(std::move(layer), sourceLayer->getID());
|
||||
} else if (sourceLayer->is<FillLayer>()) {
|
||||
std::unique_ptr<Layer> layer = sourceLayer->baseImpl->copy(layerID, "", AnnotationManager::SourceID);
|
||||
std::unique_ptr<Layer> layer = sourceLayer->baseImpl->copy(layerID, AnnotationManager::SourceID);
|
||||
layer->as<FillLayer>()->setSourceLayer(layerID);
|
||||
layer->as<FillLayer>()->setVisibility(VisibilityType::Visible);
|
||||
style.addLayer(std::move(layer), sourceLayer->getID());
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <mbgl/layout/clip_lines.hpp>
|
||||
#include <mbgl/renderer/symbol_bucket.hpp>
|
||||
#include <mbgl/style/filter_evaluator.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
#include <mbgl/sprite/sprite_atlas.hpp>
|
||||
#include <mbgl/text/glyph_atlas.hpp>
|
||||
#include <mbgl/text/get_anchors.hpp>
|
||||
@@ -26,7 +27,7 @@ namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
SymbolLayout::SymbolLayout(std::string bucketName_,
|
||||
SymbolLayout::SymbolLayout(std::vector<std::unique_ptr<Layer>> layers_,
|
||||
std::string sourceLayerName_,
|
||||
uint32_t overscaling_,
|
||||
float zoom_,
|
||||
@@ -36,7 +37,7 @@ SymbolLayout::SymbolLayout(std::string bucketName_,
|
||||
style::SymbolLayoutProperties::Evaluated layout_,
|
||||
float textMaxSize_,
|
||||
SpriteAtlas& spriteAtlas_)
|
||||
: bucketName(std::move(bucketName_)),
|
||||
: layers(std::move(layers_)),
|
||||
sourceLayerName(std::move(sourceLayerName_)),
|
||||
overscaling(overscaling_),
|
||||
zoom(zoom_),
|
||||
@@ -253,7 +254,7 @@ void SymbolLayout::addFeature(const SymbolFeature& feature,
|
||||
? SymbolPlacementType::Point
|
||||
: layout.get<SymbolPlacement>();
|
||||
const float textRepeatDistance = symbolSpacing / 2;
|
||||
IndexedSubfeature indexedFeature = {feature.index, sourceLayerName, bucketName, symbolInstances.size()};
|
||||
IndexedSubfeature indexedFeature = {feature.index, sourceLayerName, layers.at(0)->getID(), symbolInstances.size()};
|
||||
|
||||
auto addSymbolInstance = [&] (const GeometryCoordinates& line, Anchor& anchor) {
|
||||
// https://github.com/mapbox/vector-tile-spec/tree/master/2.1#41-layers
|
||||
|
||||
@@ -21,13 +21,14 @@ class SymbolBucket;
|
||||
|
||||
namespace style {
|
||||
class Filter;
|
||||
class Layer;
|
||||
} // namespace style
|
||||
|
||||
struct Anchor;
|
||||
|
||||
class SymbolLayout {
|
||||
public:
|
||||
SymbolLayout(std::string bucketName_,
|
||||
SymbolLayout(std::vector<std::unique_ptr<style::Layer>>,
|
||||
std::string sourceLayerName_,
|
||||
uint32_t overscaling,
|
||||
float zoom,
|
||||
@@ -55,7 +56,7 @@ public:
|
||||
|
||||
State state = Pending;
|
||||
|
||||
const std::string bucketName;
|
||||
const std::vector<std::unique_ptr<style::Layer>> layers;
|
||||
const std::string sourceLayerName;
|
||||
|
||||
private:
|
||||
|
||||
256
src/mbgl/style/conversion/stringify.hpp
Normal file
256
src/mbgl/style/conversion/stringify.hpp
Normal file
@@ -0,0 +1,256 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/style/filter.hpp>
|
||||
#include <mbgl/style/property_value.hpp>
|
||||
#include <mbgl/style/layout_property.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/feature.hpp>
|
||||
#include <mbgl/util/ignore.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
namespace conversion {
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, NullValue) {
|
||||
writer.Null();
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, bool v) {
|
||||
writer.Bool(v);
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, uint64_t v) {
|
||||
writer.Uint64(v);
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, int64_t v) {
|
||||
writer.Int64(v);
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, double v) {
|
||||
writer.Double(v);
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const std::string& v) {
|
||||
writer.String(v);
|
||||
}
|
||||
|
||||
template <class Writer, class T, class Enable = std::enable_if_t<std::is_enum<T>::value>>
|
||||
void stringify(Writer& writer, const T& v) {
|
||||
writer.String(Enum<T>::toString(v));
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const Color& v) {
|
||||
writer.String(v.stringify());
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const std::array<float, 2>& v) {
|
||||
writer.StartArray();
|
||||
writer.Double(v[0]);
|
||||
writer.Double(v[1]);
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const std::array<float, 4>& v) {
|
||||
writer.StartArray();
|
||||
writer.Double(v[0]);
|
||||
writer.Double(v[1]);
|
||||
writer.Double(v[2]);
|
||||
writer.Double(v[3]);
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer&, const Value&);
|
||||
|
||||
template <class Writer, class T>
|
||||
void stringify(Writer& writer, const std::vector<T>& v) {
|
||||
writer.StartArray();
|
||||
for (const auto& e : v) {
|
||||
stringify(writer, e);
|
||||
}
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
template <class Writer, class T>
|
||||
void stringify(Writer& writer, const std::unordered_map<std::string, T>& m) {
|
||||
writer.StartObject();
|
||||
for (const auto& p : m) {
|
||||
writer.Key(p.first.data(), static_cast<unsigned>(p.first.size()));
|
||||
stringify(writer, p.second);
|
||||
}
|
||||
writer.EndObject();
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const Value& v) {
|
||||
Value::visit(v, [&] (const auto& v_) { stringify(writer, v_); });
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
class StringifyFilter {
|
||||
public:
|
||||
Writer& writer;
|
||||
|
||||
void operator()(const NullFilter&) {
|
||||
writer.Null();
|
||||
}
|
||||
|
||||
void operator()(const EqualsFilter& f) {
|
||||
stringifyBinaryFilter(f, "==");
|
||||
}
|
||||
|
||||
void operator()(const NotEqualsFilter& f) {
|
||||
stringifyBinaryFilter(f, "!=");
|
||||
}
|
||||
|
||||
void operator()(const LessThanFilter& f) {
|
||||
stringifyBinaryFilter(f, "<");
|
||||
}
|
||||
|
||||
void operator()(const LessThanEqualsFilter& f) {
|
||||
stringifyBinaryFilter(f, "<=");
|
||||
}
|
||||
|
||||
void operator()(const GreaterThanFilter& f) {
|
||||
stringifyBinaryFilter(f, ">");
|
||||
}
|
||||
|
||||
void operator()(const GreaterThanEqualsFilter& f) {
|
||||
stringifyBinaryFilter(f, ">=");
|
||||
}
|
||||
|
||||
void operator()(const InFilter& f) {
|
||||
stringifySetFilter(f, "in");
|
||||
}
|
||||
|
||||
void operator()(const NotInFilter& f) {
|
||||
stringifySetFilter(f, "!in");
|
||||
}
|
||||
|
||||
void operator()(const AllFilter& f) {
|
||||
stringifyCompoundFilter(f, "all");
|
||||
}
|
||||
|
||||
void operator()(const AnyFilter& f) {
|
||||
stringifyCompoundFilter(f, "any");
|
||||
}
|
||||
|
||||
void operator()(const NoneFilter& f) {
|
||||
stringifyCompoundFilter(f, "none");
|
||||
}
|
||||
|
||||
void operator()(const HasFilter& f) {
|
||||
stringifyUnaryFilter(f, "has");
|
||||
}
|
||||
|
||||
void operator()(const NotHasFilter& f) {
|
||||
stringifyUnaryFilter(f, "!has");
|
||||
}
|
||||
|
||||
private:
|
||||
template <class F>
|
||||
void stringifyBinaryFilter(const F& f, const char * op) {
|
||||
writer.StartArray();
|
||||
writer.String(op);
|
||||
writer.String(f.key);
|
||||
stringify(writer, f.value);
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
template <class F>
|
||||
void stringifySetFilter(const F& f, const char * op) {
|
||||
writer.StartArray();
|
||||
writer.String(op);
|
||||
writer.String(f.key);
|
||||
for (const auto& value : f.values) {
|
||||
stringify(writer, value);
|
||||
}
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
template <class F>
|
||||
void stringifyCompoundFilter(const F& f, const char * op) {
|
||||
writer.StartArray();
|
||||
writer.String(op);
|
||||
for (const auto& filter : f.filters) {
|
||||
Filter::visit(filter, *this);
|
||||
}
|
||||
writer.EndArray();
|
||||
}
|
||||
|
||||
template <class F>
|
||||
void stringifyUnaryFilter(const F& f, const char * op) {
|
||||
writer.StartArray();
|
||||
writer.String(op);
|
||||
writer.String(f.key);
|
||||
writer.EndArray();
|
||||
}
|
||||
};
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const Filter& f) {
|
||||
Filter::visit(f, StringifyFilter<Writer> { writer });
|
||||
}
|
||||
|
||||
template <class Writer>
|
||||
void stringify(Writer& writer, const Undefined&) {
|
||||
assert(false); // Should be omitted entirely instead.
|
||||
writer.Null();
|
||||
}
|
||||
|
||||
template <class Writer, class T>
|
||||
void stringify(Writer& writer, const Function<T>& f) {
|
||||
writer.StartObject();
|
||||
writer.Key("base");
|
||||
writer.Double(f.getBase());
|
||||
writer.Key("stops");
|
||||
writer.StartArray();
|
||||
for (const auto& stop : f.getStops()) {
|
||||
writer.StartArray();
|
||||
writer.Double(stop.first);
|
||||
stringify(writer, stop.second);
|
||||
writer.EndArray();
|
||||
}
|
||||
writer.EndArray();
|
||||
writer.EndObject();
|
||||
}
|
||||
|
||||
template <class Writer, class T>
|
||||
void stringify(Writer& writer, const PropertyValue<T>& v) {
|
||||
v.evaluate([&] (const auto& v_) { stringify(writer, v_); });
|
||||
}
|
||||
|
||||
template <class Property, class Writer, class T>
|
||||
void stringify(Writer& writer, const PropertyValue<T>& value) {
|
||||
if (value) {
|
||||
writer.Key(Property::key);
|
||||
stringify(writer, value);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Writer, class... Ps>
|
||||
void stringify(Writer& writer, const LayoutProperties<Ps...>& ps) {
|
||||
writer.StartObject();
|
||||
util::ignore({ (stringify<Ps>(writer, ps.unevaluated.template get<Ps>()), 0)... });
|
||||
writer.EndObject();
|
||||
}
|
||||
|
||||
} // namespace conversion
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
51
src/mbgl/style/group_by_layout.cpp
Normal file
51
src/mbgl/style/group_by_layout.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <mbgl/style/group_by_layout.hpp>
|
||||
#include <mbgl/style/layer.hpp>
|
||||
#include <mbgl/style/layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
std::string layoutKey(const Layer& layer) {
|
||||
using namespace conversion;
|
||||
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
|
||||
writer.StartArray();
|
||||
writer.Uint(static_cast<uint32_t>(layer.type));
|
||||
writer.String(layer.baseImpl->source);
|
||||
writer.String(layer.baseImpl->sourceLayer);
|
||||
writer.Double(layer.baseImpl->minZoom);
|
||||
writer.Double(layer.baseImpl->maxZoom);
|
||||
writer.Uint(static_cast<uint32_t>(layer.baseImpl->visibility));
|
||||
stringify(writer, layer.baseImpl->filter);
|
||||
layer.baseImpl->stringifyLayout(writer);
|
||||
writer.EndArray();
|
||||
|
||||
return s.GetString();
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::unique_ptr<Layer>>> groupByLayout(std::vector<std::unique_ptr<Layer>> layers) {
|
||||
std::unordered_map<std::string, std::vector<std::unique_ptr<Layer>>> map;
|
||||
for (auto& layer : layers) {
|
||||
auto& vector = map[layoutKey(*layer)];
|
||||
vector.push_back(std::move(layer));
|
||||
}
|
||||
|
||||
std::vector<std::vector<std::unique_ptr<Layer>>> result;
|
||||
for (auto& pair : map) {
|
||||
result.push_back(std::move(pair.second));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
14
src/mbgl/style/group_by_layout.hpp
Normal file
14
src/mbgl/style/group_by_layout.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
class Layer;
|
||||
|
||||
std::vector<std::vector<std::unique_ptr<Layer>>> groupByLayout(std::vector<std::unique_ptr<Layer>>);
|
||||
|
||||
} // namespace style
|
||||
} // namespace mbgl
|
||||
@@ -4,19 +4,13 @@ namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
std::unique_ptr<Layer> Layer::Impl::copy(const std::string& id_,
|
||||
const std::string& ref_,
|
||||
const std::string& source_) const {
|
||||
std::unique_ptr<Layer> result = clone();
|
||||
result->baseImpl->id = id_;
|
||||
result->baseImpl->ref = ref_;
|
||||
result->baseImpl->source = source_;
|
||||
return result;
|
||||
}
|
||||
|
||||
const std::string& Layer::Impl::bucketName() const {
|
||||
return ref.empty() ? id : ref;
|
||||
}
|
||||
|
||||
bool Layer::Impl::hasRenderPass(RenderPass pass) const {
|
||||
return bool(passes & pass);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <limits>
|
||||
@@ -37,20 +40,19 @@ class Layer::Impl {
|
||||
public:
|
||||
virtual ~Impl() = default;
|
||||
|
||||
// Create a new layer with the specified `id`, `ref`, and `sourceID`. All other properties
|
||||
// Create a new layer with the specified `id` and `sourceID`. All other properties
|
||||
// are copied from this layer.
|
||||
std::unique_ptr<Layer> copy(const std::string& id,
|
||||
const std::string& ref,
|
||||
const std::string& sourceID) const;
|
||||
|
||||
// Create an identical copy of this layer.
|
||||
virtual std::unique_ptr<Layer> clone() const = 0;
|
||||
|
||||
// Create a layer, copying all properties except id, ref, and paint properties from this layer.
|
||||
// Create a layer, copying all properties except id and paint properties from this layer.
|
||||
virtual std::unique_ptr<Layer> cloneRef(const std::string& id) const = 0;
|
||||
|
||||
// If the layer has a ref, the ref. Otherwise, the id.
|
||||
const std::string& bucketName() const;
|
||||
// Utility function for automatic layer grouping.
|
||||
virtual void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const = 0;
|
||||
|
||||
// Partially evaluate paint properties based on a set of classes.
|
||||
virtual void cascade(const CascadeParameters&) = 0;
|
||||
@@ -78,7 +80,6 @@ public:
|
||||
|
||||
public:
|
||||
std::string id;
|
||||
std::string ref;
|
||||
std::string source;
|
||||
std::string sourceLayer;
|
||||
Filter filter;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/background_layer.hpp>
|
||||
#include <mbgl/style/layers/background_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -26,11 +27,13 @@ std::unique_ptr<Layer> BackgroundLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> BackgroundLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<BackgroundLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = BackgroundPaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void BackgroundLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
|
||||
|
||||
// Layout properties
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class BackgroundLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/circle_layer.hpp>
|
||||
#include <mbgl/style/layers/circle_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -27,11 +28,13 @@ std::unique_ptr<Layer> CircleLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> CircleLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<CircleLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = CirclePaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void CircleLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
|
||||
// Source
|
||||
|
||||
const std::string& CircleLayer::getSourceID() const {
|
||||
|
||||
@@ -24,11 +24,10 @@ bool CircleLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters)
|
||||
std::unique_ptr<Bucket> CircleLayer::Impl::createBucket(BucketParameters& parameters, const GeometryTileLayer& layer) const {
|
||||
auto bucket = std::make_unique<CircleBucket>(parameters.mode);
|
||||
|
||||
auto& name = bucketName();
|
||||
parameters.eachFilteredFeature(filter, layer, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
|
||||
auto geometries = feature.getGeometries();
|
||||
bucket->addGeometry(geometries);
|
||||
parameters.featureIndex.insert(geometries, index, layerName, name);
|
||||
parameters.featureIndex.insert(geometries, index, layerName, id);
|
||||
});
|
||||
|
||||
return std::move(bucket);
|
||||
|
||||
@@ -11,6 +11,7 @@ class CircleLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
@@ -34,6 +34,9 @@ std::unique_ptr<Layer> CustomLayer::Impl::cloneRef(const std::string&) const {
|
||||
return std::make_unique<CustomLayer>(*this);
|
||||
}
|
||||
|
||||
void CustomLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
|
||||
void CustomLayer::Impl::initialize() {
|
||||
assert(initializeFn);
|
||||
initializeFn(context);
|
||||
|
||||
@@ -27,6 +27,7 @@ public:
|
||||
private:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) final {}
|
||||
bool evaluate(const PropertyEvaluationParameters&) final;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/fill_extrusion_layer.hpp>
|
||||
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -27,11 +28,13 @@ std::unique_ptr<Layer> FillExtrusionLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> FillExtrusionLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<FillExtrusionLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = FillExtrusionPaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void FillExtrusionLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
|
||||
// Source
|
||||
|
||||
const std::string& FillExtrusionLayer::getSourceID() const {
|
||||
|
||||
@@ -11,6 +11,7 @@ class FillExtrusionLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/fill_layer.hpp>
|
||||
#include <mbgl/style/layers/fill_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -27,11 +28,13 @@ std::unique_ptr<Layer> FillLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> FillLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<FillLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = FillPaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void FillLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
|
||||
// Source
|
||||
|
||||
const std::string& FillLayer::getSourceID() const {
|
||||
|
||||
@@ -33,11 +33,10 @@ bool FillLayer::Impl::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
std::unique_ptr<Bucket> FillLayer::Impl::createBucket(BucketParameters& parameters, const GeometryTileLayer& layer) const {
|
||||
auto bucket = std::make_unique<FillBucket>();
|
||||
|
||||
auto& name = bucketName();
|
||||
parameters.eachFilteredFeature(filter, layer, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
|
||||
auto geometries = feature.getGeometries();
|
||||
bucket->addGeometry(geometries);
|
||||
parameters.featureIndex.insert(geometries, index, layerName, name);
|
||||
parameters.featureIndex.insert(geometries, index, layerName, id);
|
||||
});
|
||||
|
||||
return std::move(bucket);
|
||||
|
||||
@@ -11,6 +11,7 @@ class FillLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer.hpp>
|
||||
#include <mbgl/style/layers/<%- type.replace('-', '_') %>_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -40,11 +41,19 @@ std::unique_ptr<Layer> <%- camelize(type) %>Layer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> <%- camelize(type) %>Layer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<<%- camelize(type) %>Layer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = <%- camelize(type) %>PaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
<% if (layoutProperties.length) { -%>
|
||||
void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const {
|
||||
conversion::stringify(writer, layout);
|
||||
}
|
||||
<% } else { -%>
|
||||
void <%- camelize(type) %>Layer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
<% } -%>
|
||||
|
||||
<% if (type !== 'background') { -%>
|
||||
// Source
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace style {
|
||||
|
||||
<% for (const property of layoutProperties) { -%>
|
||||
struct <%- camelize(property.name) %> : LayoutProperty<<%- propertyType(property) %>> {
|
||||
static constexpr const char * key = "<%- property.name %>";
|
||||
static <%- propertyType(property) %> defaultValue() { return <%- defaultValue(property) %>; }
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/line_layer.hpp>
|
||||
#include <mbgl/style/layers/line_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -27,11 +28,14 @@ std::unique_ptr<Layer> LineLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> LineLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<LineLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = LinePaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void LineLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const {
|
||||
conversion::stringify(writer, layout);
|
||||
}
|
||||
|
||||
// Source
|
||||
|
||||
const std::string& LineLayer::getSourceID() const {
|
||||
|
||||
@@ -31,11 +31,10 @@ std::unique_ptr<Bucket> LineLayer::Impl::createBucket(BucketParameters& paramete
|
||||
|
||||
bucket->layout = layout.evaluate(PropertyEvaluationParameters(parameters.tileID.overscaledZ));
|
||||
|
||||
auto& name = bucketName();
|
||||
parameters.eachFilteredFeature(filter, layer, [&] (const auto& feature, std::size_t index, const std::string& layerName) {
|
||||
auto geometries = feature.getGeometries();
|
||||
bucket->addGeometry(geometries);
|
||||
parameters.featureIndex.insert(geometries, index, layerName, name);
|
||||
parameters.featureIndex.insert(geometries, index, layerName, id);
|
||||
});
|
||||
|
||||
return std::move(bucket);
|
||||
|
||||
@@ -11,6 +11,7 @@ class LineLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
@@ -10,18 +10,22 @@ namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
struct LineCap : LayoutProperty<LineCapType> {
|
||||
static constexpr const char * key = "line-cap";
|
||||
static LineCapType defaultValue() { return LineCapType::Butt; }
|
||||
};
|
||||
|
||||
struct LineJoin : LayoutProperty<LineJoinType> {
|
||||
static constexpr const char * key = "line-join";
|
||||
static LineJoinType defaultValue() { return LineJoinType::Miter; }
|
||||
};
|
||||
|
||||
struct LineMiterLimit : LayoutProperty<float> {
|
||||
static constexpr const char * key = "line-miter-limit";
|
||||
static float defaultValue() { return 2; }
|
||||
};
|
||||
|
||||
struct LineRoundLimit : LayoutProperty<float> {
|
||||
static constexpr const char * key = "line-round-limit";
|
||||
static float defaultValue() { return 1; }
|
||||
};
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/raster_layer.hpp>
|
||||
#include <mbgl/style/layers/raster_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -27,11 +28,13 @@ std::unique_ptr<Layer> RasterLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> RasterLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<RasterLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = RasterPaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void RasterLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const {
|
||||
}
|
||||
|
||||
// Source
|
||||
|
||||
const std::string& RasterLayer::getSourceID() const {
|
||||
|
||||
@@ -11,6 +11,7 @@ class RasterLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <mbgl/style/layers/symbol_layer.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace style {
|
||||
@@ -27,11 +28,14 @@ std::unique_ptr<Layer> SymbolLayer::Impl::clone() const {
|
||||
std::unique_ptr<Layer> SymbolLayer::Impl::cloneRef(const std::string& id_) const {
|
||||
auto result = std::make_unique<SymbolLayer>(*this);
|
||||
result->impl->id = id_;
|
||||
result->impl->ref = this->id;
|
||||
result->impl->paint = SymbolPaintProperties();
|
||||
return std::move(result);
|
||||
}
|
||||
|
||||
void SymbolLayer::Impl::stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>& writer) const {
|
||||
conversion::stringify(writer, layout);
|
||||
}
|
||||
|
||||
// Source
|
||||
|
||||
const std::string& SymbolLayer::getSourceID() const {
|
||||
|
||||
@@ -29,7 +29,9 @@ std::unique_ptr<Bucket> SymbolLayer::Impl::createBucket(BucketParameters&, const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters, const GeometryTileLayer& layer) const {
|
||||
std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters& parameters,
|
||||
const GeometryTileLayer& layer,
|
||||
std::vector<std::unique_ptr<Layer>> group) const {
|
||||
PropertyEvaluationParameters p(parameters.tileID.overscaledZ);
|
||||
SymbolLayoutProperties::Evaluated evaluated = layout.evaluate(p);
|
||||
|
||||
@@ -59,7 +61,7 @@ std::unique_ptr<SymbolLayout> SymbolLayer::Impl::createLayout(BucketParameters&
|
||||
evaluated.get<IconSize>() = layout.evaluate<IconSize>(PropertyEvaluationParameters(p.z + 1));
|
||||
evaluated.get<TextSize>() = layout.evaluate<TextSize>(PropertyEvaluationParameters(p.z + 1));
|
||||
|
||||
return std::make_unique<SymbolLayout>(id,
|
||||
return std::make_unique<SymbolLayout>(std::move(group),
|
||||
layer.getName(),
|
||||
parameters.tileID.overscaleFactor(),
|
||||
parameters.tileID.overscaledZ,
|
||||
|
||||
@@ -45,12 +45,14 @@ class SymbolLayer::Impl : public Layer::Impl {
|
||||
public:
|
||||
std::unique_ptr<Layer> clone() const override;
|
||||
std::unique_ptr<Layer> cloneRef(const std::string& id) const override;
|
||||
void stringifyLayout(rapidjson::Writer<rapidjson::StringBuffer>&) const override;
|
||||
|
||||
void cascade(const CascadeParameters&) override;
|
||||
bool evaluate(const PropertyEvaluationParameters&) override;
|
||||
|
||||
std::unique_ptr<Bucket> createBucket(BucketParameters&, const GeometryTileLayer&) const override;
|
||||
std::unique_ptr<SymbolLayout> createLayout(BucketParameters&, const GeometryTileLayer&) const;
|
||||
std::unique_ptr<SymbolLayout> createLayout(BucketParameters&, const GeometryTileLayer&,
|
||||
std::vector<std::unique_ptr<Layer>>) const;
|
||||
|
||||
SymbolPropertyValues iconPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
|
||||
SymbolPropertyValues textPropertyValues(const SymbolLayoutProperties::Evaluated&) const;
|
||||
|
||||
@@ -10,138 +10,172 @@ namespace mbgl {
|
||||
namespace style {
|
||||
|
||||
struct SymbolPlacement : LayoutProperty<SymbolPlacementType> {
|
||||
static constexpr const char * key = "symbol-placement";
|
||||
static SymbolPlacementType defaultValue() { return SymbolPlacementType::Point; }
|
||||
};
|
||||
|
||||
struct SymbolSpacing : LayoutProperty<float> {
|
||||
static constexpr const char * key = "symbol-spacing";
|
||||
static float defaultValue() { return 250; }
|
||||
};
|
||||
|
||||
struct SymbolAvoidEdges : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "symbol-avoid-edges";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct IconAllowOverlap : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "icon-allow-overlap";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct IconIgnorePlacement : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "icon-ignore-placement";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct IconOptional : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "icon-optional";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct IconRotationAlignment : LayoutProperty<AlignmentType> {
|
||||
static constexpr const char * key = "icon-rotation-alignment";
|
||||
static AlignmentType defaultValue() { return AlignmentType::Auto; }
|
||||
};
|
||||
|
||||
struct IconSize : LayoutProperty<float> {
|
||||
static constexpr const char * key = "icon-size";
|
||||
static float defaultValue() { return 1; }
|
||||
};
|
||||
|
||||
struct IconTextFit : LayoutProperty<IconTextFitType> {
|
||||
static constexpr const char * key = "icon-text-fit";
|
||||
static IconTextFitType defaultValue() { return IconTextFitType::None; }
|
||||
};
|
||||
|
||||
struct IconTextFitPadding : LayoutProperty<std::array<float, 4>> {
|
||||
static constexpr const char * key = "icon-text-fit-padding";
|
||||
static std::array<float, 4> defaultValue() { return {{ 0, 0, 0, 0 }}; }
|
||||
};
|
||||
|
||||
struct IconImage : LayoutProperty<std::string> {
|
||||
static constexpr const char * key = "icon-image";
|
||||
static std::string defaultValue() { return ""; }
|
||||
};
|
||||
|
||||
struct IconRotate : LayoutProperty<float> {
|
||||
static constexpr const char * key = "icon-rotate";
|
||||
static float defaultValue() { return 0; }
|
||||
};
|
||||
|
||||
struct IconPadding : LayoutProperty<float> {
|
||||
static constexpr const char * key = "icon-padding";
|
||||
static float defaultValue() { return 2; }
|
||||
};
|
||||
|
||||
struct IconKeepUpright : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "icon-keep-upright";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct IconOffset : LayoutProperty<std::array<float, 2>> {
|
||||
static constexpr const char * key = "icon-offset";
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
};
|
||||
|
||||
struct TextPitchAlignment : LayoutProperty<AlignmentType> {
|
||||
static constexpr const char * key = "text-pitch-alignment";
|
||||
static AlignmentType defaultValue() { return AlignmentType::Auto; }
|
||||
};
|
||||
|
||||
struct TextRotationAlignment : LayoutProperty<AlignmentType> {
|
||||
static constexpr const char * key = "text-rotation-alignment";
|
||||
static AlignmentType defaultValue() { return AlignmentType::Auto; }
|
||||
};
|
||||
|
||||
struct TextField : LayoutProperty<std::string> {
|
||||
static constexpr const char * key = "text-field";
|
||||
static std::string defaultValue() { return ""; }
|
||||
};
|
||||
|
||||
struct TextFont : LayoutProperty<std::vector<std::string>> {
|
||||
static constexpr const char * key = "text-font";
|
||||
static std::vector<std::string> defaultValue() { return { "Open Sans Regular", "Arial Unicode MS Regular" }; }
|
||||
};
|
||||
|
||||
struct TextSize : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-size";
|
||||
static float defaultValue() { return 16; }
|
||||
};
|
||||
|
||||
struct TextMaxWidth : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-max-width";
|
||||
static float defaultValue() { return 10; }
|
||||
};
|
||||
|
||||
struct TextLineHeight : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-line-height";
|
||||
static float defaultValue() { return 1.2; }
|
||||
};
|
||||
|
||||
struct TextLetterSpacing : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-letter-spacing";
|
||||
static float defaultValue() { return 0; }
|
||||
};
|
||||
|
||||
struct TextJustify : LayoutProperty<TextJustifyType> {
|
||||
static constexpr const char * key = "text-justify";
|
||||
static TextJustifyType defaultValue() { return TextJustifyType::Center; }
|
||||
};
|
||||
|
||||
struct TextAnchor : LayoutProperty<TextAnchorType> {
|
||||
static constexpr const char * key = "text-anchor";
|
||||
static TextAnchorType defaultValue() { return TextAnchorType::Center; }
|
||||
};
|
||||
|
||||
struct TextMaxAngle : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-max-angle";
|
||||
static float defaultValue() { return 45; }
|
||||
};
|
||||
|
||||
struct TextRotate : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-rotate";
|
||||
static float defaultValue() { return 0; }
|
||||
};
|
||||
|
||||
struct TextPadding : LayoutProperty<float> {
|
||||
static constexpr const char * key = "text-padding";
|
||||
static float defaultValue() { return 2; }
|
||||
};
|
||||
|
||||
struct TextKeepUpright : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "text-keep-upright";
|
||||
static bool defaultValue() { return true; }
|
||||
};
|
||||
|
||||
struct TextTransform : LayoutProperty<TextTransformType> {
|
||||
static constexpr const char * key = "text-transform";
|
||||
static TextTransformType defaultValue() { return TextTransformType::None; }
|
||||
};
|
||||
|
||||
struct TextOffset : LayoutProperty<std::array<float, 2>> {
|
||||
static constexpr const char * key = "text-offset";
|
||||
static std::array<float, 2> defaultValue() { return {{ 0, 0 }}; }
|
||||
};
|
||||
|
||||
struct TextAllowOverlap : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "text-allow-overlap";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct TextIgnorePlacement : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "text-ignore-placement";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
struct TextOptional : LayoutProperty<bool> {
|
||||
static constexpr const char * key = "text-optional";
|
||||
static bool defaultValue() { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ void GeometryTile::onError(std::exception_ptr err) {
|
||||
}
|
||||
|
||||
Bucket* GeometryTile::getBucket(const Layer& layer) {
|
||||
const auto it = buckets.find(layer.baseImpl->bucketName());
|
||||
const auto it = buckets.find(layer.baseImpl->id);
|
||||
if (it == buckets.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
|
||||
class LayoutResult {
|
||||
public:
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
|
||||
std::unique_ptr<FeatureIndex> featureIndex;
|
||||
std::unique_ptr<GeometryTileData> tileData;
|
||||
uint64_t correlationID;
|
||||
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
class PlacementResult {
|
||||
public:
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
|
||||
std::unique_ptr<CollisionTile> collisionTile;
|
||||
uint64_t correlationID;
|
||||
};
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
uint64_t correlationID = 0;
|
||||
optional<PlacementConfig> requestedConfig;
|
||||
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
|
||||
std::unique_ptr<FeatureIndex> featureIndex;
|
||||
std::unique_ptr<const GeometryTileData> data;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include <mbgl/text/glyph_atlas.hpp>
|
||||
#include <mbgl/layout/symbol_layout.hpp>
|
||||
#include <mbgl/style/bucket_parameters.hpp>
|
||||
#include <mbgl/style/group_by_layout.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/renderer/symbol_bucket.hpp>
|
||||
@@ -201,48 +202,58 @@ void GeometryTileWorker::redoLayout() {
|
||||
return;
|
||||
}
|
||||
|
||||
// We're doing a fresh parse of the tile, because the underlying data or style has changed.
|
||||
symbolLayouts.clear();
|
||||
std::vector<std::string> symbolOrder;
|
||||
for (auto it = layers->rbegin(); it != layers->rend(); it++) {
|
||||
if ((*it)->is<SymbolLayer>()) {
|
||||
symbolOrder.push_back((*it)->getID());
|
||||
}
|
||||
}
|
||||
|
||||
// We're storing a set of bucket names we've parsed to avoid parsing a bucket twice that is
|
||||
// referenced from more than one layer
|
||||
std::unordered_set<std::string> parsed;
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
std::unordered_map<std::string, std::unique_ptr<SymbolLayout>> symbolLayoutMap;
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
|
||||
auto featureIndex = std::make_unique<FeatureIndex>();
|
||||
BucketParameters parameters { id, obsolete, *featureIndex, mode };
|
||||
|
||||
for (auto i = layers->rbegin(); i != layers->rend(); i++) {
|
||||
std::vector<std::vector<std::unique_ptr<Layer>>> groups = groupByLayout(std::move(*layers));
|
||||
for (auto& group : groups) {
|
||||
if (obsolete) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Layer* layer = i->get();
|
||||
const std::string& bucketName = layer->baseImpl->bucketName();
|
||||
|
||||
featureIndex->addBucketLayerName(bucketName, layer->baseImpl->id);
|
||||
|
||||
if (parsed.find(bucketName) != parsed.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
parsed.emplace(bucketName);
|
||||
|
||||
if (!*data) {
|
||||
continue; // Tile has no data.
|
||||
}
|
||||
|
||||
auto geometryLayer = (*data)->getLayer(layer->baseImpl->sourceLayer);
|
||||
const Layer& leader = *group.at(0);
|
||||
|
||||
auto geometryLayer = (*data)->getLayer(leader.baseImpl->sourceLayer);
|
||||
if (!geometryLayer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layer->is<SymbolLayer>()) {
|
||||
symbolLayouts.push_back(layer->as<SymbolLayer>()->impl->createLayout(parameters, *geometryLayer));
|
||||
for (const auto& layer : group) {
|
||||
featureIndex->addBucketLayerName(leader.getID(), layer->getID());
|
||||
}
|
||||
|
||||
if (leader.is<SymbolLayer>()) {
|
||||
symbolLayoutMap.emplace(leader.getID(),
|
||||
leader.as<SymbolLayer>()->impl->createLayout(parameters, *geometryLayer, std::move(group)));
|
||||
} else {
|
||||
std::unique_ptr<Bucket> bucket = layer->baseImpl->createBucket(parameters, *geometryLayer);
|
||||
if (bucket->hasData()) {
|
||||
buckets.emplace(layer->baseImpl->bucketName(), std::move(bucket));
|
||||
std::shared_ptr<Bucket> bucket = leader.baseImpl->createBucket(parameters, *geometryLayer);
|
||||
if (!bucket->hasData()) {
|
||||
continue;
|
||||
}
|
||||
for (const auto& layer : group) {
|
||||
buckets.emplace(layer->getID(), bucket);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
symbolLayouts.clear();
|
||||
for (const auto& symbolLayerID : symbolOrder) {
|
||||
auto it = symbolLayoutMap.find(symbolLayerID);
|
||||
if (it != symbolLayoutMap.end()) {
|
||||
symbolLayouts.push_back(std::move(it->second));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +308,7 @@ void GeometryTileWorker::attemptPlacement() {
|
||||
}
|
||||
|
||||
auto collisionTile = std::make_unique<CollisionTile>(*placementConfig);
|
||||
std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
|
||||
std::unordered_map<std::string, std::shared_ptr<Bucket>> buckets;
|
||||
|
||||
for (auto& symbolLayout : symbolLayouts) {
|
||||
if (obsolete) {
|
||||
@@ -305,9 +316,13 @@ void GeometryTileWorker::attemptPlacement() {
|
||||
}
|
||||
|
||||
symbolLayout->state = SymbolLayout::Placed;
|
||||
if (symbolLayout->hasSymbolInstances()) {
|
||||
buckets.emplace(symbolLayout->bucketName,
|
||||
symbolLayout->place(*collisionTile));
|
||||
if (!symbolLayout->hasSymbolInstances()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<Bucket> bucket = symbolLayout->place(*collisionTile);
|
||||
for (const auto& layer : symbolLayout->layers) {
|
||||
buckets.emplace(layer->getID(), bucket);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <mbgl/util/color.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
|
||||
#include <csscolorparser/csscolorparser.hpp>
|
||||
|
||||
@@ -17,4 +18,12 @@ optional<Color> Color::parse(const std::string& s) {
|
||||
}};
|
||||
}
|
||||
|
||||
std::string Color::stringify() const {
|
||||
return "rgba(" +
|
||||
util::toString(r * 255) + "," +
|
||||
util::toString(g * 255) + "," +
|
||||
util::toString(b * 255) + "," +
|
||||
util::toString(a) + ")";
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
98
test/style/conversion/stringify.test.cpp
Normal file
98
test/style/conversion/stringify.test.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/style/conversion/stringify.hpp>
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_properties.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <rapidjson/writer.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
using namespace mbgl::style::conversion;
|
||||
|
||||
template <class T>
|
||||
std::string stringify(const T& t) {
|
||||
rapidjson::StringBuffer s;
|
||||
rapidjson::Writer<rapidjson::StringBuffer> writer(s);
|
||||
stringify(writer, t);
|
||||
return s.GetString();
|
||||
}
|
||||
|
||||
TEST(Stringify, NullValue) {
|
||||
ASSERT_EQ(stringify(NullValue()), "null");
|
||||
}
|
||||
|
||||
TEST(Stringify, Boolean) {
|
||||
ASSERT_EQ(stringify(true), "true");
|
||||
ASSERT_EQ(stringify(false), "false");
|
||||
}
|
||||
|
||||
TEST(Stringify, Uint64) {
|
||||
ASSERT_EQ(stringify(uint64_t(0)), "0");
|
||||
ASSERT_EQ(stringify(uint64_t(1)), "1");
|
||||
}
|
||||
|
||||
TEST(Stringify, Int64) {
|
||||
ASSERT_EQ(stringify(int64_t(0)), "0");
|
||||
ASSERT_EQ(stringify(int64_t(-1)), "-1");
|
||||
}
|
||||
|
||||
TEST(Stringify, Double) {
|
||||
ASSERT_EQ(stringify(0.0), "0.0");
|
||||
ASSERT_EQ(stringify(10.1234), "10.1234");
|
||||
}
|
||||
|
||||
TEST(Stringify, String) {
|
||||
ASSERT_EQ(stringify(std::string("test")), "\"test\"");
|
||||
}
|
||||
|
||||
TEST(Stringify, Enum) {
|
||||
ASSERT_EQ(stringify(VisibilityType::Visible), "\"visible\"");
|
||||
}
|
||||
|
||||
TEST(Stringify, Color) {
|
||||
ASSERT_EQ(stringify(Color::blue()), "\"rgba(0,0,255,1)\"");
|
||||
}
|
||||
|
||||
TEST(Stringify, Array) {
|
||||
ASSERT_EQ(stringify(std::array<float, 2> {{ 1, 2 }}), "[1.0,2.0]");
|
||||
}
|
||||
|
||||
TEST(Stringify, Vector) {
|
||||
ASSERT_EQ(stringify(std::vector<float> {{ 1, 2 }}), "[1.0,2.0]");
|
||||
}
|
||||
|
||||
TEST(Stringify, Map) {
|
||||
ASSERT_EQ(stringify(std::unordered_map<std::string, float> {{ "a", 1 }}), "{\"a\":1.0}");
|
||||
}
|
||||
|
||||
TEST(Stringify, Value) {
|
||||
ASSERT_EQ(stringify(Value(true)), "true");
|
||||
ASSERT_EQ(stringify(Value(uint64_t(0))), "0");
|
||||
ASSERT_EQ(stringify(Value(1.2)), "1.2");
|
||||
}
|
||||
|
||||
TEST(Stringify, Filter) {
|
||||
ASSERT_EQ(stringify(NullFilter()), "null");
|
||||
ASSERT_EQ(stringify(EqualsFilter { "a", 1.0 }), "[\"==\",\"a\",1.0]");
|
||||
}
|
||||
|
||||
TEST(Stringify, Function) {
|
||||
ASSERT_EQ(stringify(Function<float>({{0, 1}}, 2)), "{\"base\":2.0,\"stops\":[[0.0,1.0]]}");
|
||||
}
|
||||
|
||||
TEST(Stringify, PropertyValue) {
|
||||
ASSERT_EQ(stringify(PropertyValue<float>(1)), "1.0");
|
||||
ASSERT_EQ(stringify(PropertyValue<float>(Function<float>({{0, 1}}, 2))), "{\"base\":2.0,\"stops\":[[0.0,1.0]]}");
|
||||
}
|
||||
|
||||
TEST(Stringify, Layout) {
|
||||
ASSERT_EQ(stringify(SymbolLayoutProperties()), "{}");
|
||||
|
||||
SymbolLayoutProperties layout;
|
||||
layout.unevaluated.get<SymbolAvoidEdges>() = true;
|
||||
layout.unevaluated.get<IconPadding>() = 2.0;
|
||||
ASSERT_EQ(stringify(layout), "{\"symbol-avoid-edges\":true,\"icon-padding\":2.0}");
|
||||
}
|
||||
44
test/style/group_by_layout.test.cpp
Normal file
44
test/style/group_by_layout.test.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <mbgl/test/util.hpp>
|
||||
|
||||
#include <mbgl/style/group_by_layout.hpp>
|
||||
#include <mbgl/style/layers/background_layer.hpp>
|
||||
#include <mbgl/style/layers/circle_layer.hpp>
|
||||
#include <mbgl/style/layers/line_layer.hpp>
|
||||
|
||||
using namespace mbgl;
|
||||
using namespace mbgl::style;
|
||||
|
||||
TEST(GroupByLayout, Related) {
|
||||
std::vector<std::unique_ptr<Layer>> layers;
|
||||
layers.push_back(std::make_unique<LineLayer>("a", "source"));
|
||||
layers.push_back(std::make_unique<LineLayer>("b", "source"));
|
||||
auto result = groupByLayout(std::move(layers));
|
||||
ASSERT_EQ(1u, result.size());
|
||||
ASSERT_EQ(2u, result[0].size());
|
||||
}
|
||||
|
||||
TEST(GroupByLayout, UnrelatedType) {
|
||||
std::vector<std::unique_ptr<Layer>> layers;
|
||||
layers.push_back(std::make_unique<BackgroundLayer>("background"));
|
||||
layers.push_back(std::make_unique<CircleLayer>("circle", "source"));
|
||||
auto result = groupByLayout(std::move(layers));
|
||||
ASSERT_EQ(2u, result.size());
|
||||
}
|
||||
|
||||
TEST(GroupByLayout, UnrelatedFilter) {
|
||||
std::vector<std::unique_ptr<Layer>> layers;
|
||||
layers.push_back(std::make_unique<LineLayer>("a", "source"));
|
||||
layers.push_back(std::make_unique<LineLayer>("b", "source"));
|
||||
layers[0]->as<LineLayer>()->setFilter(EqualsFilter());
|
||||
auto result = groupByLayout(std::move(layers));
|
||||
ASSERT_EQ(2u, result.size());
|
||||
}
|
||||
|
||||
TEST(GroupByLayout, UnrelatedLayout) {
|
||||
std::vector<std::unique_ptr<Layer>> layers;
|
||||
layers.push_back(std::make_unique<LineLayer>("a", "source"));
|
||||
layers.push_back(std::make_unique<LineLayer>("b", "source"));
|
||||
layers[0]->as<LineLayer>()->setLineCap(LineCapType::Square);
|
||||
auto result = groupByLayout(std::move(layers));
|
||||
ASSERT_EQ(2u, result.size());
|
||||
}
|
||||
Reference in New Issue
Block a user