Port global symbol query from GL JS:

- Symbol querying is now global instead of per-tile
 - Symbols that bleed over tile boundaries no longer missed in queries
 - Symbol results now sorted based on rendering order (ie overlapping symbols change their sort order when a bearing change causes their render order to change)
 - Placement::retainedQueryData now responsible for maintaining symbol querying data for buckets that may no longer be in the TilePyramid.
This commit is contained in:
Chris Loer
2018-04-18 16:33:37 -07:00
committed by Chris Loer
parent eb39c80604
commit a62745edf9
35 changed files with 218 additions and 197 deletions

View File

@@ -396,10 +396,6 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) {
}
placementChanged = newPlacement->commit(*placement, parameters.timePoint);
// commitFeatureIndexes depends on the assumption that no new FeatureIndex has been loaded since placement
// started. If we violate this assumption, then we need to either make CollisionIndex completely independendent of
// FeatureIndex, or find a way for its entries to point to multiple FeatureIndexes.
commitFeatureIndexes();
crossTileSymbolIndex.pruneUnusedLayers(usedSymbolLayers);
if (placementChanged || symbolBucketsChanged) {
placement = std::move(newPlacement);
@@ -668,6 +664,39 @@ std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineStrin
return queryRenderedFeatures(geometry, options, layers);
}
void Renderer::Impl::queryRenderedSymbols(std::unordered_map<std::string, std::vector<Feature>>& resultsByLayer,
const ScreenLineString& geometry,
const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const {
auto renderedSymbols = placement->getCollisionIndex().queryRenderedSymbols(geometry);
std::vector<std::reference_wrapper<const RetainedQueryData>> bucketQueryData;
for (auto entry : renderedSymbols) {
bucketQueryData.push_back(placement->getQueryData(entry.first));
}
// Although symbol query is global, symbol results are only sortable within a bucket
// For a predictable global sort order, we sort the buckets based on their corresponding tile position
std::sort(bucketQueryData.begin(), bucketQueryData.end(), [](const RetainedQueryData& a, const RetainedQueryData& b) {
return
std::tie(a.tileID.canonical.z, a.tileID.canonical.y, a.tileID.wrap, a.tileID.canonical.x) <
std::tie(b.tileID.canonical.z, b.tileID.canonical.y, b.tileID.wrap, b.tileID.canonical.x);
});
for (auto wrappedQueryData : bucketQueryData) {
auto& queryData = wrappedQueryData.get();
auto bucketSymbols = queryData.featureIndex->lookupSymbolFeatures(renderedSymbols[queryData.bucketInstanceId],
options,
layers,
queryData.tileID,
queryData.featureSortOrder);
for (auto layer : bucketSymbols) {
auto& resultFeatures = resultsByLayer[layer.first];
std::move(layer.second.begin(), layer.second.end(), std::inserter(resultFeatures, resultFeatures.end()));
}
}
}
std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options, const std::vector<const RenderLayer*>& layers) const {
std::unordered_set<std::string> sourceIDs;
@@ -678,10 +707,12 @@ std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineStrin
std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
for (const auto& sourceID : sourceIDs) {
if (RenderSource* renderSource = getRenderSource(sourceID)) {
auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options, placement->getCollisionIndex());
auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options);
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
}
}
queryRenderedSymbols(resultsByLayer, geometry, layers, options);
std::vector<Feature> result;
@@ -780,15 +811,6 @@ bool Renderer::Impl::hasTransitions(TimePoint timePoint) const {
return false;
}
void Renderer::Impl::commitFeatureIndexes() {
for (auto& source : renderSources) {
for (auto& renderTile : source.second->getRenderTiles()) {
Tile& tile = renderTile.get().tile;
tile.commitFeatureIndex();
}
}
}
void Renderer::Impl::updateFadingTiles() {
fadingTiles = false;
for (auto& source : renderSources) {