summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/mbgl/actor/actor.hpp98
-rw-r--r--include/mbgl/actor/actor_ref.hpp64
-rw-r--r--include/mbgl/actor/mailbox.hpp6
-rw-r--r--include/mbgl/actor/message.hpp108
-rw-r--r--include/mbgl/actor/scheduler.hpp15
-rw-r--r--include/mbgl/annotation/annotation.hpp42
-rw-r--r--include/mbgl/map/map.hpp89
-rw-r--r--include/mbgl/map/mode.hpp11
-rw-r--r--include/mbgl/map/view.hpp18
-rw-r--r--include/mbgl/math/log2.hpp4
-rw-r--r--include/mbgl/renderer/backend_scope.hpp (renamed from include/mbgl/map/backend_scope.hpp)6
-rw-r--r--include/mbgl/renderer/query.hpp (renamed from include/mbgl/map/query.hpp)12
-rw-r--r--include/mbgl/renderer/renderer.hpp55
-rw-r--r--include/mbgl/renderer/renderer_backend.hpp (renamed from include/mbgl/map/backend.hpp)46
-rw-r--r--include/mbgl/renderer/renderer_frontend.hpp31
-rw-r--r--include/mbgl/storage/default_file_source.hpp22
-rw-r--r--include/mbgl/storage/offline.hpp4
-rw-r--r--include/mbgl/storage/online_file_source.hpp11
-rw-r--r--include/mbgl/storage/resource.hpp7
-rw-r--r--include/mbgl/storage/resource_transform.hpp26
-rw-r--r--include/mbgl/storage/response.hpp10
-rw-r--r--include/mbgl/style/conversion.hpp1
-rw-r--r--include/mbgl/style/conversion/coordinate.hpp37
-rw-r--r--include/mbgl/style/conversion/filter.hpp2
-rw-r--r--include/mbgl/style/conversion/function.hpp4
-rw-r--r--include/mbgl/style/conversion/layer.hpp23
-rw-r--r--include/mbgl/style/conversion/make_property_setters.hpp202
-rw-r--r--include/mbgl/style/conversion/make_property_setters.hpp.ejs8
-rw-r--r--include/mbgl/style/conversion/property_setter.hpp34
-rw-r--r--include/mbgl/style/conversion/source.hpp47
-rw-r--r--include/mbgl/style/data_driven_property_value.hpp8
-rw-r--r--include/mbgl/style/function/camera_function.hpp5
-rw-r--r--include/mbgl/style/function/composite_function.hpp7
-rw-r--r--include/mbgl/style/function/exponential_stops.hpp22
-rw-r--r--include/mbgl/style/function/interval_stops.hpp18
-rw-r--r--include/mbgl/style/function/source_function.hpp3
-rw-r--r--include/mbgl/style/image.hpp18
-rw-r--r--include/mbgl/style/layer.hpp49
-rw-r--r--include/mbgl/style/layers/background_layer.hpp40
-rw-r--r--include/mbgl/style/layers/circle_layer.hpp102
-rw-r--r--include/mbgl/style/layers/custom_layer.hpp29
-rw-r--r--include/mbgl/style/layers/fill_extrusion_layer.hpp72
-rw-r--r--include/mbgl/style/layers/fill_layer.hpp72
-rw-r--r--include/mbgl/style/layers/layer.hpp.ejs24
-rw-r--r--include/mbgl/style/layers/line_layer.hpp104
-rw-r--r--include/mbgl/style/layers/raster_layer.hpp72
-rw-r--r--include/mbgl/style/layers/symbol_layer.hpp160
-rw-r--r--include/mbgl/style/light.hpp16
-rw-r--r--include/mbgl/style/light.hpp.ejs16
-rw-r--r--include/mbgl/style/position.hpp2
-rw-r--r--include/mbgl/style/property_value.hpp6
-rw-r--r--include/mbgl/style/source.hpp31
-rw-r--r--include/mbgl/style/sources/geojson_source.hpp16
-rw-r--r--include/mbgl/style/sources/image_source.hpp41
-rw-r--r--include/mbgl/style/sources/raster_source.hpp17
-rw-r--r--include/mbgl/style/sources/vector_source.hpp17
-rw-r--r--include/mbgl/style/style.hpp79
-rw-r--r--include/mbgl/style/transition_options.hpp9
-rw-r--r--include/mbgl/style/types.hpp5
-rw-r--r--include/mbgl/tile/tile_id.hpp263
-rw-r--r--include/mbgl/util/constants.hpp6
-rw-r--r--include/mbgl/util/convert.hpp6
-rw-r--r--include/mbgl/util/image.hpp49
-rw-r--r--include/mbgl/util/immutable.hpp133
-rw-r--r--include/mbgl/util/indexed_tuple.hpp7
-rw-r--r--include/mbgl/util/interpolate.hpp6
-rw-r--r--include/mbgl/util/noncopyable.hpp8
-rw-r--r--include/mbgl/util/projection.hpp22
-rw-r--r--include/mbgl/util/range.hpp6
-rw-r--r--include/mbgl/util/run_loop.hpp21
-rw-r--r--include/mbgl/util/size.hpp4
-rw-r--r--include/mbgl/util/string.hpp25
-rw-r--r--include/mbgl/util/thread.hpp161
-rw-r--r--include/mbgl/util/tileset.hpp19
-rw-r--r--include/mbgl/util/unitbezier.hpp8
-rw-r--r--include/mbgl/util/util.hpp7
-rw-r--r--include/mbgl/util/work_task.hpp3
-rw-r--r--include/mbgl/util/work_task_impl.hpp44
78 files changed, 2130 insertions, 771 deletions
diff --git a/include/mbgl/actor/actor.hpp b/include/mbgl/actor/actor.hpp
new file mode 100644
index 0000000000..a0df19208e
--- /dev/null
+++ b/include/mbgl/actor/actor.hpp
@@ -0,0 +1,98 @@
+#pragma once
+
+#include <mbgl/actor/mailbox.hpp>
+#include <mbgl/actor/message.hpp>
+#include <mbgl/actor/actor_ref.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+#include <memory>
+#include <future>
+#include <type_traits>
+
+namespace mbgl {
+
+/*
+ An `Actor<O>` is an owning reference to an asynchronous object of type `O`: an "actor".
+ Communication with an actor happens via message passing: you send a message to the object
+ (using `invoke`), passing a pointer to the member function to call and arguments which
+ are then forwarded to the actor.
+
+ The actor receives messages sent to it asynchronously, in a manner defined its `Scheduler`.
+ To store incoming messages before their receipt, each actor has a `Mailbox`, which acts as
+ a FIFO queue. Messages sent from actor S to actor R are guaranteed to be processed in the
+ order sent. However, relative order of messages sent by two *different* actors S1 and S2
+ to R is *not* guaranteed (and can't be: S1 and S2 may be acting asynchronously with respect
+ to each other).
+
+ An `Actor<O>` can be converted to an `ActorRef<O>`, a non-owning value object representing
+ a (weak) reference to the actor. Messages can be sent via the `Ref` as well.
+
+ It's safe -- and encouraged -- to pass `Ref`s between actors via messages. This is how two-way
+ communication and other forms of collaboration between multiple actors is accomplished.
+
+ It's safe for a `Ref` to outlive its `Actor` -- the reference is "weak", and does not extend
+ the lifetime of the owning Actor, and sending a message to a `Ref` whose `Actor` has died is
+ a no-op. (In the future, a dead-letters queue or log may be implemented.)
+
+ Construction and destruction of an actor is currently synchronous: the corresponding `O`
+ object is constructed synchronously by the `Actor` constructor, and destructed synchronously
+ by the `~Actor` destructor, after ensuring that the `O` is not currently receiving an
+ asynchronous message. (Construction and destruction may change to be asynchronous in the
+ future.) The constructor of `O` is passed an `ActorRef<O>` referring to itself (which it
+ can use to self-send messages), followed by the forwarded arguments passed to `Actor<O>`.
+
+ Please don't send messages that contain shared pointers or references. That subverts the
+ purpose of the actor model: prohibiting direct concurrent access to shared state.
+*/
+
+template <class Object>
+class Actor : public util::noncopyable {
+public:
+
+ // Enabled for Objects with a constructor taking ActorRef<Object> as the first parameter
+ template <typename U = Object, class... Args, typename std::enable_if<std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
+ Actor(Scheduler& scheduler, Args&&... args_)
+ : mailbox(std::make_shared<Mailbox>(scheduler)),
+ object(self(), std::forward<Args>(args_)...) {
+ }
+
+ // Enabled for plain Objects
+ template<typename U = Object, class... Args, typename std::enable_if<!std::is_constructible<U, ActorRef<U>, Args...>::value>::type * = nullptr>
+ Actor(Scheduler& scheduler, Args&& ... args_)
+ : mailbox(std::make_shared<Mailbox>(scheduler)), object(std::forward<Args>(args_)...) {
+ }
+
+ ~Actor() {
+ mailbox->close();
+ }
+
+ template <typename Fn, class... Args>
+ void invoke(Fn fn, Args&&... args) {
+ mailbox->push(actor::makeMessage(object, fn, std::forward<Args>(args)...));
+ }
+
+ template <typename Fn, class... Args>
+ auto ask(Fn fn, Args&&... args) {
+ // Result type is deduced from the function's return type
+ using ResultType = typename std::result_of<decltype(fn)(Object, Args...)>::type;
+
+ std::promise<ResultType> promise;
+ auto future = promise.get_future();
+ mailbox->push(actor::makeMessage(std::move(promise), object, fn, std::forward<Args>(args)...));
+ return future;
+ }
+
+ ActorRef<std::decay_t<Object>> self() {
+ return ActorRef<std::decay_t<Object>>(object, mailbox);
+ }
+
+ operator ActorRef<std::decay_t<Object>>() {
+ return self();
+ }
+
+private:
+ std::shared_ptr<Mailbox> mailbox;
+ Object object;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/actor/actor_ref.hpp b/include/mbgl/actor/actor_ref.hpp
new file mode 100644
index 0000000000..958ee3777c
--- /dev/null
+++ b/include/mbgl/actor/actor_ref.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include <mbgl/actor/mailbox.hpp>
+#include <mbgl/actor/message.hpp>
+
+#include <memory>
+
+namespace mbgl {
+
+/*
+ An `ActorRef<O>` is a *non*-owning, weak reference to an actor of type `O`. You can send it
+ messages just like an `Actor<O>`. It's a value object: safe to copy and pass between actors
+ via messages.
+
+ An `ActorRef<O>` does not extend the lifetime of the corresponding `Actor<O>`. That's determined
+ entirely by whichever object owns the `Actor<O>` -- the actor's "supervisor".
+
+ It's safe for a `Ref` to outlive its `Actor` -- the reference is "weak", and does not extend
+ the lifetime of the owning Actor, and sending a message to a `Ref` whose `Actor` has died is
+ a no-op. (In the future, a dead-letters queue or log may be implemented.)
+*/
+
+template <class Object>
+class ActorRef {
+public:
+ ActorRef(Object& object_, std::weak_ptr<Mailbox> weakMailbox_)
+ : object(&object_),
+ weakMailbox(std::move(weakMailbox_)) {
+ }
+
+ template <typename Fn, class... Args>
+ void invoke(Fn fn, Args&&... args) {
+ if (auto mailbox = weakMailbox.lock()) {
+ mailbox->push(actor::makeMessage(*object, fn, std::forward<Args>(args)...));
+ }
+ }
+
+ template <typename Fn, class... Args>
+ auto ask(Fn fn, Args&&... args) {
+ // Result type is deduced from the function's return type
+ using ResultType = typename std::result_of<decltype(fn)(Object, Args...)>::type;
+
+ std::promise<ResultType> promise;
+ auto future = promise.get_future();
+
+ if (auto mailbox = weakMailbox.lock()) {
+ mailbox->push(
+ actor::makeMessage(
+ std::move(promise), *object, fn, std::forward<Args>(args)...
+ )
+ );
+ } else {
+ promise.set_exception(std::make_exception_ptr(std::runtime_error("Actor has gone away")));
+ }
+
+ return future;
+ }
+
+private:
+ Object* object;
+ std::weak_ptr<Mailbox> weakMailbox;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/actor/mailbox.hpp b/include/mbgl/actor/mailbox.hpp
index cff0de243a..8ecf91701a 100644
--- a/include/mbgl/actor/mailbox.hpp
+++ b/include/mbgl/actor/mailbox.hpp
@@ -23,8 +23,10 @@ public:
private:
Scheduler& scheduler;
- std::mutex closingMutex;
- bool closing { false };
+ std::recursive_mutex receivingMutex;
+ std::mutex pushingMutex;
+
+ bool closed { false };
std::mutex queueMutex;
std::queue<std::unique_ptr<Message>> queue;
diff --git a/include/mbgl/actor/message.hpp b/include/mbgl/actor/message.hpp
new file mode 100644
index 0000000000..0a20993352
--- /dev/null
+++ b/include/mbgl/actor/message.hpp
@@ -0,0 +1,108 @@
+#pragma once
+
+#include <mbgl/util/optional.hpp>
+
+#include <future>
+#include <utility>
+
+namespace mbgl {
+
+// A movable type-erasing function wrapper. This allows to store arbitrary invokable
+// things (like std::function<>, or the result of a movable-only std::bind()) in the queue.
+// Source: http://stackoverflow.com/a/29642072/331379
+class Message {
+public:
+ virtual ~Message() = default;
+ virtual void operator()() = 0;
+};
+
+template <class Object, class MemberFn, class ArgsTuple>
+class MessageImpl : public Message {
+public:
+ MessageImpl(Object& object_, MemberFn memberFn_, ArgsTuple argsTuple_)
+ : object(object_),
+ memberFn(memberFn_),
+ argsTuple(std::move(argsTuple_)) {
+ }
+
+ void operator()() override {
+ invoke(std::make_index_sequence<std::tuple_size<ArgsTuple>::value>());
+ }
+
+ template <std::size_t... I>
+ void invoke(std::index_sequence<I...>) {
+ (object.*memberFn)(std::move(std::get<I>(argsTuple))...);
+ }
+
+ Object& object;
+ MemberFn memberFn;
+ ArgsTuple argsTuple;
+};
+
+template <class ResultType, class Object, class MemberFn, class ArgsTuple>
+class AskMessageImpl : public Message {
+public:
+ AskMessageImpl(std::promise<ResultType> promise_, Object& object_, MemberFn memberFn_, ArgsTuple argsTuple_)
+ : object(object_),
+ memberFn(memberFn_),
+ argsTuple(std::move(argsTuple_)),
+ promise(std::move(promise_)) {
+ }
+
+ void operator()() override {
+ promise.set_value(ask(std::make_index_sequence<std::tuple_size<ArgsTuple>::value>()));
+ }
+
+ template <std::size_t... I>
+ ResultType ask(std::index_sequence<I...>) {
+ return (object.*memberFn)(std::move(std::get<I>(argsTuple))...);
+ }
+
+ Object& object;
+ MemberFn memberFn;
+ ArgsTuple argsTuple;
+ std::promise<ResultType> promise;
+};
+
+template <class Object, class MemberFn, class ArgsTuple>
+class AskMessageImpl<void, Object, MemberFn, ArgsTuple> : public Message {
+public:
+ AskMessageImpl(std::promise<void> promise_, Object& object_, MemberFn memberFn_, ArgsTuple argsTuple_)
+ : object(object_),
+ memberFn(memberFn_),
+ argsTuple(std::move(argsTuple_)),
+ promise(std::move(promise_)) {
+ }
+
+ void operator()() override {
+ ask(std::make_index_sequence<std::tuple_size<ArgsTuple>::value>());
+ promise.set_value();
+ }
+
+ template <std::size_t... I>
+ void ask(std::index_sequence<I...>) {
+ (object.*memberFn)(std::move(std::get<I>(argsTuple))...);
+ }
+
+ Object& object;
+ MemberFn memberFn;
+ ArgsTuple argsTuple;
+ std::promise<void> promise;
+};
+
+namespace actor {
+
+template <class Object, class MemberFn, class... Args>
+std::unique_ptr<Message> makeMessage(Object& object, MemberFn memberFn, Args&&... args) {
+ auto tuple = std::make_tuple(std::forward<Args>(args)...);
+ return std::make_unique<MessageImpl<Object, MemberFn, decltype(tuple)>>(object, memberFn, std::move(tuple));
+}
+
+template <class ResultType, class Object, class MemberFn, class... Args>
+std::unique_ptr<Message> makeMessage(std::promise<ResultType>&& promise, Object& object, MemberFn memberFn, Args&&... args) {
+ auto tuple = std::make_tuple(std::forward<Args>(args)...);
+ return std::make_unique<AskMessageImpl<ResultType, Object, MemberFn, decltype(tuple)>>(std::move(promise), object, memberFn, std::move(tuple));
+}
+
+} // namespace actor
+} // namespace mbgl
diff --git a/include/mbgl/actor/scheduler.hpp b/include/mbgl/actor/scheduler.hpp
index 83689c3348..d8a26ebeab 100644
--- a/include/mbgl/actor/scheduler.hpp
+++ b/include/mbgl/actor/scheduler.hpp
@@ -21,18 +21,21 @@ class Mailbox;
Subject to these constraints, processing can happen on whatever thread in the
pool is available.
- * `RunLoop` is a `Scheduler` that is typically used to create a mailbox and
- `ActorRef` for an object that lives on the main thread and is not itself wrapped
- as an `Actor`:
-
- auto mailbox = std::make_shared<Mailbox>(*util::RunLoop::Get());
+ * `Scheduler::GetCurrent()` is typically used to create a mailbox and `ActorRef`
+ for an object that lives on the main thread and is not itself wrapped an
+ `Actor`. The underlying implementation of this Scheduler should usually be
+ a `RunLoop`
+ auto mailbox = std::make_shared<Mailbox>(*Scheduler::Get());
Actor<Worker> worker(threadPool, ActorRef<Foo>(*this, mailbox));
*/
-
class Scheduler {
public:
virtual ~Scheduler() = default;
virtual void schedule(std::weak_ptr<Mailbox>) = 0;
+
+ // Set/Get the current Scheduler for this thread
+ static Scheduler* GetCurrent();
+ static void SetCurrent(Scheduler*);
};
} // namespace mbgl
diff --git a/include/mbgl/annotation/annotation.hpp b/include/mbgl/annotation/annotation.hpp
index de83d24712..bbe479b5ba 100644
--- a/include/mbgl/annotation/annotation.hpp
+++ b/include/mbgl/annotation/annotation.hpp
@@ -17,6 +17,10 @@ using AnnotationIDs = std::vector<AnnotationID>;
class SymbolAnnotation {
public:
+ SymbolAnnotation(Point<double> geometry_, std::string icon_ = {})
+ : geometry(std::move(geometry_)),
+ icon(std::move(icon_)) {}
+
Point<double> geometry;
std::string icon;
};
@@ -29,31 +33,41 @@ using ShapeAnnotationGeometry = variant<
class LineAnnotation {
public:
+ LineAnnotation(ShapeAnnotationGeometry geometry_,
+ style::DataDrivenPropertyValue<float> opacity_ = 1.0f,
+ style::DataDrivenPropertyValue<float> width_ = 1.0f,
+ style::DataDrivenPropertyValue<Color> color_ = Color::black())
+ : geometry(std::move(geometry_)),
+ opacity(std::move(opacity_)),
+ width(std::move(width_)),
+ color(std::move(color_)) {}
+
ShapeAnnotationGeometry geometry;
- style::DataDrivenPropertyValue<float> opacity { 1.0f };
- style::PropertyValue<float> width { 1.0f };
- style::DataDrivenPropertyValue<Color> color { Color::black() };
+ style::DataDrivenPropertyValue<float> opacity;
+ style::DataDrivenPropertyValue<float> width;
+ style::DataDrivenPropertyValue<Color> color;
};
class FillAnnotation {
public:
- ShapeAnnotationGeometry geometry;
- style::DataDrivenPropertyValue<float> opacity { 1.0f };
- style::DataDrivenPropertyValue<Color> color { Color::black() };
- style::DataDrivenPropertyValue<Color> outlineColor {};
-};
+ FillAnnotation(ShapeAnnotationGeometry geometry_,
+ style::DataDrivenPropertyValue<float> opacity_ = 1.0f,
+ style::DataDrivenPropertyValue<Color> color_ = Color::black(),
+ style::DataDrivenPropertyValue<Color> outlineColor_ = {})
+ : geometry(std::move(geometry_)),
+ opacity(std::move(opacity_)),
+ color(std::move(color_)),
+ outlineColor(std::move(outlineColor_)) {}
-// An annotation whose type and properties are sourced from a style layer.
-class StyleSourcedAnnotation {
-public:
ShapeAnnotationGeometry geometry;
- std::string layerID;
+ style::DataDrivenPropertyValue<float> opacity;
+ style::DataDrivenPropertyValue<Color> color;
+ style::DataDrivenPropertyValue<Color> outlineColor;
};
using Annotation = variant<
SymbolAnnotation,
LineAnnotation,
- FillAnnotation,
- StyleSourcedAnnotation>;
+ FillAnnotation>;
} // namespace mbgl
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
index bbeeeac6cc..4108725776 100644
--- a/include/mbgl/map/map.hpp
+++ b/include/mbgl/map/map.hpp
@@ -4,14 +4,10 @@
#include <mbgl/util/chrono.hpp>
#include <mbgl/map/map_observer.hpp>
#include <mbgl/map/mode.hpp>
-#include <mbgl/util/geo.hpp>
-#include <mbgl/util/feature.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/size.hpp>
#include <mbgl/annotation/annotation.hpp>
-#include <mbgl/style/transition_options.hpp>
#include <mbgl/map/camera.hpp>
-#include <mbgl/map/query.hpp>
#include <cstdint>
#include <string>
@@ -21,58 +17,41 @@
namespace mbgl {
-class Backend;
-class View;
class FileSource;
class Scheduler;
+class RendererFrontend;
namespace style {
class Image;
-class Source;
-class Layer;
-class Light;
+class Style;
} // namespace style
class Map : private util::noncopyable {
public:
- explicit Map(Backend&,
+ explicit Map(RendererFrontend&,
+ MapObserver&,
Size size,
float pixelRatio,
FileSource&,
Scheduler&,
MapMode mapMode = MapMode::Continuous,
- GLContextMode contextMode = GLContextMode::Unique,
ConstrainMode constrainMode = ConstrainMode::HeightOnly,
- ViewportMode viewportMode = ViewportMode::Default,
- const optional<std::string>& programCacheDir = {});
+ ViewportMode viewportMode = ViewportMode::Default);
~Map();
// Register a callback that will get called (on the render thread) when all resources have
// been loaded and a complete render occurs.
using StillImageCallback = std::function<void (std::exception_ptr)>;
- void renderStill(View&, StillImageCallback callback);
+ void renderStill(StillImageCallback);
+ void renderStill(const CameraOptions&, MapDebugOptions, StillImageCallback);
// Triggers a repaint.
void triggerRepaint();
- // Main render function.
- void render(View&);
+ style::Style& getStyle();
+ const style::Style& getStyle() const;
- // Styling
- void addClass(const std::string&);
- void removeClass(const std::string&);
- void setClasses(const std::vector<std::string>&);
-
- style::TransitionOptions getTransitionOptions() const;
- void setTransitionOptions(const style::TransitionOptions&);
-
- bool hasClass(const std::string&) const;
- std::vector<std::string> getClasses() const;
-
- void setStyleURL(const std::string&);
- void setStyleJSON(const std::string&);
- std::string getStyleURL() const;
- std::string getStyleJSON() const;
+ void setStyle(std::unique_ptr<style::Style>);
// Transition
void cancelTransitions();
@@ -155,7 +134,7 @@ public:
LatLng latLngForPixel(const ScreenCoordinate&) const;
// Annotations
- void addAnnotationImage(const std::string&, std::unique_ptr<style::Image>);
+ void addAnnotationImage(std::unique_ptr<style::Image>);
void removeAnnotationImage(const std::string&);
double getTopOffsetPixelsForAnnotationImage(const std::string&);
@@ -163,44 +142,14 @@ public:
void updateAnnotation(AnnotationID, const Annotation&);
void removeAnnotation(AnnotationID);
- // Sources
- std::vector<style::Source*> getSources();
- style::Source* getSource(const std::string& sourceID);
- void addSource(std::unique_ptr<style::Source>);
- std::unique_ptr<style::Source> removeSource(const std::string& sourceID);
-
- // Layers
- std::vector<style::Layer*> getLayers();
- style::Layer* getLayer(const std::string& layerID);
- void addLayer(std::unique_ptr<style::Layer>, const optional<std::string>& beforeLayerID = {});
- std::unique_ptr<style::Layer> removeLayer(const std::string& layerID);
-
- // Images
- void addImage(const std::string&, std::unique_ptr<style::Image>);
- void removeImage(const std::string&);
- const style::Image* getImage(const std::string&);
-
- // Light
- void setLight(std::unique_ptr<style::Light>);
- style::Light* getLight();
-
- // Defaults
- std::string getStyleName() const;
- LatLng getDefaultLatLng() const;
- double getDefaultZoom() const;
- double getDefaultBearing() const;
- double getDefaultPitch() const;
-
- // Feature queries
- std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate&, const RenderedQueryOptions& options = {});
- std::vector<Feature> queryRenderedFeatures(const ScreenBox&, const RenderedQueryOptions& options = {});
- std::vector<Feature> querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options = {});
-
- AnnotationIDs queryPointAnnotations(const ScreenBox&);
-
- // Memory
- void setSourceTileCacheSize(size_t);
- void onLowMemory();
+ // Tile prefetching
+ //
+ // When loading a map, if `PrefetchZoomDelta` is set to any number greater than 0, the map will
+ // first request a tile for `zoom = getZoom() - delta` in a attempt to display a full map at
+ // lower resolution as quick as possible. It will get clamped at the tile source minimum zoom.
+ // The default `delta` is 4.
+ void setPrefetchZoomDelta(uint8_t delta);
+ uint8_t getPrefetchZoomDelta() const;
// Debug
void setDebug(MapDebugOptions);
diff --git a/include/mbgl/map/mode.hpp b/include/mbgl/map/mode.hpp
index afec5c0a08..05de2df22c 100644
--- a/include/mbgl/map/mode.hpp
+++ b/include/mbgl/map/mode.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/util/util.hpp>
#include <mbgl/util/traits.hpp>
#include <cstdint>
@@ -51,23 +52,23 @@ enum class MapDebugOptions : EnumType {
#endif // MBGL_USE_GLES2
};
-constexpr MapDebugOptions operator|(MapDebugOptions lhs, MapDebugOptions rhs) {
+MBGL_CONSTEXPR MapDebugOptions operator|(MapDebugOptions lhs, MapDebugOptions rhs) {
return MapDebugOptions(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs));
}
-constexpr MapDebugOptions& operator|=(MapDebugOptions& lhs, MapDebugOptions rhs) {
+MBGL_CONSTEXPR MapDebugOptions& operator|=(MapDebugOptions& lhs, MapDebugOptions rhs) {
return (lhs = MapDebugOptions(mbgl::underlying_type(lhs) | mbgl::underlying_type(rhs)));
}
-constexpr bool operator&(MapDebugOptions lhs, MapDebugOptions rhs) {
+MBGL_CONSTEXPR bool operator&(MapDebugOptions lhs, MapDebugOptions rhs) {
return mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs);
}
-constexpr MapDebugOptions& operator&=(MapDebugOptions& lhs, MapDebugOptions rhs) {
+MBGL_CONSTEXPR MapDebugOptions& operator&=(MapDebugOptions& lhs, MapDebugOptions rhs) {
return (lhs = MapDebugOptions(mbgl::underlying_type(lhs) & mbgl::underlying_type(rhs)));
}
-constexpr MapDebugOptions operator~(MapDebugOptions value) {
+MBGL_CONSTEXPR MapDebugOptions operator~(MapDebugOptions value) {
return MapDebugOptions(~mbgl::underlying_type(value));
}
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
deleted file mode 100644
index 295779fe51..0000000000
--- a/include/mbgl/map/view.hpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#pragma once
-
-namespace mbgl {
-
-class Map;
-
-class View {
-public:
- virtual ~View() = default;
-
- // Called when this View is used for rendering. Implementations should ensure that a renderable
- // object is bound and glClear/glDraw* calls can be done. They should also make sure that
- // calling .bind() repeatedly is a no-op and that the appropriate gl::Context values are
- // set to the current state.
- virtual void bind() = 0;
-};
-
-} // namespace mbgl
diff --git a/include/mbgl/math/log2.hpp b/include/mbgl/math/log2.hpp
index 8a3bc7f1c0..53d5e45545 100644
--- a/include/mbgl/math/log2.hpp
+++ b/include/mbgl/math/log2.hpp
@@ -17,9 +17,9 @@ typename std::enable_if_t<std::is_floating_point<T>::value, T> log2(T x)
// log2() is producing wrong results on ARMv5 binaries
// running on ARMv7+ CPUs.
#if defined(__ANDROID__)
- return std::log(x) / M_LN2;
+ return ::log(x) / M_LN2;
#else
- return std::log2(x);
+ return ::log2(x);
#endif
}
diff --git a/include/mbgl/map/backend_scope.hpp b/include/mbgl/renderer/backend_scope.hpp
index 322c17b3fc..73bafc84c7 100644
--- a/include/mbgl/map/backend_scope.hpp
+++ b/include/mbgl/renderer/backend_scope.hpp
@@ -2,7 +2,7 @@
namespace mbgl {
-class Backend;
+class RendererBackend;
class BackendScope {
public:
@@ -15,7 +15,7 @@ public:
Explicit,
};
- BackendScope(Backend&, ScopeType = ScopeType::Explicit);
+ BackendScope(RendererBackend&, ScopeType = ScopeType::Explicit);
~BackendScope();
// Returns true when there is currently a BackendScope active in this thread.
@@ -27,7 +27,7 @@ private:
BackendScope* priorScope;
BackendScope* nextScope;
- Backend& backend;
+ RendererBackend& backend;
const ScopeType scopeType;
bool activated = false;
};
diff --git a/include/mbgl/map/query.hpp b/include/mbgl/renderer/query.hpp
index 9fac60d71d..4cadf4f017 100644
--- a/include/mbgl/map/query.hpp
+++ b/include/mbgl/renderer/query.hpp
@@ -13,6 +13,11 @@ namespace mbgl {
*/
class RenderedQueryOptions {
public:
+ RenderedQueryOptions(optional<std::vector<std::string>> layerIDs_ = {},
+ optional<style::Filter> filter_ = {})
+ : layerIDs(std::move(layerIDs_)),
+ filter(std::move(filter_)) {}
+
/** layerIDs to include in the query */
optional<std::vector<std::string>> layerIDs;
@@ -24,10 +29,15 @@ public:
*/
class SourceQueryOptions {
public:
+ SourceQueryOptions(optional<std::vector<std::string>> sourceLayers_ = {},
+ optional<style::Filter> filter_ = {})
+ : sourceLayers(std::move(sourceLayers_)),
+ filter(std::move(filter_)) {}
+
// Required for VectorSource, ignored for GeoJSONSource
optional<std::vector<std::string>> sourceLayers;
optional<style::Filter> filter;
};
-}
+} // namespace mbgl
diff --git a/include/mbgl/renderer/renderer.hpp b/include/mbgl/renderer/renderer.hpp
new file mode 100644
index 0000000000..be8abb2c29
--- /dev/null
+++ b/include/mbgl/renderer/renderer.hpp
@@ -0,0 +1,55 @@
+#pragma once
+
+#include <mbgl/map/mode.hpp>
+#include <mbgl/renderer/query.hpp>
+#include <mbgl/annotation/annotation.hpp>
+#include <mbgl/util/geo.hpp>
+#include <mbgl/util/geo.hpp>
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace mbgl {
+
+class FileSource;
+class RendererBackend;
+class RendererObserver;
+class RenderedQueryOptions;
+class Scheduler;
+class SourceQueryOptions;
+class UpdateParameters;
+
+class Renderer {
+public:
+ Renderer(RendererBackend&, float pixelRatio_, FileSource&, Scheduler&,
+ GLContextMode = GLContextMode::Unique,
+ const optional<std::string> programCacheDir = {});
+ ~Renderer();
+
+ void markContextLost();
+
+ void setObserver(RendererObserver*);
+
+ void render(const UpdateParameters&);
+
+ // Feature queries
+ std::vector<Feature> queryRenderedFeatures(const ScreenLineString&, const RenderedQueryOptions& options = {}) const;
+ std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate& point, const RenderedQueryOptions& options = {}) const;
+ std::vector<Feature> queryRenderedFeatures(const ScreenBox& box, const RenderedQueryOptions& options = {}) const;
+ std::vector<Feature> querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options = {}) const;
+ AnnotationIDs queryPointAnnotations(const ScreenBox& box) const;
+
+ // Debug
+ void dumpDebugLogs();
+
+ // Memory
+ void onLowMemory();
+
+private:
+ class Impl;
+ std::unique_ptr<Impl> impl;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/map/backend.hpp b/include/mbgl/renderer/renderer_backend.hpp
index 69a998709b..295838c71b 100644
--- a/include/mbgl/map/backend.hpp
+++ b/include/mbgl/renderer/renderer_backend.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include <mbgl/map/map_observer.hpp>
+#include <mbgl/renderer/backend_scope.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/size.hpp>
#include <mbgl/util/util.hpp>
@@ -16,12 +16,12 @@ using ProcAddress = void (*)();
using FramebufferID = uint32_t;
} // namespace gl
-class BackendScope;
-
-class Backend : public MapObserver {
+// The RendererBackend is used by the Renderer to facilitate
+// the actual rendering.
+class RendererBackend {
public:
- Backend();
- virtual ~Backend();
+ RendererBackend();
+ virtual ~RendererBackend();
// Returns the backend's context which manages OpenGL state.
gl::Context& getContext();
@@ -29,26 +29,28 @@ public:
// Called prior to rendering to update the internally assumed OpenGL state.
virtual void updateAssumedState() = 0;
- // Called when the map needs to be rendered; the backend should call Map::render() at some point
- // in the near future. (Not called for Map::renderStill() mode.)
- virtual void invalidate() = 0;
+ // Called when this backend is used for rendering. Implementations should ensure that a renderable
+ // object is bound and glClear/glDraw* calls can be done. They should also make sure that
+ // calling .bind() repeatedly is a no-op and that the appropriate gl::Context values are
+ // set to the current state.
+ virtual void bind() = 0;
+
+ virtual Size getFramebufferSize() const = 0;
protected:
- // Called with the name of an OpenGL extension that should be loaded. Backend implementations
+ // Called with the name of an OpenGL extension that should be loaded. RendererBackend implementations
// must call the API-specific version that obtains the function pointer for this function,
// or a null pointer if unsupported/unavailable.
virtual gl::ProcAddress initializeExtension(const char*) = 0;
// Called when the backend's GL context needs to be made active or inactive. These are called,
- // as a matched pair, in four situations:
- //
- // 1. When releasing GL resources during Map destruction
- // 2. When calling a CustomLayerInitializeFunction, during Map::addLayer
- // 3. When calling a CustomLayerDeinitializeFunction, during Map::removeLayer
- // 4. When rendering for Map::renderStill
+ // as a matched pair, exclusively through BackendScope, in two situations:
//
- // They are *not* called for Map::render; it is assumed that the correct context is already
- // activated prior to calling Map::render.
+ // 1. When releasing GL resources during Renderer destruction
+ // (Including calling CustomLayerDeinitializeFunction during RenderCustomLayer destruction)
+ // 2. When renderering through Renderer::render()
+ // (Including calling CustomLayerDeinitializeFunction for newly added custom layers and
+ // CustomLayerDeinitializeFunction on layer removal)
virtual void activate() = 0;
virtual void deactivate() = 0;
@@ -62,7 +64,8 @@ protected:
// Tells the renderer that OpenGL state has already been set by the windowing toolkit.
// It sets the internal assumed state to the supplied values.
void assumeFramebufferBinding(gl::FramebufferID fbo);
- void assumeViewportSize(const Size&);
+ void assumeViewport(int32_t x, int32_t y, const Size&);
+ void assumeScissorTest(bool);
// Returns true when assumed framebuffer binding hasn't changed from the implicit binding.
bool implicitFramebufferBound();
@@ -70,7 +73,8 @@ protected:
// Triggers an OpenGL state update if the internal assumed state doesn't match the
// supplied values.
void setFramebufferBinding(gl::FramebufferID fbo);
- void setViewportSize(const Size&);
+ void setViewport(int32_t x, int32_t y, const Size&);
+ void setScissorTest(bool);
protected:
std::unique_ptr<gl::Context> context;
@@ -81,7 +85,7 @@ private:
friend class BackendScope;
};
-constexpr bool operator==(const Backend& a, const Backend& b) {
+MBGL_CONSTEXPR bool operator==(const RendererBackend& a, const RendererBackend& b) {
return &a == &b;
}
diff --git a/include/mbgl/renderer/renderer_frontend.hpp b/include/mbgl/renderer/renderer_frontend.hpp
new file mode 100644
index 0000000000..f72b0ccdde
--- /dev/null
+++ b/include/mbgl/renderer/renderer_frontend.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include <memory>
+
+namespace mbgl {
+
+class RendererObserver;
+class UpdateParameters;
+
+// The RenderFrontend is the bridge between the Map and
+// platform used to update and observer the Renderer
+//
+// It hides any threading specifics and always replies on
+// the original thread.
+class RendererFrontend {
+public:
+
+ virtual ~RendererFrontend() = default;
+
+ // Must synchronously clean up the Renderer if set
+ virtual void reset() = 0;
+
+ // Implementer must bind the renderer observer to the renderer in a
+ // appropriate manner so that the callbacks occur on the main thread
+ virtual void setObserver(RendererObserver&) = 0;
+
+ // Coalescing updates is up to the implementer
+ virtual void update(std::shared_ptr<UpdateParameters>) = 0;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/storage/default_file_source.hpp b/include/mbgl/storage/default_file_source.hpp
index f612a01aac..91e442cf85 100644
--- a/include/mbgl/storage/default_file_source.hpp
+++ b/include/mbgl/storage/default_file_source.hpp
@@ -1,10 +1,13 @@
#pragma once
+#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/storage/offline.hpp>
#include <mbgl/util/constants.hpp>
+#include <mbgl/util/optional.hpp>
#include <vector>
+#include <mutex>
namespace mbgl {
@@ -12,6 +15,8 @@ namespace util {
template <typename T> class Thread;
} // namespace util
+class ResourceTransform;
+
class DefaultFileSource : public FileSource {
public:
/*
@@ -34,12 +39,12 @@ public:
}
void setAPIBaseURL(const std::string&);
- std::string getAPIBaseURL() const;
+ std::string getAPIBaseURL();
void setAccessToken(const std::string&);
- std::string getAccessToken() const;
+ std::string getAccessToken();
- void setResourceTransform(std::function<std::string(Resource::Kind, std::string&&)>);
+ void setResourceTransform(optional<ActorRef<ResourceTransform>>&&);
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
@@ -135,15 +140,20 @@ public:
void resume();
// For testing only.
+ void setOnlineStatus(bool);
void put(const Resource&, const Response&);
class Impl;
private:
- const std::unique_ptr<util::Thread<Impl>> thread;
- const std::unique_ptr<FileSource> assetFileSource;
- const std::unique_ptr<FileSource> localFileSource;
+ // Shared so destruction is done on this thread
+ const std::shared_ptr<FileSource> assetFileSource;
+ const std::unique_ptr<util::Thread<Impl>> impl;
+
+ std::mutex cachedBaseURLMutex;
std::string cachedBaseURL = mbgl::util::API_BASE_URL;
+
+ std::mutex cachedAccessTokenMutex;
std::string cachedAccessToken;
};
diff --git a/include/mbgl/storage/offline.hpp b/include/mbgl/storage/offline.hpp
index 818cfe2ba5..117dd0591b 100644
--- a/include/mbgl/storage/offline.hpp
+++ b/include/mbgl/storage/offline.hpp
@@ -31,12 +31,14 @@ public:
/* Private */
std::vector<CanonicalTileID> tileCover(SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const;
-
+ uint64_t tileCount(SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const;
const std::string styleURL;
const LatLngBounds bounds;
const double minZoom;
const double maxZoom;
const float pixelRatio;
+private:
+ Range<uint8_t> coveringZoomRange(SourceType, uint16_t tileSize, const Range<uint8_t>& zoomRange) const;
};
/*
diff --git a/include/mbgl/storage/online_file_source.hpp b/include/mbgl/storage/online_file_source.hpp
index 51cfc5a2a1..28d70ce544 100644
--- a/include/mbgl/storage/online_file_source.hpp
+++ b/include/mbgl/storage/online_file_source.hpp
@@ -1,10 +1,14 @@
#pragma once
+#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/constants.hpp>
+#include <mbgl/util/optional.hpp>
namespace mbgl {
+class ResourceTransform;
+
class OnlineFileSource : public FileSource {
public:
OnlineFileSource();
@@ -16,12 +20,13 @@ public:
void setAccessToken(const std::string& t) { accessToken = t; }
std::string getAccessToken() const { return accessToken; }
- using ResourceTransform =
- std::function<std::unique_ptr<AsyncRequest>(Resource::Kind, std::string&&, std::function<void(std::string&&)>)>;
- void setResourceTransform(ResourceTransform&& cb);
+ void setResourceTransform(optional<ActorRef<ResourceTransform>>&&);
std::unique_ptr<AsyncRequest> request(const Resource&, Callback) override;
+ // For testing only.
+ void setOnlineStatus(bool);
+
private:
friend class OnlineFileRequest;
diff --git a/include/mbgl/storage/resource.hpp b/include/mbgl/storage/resource.hpp
index c05f40b65c..5d44f4869f 100644
--- a/include/mbgl/storage/resource.hpp
+++ b/include/mbgl/storage/resource.hpp
@@ -18,7 +18,8 @@ public:
Tile,
Glyphs,
SpriteImage,
- SpriteJSON
+ SpriteJSON,
+ Image
};
struct TileData {
@@ -55,7 +56,8 @@ public:
const std::pair<uint16_t, uint16_t>& glyphRange);
static Resource spriteImage(const std::string& base, float pixelRatio);
static Resource spriteJSON(const std::string& base, float pixelRatio);
-
+ static Resource image(const std::string& url);
+
Kind kind;
Necessity necessity;
std::string url;
@@ -66,6 +68,7 @@ public:
optional<Timestamp> priorModified = {};
optional<Timestamp> priorExpires = {};
optional<std::string> priorEtag = {};
+ std::shared_ptr<const std::string> priorData;
};
} // namespace mbgl
diff --git a/include/mbgl/storage/resource_transform.hpp b/include/mbgl/storage/resource_transform.hpp
new file mode 100644
index 0000000000..738c497176
--- /dev/null
+++ b/include/mbgl/storage/resource_transform.hpp
@@ -0,0 +1,26 @@
+#pragma once
+
+#include <mbgl/actor/actor_ref.hpp>
+#include <mbgl/storage/resource.hpp>
+
+#include <functional>
+#include <string>
+
+namespace mbgl {
+
+class Mailbox;
+
+class ResourceTransform {
+public:
+ using TransformCallback = std::function<std::string(Resource::Kind kind, const std::string&& url)>;
+ using FinishedCallback = std::function<void(const std::string&&)>;
+
+ ResourceTransform(ActorRef<ResourceTransform>, TransformCallback&&);
+
+ void transform(Resource::Kind, const std::string&& url, FinishedCallback&&);
+
+private:
+ TransformCallback transformCallback;
+};
+
+} // namespace mbgl
diff --git a/include/mbgl/storage/response.hpp b/include/mbgl/storage/response.hpp
index 32fe4e0c8a..711f008e83 100644
--- a/include/mbgl/storage/response.hpp
+++ b/include/mbgl/storage/response.hpp
@@ -27,6 +27,10 @@ public:
// This is set to true for 304 Not Modified responses.
bool notModified = false;
+ // This is set to true when the server requested that no expired resources be used by
+ // specifying "Cache-Control: must-revalidate".
+ bool mustRevalidate = false;
+
// The actual data of the response. Present only for non-error, non-notModified responses.
std::shared_ptr<const std::string> data;
@@ -37,6 +41,12 @@ public:
bool isFresh() const {
return expires ? *expires > util::now() : !error;
}
+
+ // Indicates whether we are allowed to use this response according to HTTP caching rules.
+ // It may or may not be stale.
+ bool isUsable() const {
+ return !mustRevalidate || (expires && *expires > util::now());
+ }
};
class Response::Error {
diff --git a/include/mbgl/style/conversion.hpp b/include/mbgl/style/conversion.hpp
index d6fb3a6dd0..27504a89b1 100644
--- a/include/mbgl/style/conversion.hpp
+++ b/include/mbgl/style/conversion.hpp
@@ -46,6 +46,7 @@ namespace conversion {
* `toBool(v)` -- returns `optional<bool>`, absence indicating `v` is not a JSON boolean
* `toNumber(v)` -- returns `optional<float>`, absence indicating `v` is not a JSON number
+ * `toDouble(v)` -- returns `optional<double>`, absence indicating `v` is not a JSON number
* `toString(v)` -- returns `optional<std::string>`, absence indicating `v` is not a JSON string
* `toValue(v)` -- returns `optional<mbgl::Value>`, a variant type, for generic conversion,
absence indicating `v` is not a boolean, number, or string. Numbers should be converted to
diff --git a/include/mbgl/style/conversion/coordinate.hpp b/include/mbgl/style/conversion/coordinate.hpp
new file mode 100644
index 0000000000..732624e77f
--- /dev/null
+++ b/include/mbgl/style/conversion/coordinate.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/util/geo.hpp>
+
+namespace mbgl {
+namespace style {
+namespace conversion {
+
+template<>
+struct Converter<LatLng> {
+public:
+ template <class V>
+ optional<LatLng> operator() (const V& value, Error& error) const {
+ if (!isArray(value) || arrayLength(value) < 2 ) {
+ error = { "coordinate array must contain numeric longitude and latitude values" };
+ return {};
+ }
+ //Style spec uses GeoJSON convention for specifying coordinates
+ optional<double> latitude = toDouble(arrayMember(value, 1));
+ optional<double> longitude = toDouble(arrayMember(value, 0));
+
+ if (!latitude || !longitude) {
+ error = { "coordinate array must contain numeric longitude and latitude values" };
+ return {};
+ }
+ if (*latitude < -90 || *latitude > 90 ){
+ error = { "coordinate latitude must be between -90 and 90" };
+ return {};
+ }
+ return LatLng(*latitude, *longitude);
+ }
+};
+
+} // namespace conversion
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/conversion/filter.hpp b/include/mbgl/style/conversion/filter.hpp
index 1f8f0fd161..986d1bf80d 100644
--- a/include/mbgl/style/conversion/filter.hpp
+++ b/include/mbgl/style/conversion/filter.hpp
@@ -57,7 +57,7 @@ public:
return convertUnaryFilter<NotHasFilter, NotHasIdentifierFilter>(value, error);
}
- error = { "filter operator must be one of \"==\", \"!=\", \">\", \">=\", \"<\", \"<=\", \"in\", \"!in\", \"all\", \"any\", \"none\", \"has\", or \"!has\"" };
+ error = { R"(filter operator must be one of "==", "!=", ">", ">=", "<", "<=", "in", "!in", "all", "any", "none", "has", or "!has")" };
return {};
}
diff --git a/include/mbgl/style/conversion/function.hpp b/include/mbgl/style/conversion/function.hpp
index fa8af1e2be..752b6dd045 100644
--- a/include/mbgl/style/conversion/function.hpp
+++ b/include/mbgl/style/conversion/function.hpp
@@ -156,7 +156,7 @@ struct StopsConverter<T, variant<Ts...>> {
public:
template <class V>
optional<variant<Ts...>> operator()(const V& value, Error& error) const {
- std::string type = util::Interpolatable<T> ? "exponential" : "interval";
+ std::string type = util::Interpolatable<T>::value ? "exponential" : "interval";
auto typeValue = objectMember(value, "type");
if (typeValue && toString(*typeValue)) {
@@ -218,7 +218,7 @@ optional<optional<T>> convertDefaultValue(const V& value, Error& error) {
auto defaultValue = convert<T>(*defaultValueValue, error);
if (!defaultValue) {
- error = { "wrong type for \"default\": " + error.message };
+ error = { R"(wrong type for "default": )" + error.message };
return {};
}
diff --git a/include/mbgl/style/conversion/layer.hpp b/include/mbgl/style/conversion/layer.hpp
index 3a64c36bf5..1fe467165d 100644
--- a/include/mbgl/style/conversion/layer.hpp
+++ b/include/mbgl/style/conversion/layer.hpp
@@ -28,30 +28,23 @@ optional<Error> setLayoutProperty(Layer& layer, const std::string& name, const V
}
template <class V>
-optional<Error> setPaintProperty(Layer& layer, const std::string& name, const V& value, const optional<std::string>& klass) {
+optional<Error> setPaintProperty(Layer& layer, const std::string& name, const V& value) {
static const auto setters = makePaintPropertySetters<V>();
auto it = setters.find(name);
if (it == setters.end()) {
return Error { "property not found" };
}
- return it->second(layer, value, klass);
+ return it->second(layer, value);
}
template <class V>
optional<Error> setPaintProperties(Layer& layer, const V& value) {
- return eachMember(value, [&] (const std::string& paintName, const V& paintValue) -> optional<Error> {
- if (paintName.compare(0, 5, "paint") != 0) {
- return {};
- }
-
- optional<std::string> klass;
- if (paintName.compare(0, 6, "paint.") == 0) {
- klass = paintName.substr(6);
- }
-
- return eachMember(paintValue, [&] (const std::string& k, const V& v) {
- return setPaintProperty(layer, k, v, klass);
- });
+ auto paintValue = objectMember(value, "paint");
+ if (!paintValue) {
+ return {};
+ }
+ return eachMember(*paintValue, [&] (const std::string& k, const V& v) {
+ return setPaintProperty(layer, k, v);
});
}
diff --git a/include/mbgl/style/conversion/make_property_setters.hpp b/include/mbgl/style/conversion/make_property_setters.hpp
index 105cca99d6..59b0e7be32 100644
--- a/include/mbgl/style/conversion/make_property_setters.hpp
+++ b/include/mbgl/style/conversion/make_property_setters.hpp
@@ -20,50 +20,52 @@ namespace conversion {
template <class V>
auto makeLayoutPropertySetters() {
- std::unordered_map<std::string, LayoutPropertySetter<V>> result;
+ std::unordered_map<std::string, PropertySetter<V>> result;
result["visibility"] = &setVisibility<V>;
- result["line-cap"] = &setLayoutProperty<V, LineLayer, PropertyValue<LineCapType>, &LineLayer::setLineCap>;
- result["line-join"] = &setLayoutProperty<V, LineLayer, PropertyValue<LineJoinType>, &LineLayer::setLineJoin>;
- result["line-miter-limit"] = &setLayoutProperty<V, LineLayer, PropertyValue<float>, &LineLayer::setLineMiterLimit>;
- result["line-round-limit"] = &setLayoutProperty<V, LineLayer, PropertyValue<float>, &LineLayer::setLineRoundLimit>;
-
- result["symbol-placement"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<SymbolPlacementType>, &SymbolLayer::setSymbolPlacement>;
- result["symbol-spacing"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setSymbolSpacing>;
- result["symbol-avoid-edges"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setSymbolAvoidEdges>;
- result["icon-allow-overlap"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconAllowOverlap>;
- result["icon-ignore-placement"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconIgnorePlacement>;
- result["icon-optional"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconOptional>;
- result["icon-rotation-alignment"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconRotationAlignment>;
- result["icon-size"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconSize>;
- result["icon-text-fit"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<IconTextFitType>, &SymbolLayer::setIconTextFit>;
- result["icon-text-fit-padding"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<std::array<float, 4>>, &SymbolLayer::setIconTextFitPadding>;
- result["icon-image"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setIconImage>;
- result["icon-rotate"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconRotate>;
- result["icon-padding"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconPadding>;
- result["icon-keep-upright"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconKeepUpright>;
- result["icon-offset"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::array<float, 2>>, &SymbolLayer::setIconOffset>;
- result["text-pitch-alignment"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextPitchAlignment>;
- result["text-rotation-alignment"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextRotationAlignment>;
- result["text-field"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setTextField>;
- result["text-font"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<std::vector<std::string>>, &SymbolLayer::setTextFont>;
- result["text-size"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextSize>;
- result["text-max-width"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxWidth>;
- result["text-line-height"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLineHeight>;
- result["text-letter-spacing"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLetterSpacing>;
- result["text-justify"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<TextJustifyType>, &SymbolLayer::setTextJustify>;
- result["text-anchor"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<TextAnchorType>, &SymbolLayer::setTextAnchor>;
- result["text-max-angle"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxAngle>;
- result["text-rotate"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextRotate>;
- result["text-padding"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextPadding>;
- result["text-keep-upright"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextKeepUpright>;
- result["text-transform"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<TextTransformType>, &SymbolLayer::setTextTransform>;
- result["text-offset"] = &setLayoutProperty<V, SymbolLayer, DataDrivenPropertyValue<std::array<float, 2>>, &SymbolLayer::setTextOffset>;
- result["text-allow-overlap"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextAllowOverlap>;
- result["text-ignore-placement"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextIgnorePlacement>;
- result["text-optional"] = &setLayoutProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextOptional>;
+ result["line-cap"] = &setProperty<V, LineLayer, PropertyValue<LineCapType>, &LineLayer::setLineCap>;
+ result["line-join"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<LineJoinType>, &LineLayer::setLineJoin>;
+ result["line-miter-limit"] = &setProperty<V, LineLayer, PropertyValue<float>, &LineLayer::setLineMiterLimit>;
+ result["line-round-limit"] = &setProperty<V, LineLayer, PropertyValue<float>, &LineLayer::setLineRoundLimit>;
+
+ result["symbol-placement"] = &setProperty<V, SymbolLayer, PropertyValue<SymbolPlacementType>, &SymbolLayer::setSymbolPlacement>;
+ result["symbol-spacing"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setSymbolSpacing>;
+ result["symbol-avoid-edges"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setSymbolAvoidEdges>;
+ result["icon-allow-overlap"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconAllowOverlap>;
+ result["icon-ignore-placement"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconIgnorePlacement>;
+ result["icon-optional"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconOptional>;
+ result["icon-rotation-alignment"] = &setProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconRotationAlignment>;
+ result["icon-size"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconSize>;
+ result["icon-text-fit"] = &setProperty<V, SymbolLayer, PropertyValue<IconTextFitType>, &SymbolLayer::setIconTextFit>;
+ result["icon-text-fit-padding"] = &setProperty<V, SymbolLayer, PropertyValue<std::array<float, 4>>, &SymbolLayer::setIconTextFitPadding>;
+ result["icon-image"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setIconImage>;
+ result["icon-rotate"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconRotate>;
+ result["icon-padding"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setIconPadding>;
+ result["icon-keep-upright"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setIconKeepUpright>;
+ result["icon-offset"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<std::array<float, 2>>, &SymbolLayer::setIconOffset>;
+ result["icon-anchor"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<SymbolAnchorType>, &SymbolLayer::setIconAnchor>;
+ result["icon-pitch-alignment"] = &setProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setIconPitchAlignment>;
+ result["text-pitch-alignment"] = &setProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextPitchAlignment>;
+ result["text-rotation-alignment"] = &setProperty<V, SymbolLayer, PropertyValue<AlignmentType>, &SymbolLayer::setTextRotationAlignment>;
+ result["text-field"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<std::string>, &SymbolLayer::setTextField>;
+ result["text-font"] = &setProperty<V, SymbolLayer, PropertyValue<std::vector<std::string>>, &SymbolLayer::setTextFont>;
+ result["text-size"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextSize>;
+ result["text-max-width"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextMaxWidth>;
+ result["text-line-height"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextLineHeight>;
+ result["text-letter-spacing"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextLetterSpacing>;
+ result["text-justify"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<TextJustifyType>, &SymbolLayer::setTextJustify>;
+ result["text-anchor"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<SymbolAnchorType>, &SymbolLayer::setTextAnchor>;
+ result["text-max-angle"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextMaxAngle>;
+ result["text-rotate"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextRotate>;
+ result["text-padding"] = &setProperty<V, SymbolLayer, PropertyValue<float>, &SymbolLayer::setTextPadding>;
+ result["text-keep-upright"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextKeepUpright>;
+ result["text-transform"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<TextTransformType>, &SymbolLayer::setTextTransform>;
+ result["text-offset"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<std::array<float, 2>>, &SymbolLayer::setTextOffset>;
+ result["text-allow-overlap"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextAllowOverlap>;
+ result["text-ignore-placement"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextIgnorePlacement>;
+ result["text-optional"] = &setProperty<V, SymbolLayer, PropertyValue<bool>, &SymbolLayer::setTextOptional>;
@@ -74,129 +76,131 @@ auto makeLayoutPropertySetters() {
template <class V>
auto makePaintPropertySetters() {
- std::unordered_map<std::string, PaintPropertySetter<V>> result;
+ std::unordered_map<std::string, PropertySetter<V>> result;
- result["fill-antialias"] = &setPaintProperty<V, FillLayer, PropertyValue<bool>, &FillLayer::setFillAntialias>;
+ result["fill-antialias"] = &setProperty<V, FillLayer, PropertyValue<bool>, &FillLayer::setFillAntialias>;
result["fill-antialias-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillAntialiasTransition>;
- result["fill-opacity"] = &setPaintProperty<V, FillLayer, DataDrivenPropertyValue<float>, &FillLayer::setFillOpacity>;
+ result["fill-opacity"] = &setProperty<V, FillLayer, DataDrivenPropertyValue<float>, &FillLayer::setFillOpacity>;
result["fill-opacity-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillOpacityTransition>;
- result["fill-color"] = &setPaintProperty<V, FillLayer, DataDrivenPropertyValue<Color>, &FillLayer::setFillColor>;
+ result["fill-color"] = &setProperty<V, FillLayer, DataDrivenPropertyValue<Color>, &FillLayer::setFillColor>;
result["fill-color-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillColorTransition>;
- result["fill-outline-color"] = &setPaintProperty<V, FillLayer, DataDrivenPropertyValue<Color>, &FillLayer::setFillOutlineColor>;
+ result["fill-outline-color"] = &setProperty<V, FillLayer, DataDrivenPropertyValue<Color>, &FillLayer::setFillOutlineColor>;
result["fill-outline-color-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillOutlineColorTransition>;
- result["fill-translate"] = &setPaintProperty<V, FillLayer, PropertyValue<std::array<float, 2>>, &FillLayer::setFillTranslate>;
+ result["fill-translate"] = &setProperty<V, FillLayer, PropertyValue<std::array<float, 2>>, &FillLayer::setFillTranslate>;
result["fill-translate-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillTranslateTransition>;
- result["fill-translate-anchor"] = &setPaintProperty<V, FillLayer, PropertyValue<TranslateAnchorType>, &FillLayer::setFillTranslateAnchor>;
+ result["fill-translate-anchor"] = &setProperty<V, FillLayer, PropertyValue<TranslateAnchorType>, &FillLayer::setFillTranslateAnchor>;
result["fill-translate-anchor-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillTranslateAnchorTransition>;
- result["fill-pattern"] = &setPaintProperty<V, FillLayer, PropertyValue<std::string>, &FillLayer::setFillPattern>;
+ result["fill-pattern"] = &setProperty<V, FillLayer, PropertyValue<std::string>, &FillLayer::setFillPattern>;
result["fill-pattern-transition"] = &setTransition<V, FillLayer, &FillLayer::setFillPatternTransition>;
- result["line-opacity"] = &setPaintProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineOpacity>;
+ result["line-opacity"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineOpacity>;
result["line-opacity-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineOpacityTransition>;
- result["line-color"] = &setPaintProperty<V, LineLayer, DataDrivenPropertyValue<Color>, &LineLayer::setLineColor>;
+ result["line-color"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<Color>, &LineLayer::setLineColor>;
result["line-color-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineColorTransition>;
- result["line-translate"] = &setPaintProperty<V, LineLayer, PropertyValue<std::array<float, 2>>, &LineLayer::setLineTranslate>;
+ result["line-translate"] = &setProperty<V, LineLayer, PropertyValue<std::array<float, 2>>, &LineLayer::setLineTranslate>;
result["line-translate-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineTranslateTransition>;
- result["line-translate-anchor"] = &setPaintProperty<V, LineLayer, PropertyValue<TranslateAnchorType>, &LineLayer::setLineTranslateAnchor>;
+ result["line-translate-anchor"] = &setProperty<V, LineLayer, PropertyValue<TranslateAnchorType>, &LineLayer::setLineTranslateAnchor>;
result["line-translate-anchor-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineTranslateAnchorTransition>;
- result["line-width"] = &setPaintProperty<V, LineLayer, PropertyValue<float>, &LineLayer::setLineWidth>;
+ result["line-width"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineWidth>;
result["line-width-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineWidthTransition>;
- result["line-gap-width"] = &setPaintProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineGapWidth>;
+ result["line-gap-width"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineGapWidth>;
result["line-gap-width-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineGapWidthTransition>;
- result["line-offset"] = &setPaintProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineOffset>;
+ result["line-offset"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineOffset>;
result["line-offset-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineOffsetTransition>;
- result["line-blur"] = &setPaintProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineBlur>;
+ result["line-blur"] = &setProperty<V, LineLayer, DataDrivenPropertyValue<float>, &LineLayer::setLineBlur>;
result["line-blur-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineBlurTransition>;
- result["line-dasharray"] = &setPaintProperty<V, LineLayer, PropertyValue<std::vector<float>>, &LineLayer::setLineDasharray>;
+ result["line-dasharray"] = &setProperty<V, LineLayer, PropertyValue<std::vector<float>>, &LineLayer::setLineDasharray>;
result["line-dasharray-transition"] = &setTransition<V, LineLayer, &LineLayer::setLineDasharrayTransition>;
- result["line-pattern"] = &setPaintProperty<V, LineLayer, PropertyValue<std::string>, &LineLayer::setLinePattern>;
+ result["line-pattern"] = &setProperty<V, LineLayer, PropertyValue<std::string>, &LineLayer::setLinePattern>;
result["line-pattern-transition"] = &setTransition<V, LineLayer, &LineLayer::setLinePatternTransition>;
- result["icon-opacity"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconOpacity>;
+ result["icon-opacity"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconOpacity>;
result["icon-opacity-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconOpacityTransition>;
- result["icon-color"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setIconColor>;
+ result["icon-color"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setIconColor>;
result["icon-color-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconColorTransition>;
- result["icon-halo-color"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setIconHaloColor>;
+ result["icon-halo-color"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setIconHaloColor>;
result["icon-halo-color-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconHaloColorTransition>;
- result["icon-halo-width"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconHaloWidth>;
+ result["icon-halo-width"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconHaloWidth>;
result["icon-halo-width-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconHaloWidthTransition>;
- result["icon-halo-blur"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconHaloBlur>;
+ result["icon-halo-blur"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setIconHaloBlur>;
result["icon-halo-blur-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconHaloBlurTransition>;
- result["icon-translate"] = &setPaintProperty<V, SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setIconTranslate>;
+ result["icon-translate"] = &setProperty<V, SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setIconTranslate>;
result["icon-translate-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconTranslateTransition>;
- result["icon-translate-anchor"] = &setPaintProperty<V, SymbolLayer, PropertyValue<TranslateAnchorType>, &SymbolLayer::setIconTranslateAnchor>;
+ result["icon-translate-anchor"] = &setProperty<V, SymbolLayer, PropertyValue<TranslateAnchorType>, &SymbolLayer::setIconTranslateAnchor>;
result["icon-translate-anchor-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setIconTranslateAnchorTransition>;
- result["text-opacity"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextOpacity>;
+ result["text-opacity"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextOpacity>;
result["text-opacity-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextOpacityTransition>;
- result["text-color"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setTextColor>;
+ result["text-color"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setTextColor>;
result["text-color-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextColorTransition>;
- result["text-halo-color"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setTextHaloColor>;
+ result["text-halo-color"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<Color>, &SymbolLayer::setTextHaloColor>;
result["text-halo-color-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextHaloColorTransition>;
- result["text-halo-width"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextHaloWidth>;
+ result["text-halo-width"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextHaloWidth>;
result["text-halo-width-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextHaloWidthTransition>;
- result["text-halo-blur"] = &setPaintProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextHaloBlur>;
+ result["text-halo-blur"] = &setProperty<V, SymbolLayer, DataDrivenPropertyValue<float>, &SymbolLayer::setTextHaloBlur>;
result["text-halo-blur-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextHaloBlurTransition>;
- result["text-translate"] = &setPaintProperty<V, SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setTextTranslate>;
+ result["text-translate"] = &setProperty<V, SymbolLayer, PropertyValue<std::array<float, 2>>, &SymbolLayer::setTextTranslate>;
result["text-translate-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextTranslateTransition>;
- result["text-translate-anchor"] = &setPaintProperty<V, SymbolLayer, PropertyValue<TranslateAnchorType>, &SymbolLayer::setTextTranslateAnchor>;
+ result["text-translate-anchor"] = &setProperty<V, SymbolLayer, PropertyValue<TranslateAnchorType>, &SymbolLayer::setTextTranslateAnchor>;
result["text-translate-anchor-transition"] = &setTransition<V, SymbolLayer, &SymbolLayer::setTextTranslateAnchorTransition>;
- result["circle-radius"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleRadius>;
+ result["circle-radius"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleRadius>;
result["circle-radius-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleRadiusTransition>;
- result["circle-color"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<Color>, &CircleLayer::setCircleColor>;
+ result["circle-color"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<Color>, &CircleLayer::setCircleColor>;
result["circle-color-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleColorTransition>;
- result["circle-blur"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleBlur>;
+ result["circle-blur"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleBlur>;
result["circle-blur-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleBlurTransition>;
- result["circle-opacity"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleOpacity>;
+ result["circle-opacity"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleOpacity>;
result["circle-opacity-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleOpacityTransition>;
- result["circle-translate"] = &setPaintProperty<V, CircleLayer, PropertyValue<std::array<float, 2>>, &CircleLayer::setCircleTranslate>;
+ result["circle-translate"] = &setProperty<V, CircleLayer, PropertyValue<std::array<float, 2>>, &CircleLayer::setCircleTranslate>;
result["circle-translate-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleTranslateTransition>;
- result["circle-translate-anchor"] = &setPaintProperty<V, CircleLayer, PropertyValue<TranslateAnchorType>, &CircleLayer::setCircleTranslateAnchor>;
+ result["circle-translate-anchor"] = &setProperty<V, CircleLayer, PropertyValue<TranslateAnchorType>, &CircleLayer::setCircleTranslateAnchor>;
result["circle-translate-anchor-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleTranslateAnchorTransition>;
- result["circle-pitch-scale"] = &setPaintProperty<V, CircleLayer, PropertyValue<CirclePitchScaleType>, &CircleLayer::setCirclePitchScale>;
+ result["circle-pitch-scale"] = &setProperty<V, CircleLayer, PropertyValue<CirclePitchScaleType>, &CircleLayer::setCirclePitchScale>;
result["circle-pitch-scale-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCirclePitchScaleTransition>;
- result["circle-stroke-width"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleStrokeWidth>;
+ result["circle-pitch-alignment"] = &setProperty<V, CircleLayer, PropertyValue<AlignmentType>, &CircleLayer::setCirclePitchAlignment>;
+ result["circle-pitch-alignment-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCirclePitchAlignmentTransition>;
+ result["circle-stroke-width"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleStrokeWidth>;
result["circle-stroke-width-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleStrokeWidthTransition>;
- result["circle-stroke-color"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<Color>, &CircleLayer::setCircleStrokeColor>;
+ result["circle-stroke-color"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<Color>, &CircleLayer::setCircleStrokeColor>;
result["circle-stroke-color-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleStrokeColorTransition>;
- result["circle-stroke-opacity"] = &setPaintProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleStrokeOpacity>;
+ result["circle-stroke-opacity"] = &setProperty<V, CircleLayer, DataDrivenPropertyValue<float>, &CircleLayer::setCircleStrokeOpacity>;
result["circle-stroke-opacity-transition"] = &setTransition<V, CircleLayer, &CircleLayer::setCircleStrokeOpacityTransition>;
- result["fill-extrusion-opacity"] = &setPaintProperty<V, FillExtrusionLayer, PropertyValue<float>, &FillExtrusionLayer::setFillExtrusionOpacity>;
+ result["fill-extrusion-opacity"] = &setProperty<V, FillExtrusionLayer, PropertyValue<float>, &FillExtrusionLayer::setFillExtrusionOpacity>;
result["fill-extrusion-opacity-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionOpacityTransition>;
- result["fill-extrusion-color"] = &setPaintProperty<V, FillExtrusionLayer, DataDrivenPropertyValue<Color>, &FillExtrusionLayer::setFillExtrusionColor>;
+ result["fill-extrusion-color"] = &setProperty<V, FillExtrusionLayer, DataDrivenPropertyValue<Color>, &FillExtrusionLayer::setFillExtrusionColor>;
result["fill-extrusion-color-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionColorTransition>;
- result["fill-extrusion-translate"] = &setPaintProperty<V, FillExtrusionLayer, PropertyValue<std::array<float, 2>>, &FillExtrusionLayer::setFillExtrusionTranslate>;
+ result["fill-extrusion-translate"] = &setProperty<V, FillExtrusionLayer, PropertyValue<std::array<float, 2>>, &FillExtrusionLayer::setFillExtrusionTranslate>;
result["fill-extrusion-translate-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionTranslateTransition>;
- result["fill-extrusion-translate-anchor"] = &setPaintProperty<V, FillExtrusionLayer, PropertyValue<TranslateAnchorType>, &FillExtrusionLayer::setFillExtrusionTranslateAnchor>;
+ result["fill-extrusion-translate-anchor"] = &setProperty<V, FillExtrusionLayer, PropertyValue<TranslateAnchorType>, &FillExtrusionLayer::setFillExtrusionTranslateAnchor>;
result["fill-extrusion-translate-anchor-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionTranslateAnchorTransition>;
- result["fill-extrusion-pattern"] = &setPaintProperty<V, FillExtrusionLayer, PropertyValue<std::string>, &FillExtrusionLayer::setFillExtrusionPattern>;
+ result["fill-extrusion-pattern"] = &setProperty<V, FillExtrusionLayer, PropertyValue<std::string>, &FillExtrusionLayer::setFillExtrusionPattern>;
result["fill-extrusion-pattern-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionPatternTransition>;
- result["fill-extrusion-height"] = &setPaintProperty<V, FillExtrusionLayer, DataDrivenPropertyValue<float>, &FillExtrusionLayer::setFillExtrusionHeight>;
+ result["fill-extrusion-height"] = &setProperty<V, FillExtrusionLayer, DataDrivenPropertyValue<float>, &FillExtrusionLayer::setFillExtrusionHeight>;
result["fill-extrusion-height-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionHeightTransition>;
- result["fill-extrusion-base"] = &setPaintProperty<V, FillExtrusionLayer, DataDrivenPropertyValue<float>, &FillExtrusionLayer::setFillExtrusionBase>;
+ result["fill-extrusion-base"] = &setProperty<V, FillExtrusionLayer, DataDrivenPropertyValue<float>, &FillExtrusionLayer::setFillExtrusionBase>;
result["fill-extrusion-base-transition"] = &setTransition<V, FillExtrusionLayer, &FillExtrusionLayer::setFillExtrusionBaseTransition>;
- result["raster-opacity"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterOpacity>;
+ result["raster-opacity"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterOpacity>;
result["raster-opacity-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterOpacityTransition>;
- result["raster-hue-rotate"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterHueRotate>;
+ result["raster-hue-rotate"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterHueRotate>;
result["raster-hue-rotate-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterHueRotateTransition>;
- result["raster-brightness-min"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterBrightnessMin>;
+ result["raster-brightness-min"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterBrightnessMin>;
result["raster-brightness-min-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterBrightnessMinTransition>;
- result["raster-brightness-max"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterBrightnessMax>;
+ result["raster-brightness-max"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterBrightnessMax>;
result["raster-brightness-max-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterBrightnessMaxTransition>;
- result["raster-saturation"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterSaturation>;
+ result["raster-saturation"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterSaturation>;
result["raster-saturation-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterSaturationTransition>;
- result["raster-contrast"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterContrast>;
+ result["raster-contrast"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterContrast>;
result["raster-contrast-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterContrastTransition>;
- result["raster-fade-duration"] = &setPaintProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterFadeDuration>;
+ result["raster-fade-duration"] = &setProperty<V, RasterLayer, PropertyValue<float>, &RasterLayer::setRasterFadeDuration>;
result["raster-fade-duration-transition"] = &setTransition<V, RasterLayer, &RasterLayer::setRasterFadeDurationTransition>;
- result["background-color"] = &setPaintProperty<V, BackgroundLayer, PropertyValue<Color>, &BackgroundLayer::setBackgroundColor>;
+ result["background-color"] = &setProperty<V, BackgroundLayer, PropertyValue<Color>, &BackgroundLayer::setBackgroundColor>;
result["background-color-transition"] = &setTransition<V, BackgroundLayer, &BackgroundLayer::setBackgroundColorTransition>;
- result["background-pattern"] = &setPaintProperty<V, BackgroundLayer, PropertyValue<std::string>, &BackgroundLayer::setBackgroundPattern>;
+ result["background-pattern"] = &setProperty<V, BackgroundLayer, PropertyValue<std::string>, &BackgroundLayer::setBackgroundPattern>;
result["background-pattern-transition"] = &setTransition<V, BackgroundLayer, &BackgroundLayer::setBackgroundPatternTransition>;
- result["background-opacity"] = &setPaintProperty<V, BackgroundLayer, PropertyValue<float>, &BackgroundLayer::setBackgroundOpacity>;
+ result["background-opacity"] = &setProperty<V, BackgroundLayer, PropertyValue<float>, &BackgroundLayer::setBackgroundOpacity>;
result["background-opacity-transition"] = &setTransition<V, BackgroundLayer, &BackgroundLayer::setBackgroundOpacityTransition>;
return result;
diff --git a/include/mbgl/style/conversion/make_property_setters.hpp.ejs b/include/mbgl/style/conversion/make_property_setters.hpp.ejs
index a99e75aec7..19c9f70538 100644
--- a/include/mbgl/style/conversion/make_property_setters.hpp.ejs
+++ b/include/mbgl/style/conversion/make_property_setters.hpp.ejs
@@ -16,13 +16,13 @@ namespace conversion {
template <class V>
auto makeLayoutPropertySetters() {
- std::unordered_map<std::string, LayoutPropertySetter<V>> result;
+ std::unordered_map<std::string, PropertySetter<V>> result;
result["visibility"] = &setVisibility<V>;
<% for (const layer of locals.layers) { -%>
<% for (const property of layer.layoutProperties) { -%>
- result["<%- property.name %>"] = &setLayoutProperty<V, <%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>;
+ result["<%- property.name %>"] = &setProperty<V, <%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>;
<% } -%>
<% } -%>
@@ -31,11 +31,11 @@ auto makeLayoutPropertySetters() {
template <class V>
auto makePaintPropertySetters() {
- std::unordered_map<std::string, PaintPropertySetter<V>> result;
+ std::unordered_map<std::string, PropertySetter<V>> result;
<% for (const layer of locals.layers) { -%>
<% for (const property of layer.paintProperties) { -%>
- result["<%- property.name %>"] = &setPaintProperty<V, <%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>;
+ result["<%- property.name %>"] = &setProperty<V, <%- camelize(layer.type) %>Layer, <%- propertyValueType(property) %>, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>>;
result["<%- property.name %>-transition"] = &setTransition<V, <%- camelize(layer.type) %>Layer, &<%- camelize(layer.type) %>Layer::set<%- camelize(property.name) %>Transition>;
<% } -%>
diff --git a/include/mbgl/style/conversion/property_setter.hpp b/include/mbgl/style/conversion/property_setter.hpp
index 1f537f3c4d..759c4512cc 100644
--- a/include/mbgl/style/conversion/property_setter.hpp
+++ b/include/mbgl/style/conversion/property_setter.hpp
@@ -14,14 +14,11 @@ namespace style {
namespace conversion {
template <class V>
-using LayoutPropertySetter = optional<Error> (*) (Layer&, const V&);
-
-template <class V>
-using PaintPropertySetter = optional<Error> (*) (Layer&, const V&, const optional<std::string>&);
+using PropertySetter = optional<Error> (*) (Layer&, const V&);
template <class V, class L, class PropertyValue, void (L::*setter)(PropertyValue)>
-optional<Error> setLayoutProperty(Layer& layer, const V& value) {
- L* typedLayer = layer.as<L>();
+optional<Error> setProperty(Layer& layer, const V& value) {
+ auto* typedLayer = layer.as<L>();
if (!typedLayer) {
return Error { "layer doesn't support this property" };
}
@@ -36,26 +33,9 @@ optional<Error> setLayoutProperty(Layer& layer, const V& value) {
return {};
}
-template <class V, class L, class PropertyValue, void (L::*setter)(PropertyValue, const optional<std::string>&)>
-optional<Error> setPaintProperty(Layer& layer, const V& value, const optional<std::string>& klass) {
- L* typedLayer = layer.as<L>();
- if (!typedLayer) {
- return Error { "layer doesn't support this property" };
- }
-
- Error error;
- optional<PropertyValue> typedValue = convert<PropertyValue>(value, error);
- if (!typedValue) {
- return error;
- }
-
- (typedLayer->*setter)(*typedValue, klass);
- return {};
-}
-
-template <class V, class L, void (L::*setter)(const TransitionOptions&, const optional<std::string>&)>
-optional<Error> setTransition(Layer& layer, const V& value, const optional<std::string>& klass) {
- L* typedLayer = layer.as<L>();
+template <class V, class L, void (L::*setter)(const TransitionOptions&)>
+optional<Error> setTransition(Layer& layer, const V& value) {
+ auto* typedLayer = layer.as<L>();
if (!typedLayer) {
return Error { "layer doesn't support this property" };
}
@@ -66,7 +46,7 @@ optional<Error> setTransition(Layer& layer, const V& value, const optional<std::
return error;
}
- (typedLayer->*setter)(*transition, klass);
+ (typedLayer->*setter)(*transition);
return {};
}
diff --git a/include/mbgl/style/conversion/source.hpp b/include/mbgl/style/conversion/source.hpp
index dc7cdc0d42..e0563ac10b 100644
--- a/include/mbgl/style/conversion/source.hpp
+++ b/include/mbgl/style/conversion/source.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/coordinate.hpp>
#include <mbgl/style/conversion/geojson.hpp>
#include <mbgl/style/conversion/geojson_options.hpp>
#include <mbgl/style/conversion/tileset.hpp>
@@ -8,6 +9,8 @@
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
+#include <mbgl/style/sources/image_source.hpp>
+#include <mbgl/util/geo.hpp>
namespace mbgl {
namespace style {
@@ -16,6 +19,7 @@ namespace conversion {
template <>
struct Converter<std::unique_ptr<Source>> {
public:
+
template <class V>
optional<std::unique_ptr<Source>> operator()(const V& value, Error& error, const std::string& id) const {
if (!isObject(value)) {
@@ -41,6 +45,8 @@ public:
return convertVectorSource(id, value, error);
} else if (*type == "geojson") {
return convertGeoJSONSource(id, value, error);
+ } else if (*type == "image") {
+ return convertImageSource(id, value, error);
} else {
error = { "invalid source type" };
return {};
@@ -136,6 +142,47 @@ private:
return { std::move(result) };
}
+
+ template <class V>
+ optional<std::unique_ptr<Source>> convertImageSource(const std::string& id,
+ const V& value,
+ Error& error) const {
+ auto urlValue = objectMember(value, "url");
+ if (!urlValue) {
+ error = { "Image source must have a url value" };
+ return {};
+ }
+
+ auto urlString = toString(*urlValue);
+ if (!urlString) {
+ error = { "Image url must be a URL string" };
+ return {};
+ }
+
+ auto coordinatesValue = objectMember(value, "coordinates");
+ if (!coordinatesValue) {
+ error = { "Image source must have a coordinates values" };
+ return {};
+ }
+
+ if (!isArray(*coordinatesValue) || arrayLength(*coordinatesValue) != 4) {
+ error = { "Image coordinates must be an array of four longitude latitude pairs" };
+ return {};
+ }
+
+ std::array<LatLng, 4> coordinates;
+ for (std::size_t i=0; i < 4; i++) {
+ auto latLng = conversion::convert<LatLng>(arrayMember(*coordinatesValue,i), error);
+ if (!latLng) {
+ return {};
+ }
+ coordinates[i] = *latLng;
+ }
+ auto result = std::make_unique<ImageSource>(id, coordinates);
+ result->setURL(*urlString);
+
+ return { std::move(result) };
+ }
};
} // namespace conversion
diff --git a/include/mbgl/style/data_driven_property_value.hpp b/include/mbgl/style/data_driven_property_value.hpp
index 5acf800840..5d7c596363 100644
--- a/include/mbgl/style/data_driven_property_value.hpp
+++ b/include/mbgl/style/data_driven_property_value.hpp
@@ -49,16 +49,20 @@ public:
bool isZoomConstant() const {
return !value.template is<CameraFunction<T>>() && !value.template is<CompositeFunction<T>>();
}
-
+
template <class... Ts>
auto match(Ts&&... ts) const {
return value.match(std::forward<Ts>(ts)...);
}
template <typename Evaluator>
- auto evaluate(const Evaluator& evaluator) const {
+ auto evaluate(const Evaluator& evaluator, TimePoint = {}) const {
return Value::visit(value, evaluator);
}
+
+ bool hasDataDrivenPropertyDifference(const DataDrivenPropertyValue<T>& other) const {
+ return *this != other && (isDataDriven() || other.isDataDriven());
+ }
};
} // namespace style
diff --git a/include/mbgl/style/function/camera_function.hpp b/include/mbgl/style/function/camera_function.hpp
index 2e4aac2238..7fde365b3d 100644
--- a/include/mbgl/style/function/camera_function.hpp
+++ b/include/mbgl/style/function/camera_function.hpp
@@ -12,7 +12,7 @@ template <class T>
class CameraFunction {
public:
using Stops = std::conditional_t<
- util::Interpolatable<T>,
+ util::Interpolatable<T>::value,
variant<
ExponentialStops<T>,
IntervalStops<T>>,
@@ -25,7 +25,7 @@ public:
T evaluate(float zoom) const {
return stops.match([&] (const auto& s) {
- return s.evaluate(Value(double(zoom))).value_or(T());
+ return s.evaluate(zoom).value_or(T());
});
}
@@ -35,6 +35,7 @@ public:
}
Stops stops;
+ bool useIntegerZoom = false;
};
} // namespace style
diff --git a/include/mbgl/style/function/composite_function.hpp b/include/mbgl/style/function/composite_function.hpp
index b82e63bc37..7b524b6021 100644
--- a/include/mbgl/style/function/composite_function.hpp
+++ b/include/mbgl/style/function/composite_function.hpp
@@ -24,7 +24,7 @@ template <class T>
class CompositeFunction {
public:
using InnerStops = std::conditional_t<
- util::Interpolatable<T>,
+ util::Interpolatable<T>::value,
variant<
ExponentialStops<T>,
IntervalStops<T>,
@@ -34,7 +34,7 @@ public:
CategoricalStops<T>>>;
using Stops = std::conditional_t<
- util::Interpolatable<T>,
+ util::Interpolatable<T>::value,
variant<
CompositeExponentialStops<T>,
CompositeIntervalStops<T>,
@@ -67,7 +67,7 @@ public:
// lower_bound yields first element >= zoom, but we want the *last*
// element <= zoom, so if we found a stop > zoom, back up by one.
- if (minIt != s.stops.begin() && minIt->first > zoom) {
+ if (minIt != s.stops.begin() && minIt != s.stops.end() && minIt->first > zoom) {
minIt--;
}
@@ -135,6 +135,7 @@ public:
std::string property;
Stops stops;
optional<T> defaultValue;
+ bool useIntegerZoom = false;
private:
T evaluateFinal(const CoveringRanges& ranges, const Value& value, T finalDefaultValue) const {
diff --git a/include/mbgl/style/function/exponential_stops.hpp b/include/mbgl/style/function/exponential_stops.hpp
index 051f5aa9aa..b3866c4059 100644
--- a/include/mbgl/style/function/exponential_stops.hpp
+++ b/include/mbgl/style/function/exponential_stops.hpp
@@ -22,26 +22,28 @@ public:
base(base_) {
}
- optional<T> evaluate(const Value& value) const {
+ optional<T> evaluate(float z) const {
if (stops.empty()) {
- assert(false);
- return T();
- }
-
- optional<float> z = numericValue<float>(value);
- if (!z) {
- return T();
+ return {};
}
- auto it = stops.upper_bound(*z);
+ auto it = stops.upper_bound(z);
if (it == stops.end()) {
return stops.rbegin()->second;
} else if (it == stops.begin()) {
return stops.begin()->second;
} else {
return util::interpolate(std::prev(it)->second, it->second,
- util::interpolationFactor(base, { std::prev(it)->first, it->first }, *z));
+ util::interpolationFactor(base, { std::prev(it)->first, it->first }, z));
+ }
+ }
+
+ optional<T> evaluate(const Value& value) const {
+ optional<float> z = numericValue<float>(value);
+ if (!z) {
+ return {};
}
+ return evaluate(*z);
}
friend bool operator==(const ExponentialStops& lhs,
diff --git a/include/mbgl/style/function/interval_stops.hpp b/include/mbgl/style/function/interval_stops.hpp
index 50f2b48453..45e2dc6f2e 100644
--- a/include/mbgl/style/function/interval_stops.hpp
+++ b/include/mbgl/style/function/interval_stops.hpp
@@ -18,18 +18,12 @@ public:
: stops(std::move(stops_)) {
}
- optional<T> evaluate(const Value& value) const {
+ optional<T> evaluate(float z) const {
if (stops.empty()) {
- assert(false);
return {};
}
- optional<float> z = numericValue<float>(value);
- if (!z) {
- return {};
- }
-
- auto it = stops.upper_bound(*z);
+ auto it = stops.upper_bound(z);
if (it == stops.end()) {
return stops.rbegin()->second;
} else if (it == stops.begin()) {
@@ -39,6 +33,14 @@ public:
}
}
+ optional<T> evaluate(const Value& value) const {
+ optional<float> z = numericValue<float>(value);
+ if (!z) {
+ return {};
+ }
+ return evaluate(*z);
+ }
+
friend bool operator==(const IntervalStops& lhs,
const IntervalStops& rhs) {
return lhs.stops == rhs.stops;
diff --git a/include/mbgl/style/function/source_function.hpp b/include/mbgl/style/function/source_function.hpp
index f6601d9ea3..9c2ad101ec 100644
--- a/include/mbgl/style/function/source_function.hpp
+++ b/include/mbgl/style/function/source_function.hpp
@@ -16,7 +16,7 @@ template <class T>
class SourceFunction {
public:
using Stops = std::conditional_t<
- util::Interpolatable<T>,
+ util::Interpolatable<T>::value,
variant<
ExponentialStops<T>,
IntervalStops<T>,
@@ -53,6 +53,7 @@ public:
std::string property;
Stops stops;
optional<T> defaultValue;
+ bool useIntegerZoom = false;
};
} // namespace style
diff --git a/include/mbgl/style/image.hpp b/include/mbgl/style/image.hpp
index 499377467e..ff3bfedf46 100644
--- a/include/mbgl/style/image.hpp
+++ b/include/mbgl/style/image.hpp
@@ -1,24 +1,30 @@
#pragma once
#include <mbgl/util/image.hpp>
+#include <mbgl/util/immutable.hpp>
+
+#include <string>
namespace mbgl {
namespace style {
class Image {
public:
- Image(PremultipliedImage&&, float pixelRatio, bool sdf = false);
+ Image(std::string id, PremultipliedImage&&, float pixelRatio, bool sdf = false);
+ Image(const Image&);
+
+ std::string getID() const;
- PremultipliedImage image;
+ const PremultipliedImage& getImage() const;
// Pixel ratio of the sprite image.
- const float pixelRatio;
+ float getPixelRatio() const;
// Whether this image should be interpreted as a signed distance field icon.
- const bool sdf;
+ bool isSdf() const;
- float getWidth() const { return image.size.width / pixelRatio; }
- float getHeight() const { return image.size.height / pixelRatio; }
+ class Impl;
+ Immutable<Impl> baseImpl;
};
} // namespace style
diff --git a/include/mbgl/style/layer.hpp b/include/mbgl/style/layer.hpp
index 016b3a1c8b..c6a3c0e735 100644
--- a/include/mbgl/style/layer.hpp
+++ b/include/mbgl/style/layer.hpp
@@ -2,6 +2,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/any.hpp>
+#include <mbgl/util/immutable.hpp>
#include <mbgl/style/layer_type.hpp>
#include <mbgl/style/types.hpp>
@@ -21,6 +22,7 @@ class RasterLayer;
class BackgroundLayer;
class CustomLayer;
class FillExtrusionLayer;
+class LayerObserver;
/**
* The runtime representation of a [layer](https://www.mapbox.com/mapbox-gl-style-spec/#layers) from the Mapbox Style
@@ -40,15 +42,6 @@ class FillExtrusionLayer;
*/
class Layer : public mbgl::util::noncopyable {
public:
- class Impl;
-
-protected:
-
- const LayerType type;
- Layer(LayerType, std::unique_ptr<Impl>);
-
-public:
-
virtual ~Layer();
// Check whether this layer is of the given subtype.
@@ -80,23 +73,23 @@ public:
//
template <class V>
auto accept(V&& visitor) {
- switch (type) {
+ switch (getType()) {
case LayerType::Fill:
- return visitor(*as<FillLayer>());
+ return std::forward<V>(visitor)(*as<FillLayer>());
case LayerType::Line:
- return visitor(*as<LineLayer>());
+ return std::forward<V>(visitor)(*as<LineLayer>());
case LayerType::Circle:
- return visitor(*as<CircleLayer>());
+ return std::forward<V>(visitor)(*as<CircleLayer>());
case LayerType::Symbol:
- return visitor(*as<SymbolLayer>());
+ return std::forward<V>(visitor)(*as<SymbolLayer>());
case LayerType::Raster:
- return visitor(*as<RasterLayer>());
+ return std::forward<V>(visitor)(*as<RasterLayer>());
case LayerType::Background:
- return visitor(*as<BackgroundLayer>());
+ return std::forward<V>(visitor)(*as<BackgroundLayer>());
case LayerType::Custom:
- return visitor(*as<CustomLayer>());
+ return std::forward<V>(visitor)(*as<CustomLayer>());
case LayerType::FillExtrusion:
- return visitor(*as<FillExtrusionLayer>());
+ return std::forward<V>(visitor)(*as<FillExtrusionLayer>());
}
@@ -105,20 +98,30 @@ public:
throw new std::runtime_error("unknown layer type");
}
- const std::string& getID() const;
+ LayerType getType() const;
+ std::string getID() const;
// Visibility
VisibilityType getVisibility() const;
- void setVisibility(VisibilityType);
+ virtual void setVisibility(VisibilityType) = 0;
// Zoom range
float getMinZoom() const;
- void setMinZoom(float) const;
float getMaxZoom() const;
- void setMaxZoom(float) const;
+ virtual void setMinZoom(float) = 0;
+ virtual void setMaxZoom(float) = 0;
// Private implementation
- const std::unique_ptr<Impl> baseImpl;
+ class Impl;
+ Immutable<Impl> baseImpl;
+
+ Layer(Immutable<Impl>);
+
+ // 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;
+
+ LayerObserver* observer = nullptr;
+ void setObserver(LayerObserver*);
// For use in SDK bindings, which store a reference to a platform-native peer
// object here, so that separately-obtained references to this object share
diff --git a/include/mbgl/style/layers/background_layer.hpp b/include/mbgl/style/layers/background_layer.hpp
index 6604a868f3..903983844f 100644
--- a/include/mbgl/style/layers/background_layer.hpp
+++ b/include/mbgl/style/layers/background_layer.hpp
@@ -19,38 +19,46 @@ public:
BackgroundLayer(const std::string& layerID);
~BackgroundLayer() final;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<Color> getDefaultBackgroundColor();
- PropertyValue<Color> getBackgroundColor(const optional<std::string>& klass = {}) const;
- void setBackgroundColor(PropertyValue<Color>, const optional<std::string>& klass = {});
- void setBackgroundColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getBackgroundColorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<Color> getBackgroundColor() const;
+ void setBackgroundColor(PropertyValue<Color>);
+ void setBackgroundColorTransition(const TransitionOptions&);
+ TransitionOptions getBackgroundColorTransition() const;
static PropertyValue<std::string> getDefaultBackgroundPattern();
- PropertyValue<std::string> getBackgroundPattern(const optional<std::string>& klass = {}) const;
- void setBackgroundPattern(PropertyValue<std::string>, const optional<std::string>& klass = {});
- void setBackgroundPatternTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getBackgroundPatternTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::string> getBackgroundPattern() const;
+ void setBackgroundPattern(PropertyValue<std::string>);
+ void setBackgroundPatternTransition(const TransitionOptions&);
+ TransitionOptions getBackgroundPatternTransition() const;
static PropertyValue<float> getDefaultBackgroundOpacity();
- PropertyValue<float> getBackgroundOpacity(const optional<std::string>& klass = {}) const;
- void setBackgroundOpacity(PropertyValue<float>, const optional<std::string>& klass = {});
- void setBackgroundOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getBackgroundOpacityTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getBackgroundOpacity() const;
+ void setBackgroundOpacity(PropertyValue<float>);
+ void setBackgroundOpacityTransition(const TransitionOptions&);
+ TransitionOptions getBackgroundOpacityTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- BackgroundLayer(const Impl&);
- BackgroundLayer(const BackgroundLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ BackgroundLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<BackgroundLayer>() const {
- return type == LayerType::Background;
+ return getType() == LayerType::Background;
}
} // namespace style
diff --git a/include/mbgl/style/layers/circle_layer.hpp b/include/mbgl/style/layers/circle_layer.hpp
index 3a3723249f..942dd67503 100644
--- a/include/mbgl/style/layers/circle_layer.hpp
+++ b/include/mbgl/style/layers/circle_layer.hpp
@@ -27,80 +27,94 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static DataDrivenPropertyValue<float> getDefaultCircleRadius();
- DataDrivenPropertyValue<float> getCircleRadius(const optional<std::string>& klass = {}) const;
- void setCircleRadius(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setCircleRadiusTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleRadiusTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getCircleRadius() const;
+ void setCircleRadius(DataDrivenPropertyValue<float>);
+ void setCircleRadiusTransition(const TransitionOptions&);
+ TransitionOptions getCircleRadiusTransition() const;
static DataDrivenPropertyValue<Color> getDefaultCircleColor();
- DataDrivenPropertyValue<Color> getCircleColor(const optional<std::string>& klass = {}) const;
- void setCircleColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setCircleColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getCircleColor() const;
+ void setCircleColor(DataDrivenPropertyValue<Color>);
+ void setCircleColorTransition(const TransitionOptions&);
+ TransitionOptions getCircleColorTransition() const;
static DataDrivenPropertyValue<float> getDefaultCircleBlur();
- DataDrivenPropertyValue<float> getCircleBlur(const optional<std::string>& klass = {}) const;
- void setCircleBlur(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setCircleBlurTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleBlurTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getCircleBlur() const;
+ void setCircleBlur(DataDrivenPropertyValue<float>);
+ void setCircleBlurTransition(const TransitionOptions&);
+ TransitionOptions getCircleBlurTransition() const;
static DataDrivenPropertyValue<float> getDefaultCircleOpacity();
- DataDrivenPropertyValue<float> getCircleOpacity(const optional<std::string>& klass = {}) const;
- void setCircleOpacity(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setCircleOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleOpacityTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getCircleOpacity() const;
+ void setCircleOpacity(DataDrivenPropertyValue<float>);
+ void setCircleOpacityTransition(const TransitionOptions&);
+ TransitionOptions getCircleOpacityTransition() const;
static PropertyValue<std::array<float, 2>> getDefaultCircleTranslate();
- PropertyValue<std::array<float, 2>> getCircleTranslate(const optional<std::string>& klass = {}) const;
- void setCircleTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
- void setCircleTranslateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleTranslateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::array<float, 2>> getCircleTranslate() const;
+ void setCircleTranslate(PropertyValue<std::array<float, 2>>);
+ void setCircleTranslateTransition(const TransitionOptions&);
+ TransitionOptions getCircleTranslateTransition() const;
static PropertyValue<TranslateAnchorType> getDefaultCircleTranslateAnchor();
- PropertyValue<TranslateAnchorType> getCircleTranslateAnchor(const optional<std::string>& klass = {}) const;
- void setCircleTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
- void setCircleTranslateAnchorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleTranslateAnchorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<TranslateAnchorType> getCircleTranslateAnchor() const;
+ void setCircleTranslateAnchor(PropertyValue<TranslateAnchorType>);
+ void setCircleTranslateAnchorTransition(const TransitionOptions&);
+ TransitionOptions getCircleTranslateAnchorTransition() const;
static PropertyValue<CirclePitchScaleType> getDefaultCirclePitchScale();
- PropertyValue<CirclePitchScaleType> getCirclePitchScale(const optional<std::string>& klass = {}) const;
- void setCirclePitchScale(PropertyValue<CirclePitchScaleType>, const optional<std::string>& klass = {});
- void setCirclePitchScaleTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCirclePitchScaleTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<CirclePitchScaleType> getCirclePitchScale() const;
+ void setCirclePitchScale(PropertyValue<CirclePitchScaleType>);
+ void setCirclePitchScaleTransition(const TransitionOptions&);
+ TransitionOptions getCirclePitchScaleTransition() const;
+
+ static PropertyValue<AlignmentType> getDefaultCirclePitchAlignment();
+ PropertyValue<AlignmentType> getCirclePitchAlignment() const;
+ void setCirclePitchAlignment(PropertyValue<AlignmentType>);
+ void setCirclePitchAlignmentTransition(const TransitionOptions&);
+ TransitionOptions getCirclePitchAlignmentTransition() const;
static DataDrivenPropertyValue<float> getDefaultCircleStrokeWidth();
- DataDrivenPropertyValue<float> getCircleStrokeWidth(const optional<std::string>& klass = {}) const;
- void setCircleStrokeWidth(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setCircleStrokeWidthTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleStrokeWidthTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getCircleStrokeWidth() const;
+ void setCircleStrokeWidth(DataDrivenPropertyValue<float>);
+ void setCircleStrokeWidthTransition(const TransitionOptions&);
+ TransitionOptions getCircleStrokeWidthTransition() const;
static DataDrivenPropertyValue<Color> getDefaultCircleStrokeColor();
- DataDrivenPropertyValue<Color> getCircleStrokeColor(const optional<std::string>& klass = {}) const;
- void setCircleStrokeColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setCircleStrokeColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleStrokeColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getCircleStrokeColor() const;
+ void setCircleStrokeColor(DataDrivenPropertyValue<Color>);
+ void setCircleStrokeColorTransition(const TransitionOptions&);
+ TransitionOptions getCircleStrokeColorTransition() const;
static DataDrivenPropertyValue<float> getDefaultCircleStrokeOpacity();
- DataDrivenPropertyValue<float> getCircleStrokeOpacity(const optional<std::string>& klass = {}) const;
- void setCircleStrokeOpacity(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setCircleStrokeOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getCircleStrokeOpacityTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getCircleStrokeOpacity() const;
+ void setCircleStrokeOpacity(DataDrivenPropertyValue<float>);
+ void setCircleStrokeOpacityTransition(const TransitionOptions&);
+ TransitionOptions getCircleStrokeOpacityTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- CircleLayer(const Impl&);
- CircleLayer(const CircleLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ CircleLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<CircleLayer>() const {
- return type == LayerType::Circle;
+ return getType() == LayerType::Circle;
}
} // namespace style
diff --git a/include/mbgl/style/layers/custom_layer.hpp b/include/mbgl/style/layers/custom_layer.hpp
index edc8d43f89..bf3387f95b 100644
--- a/include/mbgl/style/layers/custom_layer.hpp
+++ b/include/mbgl/style/layers/custom_layer.hpp
@@ -39,6 +39,14 @@ struct CustomLayerRenderParameters {
using CustomLayerRenderFunction = void (*)(void* context, const CustomLayerRenderParameters&);
/**
+ * Called when the system has destroyed the underlying GL context. The
+ * `CustomLayerDeinitializeFunction` will not be called in this case, however
+ * `CustomLayerInitializeFunction` will be called instead to prepare for a new render.
+ *
+ */
+using CustomLayerContextLostFunction = void (*)(void* context);
+
+/**
* Destroy any GL state needed by the custom layer, and deallocate context, if necessary. This
* method is called once, from the main thread, at a point when the GL context is active.
*
@@ -51,16 +59,33 @@ public:
CustomLayer(const std::string& id,
CustomLayerInitializeFunction,
CustomLayerRenderFunction,
+ CustomLayerContextLostFunction,
+ CustomLayerDeinitializeFunction,
+ void* context);
+
+ CustomLayer(const std::string& id,
+ CustomLayerInitializeFunction,
+ CustomLayerRenderFunction,
CustomLayerDeinitializeFunction,
void* context);
+
~CustomLayer() final;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Private implementation
class Impl;
- Impl* impl;
+ const Impl& impl() const;
+
+ Mutable<Impl> mutableImpl() const;
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
- CustomLayer(const Impl&);
CustomLayer(const CustomLayer&) = delete;
};
diff --git a/include/mbgl/style/layers/fill_extrusion_layer.hpp b/include/mbgl/style/layers/fill_extrusion_layer.hpp
index 1f79f87fac..e1c54f54ee 100644
--- a/include/mbgl/style/layers/fill_extrusion_layer.hpp
+++ b/include/mbgl/style/layers/fill_extrusion_layer.hpp
@@ -27,62 +27,70 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<float> getDefaultFillExtrusionOpacity();
- PropertyValue<float> getFillExtrusionOpacity(const optional<std::string>& klass = {}) const;
- void setFillExtrusionOpacity(PropertyValue<float>, const optional<std::string>& klass = {});
- void setFillExtrusionOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionOpacityTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getFillExtrusionOpacity() const;
+ void setFillExtrusionOpacity(PropertyValue<float>);
+ void setFillExtrusionOpacityTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionOpacityTransition() const;
static DataDrivenPropertyValue<Color> getDefaultFillExtrusionColor();
- DataDrivenPropertyValue<Color> getFillExtrusionColor(const optional<std::string>& klass = {}) const;
- void setFillExtrusionColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setFillExtrusionColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getFillExtrusionColor() const;
+ void setFillExtrusionColor(DataDrivenPropertyValue<Color>);
+ void setFillExtrusionColorTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionColorTransition() const;
static PropertyValue<std::array<float, 2>> getDefaultFillExtrusionTranslate();
- PropertyValue<std::array<float, 2>> getFillExtrusionTranslate(const optional<std::string>& klass = {}) const;
- void setFillExtrusionTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
- void setFillExtrusionTranslateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionTranslateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::array<float, 2>> getFillExtrusionTranslate() const;
+ void setFillExtrusionTranslate(PropertyValue<std::array<float, 2>>);
+ void setFillExtrusionTranslateTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionTranslateTransition() const;
static PropertyValue<TranslateAnchorType> getDefaultFillExtrusionTranslateAnchor();
- PropertyValue<TranslateAnchorType> getFillExtrusionTranslateAnchor(const optional<std::string>& klass = {}) const;
- void setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
- void setFillExtrusionTranslateAnchorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionTranslateAnchorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<TranslateAnchorType> getFillExtrusionTranslateAnchor() const;
+ void setFillExtrusionTranslateAnchor(PropertyValue<TranslateAnchorType>);
+ void setFillExtrusionTranslateAnchorTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionTranslateAnchorTransition() const;
static PropertyValue<std::string> getDefaultFillExtrusionPattern();
- PropertyValue<std::string> getFillExtrusionPattern(const optional<std::string>& klass = {}) const;
- void setFillExtrusionPattern(PropertyValue<std::string>, const optional<std::string>& klass = {});
- void setFillExtrusionPatternTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionPatternTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::string> getFillExtrusionPattern() const;
+ void setFillExtrusionPattern(PropertyValue<std::string>);
+ void setFillExtrusionPatternTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionPatternTransition() const;
static DataDrivenPropertyValue<float> getDefaultFillExtrusionHeight();
- DataDrivenPropertyValue<float> getFillExtrusionHeight(const optional<std::string>& klass = {}) const;
- void setFillExtrusionHeight(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setFillExtrusionHeightTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionHeightTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getFillExtrusionHeight() const;
+ void setFillExtrusionHeight(DataDrivenPropertyValue<float>);
+ void setFillExtrusionHeightTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionHeightTransition() const;
static DataDrivenPropertyValue<float> getDefaultFillExtrusionBase();
- DataDrivenPropertyValue<float> getFillExtrusionBase(const optional<std::string>& klass = {}) const;
- void setFillExtrusionBase(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setFillExtrusionBaseTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillExtrusionBaseTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getFillExtrusionBase() const;
+ void setFillExtrusionBase(DataDrivenPropertyValue<float>);
+ void setFillExtrusionBaseTransition(const TransitionOptions&);
+ TransitionOptions getFillExtrusionBaseTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- FillExtrusionLayer(const Impl&);
- FillExtrusionLayer(const FillExtrusionLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ FillExtrusionLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<FillExtrusionLayer>() const {
- return type == LayerType::FillExtrusion;
+ return getType() == LayerType::FillExtrusion;
}
} // namespace style
diff --git a/include/mbgl/style/layers/fill_layer.hpp b/include/mbgl/style/layers/fill_layer.hpp
index 8371ff7a8f..dfbe69d7fe 100644
--- a/include/mbgl/style/layers/fill_layer.hpp
+++ b/include/mbgl/style/layers/fill_layer.hpp
@@ -27,62 +27,70 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<bool> getDefaultFillAntialias();
- PropertyValue<bool> getFillAntialias(const optional<std::string>& klass = {}) const;
- void setFillAntialias(PropertyValue<bool>, const optional<std::string>& klass = {});
- void setFillAntialiasTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillAntialiasTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<bool> getFillAntialias() const;
+ void setFillAntialias(PropertyValue<bool>);
+ void setFillAntialiasTransition(const TransitionOptions&);
+ TransitionOptions getFillAntialiasTransition() const;
static DataDrivenPropertyValue<float> getDefaultFillOpacity();
- DataDrivenPropertyValue<float> getFillOpacity(const optional<std::string>& klass = {}) const;
- void setFillOpacity(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setFillOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillOpacityTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getFillOpacity() const;
+ void setFillOpacity(DataDrivenPropertyValue<float>);
+ void setFillOpacityTransition(const TransitionOptions&);
+ TransitionOptions getFillOpacityTransition() const;
static DataDrivenPropertyValue<Color> getDefaultFillColor();
- DataDrivenPropertyValue<Color> getFillColor(const optional<std::string>& klass = {}) const;
- void setFillColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setFillColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getFillColor() const;
+ void setFillColor(DataDrivenPropertyValue<Color>);
+ void setFillColorTransition(const TransitionOptions&);
+ TransitionOptions getFillColorTransition() const;
static DataDrivenPropertyValue<Color> getDefaultFillOutlineColor();
- DataDrivenPropertyValue<Color> getFillOutlineColor(const optional<std::string>& klass = {}) const;
- void setFillOutlineColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setFillOutlineColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillOutlineColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getFillOutlineColor() const;
+ void setFillOutlineColor(DataDrivenPropertyValue<Color>);
+ void setFillOutlineColorTransition(const TransitionOptions&);
+ TransitionOptions getFillOutlineColorTransition() const;
static PropertyValue<std::array<float, 2>> getDefaultFillTranslate();
- PropertyValue<std::array<float, 2>> getFillTranslate(const optional<std::string>& klass = {}) const;
- void setFillTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
- void setFillTranslateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillTranslateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::array<float, 2>> getFillTranslate() const;
+ void setFillTranslate(PropertyValue<std::array<float, 2>>);
+ void setFillTranslateTransition(const TransitionOptions&);
+ TransitionOptions getFillTranslateTransition() const;
static PropertyValue<TranslateAnchorType> getDefaultFillTranslateAnchor();
- PropertyValue<TranslateAnchorType> getFillTranslateAnchor(const optional<std::string>& klass = {}) const;
- void setFillTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
- void setFillTranslateAnchorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillTranslateAnchorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<TranslateAnchorType> getFillTranslateAnchor() const;
+ void setFillTranslateAnchor(PropertyValue<TranslateAnchorType>);
+ void setFillTranslateAnchorTransition(const TransitionOptions&);
+ TransitionOptions getFillTranslateAnchorTransition() const;
static PropertyValue<std::string> getDefaultFillPattern();
- PropertyValue<std::string> getFillPattern(const optional<std::string>& klass = {}) const;
- void setFillPattern(PropertyValue<std::string>, const optional<std::string>& klass = {});
- void setFillPatternTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getFillPatternTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::string> getFillPattern() const;
+ void setFillPattern(PropertyValue<std::string>);
+ void setFillPatternTransition(const TransitionOptions&);
+ TransitionOptions getFillPatternTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- FillLayer(const Impl&);
- FillLayer(const FillLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ FillLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<FillLayer>() const {
- return type == LayerType::Fill;
+ return getType() == LayerType::Fill;
}
} // namespace style
diff --git a/include/mbgl/style/layers/layer.hpp.ejs b/include/mbgl/style/layers/layer.hpp.ejs
index 59d7cd6415..4ee5545247 100644
--- a/include/mbgl/style/layers/layer.hpp.ejs
+++ b/include/mbgl/style/layers/layer.hpp.ejs
@@ -44,6 +44,13 @@ public:
<% } -%>
<% } -%>
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
<% if (layoutProperties.length) { -%>
// Layout properties
@@ -58,24 +65,25 @@ public:
<% for (const property of paintProperties) { -%>
static <%- propertyValueType(property) %> getDefault<%- camelize(property.name) %>();
- <%- propertyValueType(property) %> get<%- camelize(property.name) %>(const optional<std::string>& klass = {}) const;
- void set<%- camelize(property.name) %>(<%- propertyValueType(property) %>, const optional<std::string>& klass = {});
- void set<%- camelize(property.name) %>Transition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions get<%- camelize(property.name) %>Transition(const optional<std::string>& klass = {}) const;
+ <%- propertyValueType(property) %> get<%- camelize(property.name) %>() const;
+ void set<%- camelize(property.name) %>(<%- propertyValueType(property) %>);
+ void set<%- camelize(property.name) %>Transition(const TransitionOptions&);
+ TransitionOptions get<%- camelize(property.name) %>Transition() const;
<% } -%>
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- <%- camelize(type) %>Layer(const Impl&);
- <%- camelize(type) %>Layer(const <%- camelize(type) %>Layer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ <%- camelize(type) %>Layer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<<%- camelize(type) %>Layer>() const {
- return type == LayerType::<%- camelize(type) %>;
+ return getType() == LayerType::<%- camelize(type) %>;
}
} // namespace style
diff --git a/include/mbgl/style/layers/line_layer.hpp b/include/mbgl/style/layers/line_layer.hpp
index a5f08e553c..4519296323 100644
--- a/include/mbgl/style/layers/line_layer.hpp
+++ b/include/mbgl/style/layers/line_layer.hpp
@@ -29,15 +29,22 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Layout properties
static PropertyValue<LineCapType> getDefaultLineCap();
PropertyValue<LineCapType> getLineCap() const;
void setLineCap(PropertyValue<LineCapType>);
- static PropertyValue<LineJoinType> getDefaultLineJoin();
- PropertyValue<LineJoinType> getLineJoin() const;
- void setLineJoin(PropertyValue<LineJoinType>);
+ static DataDrivenPropertyValue<LineJoinType> getDefaultLineJoin();
+ DataDrivenPropertyValue<LineJoinType> getLineJoin() const;
+ void setLineJoin(DataDrivenPropertyValue<LineJoinType>);
static PropertyValue<float> getDefaultLineMiterLimit();
PropertyValue<float> getLineMiterLimit() const;
@@ -50,77 +57,78 @@ public:
// Paint properties
static DataDrivenPropertyValue<float> getDefaultLineOpacity();
- DataDrivenPropertyValue<float> getLineOpacity(const optional<std::string>& klass = {}) const;
- void setLineOpacity(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setLineOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineOpacityTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getLineOpacity() const;
+ void setLineOpacity(DataDrivenPropertyValue<float>);
+ void setLineOpacityTransition(const TransitionOptions&);
+ TransitionOptions getLineOpacityTransition() const;
static DataDrivenPropertyValue<Color> getDefaultLineColor();
- DataDrivenPropertyValue<Color> getLineColor(const optional<std::string>& klass = {}) const;
- void setLineColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setLineColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getLineColor() const;
+ void setLineColor(DataDrivenPropertyValue<Color>);
+ void setLineColorTransition(const TransitionOptions&);
+ TransitionOptions getLineColorTransition() const;
static PropertyValue<std::array<float, 2>> getDefaultLineTranslate();
- PropertyValue<std::array<float, 2>> getLineTranslate(const optional<std::string>& klass = {}) const;
- void setLineTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
- void setLineTranslateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineTranslateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::array<float, 2>> getLineTranslate() const;
+ void setLineTranslate(PropertyValue<std::array<float, 2>>);
+ void setLineTranslateTransition(const TransitionOptions&);
+ TransitionOptions getLineTranslateTransition() const;
static PropertyValue<TranslateAnchorType> getDefaultLineTranslateAnchor();
- PropertyValue<TranslateAnchorType> getLineTranslateAnchor(const optional<std::string>& klass = {}) const;
- void setLineTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
- void setLineTranslateAnchorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineTranslateAnchorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<TranslateAnchorType> getLineTranslateAnchor() const;
+ void setLineTranslateAnchor(PropertyValue<TranslateAnchorType>);
+ void setLineTranslateAnchorTransition(const TransitionOptions&);
+ TransitionOptions getLineTranslateAnchorTransition() const;
- static PropertyValue<float> getDefaultLineWidth();
- PropertyValue<float> getLineWidth(const optional<std::string>& klass = {}) const;
- void setLineWidth(PropertyValue<float>, const optional<std::string>& klass = {});
- void setLineWidthTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineWidthTransition(const optional<std::string>& klass = {}) const;
+ static DataDrivenPropertyValue<float> getDefaultLineWidth();
+ DataDrivenPropertyValue<float> getLineWidth() const;
+ void setLineWidth(DataDrivenPropertyValue<float>);
+ void setLineWidthTransition(const TransitionOptions&);
+ TransitionOptions getLineWidthTransition() const;
static DataDrivenPropertyValue<float> getDefaultLineGapWidth();
- DataDrivenPropertyValue<float> getLineGapWidth(const optional<std::string>& klass = {}) const;
- void setLineGapWidth(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setLineGapWidthTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineGapWidthTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getLineGapWidth() const;
+ void setLineGapWidth(DataDrivenPropertyValue<float>);
+ void setLineGapWidthTransition(const TransitionOptions&);
+ TransitionOptions getLineGapWidthTransition() const;
static DataDrivenPropertyValue<float> getDefaultLineOffset();
- DataDrivenPropertyValue<float> getLineOffset(const optional<std::string>& klass = {}) const;
- void setLineOffset(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setLineOffsetTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineOffsetTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getLineOffset() const;
+ void setLineOffset(DataDrivenPropertyValue<float>);
+ void setLineOffsetTransition(const TransitionOptions&);
+ TransitionOptions getLineOffsetTransition() const;
static DataDrivenPropertyValue<float> getDefaultLineBlur();
- DataDrivenPropertyValue<float> getLineBlur(const optional<std::string>& klass = {}) const;
- void setLineBlur(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setLineBlurTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineBlurTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getLineBlur() const;
+ void setLineBlur(DataDrivenPropertyValue<float>);
+ void setLineBlurTransition(const TransitionOptions&);
+ TransitionOptions getLineBlurTransition() const;
static PropertyValue<std::vector<float>> getDefaultLineDasharray();
- PropertyValue<std::vector<float>> getLineDasharray(const optional<std::string>& klass = {}) const;
- void setLineDasharray(PropertyValue<std::vector<float>>, const optional<std::string>& klass = {});
- void setLineDasharrayTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLineDasharrayTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::vector<float>> getLineDasharray() const;
+ void setLineDasharray(PropertyValue<std::vector<float>>);
+ void setLineDasharrayTransition(const TransitionOptions&);
+ TransitionOptions getLineDasharrayTransition() const;
static PropertyValue<std::string> getDefaultLinePattern();
- PropertyValue<std::string> getLinePattern(const optional<std::string>& klass = {}) const;
- void setLinePattern(PropertyValue<std::string>, const optional<std::string>& klass = {});
- void setLinePatternTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getLinePatternTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::string> getLinePattern() const;
+ void setLinePattern(PropertyValue<std::string>);
+ void setLinePatternTransition(const TransitionOptions&);
+ TransitionOptions getLinePatternTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- LineLayer(const Impl&);
- LineLayer(const LineLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ LineLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<LineLayer>() const {
- return type == LayerType::Line;
+ return getType() == LayerType::Line;
}
} // namespace style
diff --git a/include/mbgl/style/layers/raster_layer.hpp b/include/mbgl/style/layers/raster_layer.hpp
index c0351da5d0..8111364709 100644
--- a/include/mbgl/style/layers/raster_layer.hpp
+++ b/include/mbgl/style/layers/raster_layer.hpp
@@ -22,62 +22,70 @@ public:
// Source
const std::string& getSourceID() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Paint properties
static PropertyValue<float> getDefaultRasterOpacity();
- PropertyValue<float> getRasterOpacity(const optional<std::string>& klass = {}) const;
- void setRasterOpacity(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterOpacityTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterOpacity() const;
+ void setRasterOpacity(PropertyValue<float>);
+ void setRasterOpacityTransition(const TransitionOptions&);
+ TransitionOptions getRasterOpacityTransition() const;
static PropertyValue<float> getDefaultRasterHueRotate();
- PropertyValue<float> getRasterHueRotate(const optional<std::string>& klass = {}) const;
- void setRasterHueRotate(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterHueRotateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterHueRotateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterHueRotate() const;
+ void setRasterHueRotate(PropertyValue<float>);
+ void setRasterHueRotateTransition(const TransitionOptions&);
+ TransitionOptions getRasterHueRotateTransition() const;
static PropertyValue<float> getDefaultRasterBrightnessMin();
- PropertyValue<float> getRasterBrightnessMin(const optional<std::string>& klass = {}) const;
- void setRasterBrightnessMin(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterBrightnessMinTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterBrightnessMinTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterBrightnessMin() const;
+ void setRasterBrightnessMin(PropertyValue<float>);
+ void setRasterBrightnessMinTransition(const TransitionOptions&);
+ TransitionOptions getRasterBrightnessMinTransition() const;
static PropertyValue<float> getDefaultRasterBrightnessMax();
- PropertyValue<float> getRasterBrightnessMax(const optional<std::string>& klass = {}) const;
- void setRasterBrightnessMax(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterBrightnessMaxTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterBrightnessMaxTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterBrightnessMax() const;
+ void setRasterBrightnessMax(PropertyValue<float>);
+ void setRasterBrightnessMaxTransition(const TransitionOptions&);
+ TransitionOptions getRasterBrightnessMaxTransition() const;
static PropertyValue<float> getDefaultRasterSaturation();
- PropertyValue<float> getRasterSaturation(const optional<std::string>& klass = {}) const;
- void setRasterSaturation(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterSaturationTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterSaturationTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterSaturation() const;
+ void setRasterSaturation(PropertyValue<float>);
+ void setRasterSaturationTransition(const TransitionOptions&);
+ TransitionOptions getRasterSaturationTransition() const;
static PropertyValue<float> getDefaultRasterContrast();
- PropertyValue<float> getRasterContrast(const optional<std::string>& klass = {}) const;
- void setRasterContrast(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterContrastTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterContrastTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterContrast() const;
+ void setRasterContrast(PropertyValue<float>);
+ void setRasterContrastTransition(const TransitionOptions&);
+ TransitionOptions getRasterContrastTransition() const;
static PropertyValue<float> getDefaultRasterFadeDuration();
- PropertyValue<float> getRasterFadeDuration(const optional<std::string>& klass = {}) const;
- void setRasterFadeDuration(PropertyValue<float>, const optional<std::string>& klass = {});
- void setRasterFadeDurationTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getRasterFadeDurationTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<float> getRasterFadeDuration() const;
+ void setRasterFadeDuration(PropertyValue<float>);
+ void setRasterFadeDurationTransition(const TransitionOptions&);
+ TransitionOptions getRasterFadeDurationTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- RasterLayer(const Impl&);
- RasterLayer(const RasterLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ RasterLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<RasterLayer>() const {
- return type == LayerType::Raster;
+ return getType() == LayerType::Raster;
}
} // namespace style
diff --git a/include/mbgl/style/layers/symbol_layer.hpp b/include/mbgl/style/layers/symbol_layer.hpp
index ea6bda55d7..a72baa0b4e 100644
--- a/include/mbgl/style/layers/symbol_layer.hpp
+++ b/include/mbgl/style/layers/symbol_layer.hpp
@@ -29,6 +29,13 @@ public:
void setFilter(const Filter&);
const Filter& getFilter() const;
+ // Visibility
+ void setVisibility(VisibilityType) final;
+
+ // Zoom range
+ void setMinZoom(float) final;
+ void setMaxZoom(float) final;
+
// Layout properties
static PropertyValue<SymbolPlacementType> getDefaultSymbolPlacement();
@@ -91,6 +98,14 @@ public:
DataDrivenPropertyValue<std::array<float, 2>> getIconOffset() const;
void setIconOffset(DataDrivenPropertyValue<std::array<float, 2>>);
+ static DataDrivenPropertyValue<SymbolAnchorType> getDefaultIconAnchor();
+ DataDrivenPropertyValue<SymbolAnchorType> getIconAnchor() const;
+ void setIconAnchor(DataDrivenPropertyValue<SymbolAnchorType>);
+
+ static PropertyValue<AlignmentType> getDefaultIconPitchAlignment();
+ PropertyValue<AlignmentType> getIconPitchAlignment() const;
+ void setIconPitchAlignment(PropertyValue<AlignmentType>);
+
static PropertyValue<AlignmentType> getDefaultTextPitchAlignment();
PropertyValue<AlignmentType> getTextPitchAlignment() const;
void setTextPitchAlignment(PropertyValue<AlignmentType>);
@@ -111,25 +126,25 @@ public:
DataDrivenPropertyValue<float> getTextSize() const;
void setTextSize(DataDrivenPropertyValue<float>);
- static PropertyValue<float> getDefaultTextMaxWidth();
- PropertyValue<float> getTextMaxWidth() const;
- void setTextMaxWidth(PropertyValue<float>);
+ static DataDrivenPropertyValue<float> getDefaultTextMaxWidth();
+ DataDrivenPropertyValue<float> getTextMaxWidth() const;
+ void setTextMaxWidth(DataDrivenPropertyValue<float>);
static PropertyValue<float> getDefaultTextLineHeight();
PropertyValue<float> getTextLineHeight() const;
void setTextLineHeight(PropertyValue<float>);
- static PropertyValue<float> getDefaultTextLetterSpacing();
- PropertyValue<float> getTextLetterSpacing() const;
- void setTextLetterSpacing(PropertyValue<float>);
+ static DataDrivenPropertyValue<float> getDefaultTextLetterSpacing();
+ DataDrivenPropertyValue<float> getTextLetterSpacing() const;
+ void setTextLetterSpacing(DataDrivenPropertyValue<float>);
- static PropertyValue<TextJustifyType> getDefaultTextJustify();
- PropertyValue<TextJustifyType> getTextJustify() const;
- void setTextJustify(PropertyValue<TextJustifyType>);
+ static DataDrivenPropertyValue<TextJustifyType> getDefaultTextJustify();
+ DataDrivenPropertyValue<TextJustifyType> getTextJustify() const;
+ void setTextJustify(DataDrivenPropertyValue<TextJustifyType>);
- static PropertyValue<TextAnchorType> getDefaultTextAnchor();
- PropertyValue<TextAnchorType> getTextAnchor() const;
- void setTextAnchor(PropertyValue<TextAnchorType>);
+ static DataDrivenPropertyValue<SymbolAnchorType> getDefaultTextAnchor();
+ DataDrivenPropertyValue<SymbolAnchorType> getTextAnchor() const;
+ void setTextAnchor(DataDrivenPropertyValue<SymbolAnchorType>);
static PropertyValue<float> getDefaultTextMaxAngle();
PropertyValue<float> getTextMaxAngle() const;
@@ -170,101 +185,102 @@ public:
// Paint properties
static DataDrivenPropertyValue<float> getDefaultIconOpacity();
- DataDrivenPropertyValue<float> getIconOpacity(const optional<std::string>& klass = {}) const;
- void setIconOpacity(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setIconOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconOpacityTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getIconOpacity() const;
+ void setIconOpacity(DataDrivenPropertyValue<float>);
+ void setIconOpacityTransition(const TransitionOptions&);
+ TransitionOptions getIconOpacityTransition() const;
static DataDrivenPropertyValue<Color> getDefaultIconColor();
- DataDrivenPropertyValue<Color> getIconColor(const optional<std::string>& klass = {}) const;
- void setIconColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setIconColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getIconColor() const;
+ void setIconColor(DataDrivenPropertyValue<Color>);
+ void setIconColorTransition(const TransitionOptions&);
+ TransitionOptions getIconColorTransition() const;
static DataDrivenPropertyValue<Color> getDefaultIconHaloColor();
- DataDrivenPropertyValue<Color> getIconHaloColor(const optional<std::string>& klass = {}) const;
- void setIconHaloColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setIconHaloColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconHaloColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getIconHaloColor() const;
+ void setIconHaloColor(DataDrivenPropertyValue<Color>);
+ void setIconHaloColorTransition(const TransitionOptions&);
+ TransitionOptions getIconHaloColorTransition() const;
static DataDrivenPropertyValue<float> getDefaultIconHaloWidth();
- DataDrivenPropertyValue<float> getIconHaloWidth(const optional<std::string>& klass = {}) const;
- void setIconHaloWidth(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setIconHaloWidthTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconHaloWidthTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getIconHaloWidth() const;
+ void setIconHaloWidth(DataDrivenPropertyValue<float>);
+ void setIconHaloWidthTransition(const TransitionOptions&);
+ TransitionOptions getIconHaloWidthTransition() const;
static DataDrivenPropertyValue<float> getDefaultIconHaloBlur();
- DataDrivenPropertyValue<float> getIconHaloBlur(const optional<std::string>& klass = {}) const;
- void setIconHaloBlur(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setIconHaloBlurTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconHaloBlurTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getIconHaloBlur() const;
+ void setIconHaloBlur(DataDrivenPropertyValue<float>);
+ void setIconHaloBlurTransition(const TransitionOptions&);
+ TransitionOptions getIconHaloBlurTransition() const;
static PropertyValue<std::array<float, 2>> getDefaultIconTranslate();
- PropertyValue<std::array<float, 2>> getIconTranslate(const optional<std::string>& klass = {}) const;
- void setIconTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
- void setIconTranslateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconTranslateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::array<float, 2>> getIconTranslate() const;
+ void setIconTranslate(PropertyValue<std::array<float, 2>>);
+ void setIconTranslateTransition(const TransitionOptions&);
+ TransitionOptions getIconTranslateTransition() const;
static PropertyValue<TranslateAnchorType> getDefaultIconTranslateAnchor();
- PropertyValue<TranslateAnchorType> getIconTranslateAnchor(const optional<std::string>& klass = {}) const;
- void setIconTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
- void setIconTranslateAnchorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getIconTranslateAnchorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<TranslateAnchorType> getIconTranslateAnchor() const;
+ void setIconTranslateAnchor(PropertyValue<TranslateAnchorType>);
+ void setIconTranslateAnchorTransition(const TransitionOptions&);
+ TransitionOptions getIconTranslateAnchorTransition() const;
static DataDrivenPropertyValue<float> getDefaultTextOpacity();
- DataDrivenPropertyValue<float> getTextOpacity(const optional<std::string>& klass = {}) const;
- void setTextOpacity(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setTextOpacityTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextOpacityTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getTextOpacity() const;
+ void setTextOpacity(DataDrivenPropertyValue<float>);
+ void setTextOpacityTransition(const TransitionOptions&);
+ TransitionOptions getTextOpacityTransition() const;
static DataDrivenPropertyValue<Color> getDefaultTextColor();
- DataDrivenPropertyValue<Color> getTextColor(const optional<std::string>& klass = {}) const;
- void setTextColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setTextColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getTextColor() const;
+ void setTextColor(DataDrivenPropertyValue<Color>);
+ void setTextColorTransition(const TransitionOptions&);
+ TransitionOptions getTextColorTransition() const;
static DataDrivenPropertyValue<Color> getDefaultTextHaloColor();
- DataDrivenPropertyValue<Color> getTextHaloColor(const optional<std::string>& klass = {}) const;
- void setTextHaloColor(DataDrivenPropertyValue<Color>, const optional<std::string>& klass = {});
- void setTextHaloColorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextHaloColorTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<Color> getTextHaloColor() const;
+ void setTextHaloColor(DataDrivenPropertyValue<Color>);
+ void setTextHaloColorTransition(const TransitionOptions&);
+ TransitionOptions getTextHaloColorTransition() const;
static DataDrivenPropertyValue<float> getDefaultTextHaloWidth();
- DataDrivenPropertyValue<float> getTextHaloWidth(const optional<std::string>& klass = {}) const;
- void setTextHaloWidth(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setTextHaloWidthTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextHaloWidthTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getTextHaloWidth() const;
+ void setTextHaloWidth(DataDrivenPropertyValue<float>);
+ void setTextHaloWidthTransition(const TransitionOptions&);
+ TransitionOptions getTextHaloWidthTransition() const;
static DataDrivenPropertyValue<float> getDefaultTextHaloBlur();
- DataDrivenPropertyValue<float> getTextHaloBlur(const optional<std::string>& klass = {}) const;
- void setTextHaloBlur(DataDrivenPropertyValue<float>, const optional<std::string>& klass = {});
- void setTextHaloBlurTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextHaloBlurTransition(const optional<std::string>& klass = {}) const;
+ DataDrivenPropertyValue<float> getTextHaloBlur() const;
+ void setTextHaloBlur(DataDrivenPropertyValue<float>);
+ void setTextHaloBlurTransition(const TransitionOptions&);
+ TransitionOptions getTextHaloBlurTransition() const;
static PropertyValue<std::array<float, 2>> getDefaultTextTranslate();
- PropertyValue<std::array<float, 2>> getTextTranslate(const optional<std::string>& klass = {}) const;
- void setTextTranslate(PropertyValue<std::array<float, 2>>, const optional<std::string>& klass = {});
- void setTextTranslateTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextTranslateTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<std::array<float, 2>> getTextTranslate() const;
+ void setTextTranslate(PropertyValue<std::array<float, 2>>);
+ void setTextTranslateTransition(const TransitionOptions&);
+ TransitionOptions getTextTranslateTransition() const;
static PropertyValue<TranslateAnchorType> getDefaultTextTranslateAnchor();
- PropertyValue<TranslateAnchorType> getTextTranslateAnchor(const optional<std::string>& klass = {}) const;
- void setTextTranslateAnchor(PropertyValue<TranslateAnchorType>, const optional<std::string>& klass = {});
- void setTextTranslateAnchorTransition(const TransitionOptions&, const optional<std::string>& klass = {});
- TransitionOptions getTextTranslateAnchorTransition(const optional<std::string>& klass = {}) const;
+ PropertyValue<TranslateAnchorType> getTextTranslateAnchor() const;
+ void setTextTranslateAnchor(PropertyValue<TranslateAnchorType>);
+ void setTextTranslateAnchorTransition(const TransitionOptions&);
+ TransitionOptions getTextTranslateAnchorTransition() const;
// Private implementation
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
- SymbolLayer(const Impl&);
- SymbolLayer(const SymbolLayer&) = delete;
+ Mutable<Impl> mutableImpl() const;
+ SymbolLayer(Immutable<Impl>);
+ std::unique_ptr<Layer> cloneRef(const std::string& id) const final;
};
template <>
inline bool Layer::is<SymbolLayer>() const {
- return type == LayerType::Symbol;
+ return getType() == LayerType::Symbol;
}
} // namespace style
diff --git a/include/mbgl/style/light.hpp b/include/mbgl/style/light.hpp
index 8212a58dcc..c82792b28d 100644
--- a/include/mbgl/style/light.hpp
+++ b/include/mbgl/style/light.hpp
@@ -1,20 +1,19 @@
// This file is generated. Do not edit.
#pragma once
+
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/types.hpp>
-
-#include <memory>
+#include <mbgl/util/immutable.hpp>
namespace mbgl {
namespace style {
+class LightObserver;
+
class Light {
public:
-
- class Impl;
-
Light();
~Light();
@@ -42,7 +41,12 @@ public:
void setIntensityTransition(const TransitionOptions&);
TransitionOptions getIntensityTransition() const;
- std::shared_ptr<Impl> impl;
+ class Impl;
+ Immutable<Impl> impl;
+ Mutable<Impl> mutableImpl() const;
+
+ LightObserver* observer = nullptr;
+ void setObserver(LightObserver*);
};
} // namespace style
diff --git a/include/mbgl/style/light.hpp.ejs b/include/mbgl/style/light.hpp.ejs
index 601e0bd410..adc5b651e3 100644
--- a/include/mbgl/style/light.hpp.ejs
+++ b/include/mbgl/style/light.hpp.ejs
@@ -4,20 +4,19 @@
// This file is generated. Do not edit.
#pragma once
+
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/types.hpp>
-
-#include <memory>
+#include <mbgl/util/immutable.hpp>
namespace mbgl {
namespace style {
+class LightObserver;
+
class Light {
public:
-
- class Impl;
-
Light();
~Light();
@@ -29,7 +28,12 @@ public:
TransitionOptions get<%- camelize(property.name) %>Transition() const;
<% } -%>
- std::shared_ptr<Impl> impl;
+ class Impl;
+ Immutable<Impl> impl;
+ Mutable<Impl> mutableImpl() const;
+
+ LightObserver* observer = nullptr;
+ void setObserver(LightObserver*);
};
} // namespace style
diff --git a/include/mbgl/style/position.hpp b/include/mbgl/style/position.hpp
index 078e62bda8..3be8d1c55e 100644
--- a/include/mbgl/style/position.hpp
+++ b/include/mbgl/style/position.hpp
@@ -9,7 +9,7 @@ namespace style {
class Position {
public:
Position() = default;
- Position(const std::array<float, 3>& position_)
+ Position(std::array<float, 3>& position_)
: radial(position_[0]), azimuthal(position_[1]), polar(position_[2]) {
calculateCartesian();
};
diff --git a/include/mbgl/style/property_value.hpp b/include/mbgl/style/property_value.hpp
index 8bec7388e5..02d3a31148 100644
--- a/include/mbgl/style/property_value.hpp
+++ b/include/mbgl/style/property_value.hpp
@@ -35,9 +35,13 @@ public:
const CameraFunction<T>& asCameraFunction() const { return value.template get<CameraFunction<T>>(); }
template <typename Evaluator>
- auto evaluate(const Evaluator& evaluator) const {
+ auto evaluate(const Evaluator& evaluator, TimePoint = {}) const {
return Value::visit(value, evaluator);
}
+
+ bool hasDataDrivenPropertyDifference(const PropertyValue<T>&) const {
+ return false;
+ }
};
} // namespace style
diff --git a/include/mbgl/style/source.hpp b/include/mbgl/style/source.hpp
index 4c82e472a6..cec9619451 100644
--- a/include/mbgl/style/source.hpp
+++ b/include/mbgl/style/source.hpp
@@ -1,19 +1,25 @@
#pragma once
-#include <mbgl/util/feature.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/optional.hpp>
-#include <mbgl/util/range.hpp>
#include <mbgl/util/any.hpp>
+#include <mbgl/util/immutable.hpp>
#include <mbgl/style/types.hpp>
#include <memory>
#include <string>
-#include <vector>
namespace mbgl {
+
+class FileSource;
+
namespace style {
+class VectorSource;
+class RasterSource;
+class GeoJSONSource;
+class SourceObserver;
+
/**
* The runtime representation of a [source](https://www.mapbox.com/mapbox-gl-style-spec/#sources) from the Mapbox Style
* Specification.
@@ -49,21 +55,28 @@ public:
return is<T>() ? reinterpret_cast<const T*>(this) : nullptr;
}
- const std::string& getID() const;
+ SourceType getType() const;
+ std::string getID() const;
optional<std::string> getAttribution() const;
// Private implementation
class Impl;
- const std::unique_ptr<Impl> baseImpl;
+ Immutable<Impl> baseImpl;
+
+ Source(Immutable<Impl>);
+
+ void setObserver(SourceObserver*);
+ SourceObserver* observer = nullptr;
+
+ virtual void loadDescription(FileSource&) = 0;
+ void dumpDebugLogs() const;
+
+ bool loaded = false;
// For use in SDK bindings, which store a reference to a platform-native peer
// object here, so that separately-obtained references to this object share
// identical platform-native peers.
any peer;
-
-protected:
- const SourceType type;
- Source(SourceType, std::unique_ptr<Impl>);
};
} // namespace style
diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp
index 5b39d7821b..2dcfec51aa 100644
--- a/include/mbgl/style/sources/geojson_source.hpp
+++ b/include/mbgl/style/sources/geojson_source.hpp
@@ -5,6 +5,9 @@
#include <mbgl/util/optional.hpp>
namespace mbgl {
+
+class AsyncRequest;
+
namespace style {
struct GeoJSONOptions {
@@ -22,21 +25,26 @@ struct GeoJSONOptions {
class GeoJSONSource : public Source {
public:
GeoJSONSource(const std::string& id, const GeoJSONOptions& = {});
+ ~GeoJSONSource() final;
void setURL(const std::string& url);
void setGeoJSON(const GeoJSON&);
optional<std::string> getURL() const;
- // Private implementation
-
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+
+private:
+ optional<std::string> url;
+ std::unique_ptr<AsyncRequest> req;
};
template <>
inline bool Source::is<GeoJSONSource>() const {
- return type == SourceType::GeoJSON;
+ return getType() == SourceType::GeoJSON;
}
} // namespace style
diff --git a/include/mbgl/style/sources/image_source.hpp b/include/mbgl/style/sources/image_source.hpp
new file mode 100644
index 0000000000..009764291f
--- /dev/null
+++ b/include/mbgl/style/sources/image_source.hpp
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <mbgl/style/source.hpp>
+#include <mbgl/util/image.hpp>
+#include <mbgl/util/optional.hpp>
+
+namespace mbgl {
+class LatLng;
+class AsyncRequest;
+
+namespace style {
+
+class ImageSource : public Source {
+public:
+ ImageSource(std::string id, const std::array<LatLng, 4>);
+ ~ImageSource() override;
+
+ optional<std::string> getURL() const;
+ void setURL(const std::string& url);
+
+ void setImage(PremultipliedImage&&);
+
+ void setCoordinates(const std::array<LatLng, 4>&);
+ std::array<LatLng, 4> getCoordinates() const;
+
+ class Impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+private:
+ optional<std::string> url;
+ std::unique_ptr<AsyncRequest> req;
+};
+
+template <>
+inline bool Source::is<ImageSource>() const {
+ return getType() == SourceType::Image;
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/sources/raster_source.hpp b/include/mbgl/style/sources/raster_source.hpp
index 395f25e51d..7f23a7ca4b 100644
--- a/include/mbgl/style/sources/raster_source.hpp
+++ b/include/mbgl/style/sources/raster_source.hpp
@@ -5,23 +5,34 @@
#include <mbgl/util/variant.hpp>
namespace mbgl {
+
+class AsyncRequest;
+
namespace style {
class RasterSource : public Source {
public:
RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset, uint16_t tileSize);
+ ~RasterSource() final;
+ const variant<std::string, Tileset>& getURLOrTileset() const;
optional<std::string> getURL() const;
- // Private implementation
+ uint16_t getTileSize() const;
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+
+private:
+ const variant<std::string, Tileset> urlOrTileset;
+ std::unique_ptr<AsyncRequest> req;
};
template <>
inline bool Source::is<RasterSource>() const {
- return type == SourceType::Raster;
+ return getType() == SourceType::Raster;
}
} // namespace style
diff --git a/include/mbgl/style/sources/vector_source.hpp b/include/mbgl/style/sources/vector_source.hpp
index 8626ce160a..6f16974b40 100644
--- a/include/mbgl/style/sources/vector_source.hpp
+++ b/include/mbgl/style/sources/vector_source.hpp
@@ -5,23 +5,32 @@
#include <mbgl/util/variant.hpp>
namespace mbgl {
+
+class AsyncRequest;
+
namespace style {
class VectorSource : public Source {
public:
VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset);
+ ~VectorSource() final;
+ const variant<std::string, Tileset>& getURLOrTileset() const;
optional<std::string> getURL() const;
- // Private implementation
-
class Impl;
- Impl* const impl;
+ const Impl& impl() const;
+
+ void loadDescription(FileSource&) final;
+
+private:
+ const variant<std::string, Tileset> urlOrTileset;
+ std::unique_ptr<AsyncRequest> req;
};
template <>
inline bool Source::is<VectorSource>() const {
- return type == SourceType::Vector;
+ return getType() == SourceType::Vector;
}
} // namespace style
diff --git a/include/mbgl/style/style.hpp b/include/mbgl/style/style.hpp
new file mode 100644
index 0000000000..d6fdbd8f2c
--- /dev/null
+++ b/include/mbgl/style/style.hpp
@@ -0,0 +1,79 @@
+#pragma once
+
+#include <mbgl/style/transition_options.hpp>
+#include <mbgl/map/camera.hpp>
+#include <mbgl/util/geo.hpp>
+
+#include <string>
+#include <vector>
+#include <memory>
+
+namespace mbgl {
+
+class FileSource;
+class Scheduler;
+
+namespace style {
+
+class Light;
+class Image;
+class Source;
+class Layer;
+
+class Style {
+public:
+ Style(Scheduler&, FileSource&, float pixelRatio);
+ ~Style();
+
+ void loadJSON(const std::string&);
+ void loadURL(const std::string&);
+
+ std::string getJSON() const;
+ std::string getURL() const;
+
+ // Defaults
+ std::string getName() const;
+ CameraOptions getDefaultCamera() const;
+
+ // TransitionOptions
+ TransitionOptions getTransitionOptions() const;
+ void setTransitionOptions(const TransitionOptions&);
+
+ // Light
+ Light* getLight();
+ const Light* getLight() const;
+
+ void setLight(std::unique_ptr<Light>);
+
+ // Images
+ const Image* getImage(const std::string&) const;
+ void addImage(std::unique_ptr<Image>);
+ void removeImage(const std::string&);
+
+ // Sources
+ std::vector< Source*> getSources();
+ std::vector<const Source*> getSources() const;
+
+ Source* getSource(const std::string&);
+ const Source* getSource(const std::string&) const;
+
+ void addSource(std::unique_ptr<Source>);
+ std::unique_ptr<Source> removeSource(const std::string& sourceID);
+
+ // Layers
+ std::vector< Layer*> getLayers();
+ std::vector<const Layer*> getLayers() const;
+
+ Layer* getLayer(const std::string&);
+ const Layer* getLayer(const std::string&) const;
+
+ void addLayer(std::unique_ptr<Layer>, const optional<std::string>& beforeLayerID = {});
+ std::unique_ptr<Layer> removeLayer(const std::string& layerID);
+
+ // Private implementation
+ class Impl;
+ const std::unique_ptr<Impl> impl;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/transition_options.hpp b/include/mbgl/style/transition_options.hpp
index 1583667025..87a81717a0 100644
--- a/include/mbgl/style/transition_options.hpp
+++ b/include/mbgl/style/transition_options.hpp
@@ -8,8 +8,13 @@ namespace style {
class TransitionOptions {
public:
- optional<Duration> duration = {};
- optional<Duration> delay = {};
+ optional<Duration> duration;
+ optional<Duration> delay;
+
+ TransitionOptions(optional<Duration> duration_ = {},
+ optional<Duration> delay_ = {})
+ : duration(std::move(duration_)),
+ delay(std::move(delay_)) {}
TransitionOptions reverseMerge(const TransitionOptions& defaults) const {
return {
diff --git a/include/mbgl/style/types.hpp b/include/mbgl/style/types.hpp
index e0436efb67..ec7358de8c 100644
--- a/include/mbgl/style/types.hpp
+++ b/include/mbgl/style/types.hpp
@@ -10,7 +10,8 @@ enum class SourceType : uint8_t {
Raster,
GeoJSON,
Video,
- Annotations
+ Annotations,
+ Image
};
namespace style {
@@ -67,7 +68,7 @@ enum class TextJustifyType : uint8_t {
Right
};
-enum class TextAnchorType : uint8_t {
+enum class SymbolAnchorType : uint8_t {
Center,
Left,
Right,
diff --git a/include/mbgl/tile/tile_id.hpp b/include/mbgl/tile/tile_id.hpp
new file mode 100644
index 0000000000..0457dd3a07
--- /dev/null
+++ b/include/mbgl/tile/tile_id.hpp
@@ -0,0 +1,263 @@
+#pragma once
+
+#include <mbgl/util/constants.hpp>
+
+#include <cstdint>
+#include <array>
+#include <tuple>
+#include <forward_list>
+#include <algorithm>
+#include <iosfwd>
+#include <cassert>
+
+namespace mbgl {
+
+class OverscaledTileID;
+class CanonicalTileID;
+class UnwrappedTileID;
+
+// Has integer z/x/y coordinates
+// All tiles must be derived from 0/0/0 (=no tiles outside of the main tile pyramid)
+// Used for requesting data; represents data tiles that exist out there.
+// z is never larger than the source's maxzoom
+class CanonicalTileID {
+public:
+ CanonicalTileID(uint8_t z, uint32_t x, uint32_t y);
+ bool operator==(const CanonicalTileID&) const;
+ bool operator!=(const CanonicalTileID&) const;
+ bool operator<(const CanonicalTileID&) const;
+ bool isChildOf(const CanonicalTileID&) const;
+ CanonicalTileID scaledTo(uint8_t z) const;
+ std::array<CanonicalTileID, 4> children() const;
+
+ const uint8_t z;
+ const uint32_t x;
+ const uint32_t y;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const CanonicalTileID& rhs);
+namespace util {
+std::string toString(const CanonicalTileID&);
+} // namespace util
+
+// Has integer z/x/y coordinates
+// overscaledZ describes the zoom level this tile is intented to represent, e.g. when parsing data
+// z is never larger than the source's maxzoom
+// z/x/y describe the
+class OverscaledTileID {
+public:
+ OverscaledTileID(uint8_t overscaledZ, int16_t wrap, CanonicalTileID);
+ OverscaledTileID(uint8_t overscaledZ, int16_t wrap, uint8_t z, uint32_t x, uint32_t y);
+ OverscaledTileID(uint8_t z, uint32_t x, uint32_t y);
+ explicit OverscaledTileID(const CanonicalTileID&);
+ explicit OverscaledTileID(CanonicalTileID&&);
+ bool operator==(const OverscaledTileID&) const;
+ bool operator!=(const OverscaledTileID&) const;
+ bool operator<(const OverscaledTileID&) const;
+ bool isChildOf(const OverscaledTileID&) const;
+ uint32_t overscaleFactor() const;
+ OverscaledTileID scaledTo(uint8_t z) const;
+ UnwrappedTileID toUnwrapped() const;
+
+ const uint8_t overscaledZ;
+ const int16_t wrap;
+ const CanonicalTileID canonical;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const OverscaledTileID& rhs);
+namespace util {
+std::string toString(const OverscaledTileID&);
+} // namespace util
+
+// Has integer z/x/y coordinates
+// wrap describes tiles that are left/right of the main tile pyramid, e.g. when wrapping the world
+// Used for describing what position tiles are getting rendered at (= calc the matrix)
+// z is never larger than the source's maxzoom
+class UnwrappedTileID {
+public:
+ UnwrappedTileID(uint8_t z, int64_t x, int64_t y);
+ UnwrappedTileID(int16_t wrap, CanonicalTileID);
+ bool operator==(const UnwrappedTileID&) const;
+ bool operator!=(const UnwrappedTileID&) const;
+ bool operator<(const UnwrappedTileID&) const;
+ bool isChildOf(const UnwrappedTileID&) const;
+ std::array<UnwrappedTileID, 4> children() const;
+ OverscaledTileID overscaleTo(uint8_t z) const;
+ float pixelsToTileUnits(float pixelValue, float zoom) const;
+
+ const int16_t wrap;
+ const CanonicalTileID canonical;
+};
+
+::std::ostream& operator<<(::std::ostream& os, const UnwrappedTileID& rhs);
+namespace util {
+std::string toString(const UnwrappedTileID&);
+} // namespace util
+
+inline CanonicalTileID::CanonicalTileID(uint8_t z_, uint32_t x_, uint32_t y_) : z(z_), x(x_), y(y_) {
+ assert(z <= 32);
+ assert(x < (1ull << z));
+ assert(y < (1ull << z));
+}
+
+inline bool CanonicalTileID::operator==(const CanonicalTileID& rhs) const {
+ return z == rhs.z && x == rhs.x && y == rhs.y;
+}
+
+inline bool CanonicalTileID::operator!=(const CanonicalTileID& rhs) const {
+ return z != rhs.z || x != rhs.x || y != rhs.y;
+}
+
+inline bool CanonicalTileID::operator<(const CanonicalTileID& rhs) const {
+ return std::tie(z, x, y) < std::tie(rhs.z, rhs.x, rhs.y);
+}
+
+inline bool CanonicalTileID::isChildOf(const CanonicalTileID& parent) const {
+ // We're first testing for z == 0, to avoid a 32 bit shift, which is undefined.
+ return parent.z == 0 ||
+ (parent.z < z && parent.x == (x >> (z - parent.z)) && parent.y == (y >> (z - parent.z)));
+}
+
+inline CanonicalTileID CanonicalTileID::scaledTo(uint8_t targetZ) const {
+ if (targetZ <= z) {
+ return { targetZ, x >> (z - targetZ), y >> (z - targetZ) }; // parent or same
+ } else {
+ return { targetZ, x << (targetZ - z), y << (targetZ - z) }; // child
+ }
+}
+
+inline std::array<CanonicalTileID, 4> CanonicalTileID::children() const {
+ const uint8_t childZ = z + 1;
+ const uint32_t childX = x * 2;
+ const uint32_t childY = y * 2;
+ return { {
+ { childZ, childX, childY },
+ { childZ, childX, childY + 1 },
+ { childZ, childX + 1, childY },
+ { childZ, childX + 1, childY + 1 },
+ } };
+}
+
+inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, int16_t wrap_, CanonicalTileID canonical_)
+ : overscaledZ(overscaledZ_), wrap(wrap_), canonical(std::move(canonical_)) {
+ assert(overscaledZ >= canonical.z);
+}
+
+inline OverscaledTileID::OverscaledTileID(uint8_t overscaledZ_, int16_t wrap_, uint8_t z, uint32_t x, uint32_t y)
+ : overscaledZ(overscaledZ_), wrap(wrap_), canonical(z, x, y) {
+ assert(overscaledZ >= canonical.z);
+}
+
+inline OverscaledTileID::OverscaledTileID(uint8_t z, uint32_t x, uint32_t y)
+ : overscaledZ(z), wrap(0), canonical(z, x, y) {
+}
+
+inline OverscaledTileID::OverscaledTileID(const CanonicalTileID& canonical_)
+ : overscaledZ(canonical_.z), wrap(0), canonical(canonical_) {
+ assert(overscaledZ >= canonical.z);
+}
+
+inline OverscaledTileID::OverscaledTileID(CanonicalTileID&& canonical_)
+ : overscaledZ(canonical_.z), wrap(0), canonical(std::forward<CanonicalTileID>(canonical_)) {
+ assert(overscaledZ >= canonical.z);
+}
+
+inline bool OverscaledTileID::operator==(const OverscaledTileID& rhs) const {
+ return overscaledZ == rhs.overscaledZ && wrap == rhs.wrap &&canonical == rhs.canonical;
+}
+
+inline bool OverscaledTileID::operator!=(const OverscaledTileID& rhs) const {
+ return overscaledZ != rhs.overscaledZ || wrap != rhs.wrap || canonical != rhs.canonical;
+}
+
+inline bool OverscaledTileID::operator<(const OverscaledTileID& rhs) const {
+ return std::tie(overscaledZ, wrap, canonical) < std::tie(rhs.overscaledZ, rhs.wrap, rhs.canonical);
+}
+
+inline uint32_t OverscaledTileID::overscaleFactor() const {
+ return 1u << (overscaledZ - canonical.z);
+}
+
+inline bool OverscaledTileID::isChildOf(const OverscaledTileID& rhs) const {
+ return overscaledZ > rhs.overscaledZ &&
+ (canonical == rhs.canonical || canonical.isChildOf(rhs.canonical));
+}
+
+inline OverscaledTileID OverscaledTileID::scaledTo(uint8_t z) const {
+ return { z, wrap, z >= canonical.z ? canonical : canonical.scaledTo(z) };
+}
+
+inline UnwrappedTileID OverscaledTileID::toUnwrapped() const {
+ return { wrap, canonical };
+}
+
+inline UnwrappedTileID::UnwrappedTileID(uint8_t z_, int64_t x_, int64_t y_)
+ : wrap((x_ < 0 ? x_ - (1ll << z_) + 1 : x_) / (1ll << z_)),
+ canonical(
+ z_,
+ static_cast<uint32_t>(x_ - wrap * (1ll << z_)),
+ y_ < 0 ? 0 : std::min(static_cast<uint32_t>(y_), static_cast<uint32_t>(1ull << z_) - 1)) {
+}
+
+inline UnwrappedTileID::UnwrappedTileID(int16_t wrap_, CanonicalTileID canonical_)
+ : wrap(wrap_), canonical(std::move(canonical_)) {
+}
+
+inline bool UnwrappedTileID::operator==(const UnwrappedTileID& rhs) const {
+ return wrap == rhs.wrap && canonical == rhs.canonical;
+}
+
+inline bool UnwrappedTileID::operator!=(const UnwrappedTileID& rhs) const {
+ return wrap != rhs.wrap || canonical != rhs.canonical;
+}
+
+inline bool UnwrappedTileID::operator<(const UnwrappedTileID& rhs) const {
+ return std::tie(wrap, canonical) < std::tie(rhs.wrap, rhs.canonical);
+}
+
+inline bool UnwrappedTileID::isChildOf(const UnwrappedTileID& parent) const {
+ return wrap == parent.wrap && canonical.isChildOf(parent.canonical);
+}
+
+inline std::array<UnwrappedTileID, 4> UnwrappedTileID::children() const {
+ const uint8_t childZ = canonical.z + 1;
+ const uint32_t childX = canonical.x * 2;
+ const uint32_t childY = canonical.y * 2;
+ return { {
+ { wrap, { childZ, childX, childY } },
+ { wrap, { childZ, childX, childY + 1 } },
+ { wrap, { childZ, childX + 1, childY } },
+ { wrap, { childZ, childX + 1, childY + 1 } },
+ } };
+}
+
+inline OverscaledTileID UnwrappedTileID::overscaleTo(const uint8_t overscaledZ) const {
+ assert(overscaledZ >= canonical.z);
+ return { overscaledZ, wrap, canonical };
+}
+
+inline float UnwrappedTileID::pixelsToTileUnits(const float pixelValue, const float zoom) const {
+ return pixelValue * (util::EXTENT / (util::tileSize * std::pow(2, zoom - canonical.z)));
+}
+
+} // namespace mbgl
+
+namespace std {
+
+template <>
+struct hash<mbgl::CanonicalTileID> {
+ size_t operator()(const mbgl::CanonicalTileID& id) const;
+};
+
+template <>
+struct hash<mbgl::UnwrappedTileID> {
+ size_t operator()(const mbgl::UnwrappedTileID& id) const;
+};
+
+template <>
+struct hash<mbgl::OverscaledTileID> {
+ size_t operator()(const mbgl::OverscaledTileID& id) const;
+};
+
+} // namespace std
+
diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp
index dbc4bddde5..d5e55065c4 100644
--- a/include/mbgl/util/constants.hpp
+++ b/include/mbgl/util/constants.hpp
@@ -38,10 +38,13 @@ constexpr double MIN_ZOOM = 0.0;
constexpr double MAX_ZOOM = 25.5;
constexpr float MIN_ZOOM_F = MIN_ZOOM;
constexpr float MAX_ZOOM_F = MAX_ZOOM;
+constexpr uint8_t DEFAULT_MAX_ZOOM = 22;
+
+constexpr uint8_t DEFAULT_PREFETCH_ZOOM_DELTA = 4;
constexpr uint64_t DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024;
-constexpr Duration DEFAULT_FADE_DURATION = Milliseconds(300);
+constexpr Duration DEFAULT_TRANSITION_DURATION = Milliseconds(300);
constexpr Seconds CLOCK_SKEW_RETRY_TIMEOUT { 30 };
constexpr UnitBezier DEFAULT_TRANSITION_EASE = { 0, 0, 0.25, 1 };
@@ -58,7 +61,6 @@ extern const bool tileParseWarnings;
extern const bool styleParseWarnings;
extern const bool spriteWarnings;
extern const bool renderWarnings;
-extern const bool renderTree;
extern const bool labelTextMissingWarning;
extern const bool missingFontStackWarning;
extern const bool missingFontFaceWarning;
diff --git a/include/mbgl/util/convert.hpp b/include/mbgl/util/convert.hpp
index c2b3d9950d..02ec7feef9 100644
--- a/include/mbgl/util/convert.hpp
+++ b/include/mbgl/util/convert.hpp
@@ -1,3 +1,5 @@
+#include <mbgl/util/util.hpp>
+
#include <array>
#include <type_traits>
#include <utility>
@@ -7,8 +9,8 @@ namespace util {
template<typename To, typename From, std::size_t Size,
typename = std::enable_if_t<std::is_convertible<From, To>::value>>
-constexpr std::array<To, Size> convert(const std::array<From, Size>&from) {
- std::array<To, Size> to {};
+MBGL_CONSTEXPR std::array<To, Size> convert(const std::array<From, Size>&from) {
+ std::array<To, Size> to {{}};
std::copy(std::begin(from), std::end(from), std::begin(to));
return to;
}
diff --git a/include/mbgl/util/image.hpp b/include/mbgl/util/image.hpp
index a41b8462bd..4887058f79 100644
--- a/include/mbgl/util/image.hpp
+++ b/include/mbgl/util/image.hpp
@@ -5,6 +5,7 @@
#include <mbgl/util/size.hpp>
#include <string>
+#include <cstring>
#include <memory>
#include <algorithm>
@@ -66,9 +67,9 @@ public:
template <typename T = Image>
T clone() const {
- T copy(size);
- std::copy(data.get(), data.get() + bytes(), copy.data.get());
- return copy;
+ T copy_(size);
+ std::copy(data.get(), data.get() + bytes(), copy_.data.get());
+ return copy_;
}
size_t stride() const { return channels * size.width; }
@@ -78,10 +79,52 @@ public:
std::fill(data.get(), data.get() + bytes(), value);
}
+ void resize(Size size_) {
+ if (size == size_) {
+ return;
+ }
+ Image newImage(size_);
+ newImage.fill(0);
+ copy(*this, newImage, {0, 0}, {0, 0}, {
+ std::min(size.width, size_.width),
+ std::min(size.height, size_.height)
+ });
+ operator=(std::move(newImage));
+ }
+
+ // Clears the rect area specified by `pt` and `size` from `dstImage`.
+ static void clear(Image& dstImg, const Point<uint32_t>& pt, const Size& size) {
+ if (size.isEmpty()) {
+ return;
+ }
+
+ if (!dstImg.valid()) {
+ throw std::invalid_argument("invalid destination for image clear");
+ }
+
+ if (size.width > dstImg.size.width ||
+ size.height > dstImg.size.height ||
+ pt.x > dstImg.size.width - size.width ||
+ pt.y > dstImg.size.height - size.height) {
+ throw std::out_of_range("out of range destination coordinates for image clear");
+ }
+
+ uint8_t* dstData = dstImg.data.get();
+
+ for (uint32_t y = 0; y < size.height; y++) {
+ const std::size_t dstOffset = (pt.y + y) * dstImg.stride() + pt.x * channels;
+ std::memset(dstData + dstOffset, 0, size.width * channels);
+ }
+ }
+
// Copy image data within `rect` from `src` to the rectangle of the same size at `pt`
// in `dst`. If the specified bounds exceed the bounds of the source or destination,
// throw `std::out_of_range`. Must not be used to move data within a single Image.
static void copy(const Image& srcImg, Image& dstImg, const Point<uint32_t>& srcPt, const Point<uint32_t>& dstPt, const Size& size) {
+ if (size.isEmpty()) {
+ return;
+ }
+
if (!srcImg.valid()) {
throw std::invalid_argument("invalid source for image copy");
}
diff --git a/include/mbgl/util/immutable.hpp b/include/mbgl/util/immutable.hpp
new file mode 100644
index 0000000000..eb26c0d282
--- /dev/null
+++ b/include/mbgl/util/immutable.hpp
@@ -0,0 +1,133 @@
+#pragma once
+
+#include <memory>
+
+namespace mbgl {
+
+/**
+ * `Mutable<T>` is a non-nullable uniquely owning reference to a `T`. It can be efficiently converted
+ * to `Immutable<T>`.
+ *
+ * The lifecycle of `Mutable<T>` and `Immutable<T>` is as follows:
+ *
+ * 1. Create a `Mutable<T>` using `makeMutable(...)`
+ * 2. Mutate it freely
+ * 3. When you're ready to freeze its state and enable safe cross-thread sharing, move assign or
+ * move construct it to `Immutable<T>`
+ *
+ * The reason that `Mutable<T>` exists, rather than simply using a `std::unique_ptr<T>`, is to take advantage
+ * of the underlying single-allocation optimization provided by `std::make_shared`.
+ */
+template <class T>
+class Mutable {
+public:
+ Mutable(Mutable&&) = default;
+ Mutable& operator=(Mutable&&) = default;
+
+ Mutable(const Mutable&) = delete;
+ Mutable& operator=(const Mutable&) = delete;
+
+ T* get() { return ptr.get(); }
+ T* operator->() { return ptr.get(); }
+ T& operator*() { return *ptr; }
+
+private:
+ Mutable(std::shared_ptr<T>&& s)
+ : ptr(std::move(s)) {}
+
+ std::shared_ptr<T> ptr;
+
+ template <class S> friend class Immutable;
+ template <class S, class... Args> friend Mutable<S> makeMutable(Args&&...);
+};
+
+template <class T, class... Args>
+Mutable<T> makeMutable(Args&&... args) {
+ return Mutable<T>(std::make_shared<T>(std::forward<Args>(args)...));
+}
+
+/**
+ * `Immutable<T>` is a non-nullable shared reference to a `const T`. Construction requires
+ * a transfer of unique ownership from a `Mutable<T>`; once constructed it has the same behavior
+ * as `std::shared_ptr<const T>` but with better indication of intent.
+ *
+ * Normally one should not share state between threads because it's difficult to verify the
+ * absence of read/write data races. `Immutable` provides a guarantee that no writes are
+ * possible, and instances therefore can be freely transferred and shared between threads.
+ */
+template <class T>
+class Immutable {
+public:
+ template <class S>
+ Immutable(Mutable<S>&& s)
+ : ptr(std::const_pointer_cast<const S>(std::move(s.ptr))) {}
+
+ template <class S>
+ Immutable(Immutable<S>&& s)
+ : ptr(std::move(s.ptr)) {}
+
+ template <class S>
+ Immutable(const Immutable<S>& s)
+ : ptr(s.ptr) {}
+
+ template <class S>
+ Immutable& operator=(Mutable<S>&& s) {
+ ptr = std::const_pointer_cast<const S>(std::move(s.ptr));
+ return *this;
+ }
+
+ template <class S>
+ Immutable& operator=(Immutable<S>&& s) {
+ ptr = std::move(s.ptr);
+ return *this;
+ }
+
+ template <class S>
+ Immutable& operator=(const Immutable<S>& s) {
+ ptr = s.ptr;
+ return *this;
+ }
+
+ const T* get() const { return ptr.get(); }
+ const T* operator->() const { return ptr.get(); }
+ const T& operator*() const { return *ptr; }
+
+ friend bool operator==(const Immutable<T>& lhs, const Immutable<T>& rhs) {
+ return lhs.ptr == rhs.ptr;
+ }
+
+ friend bool operator!=(const Immutable<T>& lhs, const Immutable<T>& rhs) {
+ return lhs.ptr != rhs.ptr;
+ }
+
+private:
+ Immutable(std::shared_ptr<const T>&& s)
+ : ptr(std::move(s)) {}
+
+ std::shared_ptr<const T> ptr;
+
+ template <class S> friend class Immutable;
+ template <class S, class U> friend Immutable<S> staticImmutableCast(const Immutable<U>&);
+};
+
+template <class S, class U>
+Immutable<S> staticImmutableCast(const Immutable<U>& u) {
+ return Immutable<S>(std::static_pointer_cast<const S>(u.ptr));
+}
+
+/**
+ * Constrained mutation of an immutable reference. Makes a temporarily-mutable copy of the
+ * input Immutable using the inner type's copy constructor, runs the given callable on the
+ * mutable copy, and then freezes the copy and reassigns it to the input reference.
+ *
+ * Note that other Immutables referring to the same inner instance are not affected; they
+ * continue to referencing the original immutable instance.
+ */
+template <class T, class Fn>
+void mutate(Immutable<T>& immutable, Fn&& fn) {
+ Mutable<T> mut = makeMutable<T>(*immutable);
+ std::forward<Fn>(fn)(*mut);
+ immutable = std::move(mut);
+}
+
+} // namespace mbgl
diff --git a/include/mbgl/util/indexed_tuple.hpp b/include/mbgl/util/indexed_tuple.hpp
index a414639530..fd0b931d36 100644
--- a/include/mbgl/util/indexed_tuple.hpp
+++ b/include/mbgl/util/indexed_tuple.hpp
@@ -31,16 +31,13 @@ public:
using std::tuple<Ts...>::tuple;
template <class I>
- static constexpr std::size_t Index = TypeIndex<I, Is...>::value;
-
- template <class I>
auto& get() {
- return std::get<Index<I>>(*this);
+ return std::get<TypeIndex<I, Is...>::value>(*this);
}
template <class I>
const auto& get() const {
- return std::get<Index<I>>(*this);
+ return std::get<TypeIndex<I, Is...>::value>(*this);
}
template <class... Js, class... Us>
diff --git a/include/mbgl/util/interpolate.hpp b/include/mbgl/util/interpolate.hpp
index a2103f18b2..6738987598 100644
--- a/include/mbgl/util/interpolate.hpp
+++ b/include/mbgl/util/interpolate.hpp
@@ -95,7 +95,11 @@ struct Interpolator<std::vector<T>>
: Uninterpolated {};
template <class T>
-constexpr bool Interpolatable = !std::is_base_of<Uninterpolated, Interpolator<T>>::value;
+struct Interpolatable
+ : std::conditional_t<
+ !std::is_base_of<Uninterpolated, Interpolator<T>>::value,
+ std::true_type,
+ std::false_type> {};
} // namespace util
} // namespace mbgl
diff --git a/include/mbgl/util/noncopyable.hpp b/include/mbgl/util/noncopyable.hpp
index 105a76a9a0..8cb7e198d9 100644
--- a/include/mbgl/util/noncopyable.hpp
+++ b/include/mbgl/util/noncopyable.hpp
@@ -7,15 +7,17 @@ namespace non_copyable_
class noncopyable
{
+public:
+ noncopyable( noncopyable const& ) = delete;
+ noncopyable& operator=(noncopyable const& ) = delete;
+
protected:
constexpr noncopyable() = default;
~noncopyable() = default;
- noncopyable( noncopyable const& ) = delete;
- noncopyable& operator=(noncopyable const& ) = delete;
};
} // namespace non_copyable_
-typedef non_copyable_::noncopyable noncopyable;
+using noncopyable = non_copyable_::noncopyable;
} // namespace util
} // namespace mbgl
diff --git a/include/mbgl/util/projection.hpp b/include/mbgl/util/projection.hpp
index 3cc1146513..f64502c5bc 100644
--- a/include/mbgl/util/projection.hpp
+++ b/include/mbgl/util/projection.hpp
@@ -75,10 +75,7 @@ public:
}
static Point<double> project(const LatLng& latLng, double scale) {
- return Point<double> {
- util::LONGITUDE_MAX + latLng.longitude(),
- util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + latLng.latitude() * M_PI / util::DEGREES_MAX))
- } * worldSize(scale) / util::DEGREES_MAX;
+ return project_(latLng, worldSize(scale));
}
static LatLng unproject(const Point<double>& p, double scale, LatLng::WrapMode wrapMode = LatLng::Unwrapped) {
@@ -89,6 +86,23 @@ public:
wrapMode
};
}
+
+ // Project lat, lon to point in a zoom-dependent world size
+ static Point<double> project(const LatLng& point, uint8_t zoom, uint16_t tileSize) {
+ const double t2z = tileSize * std::pow(2, zoom);
+ Point<double> pt = project_(point, t2z);
+ // Flip y coordinate
+ auto x = std::round(std::min(pt.x, t2z));
+ auto y = std::round(std::min(t2z - pt.y, t2z));
+ return { x, y };
+ }
+private:
+ static Point<double> project_(const LatLng& latLng, double worldSize) {
+ return Point<double> {
+ util::LONGITUDE_MAX + latLng.longitude(),
+ util::LONGITUDE_MAX - util::RAD2DEG * std::log(std::tan(M_PI / 4 + latLng.latitude() * M_PI / util::DEGREES_MAX))
+ } * worldSize / util::DEGREES_MAX;
+ }
};
} // namespace mbgl
diff --git a/include/mbgl/util/range.hpp b/include/mbgl/util/range.hpp
index f7fa92eb8b..5591a22a1f 100644
--- a/include/mbgl/util/range.hpp
+++ b/include/mbgl/util/range.hpp
@@ -1,3 +1,5 @@
+#include <utility>
+
#pragma once
namespace mbgl {
@@ -5,8 +7,8 @@ namespace mbgl {
template <class T>
class Range {
public:
- constexpr Range(const T& min_, const T& max_)
- : min(min_), max(max_) {}
+ constexpr Range(T min_, T max_)
+ : min(std::move(min_)), max(std::move(max_)) {}
T min;
T max;
diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp
index 5236850d83..acbea80273 100644
--- a/include/mbgl/util/run_loop.hpp
+++ b/include/mbgl/util/run_loop.hpp
@@ -16,7 +16,7 @@
namespace mbgl {
namespace util {
-typedef void * LOOP_HANDLE;
+using LOOP_HANDLE = void *;
class RunLoop : public Scheduler,
private util::noncopyable {
@@ -62,14 +62,11 @@ public:
push(task);
return std::make_unique<WorkRequest>(task);
}
-
- // Invoke fn(args...) on this RunLoop, then invoke callback(results...) on the current RunLoop.
- template <class Fn, class... Args>
- std::unique_ptr<AsyncRequest>
- invokeWithCallback(Fn&& fn, Args&&... args) {
- std::shared_ptr<WorkTask> task = WorkTask::makeWithCallback(std::forward<Fn>(fn), std::forward<Args>(args)...);
- push(task);
- return std::make_unique<WorkRequest>(task);
+
+ void schedule(std::weak_ptr<Mailbox> mailbox) override {
+ invoke([mailbox] () {
+ Mailbox::maybeReceive(mailbox);
+ });
}
class Impl;
@@ -81,12 +78,6 @@ private:
void push(std::shared_ptr<WorkTask>);
- void schedule(std::weak_ptr<Mailbox> mailbox) override {
- invoke([mailbox] () {
- Mailbox::maybeReceive(mailbox);
- });
- }
-
void withMutex(std::function<void()>&& fn) {
std::lock_guard<std::mutex> lock(mutex);
fn();
diff --git a/include/mbgl/util/size.hpp b/include/mbgl/util/size.hpp
index 45c303969c..12c0ad056b 100644
--- a/include/mbgl/util/size.hpp
+++ b/include/mbgl/util/size.hpp
@@ -15,6 +15,10 @@ public:
constexpr uint32_t area() const {
return width * height;
}
+
+ constexpr float aspectRatio() const {
+ return static_cast<float>(width) / static_cast<float>(height);
+ }
constexpr bool isEmpty() const {
return width == 0 || height == 0;
diff --git a/include/mbgl/util/string.hpp b/include/mbgl/util/string.hpp
index de061647b5..82d317c620 100644
--- a/include/mbgl/util/string.hpp
+++ b/include/mbgl/util/string.hpp
@@ -1,9 +1,34 @@
#pragma once
+#include <sstream>
#include <string>
#include <cassert>
+#include <cstdlib>
#include <exception>
+// Polyfill needed by Qt when building for Android with GCC
+#if defined(__ANDROID__) && defined(__GLIBCXX__)
+
+namespace std {
+
+template <typename T>
+std::string to_string(T value)
+{
+ std::ostringstream oss;
+ oss << value;
+
+ return oss.str();
+}
+
+inline int stoi(const std::string &str)
+{
+ return atoi(str.c_str());
+}
+
+} // namespace std
+
+#endif
+
namespace mbgl {
namespace util {
diff --git a/include/mbgl/util/thread.hpp b/include/mbgl/util/thread.hpp
new file mode 100644
index 0000000000..672eebf6db
--- /dev/null
+++ b/include/mbgl/util/thread.hpp
@@ -0,0 +1,161 @@
+#pragma once
+
+#include <mbgl/actor/actor.hpp>
+#include <mbgl/actor/mailbox.hpp>
+#include <mbgl/actor/scheduler.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/util.hpp>
+
+#include <cassert>
+#include <future>
+#include <memory>
+#include <mutex>
+#include <queue>
+#include <string>
+#include <thread>
+#include <utility>
+
+namespace mbgl {
+namespace util {
+
+// Manages a thread with `Object`.
+
+// Upon creation of this object, it launches a thread and creates an object of type `Object`
+// in that thread. When the `Thread<>` object is destructed, the destructor waits
+// for thread termination. The `Thread<>` constructor blocks until the thread and
+// the `Object` are fully created, so after the object creation, it's safe to obtain the
+// `Object` stored in this thread. The thread created will always have low priority on
+// the platforms that support setting thread priority.
+//
+// The following properties make this class different from `ThreadPool`:
+//
+// - Only one thread is created.
+// - `Object` will live in a single thread, providing thread affinity.
+// - It is safe to use `ThreadLocal` in an `Object` managed by `Thread<>`
+// - A `RunLoop` is created for the `Object` thread.
+// - `Object` can use `Timer` and do asynchronous I/O, like wait for sockets events.
+//
+template<class Object>
+class Thread : public Scheduler {
+public:
+ template <class... Args>
+ Thread(const std::string& name, Args&&... args) {
+ std::promise<void> running;
+
+ thread = std::thread([&] {
+ platform::setCurrentThreadName(name);
+ platform::makeThreadLowPriority();
+
+ util::RunLoop loop_(util::RunLoop::Type::New);
+ loop = &loop_;
+
+ object = std::make_unique<Actor<Object>>(*this, std::forward<Args>(args)...);
+ running.set_value();
+
+ loop->run();
+ loop = nullptr;
+ });
+
+ running.get_future().get();
+ }
+
+ ~Thread() override {
+ if (paused) {
+ resume();
+ }
+
+ std::promise<void> joinable;
+
+ // Kill the actor, so we don't get more
+ // messages posted on this scheduler after
+ // we delete the RunLoop.
+ loop->invoke([&] {
+ object.reset();
+ joinable.set_value();
+ });
+
+ joinable.get_future().get();
+
+ loop->stop();
+ thread.join();
+ }
+
+ // Returns a non-owning reference to `Object` that
+ // can be used to send messages to `Object`. It is safe
+ // to the non-owning reference to outlive this object
+ // and be used after the `Thread<>` gets destroyed.
+ ActorRef<std::decay_t<Object>> actor() const {
+ return object->self();
+ }
+
+ // Pauses the `Object` thread. It will prevent the object to wake
+ // up from events such as timers and file descriptor I/O. Messages
+ // sent to a paused `Object` will be queued and only processed after
+ // `resume()` is called.
+ void pause() {
+ MBGL_VERIFY_THREAD(tid);
+
+ assert(!paused);
+
+ paused = std::make_unique<std::promise<void>>();
+ resumed = std::make_unique<std::promise<void>>();
+
+ auto pausing = paused->get_future();
+
+ loop->invoke([this] {
+ auto resuming = resumed->get_future();
+ paused->set_value();
+ resuming.get();
+ });
+
+ pausing.get();
+ }
+
+ // Resumes the `Object` thread previously paused by `pause()`.
+ void resume() {
+ MBGL_VERIFY_THREAD(tid);
+
+ assert(paused);
+
+ resumed->set_value();
+
+ resumed.reset();
+ paused.reset();
+ }
+
+private:
+ MBGL_STORE_THREAD(tid);
+
+ void schedule(std::weak_ptr<Mailbox> mailbox) override {
+ {
+ std::lock_guard<std::mutex> lock(mutex);
+ queue.push(mailbox);
+ }
+
+ loop->invoke([this] { receive(); });
+ }
+
+ void receive() {
+ std::unique_lock<std::mutex> lock(mutex);
+
+ auto mailbox = queue.front();
+ queue.pop();
+ lock.unlock();
+
+ Mailbox::maybeReceive(mailbox);
+ }
+
+ std::mutex mutex;
+ std::queue<std::weak_ptr<Mailbox>> queue;
+ std::thread thread;
+ std::unique_ptr<Actor<Object>> object;
+
+ std::unique_ptr<std::promise<void>> paused;
+ std::unique_ptr<std::promise<void>> resumed;
+
+ util::RunLoop* loop = nullptr;
+};
+
+} // namespace util
+} // namespace mbgl
diff --git a/include/mbgl/util/tileset.hpp b/include/mbgl/util/tileset.hpp
index 1f28a5039a..61aa47d4ea 100644
--- a/include/mbgl/util/tileset.hpp
+++ b/include/mbgl/util/tileset.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <mbgl/util/range.hpp>
+#include <mbgl/util/constants.hpp>
#include <vector>
#include <string>
@@ -13,11 +14,25 @@ public:
enum class Scheme : bool { XYZ, TMS };
std::vector<std::string> tiles;
- Range<uint8_t> zoomRange { 0, 22 };
+ Range<uint8_t> zoomRange;
std::string attribution;
- Scheme scheme = Scheme::XYZ;
+ Scheme scheme;
+
+ Tileset(std::vector<std::string> tiles_ = std::vector<std::string>(),
+ Range<uint8_t> zoomRange_ = { 0, util::DEFAULT_MAX_ZOOM },
+ std::string attribution_ = {},
+ Scheme scheme_ = Scheme::XYZ)
+ : tiles(std::move(tiles_)),
+ zoomRange(std::move(zoomRange_)),
+ attribution(std::move(attribution_)),
+ scheme(scheme_) {}
// TileJSON also includes center, zoom, and bounds, but they are not used by mbgl.
+
+ friend bool operator==(const Tileset& lhs, const Tileset& rhs) {
+ return std::tie(lhs.tiles, lhs.zoomRange, lhs.attribution, lhs.scheme)
+ == std::tie(rhs.tiles, rhs.zoomRange, rhs.attribution, rhs.scheme);
+ }
};
} // namespace mbgl
diff --git a/include/mbgl/util/unitbezier.hpp b/include/mbgl/util/unitbezier.hpp
index 3a4994917b..6e644e2d1f 100644
--- a/include/mbgl/util/unitbezier.hpp
+++ b/include/mbgl/util/unitbezier.hpp
@@ -34,11 +34,11 @@ struct UnitBezier {
// Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1).
constexpr UnitBezier(double p1x, double p1y, double p2x, double p2y)
: cx(3.0 * p1x)
- , bx(3.0 * (p2x - p1x) - cx)
- , ax(1.0 - cx - bx)
+ , bx(3.0 * (p2x - p1x) - (3.0 * p1x))
+ , ax(1.0 - (3.0 * p1x) - (3.0 * (p2x - p1x) - (3.0 * p1x)))
, cy(3.0 * p1y)
- , by(3.0 * (p2y - p1y) - cy)
- , ay(1.0 - cy - by) {
+ , by(3.0 * (p2y - p1y) - (3.0 * p1y))
+ , ay(1.0 - (3.0 * p1y) - (3.0 * (p2y - p1y) - (3.0 * p1y))) {
}
double sampleCurveX(double t) const {
diff --git a/include/mbgl/util/util.hpp b/include/mbgl/util/util.hpp
index c5a7cb3780..7960b40299 100644
--- a/include/mbgl/util/util.hpp
+++ b/include/mbgl/util/util.hpp
@@ -12,3 +12,10 @@
#define MBGL_VERIFY_THREAD(tid)
#endif
+
+// GCC 4.9 compatibility
+#if !defined(__GNUC__) || __GNUC__ >= 5
+#define MBGL_CONSTEXPR constexpr
+#else
+#define MBGL_CONSTEXPR inline
+#endif
diff --git a/include/mbgl/util/work_task.hpp b/include/mbgl/util/work_task.hpp
index dda8e5d00f..f2dcfcfe86 100644
--- a/include/mbgl/util/work_task.hpp
+++ b/include/mbgl/util/work_task.hpp
@@ -18,9 +18,6 @@ public:
template <class Fn, class... Args>
static std::shared_ptr<WorkTask> make(Fn&&, Args&&...);
-
- template <class Fn, class... Args>
- static std::shared_ptr<WorkTask> makeWithCallback(Fn&&, Args&&...);
};
} // namespace mbgl
diff --git a/include/mbgl/util/work_task_impl.hpp b/include/mbgl/util/work_task_impl.hpp
index 8ebc7d45f8..276e0d6237 100644
--- a/include/mbgl/util/work_task_impl.hpp
+++ b/include/mbgl/util/work_task_impl.hpp
@@ -62,48 +62,4 @@ std::shared_ptr<WorkTask> WorkTask::make(Fn&& fn, Args&&... args) {
flag);
}
-namespace detail {
-template <class Tuple, size_t... Indexes>
-auto packageArgumentsAndCallback(std::shared_ptr<std::atomic<bool>> flag,
- Tuple&& args,
- std::index_sequence<Indexes...>) {
- auto callback = std::get<sizeof...(Indexes)>(args);
-
- // Create a lambda L1 that invokes another lambda L2 on the current RunLoop R, that calls
- // the callback C. Both lambdas check the flag before proceeding. L1 needs to check the flag
- // because if the request was cancelled, then R might have been destroyed. L2 needs to check
- // the flag because the request may have been cancelled after L2 was invoked but before it
- // began executing.
-
- auto l2 = [flag, callback] (auto&&... results) {
- if (!*flag) {
- callback(std::forward<decltype(results)>(results)...);
- }
- };
-
- auto l1 = [flag, current = util::RunLoop::Get(), l2_ = l2] (auto&&... results) {
- if (!*flag) {
- current->invoke(l2_, std::forward<decltype(results)>(results)...);
- }
- };
-
- return std::make_tuple(std::get<Indexes>(std::forward<Tuple>(args))..., l1);
-}
-} // namespace detail
-
-template <class Fn, class... Args>
-std::shared_ptr<WorkTask> WorkTask::makeWithCallback(Fn&& fn, Args&&... args) {
- auto flag = std::make_shared<std::atomic<bool>>();
- *flag = false;
-
- auto tuple = detail::packageArgumentsAndCallback(flag,
- std::forward_as_tuple(std::forward<Args>(args)...),
- std::make_index_sequence<sizeof...(Args) - 1>());
-
- return std::make_shared<WorkTaskImpl<std::decay_t<Fn>, decltype(tuple)>>(
- std::forward<Fn>(fn),
- std::move(tuple),
- flag);
-}
-
} // namespace mbgl