summaryrefslogtreecommitdiff
path: root/src/mbgl/style
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style')
-rw-r--r--src/mbgl/style/source.cpp4
-rw-r--r--src/mbgl/style/source_impl.cpp281
-rw-r--r--src/mbgl/style/source_impl.hpp96
-rw-r--r--src/mbgl/style/source_observer.hpp8
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp2
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.cpp89
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.hpp21
-rw-r--r--src/mbgl/style/sources/raster_source_impl.cpp7
-rw-r--r--src/mbgl/style/sources/raster_source_impl.hpp3
-rw-r--r--src/mbgl/style/sources/vector_source_impl.cpp8
-rw-r--r--src/mbgl/style/sources/vector_source_impl.hpp3
-rw-r--r--src/mbgl/style/style.cpp127
-rw-r--r--src/mbgl/style/style.hpp11
-rw-r--r--src/mbgl/style/tile_source_impl.cpp25
-rw-r--r--src/mbgl/style/tile_source_impl.hpp4
15 files changed, 166 insertions, 523 deletions
diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp
index 51863f8eba..cfb268006b 100644
--- a/src/mbgl/style/source.cpp
+++ b/src/mbgl/style/source.cpp
@@ -18,9 +18,5 @@ optional<std::string> Source::getAttribution() const {
return baseImpl->getAttribution();
}
-optional<Range<uint8_t>> Source::getZoomRange() const {
- return baseImpl->getZoomRange();
-}
-
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp
index 19138bd781..8fdbd038de 100644
--- a/src/mbgl/style/source_impl.cpp
+++ b/src/mbgl/style/source_impl.cpp
@@ -1,23 +1,6 @@
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/source_observer.hpp>
-#include <mbgl/map/transform.hpp>
-#include <mbgl/renderer/render_tile.hpp>
-#include <mbgl/renderer/painter.hpp>
-#include <mbgl/style/update_parameters.hpp>
-#include <mbgl/text/placement_config.hpp>
#include <mbgl/util/logging.hpp>
-#include <mbgl/math/clamp.hpp>
-#include <mbgl/util/tile_cover.hpp>
-#include <mbgl/util/enum.hpp>
-#include <mbgl/map/query.hpp>
-
-#include <mbgl/algorithm/update_renderables.hpp>
-#include <mbgl/algorithm/generate_clip_ids.hpp>
-#include <mbgl/algorithm/generate_clip_ids_impl.hpp>
-
-#include <mapbox/geometry/envelope.hpp>
-
-#include <algorithm>
namespace mbgl {
namespace style {
@@ -31,271 +14,13 @@ Source::Impl::Impl(SourceType type_, std::string id_, Source& base_)
observer(&nullObserver) {
}
-Source::Impl::~Impl() = default;
-
-bool Source::Impl::isLoaded() const {
- if (!loaded) return false;
-
- for (const auto& pair : tiles) {
- if (!pair.second->isComplete()) {
- return false;
- }
- }
-
- return true;
-}
-
-void Source::Impl::detach() {
- invalidateTiles();
-}
-
-void Source::Impl::invalidateTiles() {
- tiles.clear();
- renderTiles.clear();
- cache.clear();
-}
-
-void Source::Impl::startRender(algorithm::ClipIDGenerator& generator,
- const mat4& projMatrix,
- const mat4& clipMatrix,
- const TransformState& transform) {
- if (type == SourceType::Vector ||
- type == SourceType::GeoJSON ||
- type == SourceType::Annotations) {
- generator.update(renderTiles);
- }
-
- for (auto& pair : renderTiles) {
- auto& tile = pair.second;
- tile.calculateMatrices(projMatrix, clipMatrix, transform);
- }
-}
-
-void Source::Impl::finishRender(Painter& painter) {
- for (auto& pair : renderTiles) {
- auto& tile = pair.second;
- if (tile.used) {
- painter.renderTileDebug(tile);
- }
- }
-}
-
-std::map<UnwrappedTileID, RenderTile>& Source::Impl::getRenderTiles() {
- return renderTiles;
-}
-
-void Source::Impl::updateTiles(const UpdateParameters& parameters) {
- if (!loaded) {
- return;
- }
-
- const uint16_t tileSize = getTileSize();
- const optional<Range<uint8_t>> zoomRange = getZoomRange();
-
- // Determine the overzooming/underzooming amounts and required tiles.
- int32_t overscaledZoom = util::coveringZoomLevel(parameters.transformState.getZoom(), type, tileSize);
- int32_t tileZoom = overscaledZoom;
-
- std::vector<UnwrappedTileID> idealTiles;
- if (overscaledZoom >= zoomRange->min) {
- int32_t idealZoom = std::min<int32_t>(zoomRange->max, overscaledZoom);
-
- // Make sure we're not reparsing overzoomed raster tiles.
- if (type == SourceType::Raster) {
- tileZoom = idealZoom;
- }
-
- idealTiles = util::tileCover(parameters.transformState, idealZoom);
- }
-
- // Stores a list of all the tiles that we're definitely going to retain. There are two
- // kinds of tiles we need: the ideal tiles determined by the tile cover. They may not yet be in
- // use because they're still loading. In addition to that, we also need to retain all tiles that
- // we're actively using, e.g. as a replacement for tile that aren't loaded yet.
- std::set<OverscaledTileID> retain;
-
- auto retainTileFn = [&retain](Tile& tile, Resource::Necessity necessity) -> void {
- retain.emplace(tile.id);
- tile.setNecessity(necessity);
- };
- auto getTileFn = [this](const OverscaledTileID& tileID) -> Tile* {
- auto it = tiles.find(tileID);
- return it == tiles.end() ? nullptr : it->second.get();
- };
- auto createTileFn = [this, &parameters](const OverscaledTileID& tileID) -> Tile* {
- std::unique_ptr<Tile> tile = cache.get(tileID);
- if (!tile) {
- tile = createTile(tileID, parameters);
- if (tile) {
- tile->setObserver(this);
- }
- }
- if (!tile) {
- return nullptr;
- }
- return tiles.emplace(tileID, std::move(tile)).first->second.get();
- };
- auto renderTileFn = [this](const UnwrappedTileID& tileID, Tile& tile) {
- renderTiles.emplace(tileID, RenderTile{ tileID, tile });
- };
-
- renderTiles.clear();
- algorithm::updateRenderables(getTileFn, createTileFn, retainTileFn, renderTileFn,
- idealTiles, *zoomRange, tileZoom);
-
- if (type != SourceType::Annotations) {
- size_t conservativeCacheSize =
- std::max((float)parameters.transformState.getSize().width / tileSize, 1.0f) *
- std::max((float)parameters.transformState.getSize().height / tileSize, 1.0f) *
- (parameters.transformState.getMaxZoom() - parameters.transformState.getMinZoom() + 1) *
- 0.5;
- cache.setSize(conservativeCacheSize);
- }
-
- removeStaleTiles(retain);
-
- const PlacementConfig config { parameters.transformState.getAngle(),
- parameters.transformState.getPitch(),
- parameters.debugOptions & MapDebugOptions::Collision };
-
- for (auto& pair : tiles) {
- pair.second->setPlacementConfig(config);
- }
-}
-
-// Moves all tiles to the cache except for those specified in the retain set.
-void Source::Impl::removeStaleTiles(const std::set<OverscaledTileID>& retain) {
- // Remove stale tiles. This goes through the (sorted!) tiles map and retain set in lockstep
- // and removes items from tiles that don't have the corresponding key in the retain set.
- auto tilesIt = tiles.begin();
- auto retainIt = retain.begin();
- while (tilesIt != tiles.end()) {
- if (retainIt == retain.end() || tilesIt->first < *retainIt) {
- tilesIt->second->setNecessity(Tile::Necessity::Optional);
- cache.add(tilesIt->first, std::move(tilesIt->second));
- tiles.erase(tilesIt++);
- } else {
- if (!(*retainIt < tilesIt->first)) {
- ++tilesIt;
- }
- ++retainIt;
- }
- }
-}
-
-void Source::Impl::removeTiles() {
- renderTiles.clear();
- if (!tiles.empty()) {
- removeStaleTiles({});
- }
-}
-
-void Source::Impl::reloadTiles() {
- cache.clear();
-
- for (auto& pair : tiles) {
- pair.second->redoLayout();
- }
-}
-
-std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRenderedFeatures(const ScreenLineString& geometry,
- const TransformState& transformState,
- const RenderedQueryOptions& options) const {
- std::unordered_map<std::string, std::vector<Feature>> result;
- if (renderTiles.empty() || geometry.empty()) {
- return result;
- }
-
- LineString<double> queryGeometry;
-
- for (const auto& p : geometry) {
- queryGeometry.push_back(TileCoordinate::fromScreenCoordinate(
- transformState, 0, { p.x, transformState.getSize().height - p.y }).p);
- }
-
- mapbox::geometry::box<double> box = mapbox::geometry::envelope(queryGeometry);
-
-
- auto sortRenderTiles = [](const RenderTile& a, const RenderTile& b) {
- return std::tie(a.id.canonical.z, a.id.canonical.y, a.id.wrap, a.id.canonical.x) <
- std::tie(b.id.canonical.z, b.id.canonical.y, b.id.wrap, b.id.canonical.x);
- };
- std::vector<std::reference_wrapper<const RenderTile>> sortedTiles;
- std::transform(renderTiles.cbegin(), renderTiles.cend(), std::back_inserter(sortedTiles),
- [](const auto& pair) { return std::ref(pair.second); });
- std::sort(sortedTiles.begin(), sortedTiles.end(), sortRenderTiles);
-
- for (const auto& renderTileRef : sortedTiles) {
- const RenderTile& renderTile = renderTileRef.get();
- GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
- if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) {
- continue;
- }
-
- GeometryCoordinate tileSpaceBoundsMax = TileCoordinate::toGeometryCoordinate(renderTile.id, box.max);
- if (tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) {
- continue;
- }
-
- GeometryCoordinates tileSpaceQueryGeometry;
- tileSpaceQueryGeometry.reserve(queryGeometry.size());
- for (const auto& c : queryGeometry) {
- tileSpaceQueryGeometry.push_back(TileCoordinate::toGeometryCoordinate(renderTile.id, c));
- }
-
- renderTile.tile.queryRenderedFeatures(result,
- tileSpaceQueryGeometry,
- transformState,
- options);
- }
-
- return result;
-}
-
-std::vector<Feature> Source::Impl::querySourceFeatures(const SourceQueryOptions& options) {
-
- // Only VectorSource and GeoJSON source supported
- if (type != SourceType::GeoJSON && type != SourceType::Vector) {
- Log::Warning(Event::General, "Source type not supported");
- return {};
- }
-
- std::vector<Feature> result;
-
- for (const auto& pair : tiles) {
- pair.second->querySourceFeatures(result, options);
- }
-
- return result;
-}
-
-void Source::Impl::setCacheSize(size_t size) {
- cache.setSize(size);
-}
-
-void Source::Impl::onLowMemory() {
- cache.clear();
-}
-
-void Source::Impl::setObserver(SourceObserver* observer_) {
- observer = observer_;
-}
-
-void Source::Impl::onTileChanged(Tile& tile) {
- observer->onTileChanged(base, tile.id);
-}
-
-void Source::Impl::onTileError(Tile& tile, std::exception_ptr error) {
- observer->onTileError(base, tile.id, error);
-}
-
void Source::Impl::dumpDebugLogs() const {
Log::Info(Event::General, "Source::id: %s", base.getID().c_str());
Log::Info(Event::General, "Source::loaded: %d", loaded);
+}
- for (const auto& pair : tiles) {
- pair.second->dumpDebugLogs();
- }
+void Source::Impl::setObserver(SourceObserver* observer_) {
+ observer = observer_;
}
} // namespace style
diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp
index 132d1b97f8..2514ec5120 100644
--- a/src/mbgl/style/source_impl.hpp
+++ b/src/mbgl/style/source_impl.hpp
@@ -1,117 +1,37 @@
#pragma once
#include <mbgl/style/source.hpp>
-
-#include <mbgl/tile/tile_id.hpp>
-#include <mbgl/tile/tile_observer.hpp>
-#include <mbgl/tile/tile.hpp>
-#include <mbgl/tile/tile_cache.hpp>
-#include <mbgl/style/types.hpp>
-#include <mbgl/map/query.hpp>
-
#include <mbgl/util/noncopyable.hpp>
-#include <mbgl/util/mat4.hpp>
-#include <mbgl/util/feature.hpp>
-#include <mbgl/util/range.hpp>
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-#include <map>
namespace mbgl {
-class Painter;
class FileSource;
-class TransformState;
-class RenderTile;
-class RenderedQueryOptions;
-
-namespace algorithm {
-class ClipIDGenerator;
-} // namespace algorithm
+class RenderSource;
namespace style {
-class UpdateParameters;
class SourceObserver;
-class Source::Impl : public TileObserver, private util::noncopyable {
+class Source::Impl : private util::noncopyable {
public:
Impl(SourceType, std::string id, Source&);
- ~Impl() override;
+ virtual ~Impl() = default;
virtual void loadDescription(FileSource&) = 0;
- bool isLoaded() const;
-
- // Called when the camera has changed. May load new tiles, unload obsolete tiles, or
- // trigger re-placement of existing complete tiles.
- void updateTiles(const UpdateParameters&);
-
- // Removes all tiles (by putting them into the cache).
- void removeTiles();
-
- // Remove all tiles and clear the cache.
- void invalidateTiles();
-
- // Request that all loaded tiles re-run the layout operation on the existing source
- // data with fresh style information.
- void reloadTiles();
-
- void startRender(algorithm::ClipIDGenerator&,
- const mat4& projMatrix,
- const mat4& clipMatrix,
- const TransformState&);
- void finishRender(Painter&);
-
- std::map<UnwrappedTileID, RenderTile>& getRenderTiles();
-
- std::unordered_map<std::string, std::vector<Feature>>
- queryRenderedFeatures(const ScreenLineString& geometry,
- const TransformState& transformState,
- const RenderedQueryOptions& options) const;
-
- std::vector<Feature> querySourceFeatures(const SourceQueryOptions&);
-
- void setCacheSize(size_t);
- void onLowMemory();
+ virtual std::unique_ptr<RenderSource> createRenderSource() const = 0;
- void setObserver(SourceObserver*);
- void dumpDebugLogs() const;
+ virtual optional<std::string> getAttribution() const { return {}; };
const SourceType type;
const std::string id;
- virtual optional<std::string> getAttribution() const { return {}; };
- virtual optional<Range<uint8_t>> getZoomRange() const = 0;
-
bool loaded = false;
-
- // Tracks whether the source is used by any layers visible at the current zoom level. Must
- // be initialized to true so that Style::isLoaded() does not produce false positives if
- // called before Style::recalculate().
- bool enabled = true;
-
- // Detaches from the style
- void detach();
-
-protected:
Source& base;
- SourceObserver* observer = nullptr;
- std::map<OverscaledTileID, std::unique_ptr<Tile>> tiles;
- TileCache cache;
-
-private:
- void removeStaleTiles(const std::set<OverscaledTileID>&);
-
- // TileObserver implementation.
- void onTileChanged(Tile&) override;
- void onTileError(Tile&, std::exception_ptr) override;
- virtual uint16_t getTileSize() const = 0;
- virtual std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) = 0;
+ void setObserver(SourceObserver*);
+ SourceObserver* observer = nullptr;
- std::map<UnwrappedTileID, RenderTile> renderTiles;
+ void dumpDebugLogs() const;
};
} // namespace style
diff --git a/src/mbgl/style/source_observer.hpp b/src/mbgl/style/source_observer.hpp
index c97ba19e84..c99eda955e 100644
--- a/src/mbgl/style/source_observer.hpp
+++ b/src/mbgl/style/source_observer.hpp
@@ -1,13 +1,8 @@
#pragma once
-#include <mbgl/tile/tile_observer.hpp>
-
#include <exception>
namespace mbgl {
-
-class OverscaledTileID;
-
namespace style {
class Source;
@@ -22,9 +17,6 @@ public:
// Source description needs to be reloaded
virtual void onSourceDescriptionChanged(Source&) {}
-
- virtual void onTileChanged(Source&, const OverscaledTileID&) {}
- virtual void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) {}
};
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index 62726cd127..110c1cd63c 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -4,7 +4,7 @@
namespace mbgl {
namespace style {
-GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions options)
+GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions& options)
: Source(SourceType::GeoJSON,
std::make_unique<GeoJSONSource::Impl>(std::move(id), *this, options)),
impl(static_cast<Impl*>(baseImpl.get())) {
diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp
index 6431d5faa4..08ed95ea3f 100644
--- a/src/mbgl/style/sources/geojson_source_impl.cpp
+++ b/src/mbgl/style/sources/geojson_source_impl.cpp
@@ -1,10 +1,12 @@
-#include <mbgl/util/logging.hpp>
-#include <mbgl/storage/file_source.hpp>
+#include <mbgl/style/sources/geojson_source_impl.hpp>
#include <mbgl/style/conversion/geojson.hpp>
#include <mbgl/style/source_observer.hpp>
-#include <mbgl/style/sources/geojson_source_impl.hpp>
-#include <mbgl/tile/geojson_tile.hpp>
+#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/renderer/sources/render_geojson_source.hpp>
#include <mbgl/util/rapidjson.hpp>
+#include <mbgl/util/constants.cpp>
+#include <mbgl/util/logging.hpp>
#include <mapbox/geojson.hpp>
#include <mapbox/geojson/rapidjson.hpp>
@@ -31,6 +33,34 @@ optional<GeoJSON> convertGeoJSON(const JSValue& value, Error& error) {
}
} // namespace conversion
+class GeoJSONVTData : public GeoJSONData {
+public:
+ GeoJSONVTData(const GeoJSON& geoJSON,
+ const mapbox::geojsonvt::Options& options)
+ : impl(geoJSON, options) {}
+
+ mapbox::geometry::feature_collection<int16_t> getTile(const CanonicalTileID& tileID) final {
+ return impl.getTile(tileID.z, tileID.x, tileID.y).features;
+ }
+
+private:
+ mapbox::geojsonvt::GeoJSONVT impl;
+};
+
+class SuperclusterData : public GeoJSONData {
+public:
+ SuperclusterData(const mapbox::geometry::feature_collection<double>& features,
+ const mapbox::supercluster::Options& options)
+ : impl(features, options) {}
+
+ mapbox::geometry::feature_collection<int16_t> getTile(const CanonicalTileID& tileID) final {
+ return impl.getTile(tileID.z, tileID.x, tileID.y);
+ }
+
+private:
+ mapbox::supercluster::Supercluster impl;
+};
+
GeoJSONSource::Impl::Impl(std::string id_, Source& base_, const GeoJSONOptions options_)
: Source::Impl(SourceType::GeoJSON, std::move(id_), base_), options(options_) {
}
@@ -52,18 +82,14 @@ optional<std::string> GeoJSONSource::Impl::getURL() const {
return url;
}
-
void GeoJSONSource::Impl::setGeoJSON(const GeoJSON& geoJSON) {
req.reset();
_setGeoJSON(geoJSON);
}
-// Private implementation
void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) {
double scale = util::EXTENT / util::tileSize;
- cache.clear();
-
if (options.cluster
&& geoJSON.is<mapbox::geometry::feature_collection<double>>()
&& !geoJSON.get<mapbox::geometry::feature_collection<double>>().empty()) {
@@ -71,35 +97,15 @@ void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) {
clusterOptions.maxZoom = options.clusterMaxZoom;
clusterOptions.extent = util::EXTENT;
clusterOptions.radius = std::round(scale * options.clusterRadius);
-
- const auto& features = geoJSON.get<mapbox::geometry::feature_collection<double>>();
- geoJSONOrSupercluster =
- std::make_unique<mapbox::supercluster::Supercluster>(features, clusterOptions);
+ data = std::make_unique<SuperclusterData>(
+ geoJSON.get<mapbox::geometry::feature_collection<double>>(), clusterOptions);
} else {
mapbox::geojsonvt::Options vtOptions;
vtOptions.maxZoom = options.maxzoom;
vtOptions.extent = util::EXTENT;
vtOptions.buffer = std::round(scale * options.buffer);
vtOptions.tolerance = scale * options.tolerance;
- geoJSONOrSupercluster = std::make_unique<mapbox::geojsonvt::GeoJSONVT>(geoJSON, vtOptions);
- }
-
- for (auto const &item : tiles) {
- GeoJSONTile* geoJSONTile = static_cast<GeoJSONTile*>(item.second.get());
- setTileData(*geoJSONTile, geoJSONTile->id);
- }
-}
-
-void GeoJSONSource::Impl::setTileData(GeoJSONTile& tile, const OverscaledTileID& tileID) {
- if (geoJSONOrSupercluster.is<GeoJSONVTPointer>()) {
- tile.updateData(geoJSONOrSupercluster.get<GeoJSONVTPointer>()->getTile(tileID.canonical.z,
- tileID.canonical.x,
- tileID.canonical.y).features);
- } else {
- assert(geoJSONOrSupercluster.is<SuperclusterPointer>());
- tile.updateData(geoJSONOrSupercluster.get<SuperclusterPointer>()->getTile(tileID.canonical.z,
- tileID.canonical.x,
- tileID.canonical.y));
+ data = std::make_unique<GeoJSONVTData>(geoJSON, vtOptions);
}
}
@@ -135,8 +141,6 @@ void GeoJSONSource::Impl::loadDescription(FileSource& fileSource) {
return;
}
- invalidateTiles();
-
conversion::Error error;
optional<GeoJSON> geoJSON = conversion::convertGeoJSON<JSValue>(d, error);
if (!geoJSON) {
@@ -155,19 +159,16 @@ void GeoJSONSource::Impl::loadDescription(FileSource& fileSource) {
});
}
-optional<Range<uint8_t>> GeoJSONSource::Impl::getZoomRange() const {
- if (loaded) {
- return { { 0, options.maxzoom }};
- }
- return {};
+std::unique_ptr<RenderSource> GeoJSONSource::Impl::createRenderSource() const {
+ return std::make_unique<RenderGeoJSONSource>(*this);
+}
+
+Range<uint8_t> GeoJSONSource::Impl::getZoomRange() const {
+ return { 0, options.maxzoom };
}
-std::unique_ptr<Tile> GeoJSONSource::Impl::createTile(const OverscaledTileID& tileID,
- const UpdateParameters& parameters) {
- assert(loaded);
- auto tilePointer = std::make_unique<GeoJSONTile>(tileID, base.getID(), parameters);
- setTileData(*tilePointer.get(), tileID);
- return std::move(tilePointer);
+GeoJSONData* GeoJSONSource::Impl::getData() const {
+ return data.get();
}
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp
index b827a0b26c..e8b881d05e 100644
--- a/src/mbgl/style/sources/geojson_source_impl.hpp
+++ b/src/mbgl/style/sources/geojson_source_impl.hpp
@@ -3,14 +3,19 @@
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/util/variant.hpp>
-#include <mbgl/tile/geojson_tile.hpp>
namespace mbgl {
class AsyncRequest;
+class CanonicalTileID;
namespace style {
+class GeoJSONData {
+public:
+ virtual mapbox::geometry::feature_collection<int16_t> getTile(const CanonicalTileID&) = 0;
+};
+
class GeoJSONSource::Impl : public Source::Impl {
public:
Impl(std::string id, Source&, const GeoJSONOptions);
@@ -18,27 +23,21 @@ public:
void setURL(std::string);
optional<std::string> getURL() const;
+ Range<uint8_t> getZoomRange() const;
void setGeoJSON(const GeoJSON&);
- void setTileData(GeoJSONTile&, const OverscaledTileID& tileID);
+ GeoJSONData* getData() const;
void loadDescription(FileSource&) final;
-
- uint16_t getTileSize() const final {
- return util::tileSize;
- }
-
- optional<Range<uint8_t>> getZoomRange() const final;
+ std::unique_ptr<RenderSource> createRenderSource() const final;
private:
void _setGeoJSON(const GeoJSON&);
- std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) final;
-
GeoJSONOptions options;
optional<std::string> url;
std::unique_ptr<AsyncRequest> req;
- variant<GeoJSONVTPointer, SuperclusterPointer> geoJSONOrSupercluster;
+ std::unique_ptr<GeoJSONData> data;
};
} // namespace style
diff --git a/src/mbgl/style/sources/raster_source_impl.cpp b/src/mbgl/style/sources/raster_source_impl.cpp
index b727651260..b85d221f2e 100644
--- a/src/mbgl/style/sources/raster_source_impl.cpp
+++ b/src/mbgl/style/sources/raster_source_impl.cpp
@@ -1,5 +1,5 @@
#include <mbgl/style/sources/raster_source_impl.hpp>
-#include <mbgl/tile/raster_tile.hpp>
+#include <mbgl/renderer/sources/render_raster_source.hpp>
namespace mbgl {
namespace style {
@@ -10,9 +10,8 @@ RasterSource::Impl::Impl(std::string id_, Source& base_,
: TileSourceImpl(SourceType::Raster, std::move(id_), base_, std::move(urlOrTileset_), tileSize_) {
}
-std::unique_ptr<Tile> RasterSource::Impl::createTile(const OverscaledTileID& tileID,
- const UpdateParameters& parameters) {
- return std::make_unique<RasterTile>(tileID, parameters, tileset);
+std::unique_ptr<RenderSource> RasterSource::Impl::createRenderSource() const {
+ return std::make_unique<RenderRasterSource>(*this);
}
} // namespace style
diff --git a/src/mbgl/style/sources/raster_source_impl.hpp b/src/mbgl/style/sources/raster_source_impl.hpp
index 6f34a050bb..4bc76560f8 100644
--- a/src/mbgl/style/sources/raster_source_impl.hpp
+++ b/src/mbgl/style/sources/raster_source_impl.hpp
@@ -10,8 +10,7 @@ class RasterSource::Impl : public TileSourceImpl {
public:
Impl(std::string id, Source&, variant<std::string, Tileset>, uint16_t tileSize);
-private:
- std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) final;
+ std::unique_ptr<RenderSource> createRenderSource() const final;
};
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source_impl.cpp b/src/mbgl/style/sources/vector_source_impl.cpp
index efe8afbbea..158abf8575 100644
--- a/src/mbgl/style/sources/vector_source_impl.cpp
+++ b/src/mbgl/style/sources/vector_source_impl.cpp
@@ -1,5 +1,6 @@
#include <mbgl/style/sources/vector_source_impl.hpp>
-#include <mbgl/tile/vector_tile.hpp>
+#include <mbgl/renderer/sources/render_vector_source.hpp>
+#include <mbgl/util/constants.hpp>
namespace mbgl {
namespace style {
@@ -8,9 +9,8 @@ VectorSource::Impl::Impl(std::string id_, Source& base_, variant<std::string, Ti
: TileSourceImpl(SourceType::Vector, std::move(id_), base_, std::move(urlOrTileset_), util::tileSize) {
}
-std::unique_ptr<Tile> VectorSource::Impl::createTile(const OverscaledTileID& tileID,
- const UpdateParameters& parameters) {
- return std::make_unique<VectorTile>(tileID, base.getID(), parameters, tileset);
+std::unique_ptr<RenderSource> VectorSource::Impl::createRenderSource() const {
+ return std::make_unique<RenderVectorSource>(*this);
}
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source_impl.hpp b/src/mbgl/style/sources/vector_source_impl.hpp
index 6726fa6955..844739948c 100644
--- a/src/mbgl/style/sources/vector_source_impl.hpp
+++ b/src/mbgl/style/sources/vector_source_impl.hpp
@@ -10,8 +10,7 @@ class VectorSource::Impl : public TileSourceImpl {
public:
Impl(std::string id, Source&, variant<std::string, Tileset>);
-private:
- std::unique_ptr<Tile> createTile(const OverscaledTileID&, const UpdateParameters&) final;
+ std::unique_ptr<RenderSource> createRenderSource() const final;
};
} // namespace style
diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp
index 0bc1841566..5fc9c40eba 100644
--- a/src/mbgl/style/style.cpp
+++ b/src/mbgl/style/style.cpp
@@ -22,6 +22,7 @@
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/geometry/line_atlas.hpp>
+#include <mbgl/renderer/render_source.hpp>
#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/renderer/render_background_layer.hpp>
@@ -32,12 +33,14 @@
#include <mbgl/renderer/render_line_layer.hpp>
#include <mbgl/renderer/render_raster_layer.hpp>
#include <mbgl/renderer/render_symbol_layer.hpp>
+#include <mbgl/tile/tile.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/geometry.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/math.hpp>
+#include <mbgl/util/std.hpp>
#include <mbgl/math/minmax.hpp>
#include <mbgl/map/query.hpp>
@@ -112,6 +115,7 @@ TransitionOptions Style::getTransitionOptions() const {
void Style::setJSON(const std::string& json) {
sources.clear();
+ renderSources.clear();
layers.clear();
renderLayers.clear();
classes.clear();
@@ -166,6 +170,10 @@ void Style::addSource(std::unique_ptr<Source> source) {
source->baseImpl->setObserver(this);
source->baseImpl->loadDescription(fileSource);
+ std::unique_ptr<RenderSource> renderSource = source->baseImpl->createRenderSource();
+ renderSource->setObserver(this);
+ renderSources.emplace_back(std::move(renderSource));
+
sources.emplace_back(std::move(source));
}
@@ -178,11 +186,14 @@ std::unique_ptr<Source> Style::removeSource(const std::string& id) {
return nullptr;
}
+ util::erase_if(renderSources, [&](const auto& source) {
+ return source->baseImpl.id == id;
+ });
+
auto source = std::move(*it);
sources.erase(it);
updateBatch.sourceIDs.erase(id);
- source->baseImpl->detach();
return source;
}
@@ -317,20 +328,20 @@ double Style::getDefaultPitch() const {
}
void Style::updateTiles(const UpdateParameters& parameters) {
- for (const auto& source : sources) {
- if (source->baseImpl->enabled) {
- source->baseImpl->updateTiles(parameters);
+ for (const auto& renderSource : renderSources) {
+ if (renderSource->enabled) {
+ renderSource->updateTiles(parameters);
}
}
}
void Style::relayout() {
for (const auto& sourceID : updateBatch.sourceIDs) {
- Source* source = getSource(sourceID);
- if (source && source->baseImpl->enabled) {
- source->baseImpl->reloadTiles();
- } else if (source) {
- source->baseImpl->invalidateTiles();
+ RenderSource* renderSource = getRenderSource(sourceID);
+ if (renderSource && renderSource->enabled) {
+ renderSource->reloadTiles();
+ } else if (renderSource) {
+ renderSource->invalidateTiles();
}
}
updateBatch.sourceIDs.clear();
@@ -363,8 +374,8 @@ void Style::cascade(const TimePoint& timePoint, MapMode mode) {
void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {
// Disable all sources first. If we find an enabled layer that uses this source, we will
// re-enable it later.
- for (const auto& source : sources) {
- source->baseImpl->enabled = false;
+ for (const auto& renderSource : renderSources) {
+ renderSource->enabled = false;
}
zoomHistory.update(z, timePoint);
@@ -380,24 +391,19 @@ void Style::recalculate(float z, const TimePoint& timePoint, MapMode mode) {
for (const auto& layer : renderLayers) {
hasPendingTransitions |= layer->evaluate(parameters);
- // Disable this layer if it doesn't need to be rendered.
- const bool needsRendering = layer->needsRendering(zoomHistory.lastZoom);
- if (!needsRendering) {
- continue;
- }
-
- // If this layer has a source, make sure that it gets loaded.
- if (Source* source = getSource(layer->baseImpl.source)) {
- source->baseImpl->enabled = true;
+ if (layer->needsRendering(zoomHistory.lastZoom)) {
+ if (RenderSource* renderSource = getRenderSource(layer->baseImpl.source)) {
+ renderSource->enabled = true;
+ }
}
}
evaluatedLight = EvaluatedLight(transitioningLight, parameters);
// Remove the existing tiles if we didn't end up re-enabling the source.
- for (const auto& source : sources) {
- if (!source->baseImpl->enabled) {
- source->baseImpl->removeTiles();
+ for (const auto& renderSource : renderSources) {
+ if (!renderSource->enabled) {
+ renderSource->removeTiles();
}
}
}
@@ -428,6 +434,14 @@ Source* Style::getSource(const std::string& id) const {
return it != sources.end() ? it->get() : nullptr;
}
+RenderSource* Style::getRenderSource(const std::string& id) const {
+ const auto it = std::find_if(renderSources.begin(), renderSources.end(), [&](const auto& source) {
+ return source->baseImpl.id == id;
+ });
+
+ return it != renderSources.end() ? it->get() : nullptr;
+}
+
bool Style::hasTransitions() const {
return hasPendingTransitions;
}
@@ -438,7 +452,13 @@ bool Style::isLoaded() const {
}
for (const auto& source: sources) {
- if (source->baseImpl->enabled && !source->baseImpl->isLoaded()) {
+ if (!source->baseImpl->loaded) {
+ return false;
+ }
+ }
+
+ for (const auto& renderSource: renderSources) {
+ if (!renderSource->isLoaded()) {
return false;
}
}
@@ -453,9 +473,9 @@ bool Style::isLoaded() const {
RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const {
RenderData result;
- for (const auto& source : sources) {
- if (source->baseImpl->enabled) {
- result.sources.insert(source.get());
+ for (const auto& renderSource: renderSources) {
+ if (renderSource->enabled) {
+ result.sources.insert(renderSource.get());
}
}
@@ -486,13 +506,13 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
continue;
}
- Source* source = getSource(layer->baseImpl.source);
+ RenderSource* source = getRenderSource(layer->baseImpl.source);
if (!source) {
Log::Warning(Event::Render, "can't find source for layer '%s'", layer->baseImpl.id.c_str());
continue;
}
- auto& renderTiles = source->baseImpl->getRenderTiles();
+ auto& renderTiles = source->getRenderTiles();
const bool symbolLayer = layer->is<RenderSymbolLayer>();
// Sort symbol tiles in opposite y position, so tiles with overlapping
@@ -557,26 +577,29 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
std::vector<Feature> Style::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState,
const RenderedQueryOptions& options) const {
- std::unordered_set<std::string> sourceFilter;
+ std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
if (options.layerIDs) {
+ std::unordered_set<std::string> sourceIDs;
for (const auto& layerID : *options.layerIDs) {
- auto layer = getLayer(layerID);
- if (layer) sourceFilter.emplace(layer->baseImpl->source);
+ if (Layer* layer = getLayer(layerID)) {
+ sourceIDs.emplace(layer->baseImpl->source);
+ }
+ }
+ for (const auto& sourceID : sourceIDs) {
+ if (RenderSource* renderSource = getRenderSource(sourceID)) {
+ auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, options);
+ std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
+ }
+ }
+ } else {
+ for (const auto& renderSource : renderSources) {
+ auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, options);
+ std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
}
}
std::vector<Feature> result;
- std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
-
- for (const auto& source : sources) {
- if (!sourceFilter.empty() && sourceFilter.find(source->getID()) == sourceFilter.end()) {
- continue;
- }
-
- auto sourceResults = source->baseImpl->queryRenderedFeatures(geometry, transformState, options);
- std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
- }
if (resultsByLayer.empty()) {
return result;
@@ -597,14 +620,14 @@ std::vector<Feature> Style::queryRenderedFeatures(const ScreenLineString& geomet
}
void Style::setSourceTileCacheSize(size_t size) {
- for (const auto& source : sources) {
- source->baseImpl->setCacheSize(size);
+ for (const auto& renderSource : renderSources) {
+ renderSource->setCacheSize(size);
}
}
void Style::onLowMemory() {
- for (const auto& source : sources) {
- source->baseImpl->onLowMemory();
+ for (const auto& renderSource : renderSources) {
+ renderSource->onLowMemory();
}
}
@@ -648,16 +671,14 @@ void Style::onSourceDescriptionChanged(Source& source) {
}
}
-void Style::onTileChanged(Source& source, const OverscaledTileID& tileID) {
- observer->onTileChanged(source, tileID);
+void Style::onTileChanged(RenderSource&, const OverscaledTileID&) {
observer->onUpdate(Update::Repaint);
}
-void Style::onTileError(Source& source, const OverscaledTileID& tileID, std::exception_ptr error) {
+void Style::onTileError(RenderSource& source, const OverscaledTileID& tileID, std::exception_ptr error) {
lastError = error;
Log::Error(Event::Style, "Failed to load tile %s for source %s: %s",
- util::toString(tileID).c_str(), source.getID().c_str(), util::toString(error).c_str());
- observer->onTileError(source, tileID, error);
+ util::toString(tileID).c_str(), source.baseImpl.id.c_str(), util::toString(error).c_str());
observer->onResourceError(error);
}
@@ -725,6 +746,10 @@ void Style::dumpDebugLogs() const {
source->baseImpl->dumpDebugLogs();
}
+ for (const auto& renderSource : renderSources) {
+ renderSource->dumpDebugLogs();
+ }
+
spriteAtlas->dumpDebugLogs();
}
diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp
index 26959c9fbf..6c80a2ef59 100644
--- a/src/mbgl/style/style.hpp
+++ b/src/mbgl/style/style.hpp
@@ -3,6 +3,7 @@
#include <mbgl/style/transition_options.hpp>
#include <mbgl/style/observer.hpp>
#include <mbgl/style/source_observer.hpp>
+#include <mbgl/renderer/render_source_observer.hpp>
#include <mbgl/style/layer_observer.hpp>
#include <mbgl/style/update_batch.hpp>
#include <mbgl/renderer/render_layer.hpp>
@@ -34,6 +35,7 @@ class TransformState;
class RenderedQueryOptions;
class Scheduler;
class RenderLayer;
+class RenderSource;
namespace style {
@@ -44,6 +46,7 @@ class QueryParameters;
class Style : public GlyphAtlasObserver,
public SpriteAtlasObserver,
public SourceObserver,
+ public RenderSourceObserver,
public LayerObserver,
public util::noncopyable {
public:
@@ -125,8 +128,12 @@ public:
TransitioningLight transitioningLight;
EvaluatedLight evaluatedLight;
+ RenderSource* getRenderSource(const std::string& id) const;
+
private:
std::vector<std::unique_ptr<Source>> sources;
+ std::vector<std::unique_ptr<RenderSource>> renderSources;
+
std::vector<std::unique_ptr<Layer>> layers;
std::vector<std::unique_ptr<RenderLayer>> renderLayers;
std::vector<std::string> classes;
@@ -156,8 +163,8 @@ private:
void onSourceChanged(Source&) override;
void onSourceError(Source&, std::exception_ptr) override;
void onSourceDescriptionChanged(Source&) override;
- void onTileChanged(Source&, const OverscaledTileID&) override;
- void onTileError(Source&, const OverscaledTileID&, std::exception_ptr) override;
+ void onTileChanged(RenderSource&, const OverscaledTileID&) override;
+ void onTileError(RenderSource&, const OverscaledTileID&, std::exception_ptr) override;
// LayerObserver implementation.
void onLayerFilterChanged(Layer&) override;
diff --git a/src/mbgl/style/tile_source_impl.cpp b/src/mbgl/style/tile_source_impl.cpp
index 9ea596d38b..4623714794 100644
--- a/src/mbgl/style/tile_source_impl.cpp
+++ b/src/mbgl/style/tile_source_impl.cpp
@@ -82,26 +82,7 @@ void TileSourceImpl::loadDescription(FileSource& fileSource) {
return;
}
- // Check whether previous information specifies different tile
- bool attributionChanged = false;
- if (tileset.tiles != newTileset.tiles) {
- // Tile URLs changed: force tiles to be reloaded.
- invalidateTiles();
-
- // Tile size changed: We need to recalculate the tiles we need to load because we
- // might have to load tiles for a different zoom level
- // This is done automatically when we trigger the onSourceLoaded observer below.
-
- // Min/Max zoom changed: We need to recalculate what tiles to load, if we have tiles
- // loaded that are outside the new zoom range
- // This is done automatically when we trigger the onSourceLoaded observer below.
-
- // Attribution changed: We need to notify the embedding application that this
- // changed.
- attributionChanged = true;
-
- // Center/bounds changed: We're not using these values currently
- }
+ bool attributionChanged = tileset.attribution != newTileset.attribution;
tileset = newTileset;
loaded = true;
@@ -114,9 +95,9 @@ void TileSourceImpl::loadDescription(FileSource& fileSource) {
});
}
-optional<Range<uint8_t>> TileSourceImpl::getZoomRange() const {
+optional<Tileset> TileSourceImpl::getTileset() const {
if (loaded) {
- return tileset.zoomRange;
+ return tileset;
}
return {};
}
diff --git a/src/mbgl/style/tile_source_impl.hpp b/src/mbgl/style/tile_source_impl.hpp
index 2993caf20a..405408ff54 100644
--- a/src/mbgl/style/tile_source_impl.hpp
+++ b/src/mbgl/style/tile_source_impl.hpp
@@ -26,7 +26,7 @@ public:
void loadDescription(FileSource&) final;
- uint16_t getTileSize() const final {
+ uint16_t getTileSize() const {
return tileSize;
}
@@ -35,7 +35,7 @@ public:
}
optional<std::string> getAttribution() const override;
- optional<Range<uint8_t>> getZoomRange() const final;
+ optional<Tileset> getTileset() const;
protected:
const variant<std::string, Tileset> urlOrTileset;