diff options
-rw-r--r-- | include/mbgl/style/sources/geojson_source.hpp | 5 | ||||
-rw-r--r-- | include/mbgl/util/feature_state.hpp | 19 | ||||
-rw-r--r-- | platform/glfw/glfw_view.cpp | 31 | ||||
-rw-r--r-- | platform/glfw/glfw_view.hpp | 1 | ||||
-rw-r--r-- | platform/glfw/main.cpp | 2 | ||||
-rw-r--r-- | src/mbgl/map/map.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/renderer/render_source.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/renderer_impl.cpp | 22 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.cpp | 46 | ||||
-rw-r--r-- | src/mbgl/renderer/sources/render_geojson_source.hpp | 7 | ||||
-rw-r--r-- | src/mbgl/renderer/tile_pyramid.cpp | 22 | ||||
-rw-r--r-- | src/mbgl/renderer/tile_pyramid.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/renderer/update_parameters.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/style/sources/geojson_source.cpp | 17 | ||||
-rw-r--r-- | src/mbgl/style/style_impl.cpp | 16 | ||||
-rw-r--r-- | src/mbgl/style/style_impl.hpp | 4 |
16 files changed, 175 insertions, 25 deletions
diff --git a/include/mbgl/style/sources/geojson_source.hpp b/include/mbgl/style/sources/geojson_source.hpp index a03b910279..803588ac7e 100644 --- a/include/mbgl/style/sources/geojson_source.hpp +++ b/include/mbgl/style/sources/geojson_source.hpp @@ -2,8 +2,10 @@ #include <mbgl/style/source.hpp> #include <mbgl/util/geojson.hpp> +#include <mbgl/util/feature_state.hpp> #include <mbgl/util/optional.hpp> #include <mbgl/util/constants.hpp> +#include <mbgl/util/immutable.hpp> namespace mbgl { @@ -33,6 +35,7 @@ public: void setURL(const std::string& url); void setGeoJSON(const GeoJSON&); + void setFeatureState(const FeatureIdentifier&, const std::string&, const mbgl::Value&); optional<std::string> getURL() const; @@ -41,9 +44,11 @@ public: void loadDescription(FileSource&) final; + Immutable<std::vector<FeatureStateChange>> collectFeatureStates(); private: optional<std::string> url; std::unique_ptr<AsyncRequest> req; + Mutable<std::vector<FeatureStateChange>> stateChanges; }; template <> diff --git a/include/mbgl/util/feature_state.hpp b/include/mbgl/util/feature_state.hpp index e97926c6e1..f63f3dcbff 100644 --- a/include/mbgl/util/feature_state.hpp +++ b/include/mbgl/util/feature_state.hpp @@ -15,17 +15,32 @@ struct FeatureStateChange { }; ChangeType type; + std::string sourceLayer; FeatureIdentifier id; std::string key; optional<Value> value; FeatureStateChange(ChangeType type_, - FeatureIdentifier&& id_, - std::string&& key_, + const std::string& sourceLayer_, + const FeatureIdentifier& id_, + const std::string& key_, optional<Value> value_) : type(type_), + sourceLayer(sourceLayer_), id(std::move(id_)), key(std::move(key_)), value(std::move(value_)) {} + + FeatureStateChange(ChangeType type_, + const FeatureIdentifier& id_, + const std::string& key_, + optional<Value> value_) : + type(type_), + id(std::move(id_)), + key(std::move(key_)), + value(std::move(value_)) {} + }; +using FeatureStateChangeSet = std::vector<FeatureStateChange>; + } // namespace mbgl diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 9179113139..522a0c6f61 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -15,6 +15,7 @@ #include <mbgl/renderer/renderer.hpp> #include <mbgl/renderer/backend_scope.hpp> #include <mbgl/map/camera.hpp> +#include <mbgl/style/sources/geojson_source.hpp> #include <mapbox/cheap_ruler.hpp> #include <mapbox/geometry.hpp> @@ -518,6 +519,35 @@ void GLFWView::onMouseMove(GLFWwindow *window, double x, double y) { } view->lastX = x; view->lastY = y; + + if (view->tracking || view->rotating || view->pitching) return; + + mbgl::ScreenCoordinate screenCoordinate = { x, y }; + + std::vector<mbgl::Feature> features = view->rendererFrontend->getRenderer()->queryRenderedFeatures(screenCoordinate,{ }); + + if (features.empty() && !view->hoveredId) return; + auto pointsSource = view->map->getStyle().getSource("points"); + if (pointsSource && pointsSource->is<mbgl::style::GeoJSONSource>()) { + auto gj = pointsSource->as<mbgl::style::GeoJSONSource>(); + + if (features.size() >= 1 && features[0].id) { + const auto& fId = features[0].id; + + if (view->hoveredId != fId) { + if (view->hoveredId) { + gj->setFeatureState(*(view->hoveredId), "hover", false); + } + gj->setFeatureState(*(features[0].id), "hover", true); + view->hoveredId = features[0].id; + view->invalidate(); + } + } else if (view->hoveredId) { + gj->setFeatureState(*(view->hoveredId), "hover", false); + view->hoveredId = mbgl::nullopt; + view->invalidate(); + } + } } void GLFWView::run() { @@ -539,7 +569,6 @@ void GLFWView::run() { updateAnimatedAnnotations(); activate(); - rendererFrontend->render(); glfwSwapBuffers(window); diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp index d5acf697f7..9a784660e3 100644 --- a/platform/glfw/glfw_view.hpp +++ b/platform/glfw/glfw_view.hpp @@ -125,6 +125,7 @@ private: mbgl::util::RunLoop runLoop; mbgl::util::Timer frameTick; + mbgl::optional<mbgl::FeatureIdentifier> hoveredId; GLFWwindow *window = nullptr; bool dirty = false; diff --git a/platform/glfw/main.cpp b/platform/glfw/main.cpp index 1bb2e13614..a0320d4052 100644 --- a/platform/glfw/main.cpp +++ b/platform/glfw/main.cpp @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) { fileSource.setAccessToken(std::string(token)); } - mbgl::ThreadPool threadPool(4); + mbgl::ThreadPool threadPool(1); GLFWRendererFrontend rendererFrontend { std::make_unique<mbgl::Renderer>(backend, view->getPixelRatio(), fileSource, threadPool), backend }; mbgl::Map map(rendererFrontend, backend, view->getSize(), view->getPixelRatio(), fileSource, threadPool); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 9d886cb74c..273ed1bd75 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -787,6 +787,7 @@ void Map::Impl::onUpdate() { style->impl->getImageImpls(), style->impl->getSourceImpls(), style->impl->getLayerImpls(), + style->impl->getFeatureStateChangeSets(), annotationManager, prefetchZoomDelta, bool(stillImageRequest), diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index cffb482147..0445f88a17 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -50,7 +50,7 @@ public: virtual void update(Immutable<style::Source::Impl>, const std::vector<Immutable<style::Layer::Impl>>&, - const FeatureStatesMap&, + Immutable<FeatureStateChangeSet>, bool, bool, const TileParameters&) {} diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index dc53f20110..4f9b6b248b 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -243,12 +243,22 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { filteredLayers.push_back(layer); } - //TODO: AHM: Send feature states - renderSources.at(source->id)->update(source, - filteredLayers, - needsRendering, - needsRelayout, - tileParameters); + const auto changeSet = updateParameters.stateChanges->find(source->id); + if (changeSet != updateParameters.stateChanges->end()) { + renderSources.at(source->id)->update(source, + filteredLayers, + changeSet->second, + needsRendering, + needsRelayout, + tileParameters); + } + else { + renderSources.at(source->id)->update(source, + filteredLayers, + needsRendering, + needsRelayout, + tileParameters); + } } transformState = updateParameters.transformState; diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 0e265efff4..bfbfe8d76d 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -26,6 +26,7 @@ bool RenderGeoJSONSource::isLoaded() const { void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_, const std::vector<Immutable<Layer::Impl>>& layers, + Immutable<FeatureStateChangeSet> statesChangeSet, const bool needsRendering, const bool needsRelayout, const TileParameters& parameters) { @@ -56,6 +57,7 @@ void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_, } tilePyramid.update(layers, + *statesChangeSet, needsRendering, needsRelayout, parameters, @@ -68,6 +70,50 @@ void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_, }); } +void RenderGeoJSONSource::update(Immutable<style::Source::Impl> baseImpl_, + const std::vector<Immutable<Layer::Impl>>& layers, + const bool needsRendering, + const bool needsRelayout, + const TileParameters& parameters) { + std::swap(baseImpl, baseImpl_); + + enabled = needsRendering; + + GeoJSONData* data_ = impl().getData(); + + if (data_ != data) { + data = data_; + tilePyramid.cache.clear(); + + if (data) { + const uint8_t maxZ = impl().getZoomRange().max; + for (const auto& pair : tilePyramid.tiles) { + if (pair.first.canonical.z <= maxZ) { + static_cast<GeoJSONTile*>(pair.second.get())->updateData(data->getTile(pair.first.canonical)); + } + } + } + } + + if (!data) { + tilePyramid.tiles.clear(); + tilePyramid.renderTiles.clear(); + return; + } + + tilePyramid.update(layers, + {}, + needsRendering, + needsRelayout, + parameters, + SourceType::GeoJSON, + util::tileSize, + impl().getZoomRange(), + optional<LatLngBounds>{}, + [&] (const OverscaledTileID& tileID) { + return std::make_unique<GeoJSONTile>(tileID, impl().id, parameters, data->getTile(tileID.canonical)); + }); +} void RenderGeoJSONSource::startRender(PaintParameters& parameters) { parameters.clipIDGenerator.update(tilePyramid.getRenderTiles()); tilePyramid.startRender(parameters); diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index 297fa09a29..ecba7298c1 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -18,6 +18,13 @@ public: void update(Immutable<style::Source::Impl>, const std::vector<Immutable<style::Layer::Impl>>&, + Immutable<FeatureStateChangeSet>, + bool needsRendering, + bool needsRelayout, + const TileParameters&) final; + + void update(Immutable<style::Source::Impl>, + const std::vector<Immutable<style::Layer::Impl>>&, bool needsRendering, bool needsRelayout, const TileParameters&) final; diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index b23adbec6e..a00617b321 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -71,7 +71,7 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer const Range<uint8_t> zoomRange, optional<LatLngBounds> bounds, std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile) { - FeatureStatesMap fsm; + FeatureStateChangeSet fsm; update(layers,fsm, needsRendering, needsRelayout, parameters, type, tileSize, zoomRange, bounds, createTile); } @@ -87,7 +87,7 @@ void extend(PropertyMap& a, const PropertyMap& b) { } void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layers, - const FeatureStatesMap& newStates, + const FeatureStateChangeSet& statesChangeSet, const bool needsRendering, const bool needsRelayout, const TileParameters& parameters, @@ -151,19 +151,17 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer idealTiles = util::tileCover(parameters.transformState, idealZoom); } + FeatureStatesMap newStates = {}; //Coalesce changes to the feature state before applying to tiles. std::shared_ptr<FeatureStatesMap> changedStates = std::make_shared<FeatureStatesMap>(); - for( const auto& sourceLayer: newStates) { - auto& existing = (*featureStates)[sourceLayer.first]; - auto& changed = sourceLayer.second; - FeatureStates newChanges; - //for each feature id in this sourceLayer, get and merge the PropertyMap from newStates - for (const auto& id: changed) { - auto& e = existing[id.first]; - extend(e, id.second); - newChanges[id.first] = e; +// printf("TPU: %lu statechanges\n", statesChangeSet.size()); + for( const auto& stateChange: statesChangeSet) { + auto& existing = (*featureStates)[stateChange.sourceLayer]; + if (stateChange.type == FeatureStateChange::ChangeType::Insert) { + + (existing[stateChange.id])[stateChange.key] = *(stateChange.value); } - changedStates->emplace(sourceLayer.first, newChanges); + (*changedStates)[stateChange.sourceLayer][stateChange.id] = existing[stateChange.id]; } // Stores a list of all the tiles that we're definitely going to retain. There are two diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp index c238e9f1bc..9f676b9ee8 100644 --- a/src/mbgl/renderer/tile_pyramid.hpp +++ b/src/mbgl/renderer/tile_pyramid.hpp @@ -44,7 +44,7 @@ public: std::function<std::unique_ptr<Tile> (const OverscaledTileID&)> createTile); void update(const std::vector<Immutable<style::Layer::Impl>>&, - const FeatureStatesMap& newStates, + const FeatureStateChangeSet&, bool needsRendering, bool needsRelayout, const TileParameters&, diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp index a668c64f48..78dafd48e4 100644 --- a/src/mbgl/renderer/update_parameters.hpp +++ b/src/mbgl/renderer/update_parameters.hpp @@ -8,8 +8,10 @@ #include <mbgl/style/layer.hpp> #include <mbgl/util/chrono.hpp> #include <mbgl/util/immutable.hpp> +#include <mbgl/util/feature_state.hpp> #include <vector> +#include <map> namespace mbgl { @@ -31,6 +33,7 @@ public: const Immutable<std::vector<Immutable<style::Image::Impl>>> images; const Immutable<std::vector<Immutable<style::Source::Impl>>> sources; const Immutable<std::vector<Immutable<style::Layer::Impl>>> layers; + const Immutable<std::unordered_map<std::string, Immutable<std::vector<FeatureStateChange>>>> stateChanges; AnnotationManager& annotationManager; diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp index 4e3478322d..b626855d57 100644 --- a/src/mbgl/style/sources/geojson_source.cpp +++ b/src/mbgl/style/sources/geojson_source.cpp @@ -10,7 +10,8 @@ namespace mbgl { namespace style { GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions& options) - : Source(makeMutable<Impl>(std::move(id), options)) { + : Source(makeMutable<Impl>(std::move(id), options)), + stateChanges(makeMutable<std::vector<FeatureStateChange>>()) { } GeoJSONSource::~GeoJSONSource() = default; @@ -36,6 +37,20 @@ void GeoJSONSource::setGeoJSON(const mapbox::geojson::geojson& geoJSON) { observer->onSourceChanged(*this); } +void GeoJSONSource::setFeatureState(const FeatureIdentifier& featureId, const std::string& key, const mbgl::Value& value) { + if ( featureId.valid() && !key.empty()) { + stateChanges->emplace_back(FeatureStateChange::ChangeType::Insert, featureId, key, value); +// observer->onSourceChanged(*this); + } +} + +Immutable<std::vector<FeatureStateChange>> GeoJSONSource::collectFeatureStates() { + Immutable<std::vector<FeatureStateChange>> immutable(std::move(stateChanges)); + stateChanges = makeMutable<std::vector<FeatureStateChange>>(); + printf("!)!)! Collecting feature state!@$!@$\n"); + return immutable; +} + optional<std::string> GeoJSONSource::getURL() const { return url; } diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp index 5c9edc789f..236aa4d3aa 100644 --- a/src/mbgl/style/style_impl.cpp +++ b/src/mbgl/style/style_impl.cpp @@ -21,6 +21,8 @@ #include <mbgl/storage/file_source.hpp> #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> +#include <mbgl/util/feature_state.hpp> +#include <mbgl/style/sources/geojson_source.hpp> namespace mbgl { namespace style { @@ -357,5 +359,19 @@ Immutable<std::vector<Immutable<Layer::Impl>>> Style::Impl::getLayerImpls() cons return layers.getImpls(); } +Immutable<std::unordered_map<std::string, Immutable<std::vector<FeatureStateChange>>>> Style::Impl::getFeatureStateChangeSets() { + auto sources_ = getSources(); + Mutable<std::unordered_map<std::string, Immutable<std::vector<FeatureStateChange>>>> + collectedStates(makeMutable<std::unordered_map<std::string, Immutable<std::vector<FeatureStateChange>>>>()); + + for (auto src: sources_) { + if (src->is<GeoJSONSource>()) { + GeoJSONSource * gjSrc = src->as<GeoJSONSource>(); + collectedStates->insert({gjSrc->getID(), gjSrc->collectFeatureStates()}); + } + } + return std::move(collectedStates); +} + } // namespace style } // namespace mbgl diff --git a/src/mbgl/style/style_impl.hpp b/src/mbgl/style/style_impl.hpp index 3dc222bfad..d34a69ea92 100644 --- a/src/mbgl/style/style_impl.hpp +++ b/src/mbgl/style/style_impl.hpp @@ -17,6 +17,7 @@ #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/optional.hpp> #include <mbgl/util/geo.hpp> +#include <mbgl/util/feature_state.hpp> #include <memory> #include <string> @@ -88,6 +89,9 @@ public: Immutable<std::vector<Immutable<Image::Impl>>> getImageImpls() const; Immutable<std::vector<Immutable<Source::Impl>>> getSourceImpls() const; Immutable<std::vector<Immutable<Layer::Impl>>> getLayerImpls() const; + Immutable<std::unordered_map<std::string, + Immutable<std::vector<FeatureStateChange>>>> + getFeatureStateChangeSets(); void dumpDebugLogs() const; |