[core] fix querying circles across tile boundaries
This commit is contained in:
committed by
Ansis Brammanis
parent
0767bf0686
commit
f7d20a5871
@@ -42,7 +42,7 @@ void FeatureIndex::query(
|
||||
const RenderedQueryOptions& queryOptions,
|
||||
const UnwrappedTileID& tileID,
|
||||
const std::vector<const RenderLayer*>& layers,
|
||||
const float additionalQueryRadius) const {
|
||||
const float additionalQueryPadding) const {
|
||||
|
||||
if (!tileData) {
|
||||
return;
|
||||
@@ -50,12 +50,12 @@ void FeatureIndex::query(
|
||||
|
||||
// Determine query radius
|
||||
const float pixelsToTileUnits = util::EXTENT / tileSize / scale;
|
||||
const int16_t additionalRadius = std::min<int16_t>(util::EXTENT, additionalQueryRadius * pixelsToTileUnits);
|
||||
const int16_t additionalPadding = std::min<int16_t>(util::EXTENT, additionalQueryPadding * pixelsToTileUnits);
|
||||
|
||||
// Query the grid index
|
||||
mapbox::geometry::box<int16_t> box = mapbox::geometry::envelope(queryGeometry);
|
||||
std::vector<IndexedSubfeature> features = grid.query({ convertPoint<float>(box.min - additionalRadius),
|
||||
convertPoint<float>(box.max + additionalRadius) });
|
||||
std::vector<IndexedSubfeature> features = grid.query({ convertPoint<float>(box.min - additionalPadding),
|
||||
convertPoint<float>(box.max + additionalPadding) });
|
||||
|
||||
|
||||
std::sort(features.begin(), features.end(), [](const IndexedSubfeature& a, const IndexedSubfeature& b) {
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
const RenderedQueryOptions& options,
|
||||
const UnwrappedTileID&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const float additionalQueryRadius) const;
|
||||
const float additionalQueryPadding) const;
|
||||
|
||||
static optional<GeometryCoordinates> translateQueryGeometry(
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
|
||||
@@ -264,13 +264,15 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
|
||||
});
|
||||
|
||||
for (const RenderTile& renderTile : sortedTiles) {
|
||||
auto queryPadding = renderTile.tile.getQueryPadding(layers);
|
||||
|
||||
GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
|
||||
if (tileSpaceBoundsMin.x >= util::EXTENT || tileSpaceBoundsMin.y >= util::EXTENT) {
|
||||
if (tileSpaceBoundsMin.x - queryPadding >= util::EXTENT || tileSpaceBoundsMin.y - queryPadding >= util::EXTENT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
GeometryCoordinate tileSpaceBoundsMax = TileCoordinate::toGeometryCoordinate(renderTile.id, box.max);
|
||||
if (tileSpaceBoundsMax.x < 0 || tileSpaceBoundsMax.y < 0) {
|
||||
if (tileSpaceBoundsMax.x + queryPadding < 0 || tileSpaceBoundsMax.y + queryPadding < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,17 @@ Bucket* GeometryTile::getBucket(const Layer::Impl& layer) const {
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
float GeometryTile::getQueryPadding(const std::vector<const RenderLayer*>& layers) {
|
||||
float queryPadding = 0;
|
||||
for (const RenderLayer* layer : layers) {
|
||||
auto bucket = getBucket(*layer->baseImpl);
|
||||
if (bucket) {
|
||||
queryPadding = std::max(queryPadding, bucket->getQueryRadius(*layer));
|
||||
}
|
||||
}
|
||||
return queryPadding;
|
||||
}
|
||||
|
||||
void GeometryTile::queryRenderedFeatures(
|
||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
@@ -210,14 +221,7 @@ void GeometryTile::queryRenderedFeatures(
|
||||
|
||||
if (!getData()) return;
|
||||
|
||||
// Determine the additional radius needed factoring in property functions
|
||||
float additionalRadius = 0;
|
||||
for (const RenderLayer* layer : layers) {
|
||||
auto bucket = getBucket(*layer->baseImpl);
|
||||
if (bucket) {
|
||||
additionalRadius = std::max(additionalRadius, bucket->getQueryRadius(*layer));
|
||||
}
|
||||
}
|
||||
const float queryPadding = getQueryPadding(layers);
|
||||
|
||||
latestFeatureIndex->query(result,
|
||||
queryGeometry,
|
||||
@@ -227,7 +231,7 @@ void GeometryTile::queryRenderedFeatures(
|
||||
options,
|
||||
id.toUnwrapped(),
|
||||
layers,
|
||||
additionalRadius);
|
||||
queryPadding);
|
||||
}
|
||||
|
||||
void GeometryTile::querySourceFeatures(
|
||||
|
||||
@@ -60,6 +60,8 @@ public:
|
||||
std::vector<Feature>& result,
|
||||
const SourceQueryOptions&) override;
|
||||
|
||||
float getQueryPadding(const std::vector<const RenderLayer*>&) override;
|
||||
|
||||
void cancel() override;
|
||||
|
||||
class LayoutResult {
|
||||
|
||||
@@ -39,6 +39,10 @@ void Tile::queryRenderedFeatures(
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions&) {}
|
||||
|
||||
float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Tile::querySourceFeatures(
|
||||
std::vector<Feature>&,
|
||||
const SourceQueryOptions&) {}
|
||||
|
||||
@@ -63,6 +63,8 @@ public:
|
||||
std::vector<Feature>& result,
|
||||
const SourceQueryOptions&);
|
||||
|
||||
virtual float getQueryPadding(const std::vector<const RenderLayer*>&);
|
||||
|
||||
void setTriedCache();
|
||||
|
||||
// Returns true when the tile source has received a first response, regardless of whether a load
|
||||
|
||||
Reference in New Issue
Block a user