[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:
committed by
Ansis Brammanis
parent
f7d20a5871
commit
f86fe44dbd
@@ -64,8 +64,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>& 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<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const {
|
||||
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
@@ -36,7 +36,8 @@ void FeatureIndex::insert(const GeometryCollection& geometries,
|
||||
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,
|
||||
@@ -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<std::string, std::vector<Feature>> 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<const RenderLayer*>& 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<RenderSymbolLayer>() &&
|
||||
!renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, bearing, pixelsToTileUnits)) {
|
||||
!renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, transformState, pixelsToTileUnits, posMatrix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -56,7 +58,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,
|
||||
@@ -88,8 +91,9 @@ private:
|
||||
const CanonicalTileID&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const float bearing,
|
||||
const float pixelsToTileUnits) const;
|
||||
const TransformState& transformState,
|
||||
const float pixelsToTileUnits,
|
||||
const mat4& posMatrix) const;
|
||||
|
||||
GridIndex<IndexedSubfeature> grid;
|
||||
unsigned int sortIndex = 0;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
}
|
||||
|
||||
float getCameraToTileDistance(const UnwrappedTileID&) const;
|
||||
float maxPitchScaleFactor() const;
|
||||
|
||||
private:
|
||||
bool rotatedNorth() const;
|
||||
|
||||
@@ -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;
|
||||
|
||||
// Test intersection
|
||||
return util::polygonIntersectsBufferedMultiPoint(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries(), 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;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -64,7 +64,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>& layers,
|
||||
const RenderedQueryOptions& options) const = 0;
|
||||
const RenderedQueryOptions& options,
|
||||
const mat4& projMatrix) const = 0;
|
||||
|
||||
virtual std::vector<Feature>
|
||||
querySourceFeatures(const SourceQueryOptions&) const = 0;
|
||||
|
||||
@@ -704,10 +704,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);
|
||||
auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
|
||||
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,8 +67,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>& 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<Feature> RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const {
|
||||
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
@@ -85,8 +85,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>& 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<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const {
|
||||
|
||||
@@ -31,7 +31,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
@@ -84,7 +84,8 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
|
||||
const TransformState&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions&) const {
|
||||
const RenderedQueryOptions&,
|
||||
const mat4&) const {
|
||||
return std::unordered_map<std::string, std::vector<Feature>> {};
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
|
||||
@@ -146,7 +146,8 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&,
|
||||
const TransformState&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions&) const {
|
||||
const RenderedQueryOptions&,
|
||||
const mat4&) const {
|
||||
return std::unordered_map<std::string, std::vector<Feature>> {};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
@@ -76,7 +76,8 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
|
||||
const TransformState&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions&) const {
|
||||
const RenderedQueryOptions&,
|
||||
const mat4&) const {
|
||||
return std::unordered_map<std::string, std::vector<Feature>> {};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
@@ -79,8 +79,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
||||
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>& 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<Feature> RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const {
|
||||
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
|
||||
@@ -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,
|
||||
const TransformState& transformState,
|
||||
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;
|
||||
if (renderTiles.empty() || geometry.empty()) {
|
||||
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);
|
||||
});
|
||||
|
||||
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<std::string, std::vector<Feature>> TilePyramid::queryRendered
|
||||
tileSpaceQueryGeometry,
|
||||
transformState,
|
||||
layers,
|
||||
options);
|
||||
options,
|
||||
projMatrix);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -53,7 +53,8 @@ public:
|
||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions& options) const;
|
||||
const RenderedQueryOptions& options,
|
||||
const mat4& projMatrix) const;
|
||||
|
||||
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const;
|
||||
|
||||
|
||||
@@ -217,21 +217,27 @@ void GeometryTile::queryRenderedFeatures(
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState& transformState,
|
||||
const std::vector<const RenderLayer*>& 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(
|
||||
|
||||
@@ -54,7 +54,8 @@ public:
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState&,
|
||||
const std::vector<const RenderLayer*>& layers,
|
||||
const RenderedQueryOptions& options) override;
|
||||
const RenderedQueryOptions& options,
|
||||
const mat4& projMatrix) override;
|
||||
|
||||
void querySourceFeatures(
|
||||
std::vector<Feature>& result,
|
||||
|
||||
@@ -37,7 +37,8 @@ void Tile::queryRenderedFeatures(
|
||||
const GeometryCoordinates&,
|
||||
const TransformState&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions&) {}
|
||||
const RenderedQueryOptions&,
|
||||
const mat4&) {}
|
||||
|
||||
float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) {
|
||||
return 0;
|
||||
|
||||
@@ -57,7 +57,8 @@ public:
|
||||
const GeometryCoordinates& queryGeometry,
|
||||
const TransformState&,
|
||||
const std::vector<const RenderLayer*>&,
|
||||
const RenderedQueryOptions& options);
|
||||
const RenderedQueryOptions& options,
|
||||
const mat4& projMatrix);
|
||||
|
||||
virtual void querySourceFeatures(
|
||||
std::vector<Feature>& result,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user