From f86fe44dbd4de44c9fc8cb364521f966039289d7 Mon Sep 17 00:00:00 2001 From: Chris Loer Date: Mon, 2 Apr 2018 17:41:55 -0700 Subject: [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 --- src/mbgl/annotation/render_annotation_source.cpp | 5 +- src/mbgl/annotation/render_annotation_source.hpp | 3 +- src/mbgl/geometry/feature_index.cpp | 14 +++-- src/mbgl/geometry/feature_index.hpp | 10 +++- src/mbgl/map/transform_state.cpp | 13 +++++ src/mbgl/map/transform_state.hpp | 1 + src/mbgl/renderer/layers/render_circle_layer.cpp | 66 +++++++++++++++++++--- src/mbgl/renderer/layers/render_circle_layer.hpp | 3 +- .../layers/render_fill_extrusion_layer.cpp | 7 ++- .../layers/render_fill_extrusion_layer.hpp | 3 +- src/mbgl/renderer/layers/render_fill_layer.cpp | 7 ++- src/mbgl/renderer/layers/render_fill_layer.hpp | 3 +- src/mbgl/renderer/layers/render_heatmap_layer.cpp | 6 +- src/mbgl/renderer/layers/render_heatmap_layer.hpp | 3 +- src/mbgl/renderer/layers/render_line_layer.cpp | 7 ++- src/mbgl/renderer/layers/render_line_layer.hpp | 3 +- src/mbgl/renderer/render_layer.hpp | 5 +- src/mbgl/renderer/render_source.hpp | 3 +- src/mbgl/renderer/renderer_impl.cpp | 5 +- .../sources/render_custom_geometry_source.cpp | 5 +- .../sources/render_custom_geometry_source.hpp | 3 +- .../renderer/sources/render_geojson_source.cpp | 5 +- .../renderer/sources/render_geojson_source.hpp | 3 +- src/mbgl/renderer/sources/render_image_source.cpp | 3 +- src/mbgl/renderer/sources/render_image_source.hpp | 3 +- .../renderer/sources/render_raster_dem_source.cpp | 3 +- .../renderer/sources/render_raster_dem_source.hpp | 3 +- src/mbgl/renderer/sources/render_raster_source.cpp | 3 +- src/mbgl/renderer/sources/render_raster_source.hpp | 3 +- src/mbgl/renderer/sources/render_vector_source.cpp | 5 +- src/mbgl/renderer/sources/render_vector_source.hpp | 3 +- src/mbgl/renderer/tile_pyramid.cpp | 11 +++- src/mbgl/renderer/tile_pyramid.hpp | 3 +- src/mbgl/tile/geometry_tile.cpp | 12 +++- src/mbgl/tile/geometry_tile.hpp | 3 +- src/mbgl/tile/tile.cpp | 3 +- src/mbgl/tile/tile.hpp | 3 +- src/mbgl/util/intersection_tests.cpp | 9 ++- src/mbgl/util/intersection_tests.hpp | 1 + 39 files changed, 186 insertions(+), 68 deletions(-) diff --git a/src/mbgl/annotation/render_annotation_source.cpp b/src/mbgl/annotation/render_annotation_source.cpp index 19d19d2901..7d776f21c4 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -64,8 +64,9 @@ std::unordered_map> RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); + const RenderedQueryOptions& options, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix); } std::vector RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const { diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp index da5376ab2d..da87d13814 100644 --- a/src/mbgl/annotation/render_annotation_source.hpp +++ b/src/mbgl/annotation/render_annotation_source.hpp @@ -27,7 +27,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index 728996a2eb..e7759b0868 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -36,7 +36,8 @@ void FeatureIndex::insert(const GeometryCollection& geometries, void FeatureIndex::query( std::unordered_map>& result, const GeometryCoordinates& queryGeometry, - const float bearing, + const TransformState& transformState, + const mat4& posMatrix, const double tileSize, const double scale, const RenderedQueryOptions& queryOptions, @@ -68,7 +69,7 @@ void FeatureIndex::query( if (indexedFeature.sortIndex == previousSortIndex) continue; 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> FeatureIndex::lookupSymbol }); 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; } @@ -117,8 +118,9 @@ void FeatureIndex::addFeature( const CanonicalTileID& tileID, const std::vector& layers, const GeometryCoordinates& queryGeometry, - const float bearing, - const float pixelsToTileUnits) const { + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4& posMatrix) const { auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* { for (const auto& layer : layers) { @@ -148,7 +150,7 @@ void FeatureIndex::addFeature( } if (!renderLayer->is() && - !renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, bearing, pixelsToTileUnits)) { + !renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, transformState, pixelsToTileUnits, posMatrix)) { continue; } diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp index f105260c0c..cc91791d36 100644 --- a/src/mbgl/geometry/feature_index.hpp +++ b/src/mbgl/geometry/feature_index.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -14,6 +15,7 @@ namespace mbgl { class RenderedQueryOptions; class RenderLayer; +class TransformState; class CollisionIndex; @@ -56,7 +58,8 @@ public: void query( std::unordered_map>& result, const GeometryCoordinates& queryGeometry, - const float bearing, + const TransformState&, + const mat4& posMatrix, const double tileSize, const double scale, const RenderedQueryOptions& options, @@ -88,8 +91,9 @@ private: const CanonicalTileID&, const std::vector&, const GeometryCoordinates& queryGeometry, - const float bearing, - const float pixelsToTileUnits) const; + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4& posMatrix) const; GridIndex grid; unsigned int sortIndex = 0; diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp index 18d2c24aee..a85b251fb4 100644 --- a/src/mbgl/map/transform_state.cpp +++ b/src/mbgl/map/transform_state.cpp @@ -421,4 +421,17 @@ float TransformState::getCameraToTileDistance(const UnwrappedTileID& tileID) con return projectedCenter[3]; } +float TransformState::maxPitchScaleFactor() const { + if (size.isEmpty()) { + return {}; + } + auto latLng = screenCoordinateToLatLng({ 0, static_cast(getSize().height) }); + mat4 mat = coordinatePointMatrix(getZoom()); + Point 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 diff --git a/src/mbgl/map/transform_state.hpp b/src/mbgl/map/transform_state.hpp index 451802034d..b6f8ae4424 100644 --- a/src/mbgl/map/transform_state.hpp +++ b/src/mbgl/map/transform_state.hpp @@ -87,6 +87,7 @@ public: } float getCameraToTileDistance(const UnwrappedTileID&) const; + float maxPitchScaleFactor() const; private: bool rotatedNorth() const; diff --git a/src/mbgl/renderer/layers/render_circle_layer.cpp b/src/mbgl/renderer/layers/render_circle_layer.cpp index 6092ff5452..6e1c867a30 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.cpp +++ b/src/mbgl/renderer/layers/render_circle_layer.cpp @@ -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(p.x), static_cast(p.y), 0, 1 }}; + matrix::transformMat4(pos, pos, posMatrix); + return { + static_cast((static_cast(pos[0] / pos[3]) + 1) * size.width * 0.5), + static_cast((static_cast(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( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, const float zoom, - const float bearing, - const float pixelsToTileUnits) const { + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4& posMatrix) const { // Translate query geometry - auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( + const GeometryCoordinates& translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), evaluated.get(), - bearing, - pixelsToTileUnits); + transformState.getAngle(), + pixelsToTileUnits).value_or(queryGeometry); // Evaluate functions - auto radius = evaluated.evaluate(zoom, feature) * pixelsToTileUnits; - auto stroke = evaluated.evaluate(zoom, feature) * pixelsToTileUnits; + auto radius = evaluated.evaluate(zoom, feature); + auto stroke = evaluated.evaluate(zoom, feature); + auto size = radius + stroke; + + // For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile + // 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(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(point.x), static_cast(point.y), 0, 1 }}; + matrix::transformMat4(center, center, posMatrix); + auto pitchScale = evaluated.evaluate(zoom, feature); + auto pitchAlignment = evaluated.evaluate(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; + } + } - // Test intersection - return util::polygonIntersectsBufferedMultiPoint(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries(), radius + stroke); + return false; } } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_circle_layer.hpp b/src/mbgl/renderer/layers/render_circle_layer.hpp index f31715f98f..c9eeae4652 100644 --- a/src/mbgl/renderer/layers/render_circle_layer.hpp +++ b/src/mbgl/renderer/layers/render_circle_layer.hpp @@ -20,8 +20,9 @@ public: const GeometryCoordinates&, const GeometryTileFeature&, const float, + const TransformState&, const float, - const float) const override; + const mat4&) const override; std::unique_ptr createBucket(const BucketParameters&, const std::vector&) const override; diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp index fbd6160e8a..871464223c 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.cpp @@ -151,14 +151,15 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, const float, - const float bearing, - const float pixelsToTileUnits) const { + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4&) const { auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), evaluated.get(), - bearing, + transformState.getAngle(), pixelsToTileUnits); return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries()); diff --git a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp index 838494cf91..f7ba13c267 100644 --- a/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_extrusion_layer.hpp @@ -22,8 +22,9 @@ public: const GeometryCoordinates&, const GeometryTileFeature&, const float, + const TransformState&, const float, - const float) const override; + const mat4&) const override; std::unique_ptr createBucket(const BucketParameters&, const std::vector&) const override; diff --git a/src/mbgl/renderer/layers/render_fill_layer.cpp b/src/mbgl/renderer/layers/render_fill_layer.cpp index 22cb9563c1..efd3f4215c 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.cpp +++ b/src/mbgl/renderer/layers/render_fill_layer.cpp @@ -188,14 +188,15 @@ bool RenderFillLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, const float, - const float bearing, - const float pixelsToTileUnits) const { + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4&) const { auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), evaluated.get(), - bearing, + transformState.getAngle(), pixelsToTileUnits); return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries()); diff --git a/src/mbgl/renderer/layers/render_fill_layer.hpp b/src/mbgl/renderer/layers/render_fill_layer.hpp index a51865698f..bd195fb828 100644 --- a/src/mbgl/renderer/layers/render_fill_layer.hpp +++ b/src/mbgl/renderer/layers/render_fill_layer.hpp @@ -20,8 +20,9 @@ public: const GeometryCoordinates&, const GeometryTileFeature&, const float, + const TransformState&, const float, - const float) const override; + const mat4&) const override; std::unique_ptr createBucket(const BucketParameters&, const std::vector&) const override; diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.cpp b/src/mbgl/renderer/layers/render_heatmap_layer.cpp index 4f2e899220..72c60446aa 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.cpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.cpp @@ -165,12 +165,12 @@ bool RenderHeatmapLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, const float zoom, - const float bearing, - const float pixelsToTileUnits) const { + const TransformState&, + const float pixelsToTileUnits, + const mat4&) const { (void) queryGeometry; (void) feature; (void) zoom; - (void) bearing; (void) pixelsToTileUnits; return false; } diff --git a/src/mbgl/renderer/layers/render_heatmap_layer.hpp b/src/mbgl/renderer/layers/render_heatmap_layer.hpp index 3f0b1f91b4..29fad7d8b8 100644 --- a/src/mbgl/renderer/layers/render_heatmap_layer.hpp +++ b/src/mbgl/renderer/layers/render_heatmap_layer.hpp @@ -22,8 +22,9 @@ public: const GeometryCoordinates&, const GeometryTileFeature&, const float, + const TransformState&, const float, - const float) const override; + const mat4&) const override; void updateColorRamp(); diff --git a/src/mbgl/renderer/layers/render_line_layer.cpp b/src/mbgl/renderer/layers/render_line_layer.cpp index 1b4a1c0ff7..02f61af0fa 100644 --- a/src/mbgl/renderer/layers/render_line_layer.cpp +++ b/src/mbgl/renderer/layers/render_line_layer.cpp @@ -162,15 +162,16 @@ bool RenderLineLayer::queryIntersectsFeature( const GeometryCoordinates& queryGeometry, const GeometryTileFeature& feature, const float zoom, - const float bearing, - const float pixelsToTileUnits) const { + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4&) const { // Translate query geometry auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry( queryGeometry, evaluated.get(), evaluated.get(), - bearing, + transformState.getAngle(), pixelsToTileUnits); // Evaluate function diff --git a/src/mbgl/renderer/layers/render_line_layer.hpp b/src/mbgl/renderer/layers/render_line_layer.hpp index 8bf7e2329d..5d5d79c044 100644 --- a/src/mbgl/renderer/layers/render_line_layer.hpp +++ b/src/mbgl/renderer/layers/render_line_layer.hpp @@ -29,8 +29,9 @@ public: const GeometryCoordinates&, const GeometryTileFeature&, const float, + const TransformState&, const float, - const float) const override; + const mat4&) const override; std::unique_ptr createBucket(const BucketParameters&, const std::vector&) const override; diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 55831cb72c..04a1608564 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,7 @@ class PropertyEvaluationParameters; class PaintParameters; class RenderSource; class RenderTile; +class TransformState; class RenderLayer { protected: @@ -69,8 +71,9 @@ public: const GeometryCoordinates&, const GeometryTileFeature&, const float, + const TransformState&, const float, - const float) const { return false; }; + const mat4&) const { return false; }; virtual std::unique_ptr createBucket(const BucketParameters&, const std::vector&) const = 0; diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index 54a0b5db43..dc80cb1dc6 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -64,7 +64,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const = 0; + const RenderedQueryOptions& options, + const mat4& projMatrix) const = 0; virtual std::vector querySourceFeatures(const SourceQueryOptions&) const = 0; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 5b739678fb..ded07a0909 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -704,10 +704,13 @@ std::vector Renderer::Impl::queryRenderedFeatures(const ScreenLineStrin sourceIDs.emplace(layer->baseImpl->source); } + mat4 projMatrix; + transformState.getProjMatrix(projMatrix); + std::unordered_map> resultsByLayer; for (const auto& sourceID : sourceIDs) { 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())); } } diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp index 88792db00b..2d28b8dd84 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp @@ -67,8 +67,9 @@ std::unordered_map> RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); + const RenderedQueryOptions& options, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix); } std::vector RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const { diff --git a/src/mbgl/renderer/sources/render_custom_geometry_source.hpp b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp index 9e47b9e392..5533fe2b83 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.hpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp @@ -27,7 +27,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/sources/render_geojson_source.cpp b/src/mbgl/renderer/sources/render_geojson_source.cpp index 7492a4cf16..0e265efff4 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -85,8 +85,9 @@ std::unordered_map> RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); + const RenderedQueryOptions& options, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix); } std::vector RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const { diff --git a/src/mbgl/renderer/sources/render_geojson_source.hpp b/src/mbgl/renderer/sources/render_geojson_source.hpp index bcdc109953..297fa09a29 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -31,7 +31,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/sources/render_image_source.cpp b/src/mbgl/renderer/sources/render_image_source.cpp index b35e151f82..5c497e8144 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -84,7 +84,8 @@ std::unordered_map> RenderImageSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const std::vector&, - const RenderedQueryOptions&) const { + const RenderedQueryOptions&, + const mat4&) const { return std::unordered_map> {}; } diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp index 7dc89d3591..cf14e180fd 100644 --- a/src/mbgl/renderer/sources/render_image_source.hpp +++ b/src/mbgl/renderer/sources/render_image_source.hpp @@ -32,7 +32,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.cpp b/src/mbgl/renderer/sources/render_raster_dem_source.cpp index 58bdba1840..fbf2c09d19 100644 --- a/src/mbgl/renderer/sources/render_raster_dem_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_dem_source.cpp @@ -146,7 +146,8 @@ std::unordered_map> RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const std::vector&, - const RenderedQueryOptions&) const { + const RenderedQueryOptions&, + const mat4&) const { return std::unordered_map> {}; } diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.hpp b/src/mbgl/renderer/sources/render_raster_dem_source.hpp index 512fe6367c..48c7803e92 100644 --- a/src/mbgl/renderer/sources/render_raster_dem_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_dem_source.hpp @@ -27,7 +27,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/sources/render_raster_source.cpp b/src/mbgl/renderer/sources/render_raster_source.cpp index 3162acc7b4..f97ce4e65b 100644 --- a/src/mbgl/renderer/sources/render_raster_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_source.cpp @@ -76,7 +76,8 @@ std::unordered_map> RenderRasterSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const std::vector&, - const RenderedQueryOptions&) const { + const RenderedQueryOptions&, + const mat4&) const { return std::unordered_map> {}; } diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp index c60a51c63b..32539a046d 100644 --- a/src/mbgl/renderer/sources/render_raster_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_source.hpp @@ -27,7 +27,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/sources/render_vector_source.cpp b/src/mbgl/renderer/sources/render_vector_source.cpp index c9c47359f4..4de4f01e3f 100644 --- a/src/mbgl/renderer/sources/render_vector_source.cpp +++ b/src/mbgl/renderer/sources/render_vector_source.cpp @@ -79,8 +79,9 @@ std::unordered_map> RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options); + const RenderedQueryOptions& options, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix); } std::vector RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const { diff --git a/src/mbgl/renderer/sources/render_vector_source.hpp b/src/mbgl/renderer/sources/render_vector_source.hpp index a0351c226c..6fd2425aa3 100644 --- a/src/mbgl/renderer/sources/render_vector_source.hpp +++ b/src/mbgl/renderer/sources/render_vector_source.hpp @@ -27,7 +27,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const final; + const RenderedQueryOptions& options, + const mat4& projMatrix) const final; std::vector querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index b2d72680e7..d28e95181b 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -241,7 +241,8 @@ void TilePyramid::update(const std::vector>& layer std::unordered_map> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) const { + const RenderedQueryOptions& options, + const mat4& projMatrix) const { std::unordered_map> result; if (renderTiles.empty() || geometry.empty()) { return result; @@ -263,8 +264,11 @@ std::unordered_map> TilePyramid::queryRendered 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) { - 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); if (tileSpaceBoundsMin.x - queryPadding >= util::EXTENT || tileSpaceBoundsMin.y - queryPadding >= util::EXTENT) { @@ -286,7 +290,8 @@ std::unordered_map> TilePyramid::queryRendered tileSpaceQueryGeometry, transformState, layers, - options); + options, + projMatrix); } return result; diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp index bf3ba0d7b8..0cef9e2c40 100644 --- a/src/mbgl/renderer/tile_pyramid.hpp +++ b/src/mbgl/renderer/tile_pyramid.hpp @@ -53,7 +53,8 @@ public: queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector&, - const RenderedQueryOptions& options) const; + const RenderedQueryOptions& options, + const mat4& projMatrix) const; std::vector querySourceFeatures(const SourceQueryOptions&) const; diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 92a226d3c1..cb4b6aa39c 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -217,21 +217,27 @@ void GeometryTile::queryRenderedFeatures( const GeometryCoordinates& queryGeometry, const TransformState& transformState, const std::vector& layers, - const RenderedQueryOptions& options) { + const RenderedQueryOptions& options, + const mat4& projMatrix) { if (!getData()) return; const float queryPadding = getQueryPadding(layers); + mat4 posMatrix; + transformState.matrixFor(posMatrix, id.toUnwrapped()); + matrix::multiply(posMatrix, projMatrix, posMatrix); + latestFeatureIndex->query(result, queryGeometry, - transformState.getAngle(), + transformState, + posMatrix, util::tileSize * id.overscaleFactor(), std::pow(2, transformState.getZoom() - id.overscaledZ), options, id.toUnwrapped(), layers, - queryPadding); + queryPadding * transformState.maxPitchScaleFactor()); } void GeometryTile::querySourceFeatures( diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index a43bf44940..d0490f1009 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -54,7 +54,8 @@ public: const GeometryCoordinates& queryGeometry, const TransformState&, const std::vector& layers, - const RenderedQueryOptions& options) override; + const RenderedQueryOptions& options, + const mat4& projMatrix) override; void querySourceFeatures( std::vector& result, diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp index 56698e84c4..b95944f10e 100644 --- a/src/mbgl/tile/tile.cpp +++ b/src/mbgl/tile/tile.cpp @@ -37,7 +37,8 @@ void Tile::queryRenderedFeatures( const GeometryCoordinates&, const TransformState&, const std::vector&, - const RenderedQueryOptions&) {} + const RenderedQueryOptions&, + const mat4&) {} float Tile::getQueryPadding(const std::vector&) { return 0; diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 5f7a076850..23d6864205 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -57,7 +57,8 @@ public: const GeometryCoordinates& queryGeometry, const TransformState&, const std::vector&, - const RenderedQueryOptions& options); + const RenderedQueryOptions& options, + const mat4& projMatrix); virtual void querySourceFeatures( std::vector& result, diff --git a/src/mbgl/util/intersection_tests.cpp b/src/mbgl/util/intersection_tests.cpp index e6ce245c0e..780fce98f9 100644 --- a/src/mbgl/util/intersection_tests.cpp +++ b/src/mbgl/util/intersection_tests.cpp @@ -82,11 +82,16 @@ bool lineIntersectsBufferedLine(const GeometryCoordinates& lineA, const Geometry 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) { for (auto& ring : rings) { for (auto& point : ring) { - if (polygonContainsPoint(polygon, point)) return true; - if (pointIntersectsBufferedLine(point, polygon, radius)) return true; + if (polygonIntersectsBufferedPoint(polygon, point, radius)) return true; } } return false; diff --git a/src/mbgl/util/intersection_tests.hpp b/src/mbgl/util/intersection_tests.hpp index 5bcb29c767..c105fe4dd0 100644 --- a/src/mbgl/util/intersection_tests.hpp +++ b/src/mbgl/util/intersection_tests.hpp @@ -9,6 +9,7 @@ bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates&, const Geome bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius); bool polygonIntersectsPolygon(const GeometryCoordinates&, const GeometryCoordinates&); bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&); +bool polygonIntersectsBufferedPoint(const GeometryCoordinates& polygon, const GeometryCoordinate& point, float radius); } // namespace util } // namespace mbgl -- cgit v1.2.1