diff options
author | Chris Loer <chris.loer@gmail.com> | 2018-04-02 17:41:55 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@gmail.com> | 2018-04-02 17:41:55 -0700 |
commit | 8fab2a0c02962bc0620e52b674c867a113514fbc (patch) | |
tree | 35c42da95d9b6f3e5765af43d92673e72a872542 | |
parent | da1ed34766dfecd6b6034dc15e219550a0744b33 (diff) | |
download | qtlocation-mapboxgl-8fab2a0c02962bc0620e52b674c867a113514fbc.tar.gz |
[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
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 a237100d13..d40930a255 100644 --- a/src/mbgl/annotation/render_annotation_source.cpp +++ b/src/mbgl/annotation/render_annotation_source.cpp @@ -65,8 +65,9 @@ RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex); + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex, projMatrix); } std::vector<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const { diff --git a/src/mbgl/annotation/render_annotation_source.hpp b/src/mbgl/annotation/render_annotation_source.hpp index e812ec2883..2c318f2026 100644 --- a/src/mbgl/annotation/render_annotation_source.hpp +++ b/src/mbgl/annotation/render_annotation_source.hpp @@ -28,7 +28,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const final; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const final; std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp index 8a53381650..ea0e8b61d1 100644 --- a/src/mbgl/geometry/feature_index.cpp +++ b/src/mbgl/geometry/feature_index.cpp @@ -44,7 +44,8 @@ static bool topDownSymbols(const IndexedSubfeature& a, const IndexedSubfeature& void FeatureIndex::query( std::unordered_map<std::string, std::vector<Feature>>& result, const GeometryCoordinates& queryGeometry, - const float bearing, + const TransformState& transformState, + const mat4& posMatrix, const double tileSize, const double scale, const RenderedQueryOptions& queryOptions, @@ -76,13 +77,13 @@ void FeatureIndex::query( if (indexedFeature.sortIndex == previousSortIndex) continue; previousSortIndex = indexedFeature.sortIndex; - addFeature(result, indexedFeature, queryGeometry, queryOptions, tileID.canonical, layers, bearing, pixelsToTileUnits); + addFeature(result, indexedFeature, queryGeometry, queryOptions, tileID.canonical, layers, transformState, pixelsToTileUnits, posMatrix); } std::vector<IndexedSubfeature> symbolFeatures = collisionIndex.queryRenderedSymbols(queryGeometry, tileID, sourceID); std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols); for (const auto& symbolFeature : symbolFeatures) { - addFeature(result, symbolFeature, queryGeometry, queryOptions, tileID.canonical, layers, bearing, pixelsToTileUnits); + addFeature(result, symbolFeature, queryGeometry, queryOptions, tileID.canonical, layers, transformState, pixelsToTileUnits, posMatrix); } } @@ -93,8 +94,9 @@ void FeatureIndex::addFeature( const RenderedQueryOptions& options, const CanonicalTileID& tileID, const std::vector<const RenderLayer*>& layers, - 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) { @@ -124,7 +126,7 @@ void FeatureIndex::addFeature( } if (!renderLayer->is<RenderSymbolLayer>() && - !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 f00179b0ca..2061f0a523 100644 --- a/src/mbgl/geometry/feature_index.hpp +++ b/src/mbgl/geometry/feature_index.hpp @@ -5,6 +5,7 @@ #include <mbgl/tile/tile_id.hpp> #include <mbgl/util/grid_index.hpp> #include <mbgl/util/feature.hpp> +#include <mbgl/util/mat4.hpp> #include <vector> #include <string> @@ -14,6 +15,7 @@ namespace mbgl { class RenderedQueryOptions; class RenderLayer; +class TransformState; class CollisionIndex; @@ -59,7 +61,8 @@ public: void query( std::unordered_map<std::string, std::vector<Feature>>& result, const GeometryCoordinates& queryGeometry, - const float bearing, + const TransformState&, + const mat4& posMatrix, const double tileSize, const double scale, const RenderedQueryOptions& options, @@ -86,8 +89,9 @@ private: const RenderedQueryOptions& options, const CanonicalTileID&, const std::vector<const RenderLayer*>&, - const float bearing, - const float pixelsToTileUnits) const; + const TransformState& transformState, + const float pixelsToTileUnits, + const mat4& posMatrix) const; GridIndex<IndexedSubfeature> 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<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 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<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( 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<style::CircleTranslate>(), evaluated.get<style::CircleTranslateAnchor>(), - bearing, - pixelsToTileUnits); + transformState.getAngle(), + pixelsToTileUnits).value_or(queryGeometry); // Evaluate functions - auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature) * pixelsToTileUnits; - auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(zoom, feature) * pixelsToTileUnits; + auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature); + auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(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<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; + } + } - // 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<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) 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<style::FillExtrusionTranslate>(), evaluated.get<style::FillExtrusionTranslateAnchor>(), - 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<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) 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<style::FillTranslate>(), evaluated.get<style::FillTranslateAnchor>(), - 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<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) 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<style::LineTranslate>(), evaluated.get<style::LineTranslateAnchor>(), - 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<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) 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 <mbgl/style/layer_impl.hpp> #include <mbgl/style/layer_type.hpp> #include <mbgl/tile/geometry_tile_data.hpp> +#include <mbgl/util/mat4.hpp> #include <memory> #include <string> @@ -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<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0; diff --git a/src/mbgl/renderer/render_source.hpp b/src/mbgl/renderer/render_source.hpp index 53519c763e..b473ea76ff 100644 --- a/src/mbgl/renderer/render_source.hpp +++ b/src/mbgl/renderer/render_source.hpp @@ -65,7 +65,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const = 0; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const = 0; virtual std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const = 0; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 2ac714e122..e34dfd9073 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -680,10 +680,13 @@ std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineStrin sourceIDs.emplace(layer->baseImpl->source); } + mat4 projMatrix; + transformState.getProjMatrix(projMatrix); + 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, placement->getCollisionIndex(), 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 057ad5a4a7..f3aa3f77c2 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.cpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.cpp @@ -68,8 +68,9 @@ RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geomet const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex); + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex, projMatrix); } std::vector<Feature> 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 033d731029..23c71136a5 100644 --- a/src/mbgl/renderer/sources/render_custom_geometry_source.hpp +++ b/src/mbgl/renderer/sources/render_custom_geometry_source.hpp @@ -28,7 +28,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const final; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const final; std::vector<Feature> 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 cbf4db70b5..502ed61e99 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.cpp +++ b/src/mbgl/renderer/sources/render_geojson_source.cpp @@ -86,8 +86,9 @@ RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex); + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex, projMatrix); } std::vector<Feature> 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 72fccbd043..36b6c37ac2 100644 --- a/src/mbgl/renderer/sources/render_geojson_source.hpp +++ b/src/mbgl/renderer/sources/render_geojson_source.hpp @@ -32,7 +32,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex&) const final; + const CollisionIndex&, + const mat4& projMatrix) const final; std::vector<Feature> 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 31a5916a34..859fe341ea 100644 --- a/src/mbgl/renderer/sources/render_image_source.cpp +++ b/src/mbgl/renderer/sources/render_image_source.cpp @@ -85,7 +85,8 @@ RenderImageSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const std::vector<const RenderLayer*>&, const RenderedQueryOptions&, - const CollisionIndex&) const { + const CollisionIndex&, + const mat4&) const { return std::unordered_map<std::string, std::vector<Feature>> {}; } diff --git a/src/mbgl/renderer/sources/render_image_source.hpp b/src/mbgl/renderer/sources/render_image_source.hpp index 85ee0ace11..fc49cfdfd0 100644 --- a/src/mbgl/renderer/sources/render_image_source.hpp +++ b/src/mbgl/renderer/sources/render_image_source.hpp @@ -33,7 +33,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const final; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const final; std::vector<Feature> 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 b3153622c3..8fe0c4bc15 100644 --- a/src/mbgl/renderer/sources/render_raster_dem_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_dem_source.cpp @@ -147,7 +147,8 @@ RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const std::vector<const RenderLayer*>&, const RenderedQueryOptions&, - const CollisionIndex& ) const { + const CollisionIndex&, + const mat4&) const { return std::unordered_map<std::string, std::vector<Feature>> {}; } diff --git a/src/mbgl/renderer/sources/render_raster_dem_source.hpp b/src/mbgl/renderer/sources/render_raster_dem_source.hpp index 741214a14d..80478a0648 100644 --- a/src/mbgl/renderer/sources/render_raster_dem_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_dem_source.hpp @@ -28,7 +28,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const final; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const final; std::vector<Feature> 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 60b3fa9a3b..fa744c3626 100644 --- a/src/mbgl/renderer/sources/render_raster_source.cpp +++ b/src/mbgl/renderer/sources/render_raster_source.cpp @@ -77,7 +77,8 @@ RenderRasterSource::queryRenderedFeatures(const ScreenLineString&, const TransformState&, const std::vector<const RenderLayer*>&, const RenderedQueryOptions&, - const CollisionIndex& ) const { + const CollisionIndex&, + const mat4&) const { return std::unordered_map<std::string, std::vector<Feature>> {}; } diff --git a/src/mbgl/renderer/sources/render_raster_source.hpp b/src/mbgl/renderer/sources/render_raster_source.hpp index 78eda199ac..f2f67af4ba 100644 --- a/src/mbgl/renderer/sources/render_raster_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_source.hpp @@ -28,7 +28,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const final; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const final; std::vector<Feature> 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 e87bea5dcd..555d314807 100644 --- a/src/mbgl/renderer/sources/render_vector_source.cpp +++ b/src/mbgl/renderer/sources/render_vector_source.cpp @@ -80,8 +80,9 @@ RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry, const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const { - return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex); + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const { + return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, collisionIndex, projMatrix); } std::vector<Feature> 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 592160dc16..967f3d31b7 100644 --- a/src/mbgl/renderer/sources/render_vector_source.hpp +++ b/src/mbgl/renderer/sources/render_vector_source.hpp @@ -28,7 +28,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const final; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const final; std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final; diff --git a/src/mbgl/renderer/tile_pyramid.cpp b/src/mbgl/renderer/tile_pyramid.cpp index 624a28d298..c948e2d253 100644 --- a/src/mbgl/renderer/tile_pyramid.cpp +++ b/src/mbgl/renderer/tile_pyramid.cpp @@ -242,7 +242,8 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const { + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const { std::unordered_map<std::string, std::vector<Feature>> result; if (renderTiles.empty() || geometry.empty()) { return result; @@ -264,8 +265,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); }); + 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) { @@ -288,7 +292,8 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered transformState, layers, options, - collisionIndex); + collisionIndex, + projMatrix); } return result; diff --git a/src/mbgl/renderer/tile_pyramid.hpp b/src/mbgl/renderer/tile_pyramid.hpp index 2638599c38..364eac6509 100644 --- a/src/mbgl/renderer/tile_pyramid.hpp +++ b/src/mbgl/renderer/tile_pyramid.hpp @@ -54,7 +54,8 @@ public: const TransformState& transformState, const std::vector<const RenderLayer*>&, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) const; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) const; std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const; diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 76c6a36109..bcc3ed49ba 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -227,15 +227,21 @@ void GeometryTile::queryRenderedFeatures( const TransformState& transformState, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) { + const CollisionIndex& collisionIndex, + const mat4& projMatrix) { if (!getData()) return; const float queryPadding = getQueryPadding(layers); + mat4 posMatrix; + transformState.matrixFor(posMatrix, id.toUnwrapped()); + matrix::multiply(posMatrix, projMatrix, posMatrix); + featureIndex->query(result, queryGeometry, - transformState.getAngle(), + transformState, + posMatrix, util::tileSize * id.overscaleFactor(), std::pow(2, transformState.getZoom() - id.overscaledZ), options, @@ -243,7 +249,7 @@ void GeometryTile::queryRenderedFeatures( sourceID, layers, collisionIndex, - queryPadding); + queryPadding * transformState.maxPitchScaleFactor()); } void GeometryTile::querySourceFeatures( diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp index 013bee4670..ab308a9e60 100644 --- a/src/mbgl/tile/geometry_tile.hpp +++ b/src/mbgl/tile/geometry_tile.hpp @@ -55,7 +55,8 @@ public: const TransformState&, const std::vector<const RenderLayer*>& layers, const RenderedQueryOptions& options, - const CollisionIndex& collisionIndex) override; + const CollisionIndex& collisionIndex, + const mat4& projMatrix) override; void querySourceFeatures( std::vector<Feature>& result, diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp index 410c9636e2..afcc6e3f08 100644 --- a/src/mbgl/tile/tile.cpp +++ b/src/mbgl/tile/tile.cpp @@ -38,7 +38,8 @@ void Tile::queryRenderedFeatures( const TransformState&, const std::vector<const RenderLayer*>&, const RenderedQueryOptions&, - const CollisionIndex&) {} + const CollisionIndex&, + const mat4&) {} float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) { return 0; diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp index 7a772581df..9471661ce6 100644 --- a/src/mbgl/tile/tile.hpp +++ b/src/mbgl/tile/tile.hpp @@ -58,7 +58,8 @@ public: const TransformState&, const std::vector<const RenderLayer*>&, const RenderedQueryOptions& options, - const CollisionIndex&); + const CollisionIndex&, + const mat4& projMatrix); virtual void querySourceFeatures( std::vector<Feature>& 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 |