diff options
Diffstat (limited to 'include/mbgl/map')
-rw-r--r-- | include/mbgl/map/map.hpp | 194 | ||||
-rw-r--r-- | include/mbgl/map/raster_tile_data.hpp | 28 | ||||
-rw-r--r-- | include/mbgl/map/source.hpp | 72 | ||||
-rw-r--r-- | include/mbgl/map/sprite.hpp | 65 | ||||
-rw-r--r-- | include/mbgl/map/tile.hpp | 73 | ||||
-rw-r--r-- | include/mbgl/map/tile_data.hpp | 77 | ||||
-rw-r--r-- | include/mbgl/map/tile_parser.hpp | 68 | ||||
-rw-r--r-- | include/mbgl/map/transform.hpp | 106 | ||||
-rw-r--r-- | include/mbgl/map/transform_state.hpp | 69 | ||||
-rw-r--r-- | include/mbgl/map/vector_tile.hpp | 119 | ||||
-rw-r--r-- | include/mbgl/map/vector_tile_data.hpp | 55 | ||||
-rw-r--r-- | include/mbgl/map/view.hpp | 54 |
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 ↦ + 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 ↦ + + // 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 |