[core] fix circle querying for scale and alignment

This fixes circle querying for cases where either
    circle-pitch-alignment=map
or
    circle-pitch-scaling=viewport
This commit is contained in:
Chris Loer
2018-04-02 17:41:55 -07:00
committed by Ansis Brammanis
parent f7d20a5871
commit f86fe44dbd
39 changed files with 186 additions and 68 deletions

View File

@@ -64,8 +64,9 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry, RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const { const RenderedQueryOptions& options,
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
} }
std::vector<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const { std::vector<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const {

View File

@@ -27,7 +27,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const final; querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -36,7 +36,8 @@ void FeatureIndex::insert(const GeometryCollection& geometries,
void FeatureIndex::query( void FeatureIndex::query(
std::unordered_map<std::string, std::vector<Feature>>& result, std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const float bearing, const TransformState& transformState,
const mat4& posMatrix,
const double tileSize, const double tileSize,
const double scale, const double scale,
const RenderedQueryOptions& queryOptions, const RenderedQueryOptions& queryOptions,
@@ -68,7 +69,7 @@ void FeatureIndex::query(
if (indexedFeature.sortIndex == previousSortIndex) continue; if (indexedFeature.sortIndex == previousSortIndex) continue;
previousSortIndex = indexedFeature.sortIndex; previousSortIndex = indexedFeature.sortIndex;
addFeature(result, indexedFeature, queryOptions, tileID.canonical, layers, queryGeometry, bearing, pixelsToTileUnits); addFeature(result, indexedFeature, queryOptions, tileID.canonical, layers, queryGeometry, transformState, pixelsToTileUnits, posMatrix);
} }
} }
@@ -105,7 +106,7 @@ std::unordered_map<std::string, std::vector<Feature>> FeatureIndex::lookupSymbol
}); });
for (const auto& symbolFeature : sortedFeatures) { for (const auto& symbolFeature : sortedFeatures) {
addFeature(result, symbolFeature, queryOptions, tileID.canonical, layers, GeometryCoordinates(), 0, 0); addFeature(result, symbolFeature, queryOptions, tileID.canonical, layers, GeometryCoordinates(), {}, 0, {});
} }
return result; return result;
} }
@@ -117,8 +118,9 @@ void FeatureIndex::addFeature(
const CanonicalTileID& tileID, const CanonicalTileID& tileID,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const float bearing, const TransformState& transformState,
const float pixelsToTileUnits) const { const float pixelsToTileUnits,
const mat4& posMatrix) const {
auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* { auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* {
for (const auto& layer : layers) { for (const auto& layer : layers) {
@@ -148,7 +150,7 @@ void FeatureIndex::addFeature(
} }
if (!renderLayer->is<RenderSymbolLayer>() && if (!renderLayer->is<RenderSymbolLayer>() &&
!renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, bearing, pixelsToTileUnits)) { !renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, transformState, pixelsToTileUnits, posMatrix)) {
continue; continue;
} }

View File

@@ -5,6 +5,7 @@
#include <mbgl/tile/tile_id.hpp> #include <mbgl/tile/tile_id.hpp>
#include <mbgl/util/grid_index.hpp> #include <mbgl/util/grid_index.hpp>
#include <mbgl/util/feature.hpp> #include <mbgl/util/feature.hpp>
#include <mbgl/util/mat4.hpp>
#include <vector> #include <vector>
#include <string> #include <string>
@@ -14,6 +15,7 @@ namespace mbgl {
class RenderedQueryOptions; class RenderedQueryOptions;
class RenderLayer; class RenderLayer;
class TransformState;
class CollisionIndex; class CollisionIndex;
@@ -56,7 +58,8 @@ public:
void query( void query(
std::unordered_map<std::string, std::vector<Feature>>& result, std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const float bearing, const TransformState&,
const mat4& posMatrix,
const double tileSize, const double tileSize,
const double scale, const double scale,
const RenderedQueryOptions& options, const RenderedQueryOptions& options,
@@ -88,8 +91,9 @@ private:
const CanonicalTileID&, const CanonicalTileID&,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const float bearing, const TransformState& transformState,
const float pixelsToTileUnits) const; const float pixelsToTileUnits,
const mat4& posMatrix) const;
GridIndex<IndexedSubfeature> grid; GridIndex<IndexedSubfeature> grid;
unsigned int sortIndex = 0; unsigned int sortIndex = 0;

View File

@@ -421,4 +421,17 @@ float TransformState::getCameraToTileDistance(const UnwrappedTileID& tileID) con
return projectedCenter[3]; return projectedCenter[3];
} }
float TransformState::maxPitchScaleFactor() const {
if (size.isEmpty()) {
return {};
}
auto latLng = screenCoordinateToLatLng({ 0, static_cast<float>(getSize().height) });
mat4 mat = coordinatePointMatrix(getZoom());
Point<double> pt = Projection::project(latLng, scale) / double(util::tileSize);
vec4 p = {{ pt.x, pt.y, 0, 1 }};
vec4 topPoint;
matrix::transformMat4(topPoint, p, mat);
return topPoint[3] / getCameraToCenterDistance();
}
} // namespace mbgl } // namespace mbgl

View File

@@ -87,6 +87,7 @@ public:
} }
float getCameraToTileDistance(const UnwrappedTileID&) const; float getCameraToTileDistance(const UnwrappedTileID&) const;
float maxPitchScaleFactor() const;
private: private:
bool rotatedNorth() const; bool rotatedNorth() const;

View File

@@ -93,27 +93,75 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) {
} }
} }
GeometryCoordinate projectPoint(const GeometryCoordinate& p, const mat4& posMatrix, const Size& size) {
vec4 pos = {{ static_cast<double>(p.x), static_cast<double>(p.y), 0, 1 }};
matrix::transformMat4(pos, pos, posMatrix);
return {
static_cast<int16_t>((static_cast<float>(pos[0] / pos[3]) + 1) * size.width * 0.5),
static_cast<int16_t>((static_cast<float>(pos[1] / pos[3]) + 1) * size.height * 0.5)
};
}
GeometryCoordinates projectQueryGeometry(const GeometryCoordinates& queryGeometry, const mat4& posMatrix, const Size& size) {
GeometryCoordinates projectedGeometry;
for (auto& p : queryGeometry) {
projectedGeometry.push_back(projectPoint(p, posMatrix, size));
}
return projectedGeometry;
}
bool RenderCircleLayer::queryIntersectsFeature( bool RenderCircleLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature, const GeometryTileFeature& feature,
const float zoom, const float zoom,
const float bearing, const TransformState& transformState,
const float pixelsToTileUnits) const { const float pixelsToTileUnits,
const mat4& posMatrix) const {
// Translate query geometry // Translate query geometry
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( const GeometryCoordinates& translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, queryGeometry,
evaluated.get<style::CircleTranslate>(), evaluated.get<style::CircleTranslate>(),
evaluated.get<style::CircleTranslateAnchor>(), evaluated.get<style::CircleTranslateAnchor>(),
bearing, transformState.getAngle(),
pixelsToTileUnits); pixelsToTileUnits).value_or(queryGeometry);
// Evaluate functions // Evaluate functions
auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature) * pixelsToTileUnits; auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature);
auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(zoom, feature) * pixelsToTileUnits; auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(zoom, feature);
auto size = radius + stroke;
// Test intersection // For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile
return util::polygonIntersectsBufferedMultiPoint(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries(), radius + stroke); // Otherwise, compare geometry in the plane of the viewport
// A circle with fixed scaling relative to the viewport gets larger in tile space as it moves into the distance
// A circle with fixed scaling relative to the map gets smaller in viewport space as it moves into the distance
bool alignWithMap = evaluated.evaluate<style::CirclePitchAlignment>(zoom, feature) == AlignmentType::Map;
const GeometryCoordinates& transformedQueryGeometry = alignWithMap ?
translatedQueryGeometry :
projectQueryGeometry(translatedQueryGeometry, posMatrix, transformState.getSize());
auto transformedSize = alignWithMap ? size * pixelsToTileUnits : size;
auto geometry = feature.getGeometries();
for (auto& ring : geometry) {
for (auto& point : ring) {
const GeometryCoordinate& transformedPoint = alignWithMap ? point : projectPoint(point, posMatrix, transformState.getSize());
float adjustedSize = transformedSize;
vec4 center = {{ static_cast<double>(point.x), static_cast<double>(point.y), 0, 1 }};
matrix::transformMat4(center, center, posMatrix);
auto pitchScale = evaluated.evaluate<style::CirclePitchScale>(zoom, feature);
auto pitchAlignment = evaluated.evaluate<style::CirclePitchAlignment>(zoom, feature);
if (pitchScale == CirclePitchScaleType::Viewport && pitchAlignment == AlignmentType::Map) {
adjustedSize *= center[3] / transformState.getCameraToCenterDistance();
} else if (pitchScale == CirclePitchScaleType::Map && pitchAlignment == AlignmentType::Viewport) {
adjustedSize *= transformState.getCameraToCenterDistance() / center[3];
}
if (util::polygonIntersectsBufferedPoint(transformedQueryGeometry, transformedPoint, adjustedSize)) return true;
}
}
return false;
} }
} // namespace mbgl } // namespace mbgl

View File

@@ -20,8 +20,9 @@ public:
const GeometryCoordinates&, const GeometryCoordinates&,
const GeometryTileFeature&, const GeometryTileFeature&,
const float, const float,
const TransformState&,
const float, const float,
const float) const override; const mat4&) const override;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;

View File

@@ -151,14 +151,15 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature, const GeometryTileFeature& feature,
const float, const float,
const float bearing, const TransformState& transformState,
const float pixelsToTileUnits) const { const float pixelsToTileUnits,
const mat4&) const {
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, queryGeometry,
evaluated.get<style::FillExtrusionTranslate>(), evaluated.get<style::FillExtrusionTranslate>(),
evaluated.get<style::FillExtrusionTranslateAnchor>(), evaluated.get<style::FillExtrusionTranslateAnchor>(),
bearing, transformState.getAngle(),
pixelsToTileUnits); pixelsToTileUnits);
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries()); return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());

View File

@@ -22,8 +22,9 @@ public:
const GeometryCoordinates&, const GeometryCoordinates&,
const GeometryTileFeature&, const GeometryTileFeature&,
const float, const float,
const TransformState&,
const float, const float,
const float) const override; const mat4&) const override;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;

View File

@@ -188,14 +188,15 @@ bool RenderFillLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature, const GeometryTileFeature& feature,
const float, const float,
const float bearing, const TransformState& transformState,
const float pixelsToTileUnits) const { const float pixelsToTileUnits,
const mat4&) const {
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, queryGeometry,
evaluated.get<style::FillTranslate>(), evaluated.get<style::FillTranslate>(),
evaluated.get<style::FillTranslateAnchor>(), evaluated.get<style::FillTranslateAnchor>(),
bearing, transformState.getAngle(),
pixelsToTileUnits); pixelsToTileUnits);
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries()); return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());

View File

@@ -20,8 +20,9 @@ public:
const GeometryCoordinates&, const GeometryCoordinates&,
const GeometryTileFeature&, const GeometryTileFeature&,
const float, const float,
const TransformState&,
const float, const float,
const float) const override; const mat4&) const override;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;

View File

@@ -165,12 +165,12 @@ bool RenderHeatmapLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature, const GeometryTileFeature& feature,
const float zoom, const float zoom,
const float bearing, const TransformState&,
const float pixelsToTileUnits) const { const float pixelsToTileUnits,
const mat4&) const {
(void) queryGeometry; (void) queryGeometry;
(void) feature; (void) feature;
(void) zoom; (void) zoom;
(void) bearing;
(void) pixelsToTileUnits; (void) pixelsToTileUnits;
return false; return false;
} }

View File

@@ -22,8 +22,9 @@ public:
const GeometryCoordinates&, const GeometryCoordinates&,
const GeometryTileFeature&, const GeometryTileFeature&,
const float, const float,
const TransformState&,
const float, const float,
const float) const override; const mat4&) const override;
void updateColorRamp(); void updateColorRamp();

View File

@@ -162,15 +162,16 @@ bool RenderLineLayer::queryIntersectsFeature(
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const GeometryTileFeature& feature, const GeometryTileFeature& feature,
const float zoom, const float zoom,
const float bearing, const TransformState& transformState,
const float pixelsToTileUnits) const { const float pixelsToTileUnits,
const mat4&) const {
// Translate query geometry // Translate query geometry
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, queryGeometry,
evaluated.get<style::LineTranslate>(), evaluated.get<style::LineTranslate>(),
evaluated.get<style::LineTranslateAnchor>(), evaluated.get<style::LineTranslateAnchor>(),
bearing, transformState.getAngle(),
pixelsToTileUnits); pixelsToTileUnits);
// Evaluate function // Evaluate function

View File

@@ -29,8 +29,9 @@ public:
const GeometryCoordinates&, const GeometryCoordinates&,
const GeometryTileFeature&, const GeometryTileFeature&,
const float, const float,
const TransformState&,
const float, const float,
const float) const override; const mat4&) const override;
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override; std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;

View File

@@ -4,6 +4,7 @@
#include <mbgl/style/layer_impl.hpp> #include <mbgl/style/layer_impl.hpp>
#include <mbgl/style/layer_type.hpp> #include <mbgl/style/layer_type.hpp>
#include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/tile/geometry_tile_data.hpp>
#include <mbgl/util/mat4.hpp>
#include <memory> #include <memory>
#include <string> #include <string>
@@ -17,6 +18,7 @@ class PropertyEvaluationParameters;
class PaintParameters; class PaintParameters;
class RenderSource; class RenderSource;
class RenderTile; class RenderTile;
class TransformState;
class RenderLayer { class RenderLayer {
protected: protected:
@@ -69,8 +71,9 @@ public:
const GeometryCoordinates&, const GeometryCoordinates&,
const GeometryTileFeature&, const GeometryTileFeature&,
const float, const float,
const TransformState&,
const float, const float,
const float) const { return false; }; const mat4&) const { return false; };
virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0; virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0;

View File

@@ -64,7 +64,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const = 0; const RenderedQueryOptions& options,
const mat4& projMatrix) const = 0;
virtual std::vector<Feature> virtual std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const = 0; querySourceFeatures(const SourceQueryOptions&) const = 0;

View File

@@ -704,10 +704,13 @@ std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineStrin
sourceIDs.emplace(layer->baseImpl->source); sourceIDs.emplace(layer->baseImpl->source);
} }
mat4 projMatrix;
transformState.getProjMatrix(projMatrix);
std::unordered_map<std::string, std::vector<Feature>> resultsByLayer; std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
for (const auto& sourceID : sourceIDs) { for (const auto& sourceID : sourceIDs) {
if (RenderSource* renderSource = getRenderSource(sourceID)) { if (RenderSource* renderSource = getRenderSource(sourceID)) {
auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options); auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin())); std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
} }
} }

View File

@@ -67,8 +67,9 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry, RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const { const RenderedQueryOptions& options,
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
} }
std::vector<Feature> RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const { std::vector<Feature> RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const {

View File

@@ -27,7 +27,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const final; querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -85,8 +85,9 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry, RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const { const RenderedQueryOptions& options,
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
} }
std::vector<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const { std::vector<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const {

View File

@@ -31,7 +31,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const final; querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -84,7 +84,8 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderImageSource::queryRenderedFeatures(const ScreenLineString&, RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&, const TransformState&,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const RenderedQueryOptions&) const { const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>> {}; return std::unordered_map<std::string, std::vector<Feature>> {};
} }

View File

@@ -32,7 +32,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final; std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -146,7 +146,8 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&, RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&, const TransformState&,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const RenderedQueryOptions&) const { const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>> {}; return std::unordered_map<std::string, std::vector<Feature>> {};
} }

View File

@@ -27,7 +27,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const final; querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -76,7 +76,8 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&, RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
const TransformState&, const TransformState&,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const RenderedQueryOptions&) const { const RenderedQueryOptions&,
const mat4&) const {
return std::unordered_map<std::string, std::vector<Feature>> {}; return std::unordered_map<std::string, std::vector<Feature>> {};
} }

View File

@@ -27,7 +27,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const final; querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -79,8 +79,9 @@ std::unordered_map<std::string, std::vector<Feature>>
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry, RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const { const RenderedQueryOptions& options,
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); const mat4& projMatrix) const {
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
} }
std::vector<Feature> RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const { std::vector<Feature> RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const {

View File

@@ -27,7 +27,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const final; const RenderedQueryOptions& options,
const mat4& projMatrix) const final;
std::vector<Feature> std::vector<Feature>
querySourceFeatures(const SourceQueryOptions&) const final; querySourceFeatures(const SourceQueryOptions&) const final;

View File

@@ -241,7 +241,8 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry, std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) const { const RenderedQueryOptions& options,
const mat4& projMatrix) const {
std::unordered_map<std::string, std::vector<Feature>> result; std::unordered_map<std::string, std::vector<Feature>> result;
if (renderTiles.empty() || geometry.empty()) { if (renderTiles.empty() || geometry.empty()) {
return result; return result;
@@ -263,8 +264,11 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
std::tie(b.id.canonical.z, b.id.canonical.y, b.id.wrap, b.id.canonical.x); std::tie(b.id.canonical.z, b.id.canonical.y, b.id.wrap, b.id.canonical.x);
}); });
auto maxPitchScaleFactor = transformState.maxPitchScaleFactor();
for (const RenderTile& renderTile : sortedTiles) { for (const RenderTile& renderTile : sortedTiles) {
auto queryPadding = renderTile.tile.getQueryPadding(layers); const float scale = std::pow(2, transformState.getZoom() - renderTile.id.canonical.z);
auto queryPadding = maxPitchScaleFactor * renderTile.tile.getQueryPadding(layers) * util::EXTENT / util::tileSize / scale;
GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min); GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
if (tileSpaceBoundsMin.x - queryPadding >= util::EXTENT || tileSpaceBoundsMin.y - queryPadding >= util::EXTENT) { if (tileSpaceBoundsMin.x - queryPadding >= util::EXTENT || tileSpaceBoundsMin.y - queryPadding >= util::EXTENT) {
@@ -286,7 +290,8 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
tileSpaceQueryGeometry, tileSpaceQueryGeometry,
transformState, transformState,
layers, layers,
options); options,
projMatrix);
} }
return result; return result;

View File

@@ -53,7 +53,8 @@ public:
queryRenderedFeatures(const ScreenLineString& geometry, queryRenderedFeatures(const ScreenLineString& geometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const RenderedQueryOptions& options) const; const RenderedQueryOptions& options,
const mat4& projMatrix) const;
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const; std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const;

View File

@@ -217,21 +217,27 @@ void GeometryTile::queryRenderedFeatures(
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const TransformState& transformState, const TransformState& transformState,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) { const RenderedQueryOptions& options,
const mat4& projMatrix) {
if (!getData()) return; if (!getData()) return;
const float queryPadding = getQueryPadding(layers); const float queryPadding = getQueryPadding(layers);
mat4 posMatrix;
transformState.matrixFor(posMatrix, id.toUnwrapped());
matrix::multiply(posMatrix, projMatrix, posMatrix);
latestFeatureIndex->query(result, latestFeatureIndex->query(result,
queryGeometry, queryGeometry,
transformState.getAngle(), transformState,
posMatrix,
util::tileSize * id.overscaleFactor(), util::tileSize * id.overscaleFactor(),
std::pow(2, transformState.getZoom() - id.overscaledZ), std::pow(2, transformState.getZoom() - id.overscaledZ),
options, options,
id.toUnwrapped(), id.toUnwrapped(),
layers, layers,
queryPadding); queryPadding * transformState.maxPitchScaleFactor());
} }
void GeometryTile::querySourceFeatures( void GeometryTile::querySourceFeatures(

View File

@@ -54,7 +54,8 @@ public:
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const TransformState&, const TransformState&,
const std::vector<const RenderLayer*>& layers, const std::vector<const RenderLayer*>& layers,
const RenderedQueryOptions& options) override; const RenderedQueryOptions& options,
const mat4& projMatrix) override;
void querySourceFeatures( void querySourceFeatures(
std::vector<Feature>& result, std::vector<Feature>& result,

View File

@@ -37,7 +37,8 @@ void Tile::queryRenderedFeatures(
const GeometryCoordinates&, const GeometryCoordinates&,
const TransformState&, const TransformState&,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const RenderedQueryOptions&) {} const RenderedQueryOptions&,
const mat4&) {}
float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) { float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) {
return 0; return 0;

View File

@@ -57,7 +57,8 @@ public:
const GeometryCoordinates& queryGeometry, const GeometryCoordinates& queryGeometry,
const TransformState&, const TransformState&,
const std::vector<const RenderLayer*>&, const std::vector<const RenderLayer*>&,
const RenderedQueryOptions& options); const RenderedQueryOptions& options,
const mat4& projMatrix);
virtual void querySourceFeatures( virtual void querySourceFeatures(
std::vector<Feature>& result, std::vector<Feature>& result,

View File

@@ -82,11 +82,16 @@ bool lineIntersectsBufferedLine(const GeometryCoordinates& lineA, const Geometry
return false; return false;
} }
bool polygonIntersectsBufferedPoint(const GeometryCoordinates& polygon, const GeometryCoordinate& point, float radius) {
if (polygonContainsPoint(polygon, point)) return true;
if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
return false;
}
bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates& polygon, const GeometryCollection& rings, float radius) { bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates& polygon, const GeometryCollection& rings, float radius) {
for (auto& ring : rings) { for (auto& ring : rings) {
for (auto& point : ring) { for (auto& point : ring) {
if (polygonContainsPoint(polygon, point)) return true; if (polygonIntersectsBufferedPoint(polygon, point, radius)) return true;
if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
} }
} }
return false; return false;

View File

@@ -9,6 +9,7 @@ bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates&, const Geome
bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius); bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius);
bool polygonIntersectsPolygon(const GeometryCoordinates&, const GeometryCoordinates&); bool polygonIntersectsPolygon(const GeometryCoordinates&, const GeometryCoordinates&);
bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&); bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&);
bool polygonIntersectsBufferedPoint(const GeometryCoordinates& polygon, const GeometryCoordinate& point, float radius);
} // namespace util } // namespace util
} // namespace mbgl } // namespace mbgl