summaryrefslogtreecommitdiff
path: root/include/mbgl/map
diff options
context:
space:
mode:
Diffstat (limited to 'include/mbgl/map')
-rw-r--r--include/mbgl/map/map.hpp194
-rw-r--r--include/mbgl/map/raster_tile_data.hpp28
-rw-r--r--include/mbgl/map/source.hpp72
-rw-r--r--include/mbgl/map/sprite.hpp65
-rw-r--r--include/mbgl/map/tile.hpp73
-rw-r--r--include/mbgl/map/tile_data.hpp77
-rw-r--r--include/mbgl/map/tile_parser.hpp68
-rw-r--r--include/mbgl/map/transform.hpp106
-rw-r--r--include/mbgl/map/transform_state.hpp69
-rw-r--r--include/mbgl/map/vector_tile.hpp119
-rw-r--r--include/mbgl/map/vector_tile_data.hpp55
-rw-r--r--include/mbgl/map/view.hpp54
12 files changed, 980 insertions, 0 deletions
diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp
new file mode 100644
index 0000000000..774e5e1292
--- /dev/null
+++ b/include/mbgl/map/map.hpp
@@ -0,0 +1,194 @@
+
+#ifndef MBGL_MAP_MAP
+#define MBGL_MAP_MAP
+
+#include <uv.h>
+
+#include <mbgl/map/view.hpp>
+#include <mbgl/map/transform.hpp>
+#include <mbgl/style/style.hpp>
+#include <mbgl/geometry/glyph_atlas.hpp>
+#include <mbgl/text/glyph_store.hpp>
+#include <mbgl/renderer/painter.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/texturepool.hpp>
+
+#include <cstdint>
+#include <string>
+#include <map>
+
+namespace mbgl {
+
+class Source;
+class SpriteAtlas;
+
+class Map : private util::noncopyable {
+public:
+ explicit Map(View &view);
+ ~Map();
+
+ // Start/stop the map render thread
+ void start();
+ void stop();
+
+ // Runs the map event loop.
+ void run();
+
+ // Triggers a lazy rerender: only performs a render when the map is not clean.
+ void rerender();
+
+ // Forces a map update: always triggers a rerender.
+ void update();
+
+ // Triggers a cleanup that releases resources.
+ void cleanup();
+
+ // Controls buffer swapping.
+ bool needsSwap();
+ void swapped();
+
+ // Size
+ void resize(uint16_t width, uint16_t height, float ratio = 1);
+ void resize(uint16_t width, uint16_t height, float ratio, uint16_t fb_width, uint16_t fb_height);
+
+ // Styling
+ const std::set<std::shared_ptr<StyleSource>> getActiveSources() const;
+ void setAppliedClasses(const std::vector<std::string> &classes);
+ void toggleClass(const std::string &name);
+ const std::vector<std::string> &getAppliedClasses() const;
+ void setDefaultTransitionDuration(uint64_t duration_milliseconds = 0);
+ void setStyleJSON(std::string newStyleJSON);
+ std::string getStyleJSON() const;
+ void setAccessToken(std::string access_token);
+ std::string getAccessToken() const;
+
+ // Transition
+ void cancelTransitions();
+
+ // Position
+ void moveBy(double dx, double dy, double duration = 0);
+ void setLonLat(double lon, double lat, double duration = 0);
+ void getLonLat(double &lon, double &lat) const;
+ void startPanning();
+ void stopPanning();
+ void resetPosition();
+
+ // Scale
+ void scaleBy(double ds, double cx = -1, double cy = -1, double duration = 0);
+ void setScale(double scale, double cx = -1, double cy = -1, double duration = 0);
+ double getScale() const;
+ void setZoom(double zoom, double duration = 0);
+ double getZoom() const;
+ void setLonLatZoom(double lon, double lat, double zoom, double duration = 0);
+ void getLonLatZoom(double &lon, double &lat, double &zoom) const;
+ void resetZoom();
+ void startScaling();
+ void stopScaling();
+ double getMinZoom() const;
+ double getMaxZoom() const;
+
+ // Rotation
+ void rotateBy(double sx, double sy, double ex, double ey, double duration = 0);
+ void setAngle(double angle, double duration = 0);
+ void setAngle(double angle, double cx, double cy);
+ double getAngle() const;
+ void resetNorth();
+ void startRotating();
+ void stopRotating();
+ bool canRotate();
+
+ // Debug
+ void setDebug(bool value);
+ void toggleDebug();
+ bool getDebug() const;
+
+public:
+ inline const TransformState &getState() const { return state; }
+ inline std::shared_ptr<const Style> getStyle() const { return style; }
+ inline std::shared_ptr<GlyphAtlas> getGlyphAtlas() { return glyphAtlas; }
+ inline std::shared_ptr<GlyphStore> getGlyphStore() { return glyphStore; }
+ inline std::shared_ptr<SpriteAtlas> getSpriteAtlas() { return spriteAtlas; }
+ inline std::shared_ptr<Texturepool> getTexturepool() { return texturepool; }
+ inline std::shared_ptr<uv::loop> getLoop() { return loop; }
+ inline timestamp getAnimationTime() const { return animationTime; }
+ inline timestamp getTime() const { return animationTime; }
+
+private:
+ // uv async callbacks
+ static void render(uv_async_t *async);
+ static void terminate(uv_async_t *async);
+ static void cleanup(uv_async_t *async);
+ static void delete_async(uv_handle_t *handle);
+
+ // Setup
+ void setup();
+
+ void updateSources();
+ void updateSources(const std::shared_ptr<StyleLayerGroup> &group);
+
+ void updateTiles();
+ void updateRenderState();
+
+ size_t countLayers(const std::vector<LayerDescription>& layers);
+
+ // Prepares a map render by updating the tiles we need for the current view, as well as updating
+ // the stylesheet.
+ void prepare();
+
+ enum RenderPass { Opaque, Translucent };
+
+ // Unconditionally performs a render with the current map state.
+ void render();
+ void renderLayers(std::shared_ptr<StyleLayerGroup> group);
+ void renderLayer(std::shared_ptr<StyleLayer> layer_desc, RenderPass pass);
+
+private:
+ // If cleared, the next time the render thread attempts to render the map, it will *actually*
+ // render the map.
+ std::atomic_flag is_clean = ATOMIC_FLAG_INIT;
+
+ // If this flag is cleared, the current back buffer is ready for being swapped with the front
+ // buffer (i.e. it has rendered data).
+ std::atomic_flag is_swapped = ATOMIC_FLAG_INIT;
+
+ // This is cleared once the current front buffer has been presented and the back buffer is
+ // ready for rendering.
+ std::atomic_flag is_rendered = ATOMIC_FLAG_INIT;
+
+public:
+ View &view;
+
+private:
+ Transform transform;
+ TransformState state;
+
+ std::shared_ptr<Style> style;
+ std::shared_ptr<GlyphAtlas> glyphAtlas;
+ std::shared_ptr<GlyphStore> glyphStore;
+ std::shared_ptr<SpriteAtlas> spriteAtlas;
+ std::shared_ptr<Texturepool> texturepool;
+
+ Painter painter;
+
+ std::string styleJSON = "";
+ std::string accessToken = "";
+
+ bool debug = false;
+ timestamp animationTime = 0;
+
+ int indent = 0;
+
+ std::set<std::shared_ptr<StyleSource>> activeSources;
+
+private:
+ bool async = false;
+ std::shared_ptr<uv::loop> loop;
+ uv_thread_t thread;
+ uv_async_t *async_terminate = nullptr;
+ uv_async_t *async_render = nullptr;
+ uv_async_t *async_cleanup = nullptr;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/raster_tile_data.hpp b/include/mbgl/map/raster_tile_data.hpp
new file mode 100644
index 0000000000..976faa91bc
--- /dev/null
+++ b/include/mbgl/map/raster_tile_data.hpp
@@ -0,0 +1,28 @@
+#ifndef MBGL_MAP_RASTER_TILE_DATA
+#define MBGL_MAP_RASTER_TILE_DATA
+
+#include <mbgl/map/tile_data.hpp>
+
+#include <mbgl/renderer/raster_bucket.hpp>
+
+
+namespace mbgl {
+
+class RasterTileData : public TileData {
+ friend class TileParser;
+
+public:
+ RasterTileData(Tile::ID id, Map &map, const std::string url);
+ ~RasterTileData();
+
+ virtual void parse();
+ virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc);
+ virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const;
+
+protected:
+ RasterBucket bucket;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/source.hpp b/include/mbgl/map/source.hpp
new file mode 100644
index 0000000000..be5fad3af8
--- /dev/null
+++ b/include/mbgl/map/source.hpp
@@ -0,0 +1,72 @@
+#ifndef MBGL_MAP_SOURCE
+#define MBGL_MAP_SOURCE
+
+#include <mbgl/map/tile.hpp>
+#include <mbgl/map/tile_data.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/time.hpp>
+#include <mbgl/style/style_source.hpp>
+#include <mbgl/style/types.hpp>
+
+#include <list>
+#include <forward_list>
+#include <memory>
+#include <vector>
+#include <string>
+#include <map>
+#include <set>
+
+namespace mbgl {
+
+class TransformState;
+class Texturepool;
+
+class Source : public std::enable_shared_from_this<Source>, private util::noncopyable {
+public:
+ Source(StyleSource style_source, const std::string &access_token = "");
+ Source(SourceType type = SourceType::Vector, const std::string &url = "",
+ uint32_t tile_size = 512, uint32_t min_zoom = 0, uint32_t max_zoom = 22,
+ const std::string &access_token = "");
+
+ bool update(Map &map);
+ void updateMatrices(const mat4 &projMatrix, const TransformState &transform);
+ void drawClippingMasks(Painter &painter);
+ size_t getTileCount() const;
+ void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc);
+ void finishRender(Painter &painter);
+
+ std::forward_list<Tile::ID> getIDs() const;
+ void updateClipIDs(const std::map<Tile::ID, ClipID> &mapping);
+
+ static std::string normalizeSourceURL(const std::string &url, const std::string &access_token);
+
+public:
+ const SourceType type;
+ const std::string url;
+ const uint32_t tile_size;
+ const int32_t min_zoom;
+ const int32_t max_zoom;
+
+private:
+ bool findLoadedChildren(const Tile::ID& id, int32_t maxCoveringZoom, std::forward_list<Tile::ID>& retain);
+ bool findLoadedParent(const Tile::ID& id, int32_t minCoveringZoom, std::forward_list<Tile::ID>& retain);
+ std::forward_list<Tile::ID> covering_tiles(const TransformState &state, int32_t clamped_zoom, const box& points);
+
+ bool updateTiles(Map &map);
+
+ TileData::State addTile(Map &map, const Tile::ID& id);
+ TileData::State hasTile(const Tile::ID& id);
+
+ double getZoom(const TransformState &state) const;
+
+private:
+ // Stores the time when this source was most recently updated.
+ timestamp updated = 0;
+
+ std::map<Tile::ID, std::unique_ptr<Tile>> tiles;
+ std::map<Tile::ID, std::weak_ptr<TileData>> tile_data;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/sprite.hpp b/include/mbgl/map/sprite.hpp
new file mode 100644
index 0000000000..22126eb6a1
--- /dev/null
+++ b/include/mbgl/map/sprite.hpp
@@ -0,0 +1,65 @@
+#ifndef MBGL_STYLE_SPRITE
+#define MBGL_STYLE_SPRITE
+
+#include <mbgl/util/raster.hpp>
+#include <mbgl/util/vec.hpp>
+
+#include <string>
+#include <mutex>
+#include <memory>
+#include <atomic>
+#include <unordered_map>
+
+namespace mbgl {
+
+class Map;
+
+class SpritePosition {
+public:
+ explicit SpritePosition() {}
+ explicit SpritePosition(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t pixelRatio = 1);
+
+ operator bool() const {
+ return !(width == 0 && height == 0 && x == 0 && y == 0);
+ }
+
+ uint16_t x = 0, y = 0;
+ uint16_t width = 0, height = 0;
+ uint8_t pixelRatio = 1;
+};
+
+class Sprite : public std::enable_shared_from_this<Sprite> {
+public:
+ Sprite(Map &map, float pixelRatio = 1);
+
+ void load(const std::string& base_url);
+
+ const SpritePosition &getSpritePosition(const std::string& name) const;
+
+ bool isLoaded() const;
+
+public:
+ const float pixelRatio;
+ std::unique_ptr<util::Image> raster;
+
+private:
+ void asyncParseJSON();
+ void asyncParseImage();
+
+ static void parseJSON(std::shared_ptr<Sprite> &sprite);
+ static void parseImage(std::shared_ptr<Sprite> &sprite);
+ static void complete(std::shared_ptr<Sprite> &sprite);
+
+private:
+ Map &map;
+ std::string url;
+ std::string body;
+ std::string image;
+ std::atomic<bool> loaded;
+ std::unordered_map<std::string, SpritePosition> pos;
+ const SpritePosition empty;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/tile.hpp b/include/mbgl/map/tile.hpp
new file mode 100644
index 0000000000..7e868afad9
--- /dev/null
+++ b/include/mbgl/map/tile.hpp
@@ -0,0 +1,73 @@
+#ifndef MBGL_MAP_TILE
+#define MBGL_MAP_TILE
+
+#include <mbgl/util/vec.hpp>
+#include <mbgl/util/mat4.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
+#include <cstdint>
+#include <forward_list>
+#include <string>
+#include <bitset>
+#include <memory>
+
+namespace mbgl {
+
+class TileData;
+
+struct ClipID {
+ explicit ClipID() {}
+ explicit ClipID(const std::bitset<8> &mask, uint8_t length) : mask(mask), length(length) {}
+ explicit ClipID(const std::string &mask, uint8_t length) : mask(mask), length(length) {}
+ std::bitset<8> mask;
+ uint8_t length = 0;
+};
+
+class Tile : private util::noncopyable {
+public:
+ struct ID {
+ const int16_t w = 0;
+ const int8_t z = 0;
+ const int32_t x = 0, y = 0;
+
+ inline explicit ID(int8_t z, int32_t x, int32_t y)
+ : w((x < 0 ? x - (1 << z) + 1 : x) / (1 << z)), z(z), x(x), y(y) {}
+
+ inline uint64_t to_uint64() const {
+ return ((std::pow(2, z) * y + x) * 32) + z;
+ }
+
+ inline operator std::string() const {
+ return std::to_string(z) + "/" + std::to_string(x) + "/" + std::to_string(y);
+ }
+
+ inline bool operator==(const ID& rhs) const {
+ return w == rhs.w && z == rhs.z && x == rhs.x && y == rhs.y;
+ }
+
+ inline bool operator<(const ID &rhs) const {
+ if (w != rhs.w) return w < rhs.w;
+ if (z != rhs.z) return z < rhs.z;
+ if (x != rhs.x) return x < rhs.x;
+ return y < rhs.y;
+ }
+
+ ID parent(int8_t z) const;
+ ID normalized() const;
+ std::forward_list<ID> children(int32_t z) const;
+ bool isChildOf(const Tile::ID &id) const;
+ };
+
+public:
+ explicit Tile(const ID& id);
+
+public:
+ const Tile::ID id;
+ ClipID clip;
+ mat4 matrix;
+ std::shared_ptr<TileData> data;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/tile_data.hpp b/include/mbgl/map/tile_data.hpp
new file mode 100644
index 0000000000..a4b73c339f
--- /dev/null
+++ b/include/mbgl/map/tile_data.hpp
@@ -0,0 +1,77 @@
+#ifndef MBGL_MAP_TILE_DATA
+#define MBGL_MAP_TILE_DATA
+
+#include <mbgl/map/tile.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/platform/platform.hpp>
+#include <mbgl/geometry/vao.hpp>
+#include <mbgl/renderer/debug_bucket.hpp>
+
+#include <cstdint>
+#include <string>
+#include <memory>
+#include <atomic>
+
+namespace mbgl {
+
+class Map;
+class Painter;
+class StyleLayer;
+
+class TileData : public std::enable_shared_from_this<TileData>,
+ private util::noncopyable {
+public:
+ struct exception : std::exception {};
+ struct geometry_too_long_exception : exception {};
+
+public:
+ typedef std::shared_ptr<TileData> Ptr;
+
+ enum class State {
+ invalid,
+ initial,
+ loading,
+ loaded,
+ parsed,
+ obsolete
+ };
+
+public:
+ TileData(Tile::ID id, Map &map, const std::string url);
+ ~TileData();
+
+ void request();
+ void cancel();
+ void reparse();
+ const std::string toString() const;
+
+ // Override this in the child class.
+ virtual void beforeParse();
+ virtual void parse() = 0;
+ virtual void afterParse();
+ virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc) = 0;
+ virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const = 0;
+
+
+public:
+ const Tile::ID id;
+ std::atomic<State> state;
+
+protected:
+ Map &map;
+
+ // Request-related information.
+ const std::string url;
+ std::weak_ptr<platform::Request> req;
+ std::string data;
+
+ // Contains the tile ID string for painting debug information.
+ DebugFontBuffer debugFontBuffer;
+
+public:
+ DebugBucket debugBucket;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/tile_parser.hpp b/include/mbgl/map/tile_parser.hpp
new file mode 100644
index 0000000000..14e00946b8
--- /dev/null
+++ b/include/mbgl/map/tile_parser.hpp
@@ -0,0 +1,68 @@
+#ifndef MBGL_MAP_TILE_PARSER
+#define MBGL_MAP_TILE_PARSER
+
+#include <mbgl/map/vector_tile.hpp>
+#include <mbgl/text/placement.hpp>
+#include <mbgl/text/glyph_store.hpp>
+#include <mbgl/text/glyph.hpp>
+#include <mbgl/util/utf.hpp>
+#include <mbgl/style/filter_expression.hpp>
+
+namespace mbgl {
+
+class Style;
+class GlyphAtlas;
+class GlyphStore;
+class SpriteAtlas;
+class VectorTileData;
+class StyleLayer;
+class StyleLayerGroup;
+class StyleBucket;
+class StyleBucketFill;
+class StyleBucketLine;
+class StyleBucketIcon;
+
+class Bucket;
+
+class TileParser {
+public:
+ TileParser(const std::string &data, VectorTileData &tile,
+ const std::shared_ptr<const Style> &style,
+ const std::shared_ptr<GlyphAtlas> &glyphAtlas,
+ const std::shared_ptr<GlyphStore> &glyphStore,
+ const std::shared_ptr<SpriteAtlas> &spriteAtlas);
+
+public:
+ void parse();
+
+private:
+ bool obsolete() const;
+ void parseGlyphs();
+ void parseStyleLayers(std::shared_ptr<StyleLayerGroup> group);
+ void addGlyph(uint64_t tileid, const std::string stackname, const std::u32string &string, const FontStack &fontStack, GlyphAtlas &glyphAtlas, GlyphPositions &face);
+ std::unique_ptr<Bucket> createBucket(std::shared_ptr<StyleBucket> bucket_desc);
+
+ std::unique_ptr<Bucket> createFillBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketFill &fill);
+ std::unique_ptr<Bucket> createLineBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketLine &line);
+ std::unique_ptr<Bucket> createIconBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketIcon &icon);
+ std::unique_ptr<Bucket> createTextBucket(const VectorTileLayer& layer, const FilterExpression &filter, const StyleBucketText &text);
+
+ template <class Bucket> void addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const FilterExpression &filter);
+ template <class Bucket, typename ...Args> void addBucketFeatures(Bucket& bucket, const VectorTileLayer& layer, const FilterExpression &filter, Args&& ...args);
+
+private:
+ const VectorTile vector_data;
+ VectorTileData& tile;
+
+ // Cross-thread shared data.
+ std::shared_ptr<const Style> style;
+ std::shared_ptr<GlyphAtlas> glyphAtlas;
+ std::shared_ptr<GlyphStore> glyphStore;
+ std::shared_ptr<SpriteAtlas> spriteAtlas;
+
+ Placement placement;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/transform.hpp b/include/mbgl/map/transform.hpp
new file mode 100644
index 0000000000..61bef76563
--- /dev/null
+++ b/include/mbgl/map/transform.hpp
@@ -0,0 +1,106 @@
+#ifndef MBGL_MAP_TRANSFORM
+#define MBGL_MAP_TRANSFORM
+
+#include <mbgl/util/transition.hpp>
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/uv.hpp>
+
+#include "view.hpp"
+#include "transform_state.hpp"
+
+#include <forward_list>
+
+namespace mbgl {
+
+struct box;
+
+ class Transform : private util::noncopyable {
+public:
+ Transform(View &view);
+
+ // Map view
+ // Note: width * ratio does not necessarily equal fb_width
+ bool resize(uint16_t width, uint16_t height, float ratio,
+ uint16_t fb_width, uint16_t fb_height);
+
+ // Position
+ void moveBy(double dx, double dy, timestamp duration = 0);
+ void setLonLat(double lon, double lat, timestamp duration = 0);
+ void setLonLatZoom(double lon, double lat, double zoom, timestamp duration = 0);
+ void getLonLat(double& lon, double& lat) const;
+ void getLonLatZoom(double& lon, double& lat, double& zoom) const;
+ void startPanning();
+ void stopPanning();
+
+ // Zoom
+ void scaleBy(double ds, double cx = -1, double cy = -1, timestamp duration = 0);
+ void setScale(double scale, double cx = -1, double cy = -1, timestamp duration = 0);
+ void setZoom(double zoom, timestamp duration = 0);
+ double getZoom() const;
+ double getScale() const;
+ void startScaling();
+ void stopScaling();
+ double getMinZoom() const;
+ double getMaxZoom() const;
+
+ // Angle
+ void rotateBy(double sx, double sy, double ex, double ey, timestamp duration = 0);
+ void setAngle(double angle, timestamp duration = 0);
+ void setAngle(double angle, double cx, double cy);
+ double getAngle() const;
+ void startRotating();
+ void stopRotating();
+ bool canRotate();
+
+ // Transitions
+ bool needsTransition() const;
+ void updateTransitions(timestamp now);
+ void cancelTransitions();
+
+ // Transform state
+ const TransformState currentState() const;
+ const TransformState finalState() const;
+
+private:
+ // Functions prefixed with underscores will *not* perform any locks. It is the caller's
+ // responsibility to lock this object.
+ void _moveBy(double dx, double dy, timestamp duration = 0);
+ void _setScale(double scale, double cx, double cy, timestamp duration = 0);
+ void _setScaleXY(double new_scale, double xn, double yn, timestamp duration = 0);
+ void _setAngle(double angle, timestamp duration = 0);
+ void _clearPanning();
+ void _clearRotating();
+ void _clearScaling();
+
+ void constrain(double& scale, double& y) const;
+
+private:
+ View &view;
+
+ mutable uv::rwlock mtx;
+
+ // This reflects the current state of the transform, representing the actual position of the
+ // map. After calling a transform function with a timer, this will likely remain the same until
+ // you render a new frame.
+ TransformState current;
+
+ // This reflects the final position of the transform, after all possible transition took place.
+ TransformState final;
+
+ // Limit the amount of zooming possible on the map.
+ // TODO: make these modifiable from outside.
+ const double min_scale = std::pow(2, 0);
+ const double max_scale = std::pow(2, 18);
+
+ // cache values for spherical mercator math
+ double zc, Bc, Cc;
+
+ std::forward_list<std::shared_ptr<util::transition>> transitions;
+ std::shared_ptr<util::transition> scale_timeout;
+ std::shared_ptr<util::transition> rotate_timeout;
+ std::shared_ptr<util::transition> pan_timeout;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/transform_state.hpp b/include/mbgl/map/transform_state.hpp
new file mode 100644
index 0000000000..85dd2eb87d
--- /dev/null
+++ b/include/mbgl/map/transform_state.hpp
@@ -0,0 +1,69 @@
+#ifndef MBGL_MAP_TRANSFORM_STATE
+#define MBGL_MAP_TRANSFORM_STATE
+
+#include <mbgl/util/mat4.hpp>
+#include <mbgl/map/tile.hpp>
+
+#include <cstdint>
+
+namespace mbgl {
+
+class Transform;
+
+class TransformState {
+ friend class Transform;
+
+public:
+ // Matrix
+ void matrixFor(mat4& matrix, const Tile::ID& id) const;
+ box cornersToBox(uint32_t z) const;
+
+ // Dimensions
+ bool hasSize() const;
+ uint16_t getWidth() const;
+ uint16_t getHeight() const;
+ uint16_t getFramebufferWidth() const;
+ uint16_t getFramebufferHeight() const;
+ const std::array<uint16_t, 2> getFramebufferDimensions() const;
+ float getPixelRatio() const;
+
+ // Zoom
+ float getNormalizedZoom() const;
+ int32_t getIntegerZoom() const;
+ double getZoom() const;
+ double getScale() const;
+
+ // Rotation
+ float getAngle() const;
+
+ // Changing
+ bool isChanging() const;
+
+private:
+ double pixel_x() const;
+ double pixel_y() const;
+
+private:
+ // logical dimensions
+ uint16_t width = 0, height = 0;
+
+ // physical (framebuffer) dimensions
+ std::array<uint16_t, 2> framebuffer = {{ 0, 0 }};
+
+ // map scale factor
+ float pixelRatio = 0;
+
+ // animation state
+ bool rotating = false;
+ bool scaling = false;
+ bool panning = false;
+
+ // map position
+ double x = 0, y = 0;
+ double angle = 0;
+ double scale = std::numeric_limits<double>::infinity();
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/vector_tile.hpp b/include/mbgl/map/vector_tile.hpp
new file mode 100644
index 0000000000..77e379865f
--- /dev/null
+++ b/include/mbgl/map/vector_tile.hpp
@@ -0,0 +1,119 @@
+#ifndef MBGL_MAP_VECTOR_TILE
+#define MBGL_MAP_VECTOR_TILE
+
+#include <mbgl/util/pbf.hpp>
+#include <mbgl/util/vec.hpp>
+#include <mbgl/style/value.hpp>
+#include <mbgl/text/glyph.hpp>
+#include <mbgl/style/filter_expression.hpp>
+#include <vector>
+#include <map>
+#include <unordered_map>
+#include <set>
+#include <limits>
+
+namespace mbgl {
+
+class BucketDescription;
+class VectorTileLayer;
+
+struct pbf;
+
+enum class FeatureType {
+ Unknown = 0,
+ Point = 1,
+ LineString = 2,
+ Polygon = 3
+};
+
+std::ostream& operator<<(std::ostream&, const FeatureType& type);
+
+class VectorTileFeature {
+public:
+ VectorTileFeature(pbf feature, const VectorTileLayer& layer);
+
+ uint64_t id = 0;
+ FeatureType type = FeatureType::Unknown;
+ std::map<std::string, Value> properties;
+ pbf geometry;
+};
+
+std::ostream& operator<<(std::ostream&, const VectorTileFeature& feature);
+
+
+class VectorTileTagExtractor {
+public:
+ VectorTileTagExtractor(const VectorTileLayer &layer);
+
+ void setTags(const pbf &pbf);
+ std::vector<Value> getValues(const std::string &key) const;
+ void setType(FilterExpression::GeometryType type);
+ FilterExpression::GeometryType getType() const;
+
+private:
+ const VectorTileLayer &layer_;
+ pbf tags_;
+ FilterExpression::GeometryType type_ = FilterExpression::GeometryType::Any;
+};
+
+/*
+ * Allows iterating over the features of a VectorTileLayer using a
+ * BucketDescription as filter. Only features matching the descriptions will
+ * be returned (as pbf).
+ */
+class FilteredVectorTileLayer {
+public:
+ class iterator {
+ public:
+ iterator(const FilteredVectorTileLayer& filter, const pbf& data);
+ void operator++();
+ bool operator!=(const iterator& other) const;
+ const pbf& operator*() const;
+
+ private:
+ const FilteredVectorTileLayer& parent;
+ bool valid = false;
+ pbf feature;
+ pbf data;
+ };
+
+public:
+ FilteredVectorTileLayer(const VectorTileLayer& layer, const FilterExpression &filterExpression);
+
+ iterator begin() const;
+ iterator end() const;
+
+private:
+ const VectorTileLayer& layer;
+ const FilterExpression& filterExpression;
+};
+
+std::ostream& operator<<(std::ostream&, const GlyphPlacement& placement);
+
+class VectorTileLayer {
+public:
+ VectorTileLayer(pbf data);
+
+ const pbf data;
+ std::string name;
+ uint32_t extent = 4096;
+ std::vector<std::string> keys;
+ std::unordered_map<std::string, uint32_t> key_index;
+ std::vector<Value> values;
+ std::map<std::string, std::map<Value, Shaping>> shaping;
+};
+
+class VectorTile {
+public:
+ VectorTile();
+ VectorTile(pbf data);
+ VectorTile& operator=(VectorTile&& other);
+
+ std::map<std::string, const VectorTileLayer> layers;
+};
+
+
+
+}
+
+#endif
diff --git a/include/mbgl/map/vector_tile_data.hpp b/include/mbgl/map/vector_tile_data.hpp
new file mode 100644
index 0000000000..dd55e8dae1
--- /dev/null
+++ b/include/mbgl/map/vector_tile_data.hpp
@@ -0,0 +1,55 @@
+#ifndef MBGL_MAP_VECTOR_TILE_DATA
+#define MBGL_MAP_VECTOR_TILE_DATA
+
+#include <mbgl/map/tile_data.hpp>
+
+
+#include <mbgl/renderer/bucket.hpp>
+
+#include <mbgl/geometry/vertex_buffer.hpp>
+#include <mbgl/geometry/elements_buffer.hpp>
+#include <mbgl/geometry/fill_buffer.hpp>
+#include <mbgl/geometry/line_buffer.hpp>
+#include <mbgl/geometry/icon_buffer.hpp>
+#include <mbgl/geometry/text_buffer.hpp>
+#include <mbgl/map/tile_parser.hpp>
+
+#include <unordered_map>
+
+namespace mbgl {
+
+
+class VectorTileData : public TileData {
+ friend class TileParser;
+
+public:
+ VectorTileData(Tile::ID id, Map &map, const std::string url);
+ ~VectorTileData();
+
+ virtual void beforeParse();
+ virtual void parse();
+ virtual void afterParse();
+ virtual void render(Painter &painter, std::shared_ptr<StyleLayer> layer_desc);
+ virtual bool hasData(std::shared_ptr<StyleLayer> layer_desc) const;
+
+protected:
+ // Holds the actual geometries in this tile.
+ FillVertexBuffer fillVertexBuffer;
+ LineVertexBuffer lineVertexBuffer;
+ IconVertexBuffer iconVertexBuffer;
+ TextVertexBuffer textVertexBuffer;
+
+ TriangleElementsBuffer triangleElementsBuffer;
+ LineElementsBuffer lineElementsBuffer;
+ PointElementsBuffer pointElementsBuffer;
+
+ // Holds the buckets of this tile.
+ // They contain the location offsets in the buffers stored above
+ std::unordered_map<std::string, std::unique_ptr<Bucket>> buckets;
+
+ std::unique_ptr<TileParser> parser;
+};
+
+}
+
+#endif
diff --git a/include/mbgl/map/view.hpp b/include/mbgl/map/view.hpp
new file mode 100644
index 0000000000..92d60d4d02
--- /dev/null
+++ b/include/mbgl/map/view.hpp
@@ -0,0 +1,54 @@
+#ifndef MBGL_MAP_VIEW
+#define MBGL_MAP_VIEW
+
+#include <mbgl/util/time.hpp>
+
+namespace mbgl {
+
+class Map;
+
+enum MapChange : uint8_t {
+ MapChangeRegionWillChange = 0,
+ MapChangeRegionWillChangeAnimated = 1,
+ MapChangeRegionDidChange = 2,
+ MapChangeRegionDidChangeAnimated = 3,
+ MapChangeWillStartLoadingMap = 4,
+ MapChangeDidFinishLoadingMap = 5,
+ MapChangeDidFailLoadingMap = 6,
+ MapChangeWillStartRenderingMap = 7,
+ MapChangeDidFinishRenderingMap = 8,
+ MapChangeDidFinishRenderingMapFullyRendered = 9
+};
+
+class View {
+public:
+ virtual void initialize(Map *map) {
+ this->map = map;
+ }
+
+ // Called from the render (=GL) thread. Signals that the context should
+ // swap the front and the back buffer.
+ virtual void swap() = 0;
+
+ // Called from the render thread. Makes the GL context active in the current
+ // thread. This is typically just called once at the beginning of the
+ // renderer setup since the render thread doesn't switch the contexts.
+ virtual void make_active() = 0;
+
+ // Returns the base framebuffer object, if any, and 0 if using the system
+ // provided framebuffer.
+ virtual unsigned int root_fbo() {
+ return 0;
+ }
+
+ // Notifies a watcher of map x/y/scale/rotation changes.
+ // Must only be called from the same thread that caused the change.
+ // Must not be called from the render thread.
+ virtual void notify_map_change(MapChange change, timestamp delay = 0) = 0;
+
+protected:
+ mbgl::Map *map = nullptr;
+};
+}
+
+#endif