[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,
|
RenderAnnotationSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const {
|
const RenderedQueryOptions& options,
|
||||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options);
|
const mat4& projMatrix) const {
|
||||||
|
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const {
|
std::vector<Feature> RenderAnnotationSource::querySourceFeatures(const SourceQueryOptions&) const {
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature>
|
std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const final;
|
querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ void FeatureIndex::insert(const GeometryCollection& geometries,
|
|||||||
void FeatureIndex::query(
|
void FeatureIndex::query(
|
||||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
|
const mat4& posMatrix,
|
||||||
const double tileSize,
|
const double tileSize,
|
||||||
const double scale,
|
const double scale,
|
||||||
const RenderedQueryOptions& queryOptions,
|
const RenderedQueryOptions& queryOptions,
|
||||||
@@ -68,7 +69,7 @@ void FeatureIndex::query(
|
|||||||
if (indexedFeature.sortIndex == previousSortIndex) continue;
|
if (indexedFeature.sortIndex == previousSortIndex) continue;
|
||||||
previousSortIndex = indexedFeature.sortIndex;
|
previousSortIndex = indexedFeature.sortIndex;
|
||||||
|
|
||||||
addFeature(result, indexedFeature, queryOptions, tileID.canonical, layers, queryGeometry, bearing, pixelsToTileUnits);
|
addFeature(result, indexedFeature, queryOptions, tileID.canonical, layers, queryGeometry, transformState, pixelsToTileUnits, posMatrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ std::unordered_map<std::string, std::vector<Feature>> FeatureIndex::lookupSymbol
|
|||||||
});
|
});
|
||||||
|
|
||||||
for (const auto& symbolFeature : sortedFeatures) {
|
for (const auto& symbolFeature : sortedFeatures) {
|
||||||
addFeature(result, symbolFeature, queryOptions, tileID.canonical, layers, GeometryCoordinates(), 0, 0);
|
addFeature(result, symbolFeature, queryOptions, tileID.canonical, layers, GeometryCoordinates(), {}, 0, {});
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -117,8 +118,9 @@ void FeatureIndex::addFeature(
|
|||||||
const CanonicalTileID& tileID,
|
const CanonicalTileID& tileID,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
const float pixelsToTileUnits) const {
|
const float pixelsToTileUnits,
|
||||||
|
const mat4& posMatrix) const {
|
||||||
|
|
||||||
auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* {
|
auto getRenderLayer = [&] (const std::string& layerID) -> const RenderLayer* {
|
||||||
for (const auto& layer : layers) {
|
for (const auto& layer : layers) {
|
||||||
@@ -148,7 +150,7 @@ void FeatureIndex::addFeature(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!renderLayer->is<RenderSymbolLayer>() &&
|
if (!renderLayer->is<RenderSymbolLayer>() &&
|
||||||
!renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, bearing, pixelsToTileUnits)) {
|
!renderLayer->queryIntersectsFeature(queryGeometry, *geometryTileFeature, tileID.z, transformState, pixelsToTileUnits, posMatrix)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <mbgl/tile/tile_id.hpp>
|
#include <mbgl/tile/tile_id.hpp>
|
||||||
#include <mbgl/util/grid_index.hpp>
|
#include <mbgl/util/grid_index.hpp>
|
||||||
#include <mbgl/util/feature.hpp>
|
#include <mbgl/util/feature.hpp>
|
||||||
|
#include <mbgl/util/mat4.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -14,6 +15,7 @@ namespace mbgl {
|
|||||||
|
|
||||||
class RenderedQueryOptions;
|
class RenderedQueryOptions;
|
||||||
class RenderLayer;
|
class RenderLayer;
|
||||||
|
class TransformState;
|
||||||
|
|
||||||
class CollisionIndex;
|
class CollisionIndex;
|
||||||
|
|
||||||
@@ -56,7 +58,8 @@ public:
|
|||||||
void query(
|
void query(
|
||||||
std::unordered_map<std::string, std::vector<Feature>>& result,
|
std::unordered_map<std::string, std::vector<Feature>>& result,
|
||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const float bearing,
|
const TransformState&,
|
||||||
|
const mat4& posMatrix,
|
||||||
const double tileSize,
|
const double tileSize,
|
||||||
const double scale,
|
const double scale,
|
||||||
const RenderedQueryOptions& options,
|
const RenderedQueryOptions& options,
|
||||||
@@ -88,8 +91,9 @@ private:
|
|||||||
const CanonicalTileID&,
|
const CanonicalTileID&,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
const float pixelsToTileUnits) const;
|
const float pixelsToTileUnits,
|
||||||
|
const mat4& posMatrix) const;
|
||||||
|
|
||||||
GridIndex<IndexedSubfeature> grid;
|
GridIndex<IndexedSubfeature> grid;
|
||||||
unsigned int sortIndex = 0;
|
unsigned int sortIndex = 0;
|
||||||
|
|||||||
@@ -421,4 +421,17 @@ float TransformState::getCameraToTileDistance(const UnwrappedTileID& tileID) con
|
|||||||
return projectedCenter[3];
|
return projectedCenter[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float TransformState::maxPitchScaleFactor() const {
|
||||||
|
if (size.isEmpty()) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
auto latLng = screenCoordinateToLatLng({ 0, static_cast<float>(getSize().height) });
|
||||||
|
mat4 mat = coordinatePointMatrix(getZoom());
|
||||||
|
Point<double> pt = Projection::project(latLng, scale) / double(util::tileSize);
|
||||||
|
vec4 p = {{ pt.x, pt.y, 0, 1 }};
|
||||||
|
vec4 topPoint;
|
||||||
|
matrix::transformMat4(topPoint, p, mat);
|
||||||
|
return topPoint[3] / getCameraToCenterDistance();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
float getCameraToTileDistance(const UnwrappedTileID&) const;
|
float getCameraToTileDistance(const UnwrappedTileID&) const;
|
||||||
|
float maxPitchScaleFactor() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool rotatedNorth() const;
|
bool rotatedNorth() const;
|
||||||
|
|||||||
@@ -93,27 +93,75 @@ void RenderCircleLayer::render(PaintParameters& parameters, RenderSource*) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GeometryCoordinate projectPoint(const GeometryCoordinate& p, const mat4& posMatrix, const Size& size) {
|
||||||
|
vec4 pos = {{ static_cast<double>(p.x), static_cast<double>(p.y), 0, 1 }};
|
||||||
|
matrix::transformMat4(pos, pos, posMatrix);
|
||||||
|
return {
|
||||||
|
static_cast<int16_t>((static_cast<float>(pos[0] / pos[3]) + 1) * size.width * 0.5),
|
||||||
|
static_cast<int16_t>((static_cast<float>(pos[1] / pos[3]) + 1) * size.height * 0.5)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
GeometryCoordinates projectQueryGeometry(const GeometryCoordinates& queryGeometry, const mat4& posMatrix, const Size& size) {
|
||||||
|
GeometryCoordinates projectedGeometry;
|
||||||
|
for (auto& p : queryGeometry) {
|
||||||
|
projectedGeometry.push_back(projectPoint(p, posMatrix, size));
|
||||||
|
}
|
||||||
|
return projectedGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
bool RenderCircleLayer::queryIntersectsFeature(
|
bool RenderCircleLayer::queryIntersectsFeature(
|
||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const GeometryTileFeature& feature,
|
const GeometryTileFeature& feature,
|
||||||
const float zoom,
|
const float zoom,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
const float pixelsToTileUnits) const {
|
const float pixelsToTileUnits,
|
||||||
|
const mat4& posMatrix) const {
|
||||||
|
|
||||||
// Translate query geometry
|
// Translate query geometry
|
||||||
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
const GeometryCoordinates& translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
||||||
queryGeometry,
|
queryGeometry,
|
||||||
evaluated.get<style::CircleTranslate>(),
|
evaluated.get<style::CircleTranslate>(),
|
||||||
evaluated.get<style::CircleTranslateAnchor>(),
|
evaluated.get<style::CircleTranslateAnchor>(),
|
||||||
bearing,
|
transformState.getAngle(),
|
||||||
pixelsToTileUnits);
|
pixelsToTileUnits).value_or(queryGeometry);
|
||||||
|
|
||||||
// Evaluate functions
|
// Evaluate functions
|
||||||
auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature) * pixelsToTileUnits;
|
auto radius = evaluated.evaluate<style::CircleRadius>(zoom, feature);
|
||||||
auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(zoom, feature) * pixelsToTileUnits;
|
auto stroke = evaluated.evaluate<style::CircleStrokeWidth>(zoom, feature);
|
||||||
|
auto size = radius + stroke;
|
||||||
|
|
||||||
// Test intersection
|
// For pitch-alignment: map, compare feature geometry to query geometry in the plane of the tile
|
||||||
return util::polygonIntersectsBufferedMultiPoint(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries(), radius + stroke);
|
// Otherwise, compare geometry in the plane of the viewport
|
||||||
|
// A circle with fixed scaling relative to the viewport gets larger in tile space as it moves into the distance
|
||||||
|
// A circle with fixed scaling relative to the map gets smaller in viewport space as it moves into the distance
|
||||||
|
bool alignWithMap = evaluated.evaluate<style::CirclePitchAlignment>(zoom, feature) == AlignmentType::Map;
|
||||||
|
const GeometryCoordinates& transformedQueryGeometry = alignWithMap ?
|
||||||
|
translatedQueryGeometry :
|
||||||
|
projectQueryGeometry(translatedQueryGeometry, posMatrix, transformState.getSize());
|
||||||
|
auto transformedSize = alignWithMap ? size * pixelsToTileUnits : size;
|
||||||
|
|
||||||
|
auto geometry = feature.getGeometries();
|
||||||
|
for (auto& ring : geometry) {
|
||||||
|
for (auto& point : ring) {
|
||||||
|
const GeometryCoordinate& transformedPoint = alignWithMap ? point : projectPoint(point, posMatrix, transformState.getSize());
|
||||||
|
|
||||||
|
float adjustedSize = transformedSize;
|
||||||
|
vec4 center = {{ static_cast<double>(point.x), static_cast<double>(point.y), 0, 1 }};
|
||||||
|
matrix::transformMat4(center, center, posMatrix);
|
||||||
|
auto pitchScale = evaluated.evaluate<style::CirclePitchScale>(zoom, feature);
|
||||||
|
auto pitchAlignment = evaluated.evaluate<style::CirclePitchAlignment>(zoom, feature);
|
||||||
|
if (pitchScale == CirclePitchScaleType::Viewport && pitchAlignment == AlignmentType::Map) {
|
||||||
|
adjustedSize *= center[3] / transformState.getCameraToCenterDistance();
|
||||||
|
} else if (pitchScale == CirclePitchScaleType::Map && pitchAlignment == AlignmentType::Viewport) {
|
||||||
|
adjustedSize *= transformState.getCameraToCenterDistance() / center[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (util::polygonIntersectsBufferedPoint(transformedQueryGeometry, transformedPoint, adjustedSize)) return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ public:
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const GeometryTileFeature&,
|
const GeometryTileFeature&,
|
||||||
const float,
|
const float,
|
||||||
|
const TransformState&,
|
||||||
const float,
|
const float,
|
||||||
const float) const override;
|
const mat4&) const override;
|
||||||
|
|
||||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -151,14 +151,15 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature(
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const GeometryTileFeature& feature,
|
const GeometryTileFeature& feature,
|
||||||
const float,
|
const float,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
const float pixelsToTileUnits) const {
|
const float pixelsToTileUnits,
|
||||||
|
const mat4&) const {
|
||||||
|
|
||||||
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
||||||
queryGeometry,
|
queryGeometry,
|
||||||
evaluated.get<style::FillExtrusionTranslate>(),
|
evaluated.get<style::FillExtrusionTranslate>(),
|
||||||
evaluated.get<style::FillExtrusionTranslateAnchor>(),
|
evaluated.get<style::FillExtrusionTranslateAnchor>(),
|
||||||
bearing,
|
transformState.getAngle(),
|
||||||
pixelsToTileUnits);
|
pixelsToTileUnits);
|
||||||
|
|
||||||
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());
|
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ public:
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const GeometryTileFeature&,
|
const GeometryTileFeature&,
|
||||||
const float,
|
const float,
|
||||||
|
const TransformState&,
|
||||||
const float,
|
const float,
|
||||||
const float) const override;
|
const mat4&) const override;
|
||||||
|
|
||||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -188,14 +188,15 @@ bool RenderFillLayer::queryIntersectsFeature(
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const GeometryTileFeature& feature,
|
const GeometryTileFeature& feature,
|
||||||
const float,
|
const float,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
const float pixelsToTileUnits) const {
|
const float pixelsToTileUnits,
|
||||||
|
const mat4&) const {
|
||||||
|
|
||||||
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
||||||
queryGeometry,
|
queryGeometry,
|
||||||
evaluated.get<style::FillTranslate>(),
|
evaluated.get<style::FillTranslate>(),
|
||||||
evaluated.get<style::FillTranslateAnchor>(),
|
evaluated.get<style::FillTranslateAnchor>(),
|
||||||
bearing,
|
transformState.getAngle(),
|
||||||
pixelsToTileUnits);
|
pixelsToTileUnits);
|
||||||
|
|
||||||
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());
|
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), feature.getGeometries());
|
||||||
|
|||||||
@@ -20,8 +20,9 @@ public:
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const GeometryTileFeature&,
|
const GeometryTileFeature&,
|
||||||
const float,
|
const float,
|
||||||
|
const TransformState&,
|
||||||
const float,
|
const float,
|
||||||
const float) const override;
|
const mat4&) const override;
|
||||||
|
|
||||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -165,12 +165,12 @@ bool RenderHeatmapLayer::queryIntersectsFeature(
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const GeometryTileFeature& feature,
|
const GeometryTileFeature& feature,
|
||||||
const float zoom,
|
const float zoom,
|
||||||
const float bearing,
|
const TransformState&,
|
||||||
const float pixelsToTileUnits) const {
|
const float pixelsToTileUnits,
|
||||||
|
const mat4&) const {
|
||||||
(void) queryGeometry;
|
(void) queryGeometry;
|
||||||
(void) feature;
|
(void) feature;
|
||||||
(void) zoom;
|
(void) zoom;
|
||||||
(void) bearing;
|
|
||||||
(void) pixelsToTileUnits;
|
(void) pixelsToTileUnits;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ public:
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const GeometryTileFeature&,
|
const GeometryTileFeature&,
|
||||||
const float,
|
const float,
|
||||||
|
const TransformState&,
|
||||||
const float,
|
const float,
|
||||||
const float) const override;
|
const mat4&) const override;
|
||||||
|
|
||||||
void updateColorRamp();
|
void updateColorRamp();
|
||||||
|
|
||||||
|
|||||||
@@ -162,15 +162,16 @@ bool RenderLineLayer::queryIntersectsFeature(
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const GeometryTileFeature& feature,
|
const GeometryTileFeature& feature,
|
||||||
const float zoom,
|
const float zoom,
|
||||||
const float bearing,
|
const TransformState& transformState,
|
||||||
const float pixelsToTileUnits) const {
|
const float pixelsToTileUnits,
|
||||||
|
const mat4&) const {
|
||||||
|
|
||||||
// Translate query geometry
|
// Translate query geometry
|
||||||
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
|
||||||
queryGeometry,
|
queryGeometry,
|
||||||
evaluated.get<style::LineTranslate>(),
|
evaluated.get<style::LineTranslate>(),
|
||||||
evaluated.get<style::LineTranslateAnchor>(),
|
evaluated.get<style::LineTranslateAnchor>(),
|
||||||
bearing,
|
transformState.getAngle(),
|
||||||
pixelsToTileUnits);
|
pixelsToTileUnits);
|
||||||
|
|
||||||
// Evaluate function
|
// Evaluate function
|
||||||
|
|||||||
@@ -29,8 +29,9 @@ public:
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const GeometryTileFeature&,
|
const GeometryTileFeature&,
|
||||||
const float,
|
const float,
|
||||||
|
const TransformState&,
|
||||||
const float,
|
const float,
|
||||||
const float) const override;
|
const mat4&) const override;
|
||||||
|
|
||||||
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const override;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <mbgl/style/layer_impl.hpp>
|
#include <mbgl/style/layer_impl.hpp>
|
||||||
#include <mbgl/style/layer_type.hpp>
|
#include <mbgl/style/layer_type.hpp>
|
||||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||||
|
#include <mbgl/util/mat4.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -17,6 +18,7 @@ class PropertyEvaluationParameters;
|
|||||||
class PaintParameters;
|
class PaintParameters;
|
||||||
class RenderSource;
|
class RenderSource;
|
||||||
class RenderTile;
|
class RenderTile;
|
||||||
|
class TransformState;
|
||||||
|
|
||||||
class RenderLayer {
|
class RenderLayer {
|
||||||
protected:
|
protected:
|
||||||
@@ -69,8 +71,9 @@ public:
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const GeometryTileFeature&,
|
const GeometryTileFeature&,
|
||||||
const float,
|
const float,
|
||||||
|
const TransformState&,
|
||||||
const float,
|
const float,
|
||||||
const float) const { return false; };
|
const mat4&) const { return false; };
|
||||||
|
|
||||||
virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0;
|
virtual std::unique_ptr<Bucket> createBucket(const BucketParameters&, const std::vector<const RenderLayer*>&) const = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const = 0;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const = 0;
|
||||||
|
|
||||||
virtual std::vector<Feature>
|
virtual std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const = 0;
|
querySourceFeatures(const SourceQueryOptions&) const = 0;
|
||||||
|
|||||||
@@ -704,10 +704,13 @@ std::vector<Feature> Renderer::Impl::queryRenderedFeatures(const ScreenLineStrin
|
|||||||
sourceIDs.emplace(layer->baseImpl->source);
|
sourceIDs.emplace(layer->baseImpl->source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mat4 projMatrix;
|
||||||
|
transformState.getProjMatrix(projMatrix);
|
||||||
|
|
||||||
std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
|
std::unordered_map<std::string, std::vector<Feature>> resultsByLayer;
|
||||||
for (const auto& sourceID : sourceIDs) {
|
for (const auto& sourceID : sourceIDs) {
|
||||||
if (RenderSource* renderSource = getRenderSource(sourceID)) {
|
if (RenderSource* renderSource = getRenderSource(sourceID)) {
|
||||||
auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options);
|
auto sourceResults = renderSource->queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
|
||||||
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
|
std::move(sourceResults.begin(), sourceResults.end(), std::inserter(resultsByLayer, resultsByLayer.begin()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
|||||||
RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry,
|
RenderCustomGeometrySource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const {
|
const RenderedQueryOptions& options,
|
||||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options);
|
const mat4& projMatrix) const {
|
||||||
|
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Feature> RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const {
|
std::vector<Feature> RenderCustomGeometrySource::querySourceFeatures(const SourceQueryOptions& options) const {
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature>
|
std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const final;
|
querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|||||||
@@ -85,8 +85,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
|||||||
RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
RenderGeoJSONSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const {
|
const RenderedQueryOptions& options,
|
||||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options);
|
const mat4& projMatrix) const {
|
||||||
|
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const {
|
std::vector<Feature> RenderGeoJSONSource::querySourceFeatures(const SourceQueryOptions& options) const {
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature>
|
std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const final;
|
querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|||||||
@@ -84,7 +84,8 @@ std::unordered_map<std::string, std::vector<Feature>>
|
|||||||
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
|
RenderImageSource::queryRenderedFeatures(const ScreenLineString&,
|
||||||
const TransformState&,
|
const TransformState&,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const RenderedQueryOptions&) const {
|
const RenderedQueryOptions&,
|
||||||
|
const mat4&) const {
|
||||||
return std::unordered_map<std::string, std::vector<Feature>> {};
|
return std::unordered_map<std::string, std::vector<Feature>> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final;
|
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,8 @@ std::unordered_map<std::string, std::vector<Feature>>
|
|||||||
RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&,
|
RenderRasterDEMSource::queryRenderedFeatures(const ScreenLineString&,
|
||||||
const TransformState&,
|
const TransformState&,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const RenderedQueryOptions&) const {
|
const RenderedQueryOptions&,
|
||||||
|
const mat4&) const {
|
||||||
return std::unordered_map<std::string, std::vector<Feature>> {};
|
return std::unordered_map<std::string, std::vector<Feature>> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature>
|
std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const final;
|
querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ std::unordered_map<std::string, std::vector<Feature>>
|
|||||||
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
|
RenderRasterSource::queryRenderedFeatures(const ScreenLineString&,
|
||||||
const TransformState&,
|
const TransformState&,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const RenderedQueryOptions&) const {
|
const RenderedQueryOptions&,
|
||||||
|
const mat4&) const {
|
||||||
return std::unordered_map<std::string, std::vector<Feature>> {};
|
return std::unordered_map<std::string, std::vector<Feature>> {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature>
|
std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const final;
|
querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|||||||
@@ -79,8 +79,9 @@ std::unordered_map<std::string, std::vector<Feature>>
|
|||||||
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
RenderVectorSource::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const {
|
const RenderedQueryOptions& options,
|
||||||
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options);
|
const mat4& projMatrix) const {
|
||||||
|
return tilePyramid.queryRenderedFeatures(geometry, transformState, layers, options, projMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Feature> RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const {
|
std::vector<Feature> RenderVectorSource::querySourceFeatures(const SourceQueryOptions& options) const {
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const final;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const final;
|
||||||
|
|
||||||
std::vector<Feature>
|
std::vector<Feature>
|
||||||
querySourceFeatures(const SourceQueryOptions&) const final;
|
querySourceFeatures(const SourceQueryOptions&) const final;
|
||||||
|
|||||||
@@ -241,7 +241,8 @@ void TilePyramid::update(const std::vector<Immutable<style::Layer::Impl>>& layer
|
|||||||
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
|
std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) const {
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const {
|
||||||
std::unordered_map<std::string, std::vector<Feature>> result;
|
std::unordered_map<std::string, std::vector<Feature>> result;
|
||||||
if (renderTiles.empty() || geometry.empty()) {
|
if (renderTiles.empty() || geometry.empty()) {
|
||||||
return result;
|
return result;
|
||||||
@@ -263,8 +264,11 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
|
|||||||
std::tie(b.id.canonical.z, b.id.canonical.y, b.id.wrap, b.id.canonical.x);
|
std::tie(b.id.canonical.z, b.id.canonical.y, b.id.wrap, b.id.canonical.x);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto maxPitchScaleFactor = transformState.maxPitchScaleFactor();
|
||||||
|
|
||||||
for (const RenderTile& renderTile : sortedTiles) {
|
for (const RenderTile& renderTile : sortedTiles) {
|
||||||
auto queryPadding = renderTile.tile.getQueryPadding(layers);
|
const float scale = std::pow(2, transformState.getZoom() - renderTile.id.canonical.z);
|
||||||
|
auto queryPadding = maxPitchScaleFactor * renderTile.tile.getQueryPadding(layers) * util::EXTENT / util::tileSize / scale;
|
||||||
|
|
||||||
GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
|
GeometryCoordinate tileSpaceBoundsMin = TileCoordinate::toGeometryCoordinate(renderTile.id, box.min);
|
||||||
if (tileSpaceBoundsMin.x - queryPadding >= util::EXTENT || tileSpaceBoundsMin.y - queryPadding >= util::EXTENT) {
|
if (tileSpaceBoundsMin.x - queryPadding >= util::EXTENT || tileSpaceBoundsMin.y - queryPadding >= util::EXTENT) {
|
||||||
@@ -286,7 +290,8 @@ std::unordered_map<std::string, std::vector<Feature>> TilePyramid::queryRendered
|
|||||||
tileSpaceQueryGeometry,
|
tileSpaceQueryGeometry,
|
||||||
transformState,
|
transformState,
|
||||||
layers,
|
layers,
|
||||||
options);
|
options,
|
||||||
|
projMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ public:
|
|||||||
queryRenderedFeatures(const ScreenLineString& geometry,
|
queryRenderedFeatures(const ScreenLineString& geometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const RenderedQueryOptions& options) const;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) const;
|
||||||
|
|
||||||
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const;
|
std::vector<Feature> querySourceFeatures(const SourceQueryOptions&) const;
|
||||||
|
|
||||||
|
|||||||
@@ -217,21 +217,27 @@ void GeometryTile::queryRenderedFeatures(
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const TransformState& transformState,
|
const TransformState& transformState,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) {
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) {
|
||||||
|
|
||||||
if (!getData()) return;
|
if (!getData()) return;
|
||||||
|
|
||||||
const float queryPadding = getQueryPadding(layers);
|
const float queryPadding = getQueryPadding(layers);
|
||||||
|
|
||||||
|
mat4 posMatrix;
|
||||||
|
transformState.matrixFor(posMatrix, id.toUnwrapped());
|
||||||
|
matrix::multiply(posMatrix, projMatrix, posMatrix);
|
||||||
|
|
||||||
latestFeatureIndex->query(result,
|
latestFeatureIndex->query(result,
|
||||||
queryGeometry,
|
queryGeometry,
|
||||||
transformState.getAngle(),
|
transformState,
|
||||||
|
posMatrix,
|
||||||
util::tileSize * id.overscaleFactor(),
|
util::tileSize * id.overscaleFactor(),
|
||||||
std::pow(2, transformState.getZoom() - id.overscaledZ),
|
std::pow(2, transformState.getZoom() - id.overscaledZ),
|
||||||
options,
|
options,
|
||||||
id.toUnwrapped(),
|
id.toUnwrapped(),
|
||||||
layers,
|
layers,
|
||||||
queryPadding);
|
queryPadding * transformState.maxPitchScaleFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GeometryTile::querySourceFeatures(
|
void GeometryTile::querySourceFeatures(
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ public:
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const TransformState&,
|
const TransformState&,
|
||||||
const std::vector<const RenderLayer*>& layers,
|
const std::vector<const RenderLayer*>& layers,
|
||||||
const RenderedQueryOptions& options) override;
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix) override;
|
||||||
|
|
||||||
void querySourceFeatures(
|
void querySourceFeatures(
|
||||||
std::vector<Feature>& result,
|
std::vector<Feature>& result,
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ void Tile::queryRenderedFeatures(
|
|||||||
const GeometryCoordinates&,
|
const GeometryCoordinates&,
|
||||||
const TransformState&,
|
const TransformState&,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const RenderedQueryOptions&) {}
|
const RenderedQueryOptions&,
|
||||||
|
const mat4&) {}
|
||||||
|
|
||||||
float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) {
|
float Tile::getQueryPadding(const std::vector<const RenderLayer*>&) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ public:
|
|||||||
const GeometryCoordinates& queryGeometry,
|
const GeometryCoordinates& queryGeometry,
|
||||||
const TransformState&,
|
const TransformState&,
|
||||||
const std::vector<const RenderLayer*>&,
|
const std::vector<const RenderLayer*>&,
|
||||||
const RenderedQueryOptions& options);
|
const RenderedQueryOptions& options,
|
||||||
|
const mat4& projMatrix);
|
||||||
|
|
||||||
virtual void querySourceFeatures(
|
virtual void querySourceFeatures(
|
||||||
std::vector<Feature>& result,
|
std::vector<Feature>& result,
|
||||||
|
|||||||
@@ -82,11 +82,16 @@ bool lineIntersectsBufferedLine(const GeometryCoordinates& lineA, const Geometry
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool polygonIntersectsBufferedPoint(const GeometryCoordinates& polygon, const GeometryCoordinate& point, float radius) {
|
||||||
|
if (polygonContainsPoint(polygon, point)) return true;
|
||||||
|
if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates& polygon, const GeometryCollection& rings, float radius) {
|
bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates& polygon, const GeometryCollection& rings, float radius) {
|
||||||
for (auto& ring : rings) {
|
for (auto& ring : rings) {
|
||||||
for (auto& point : ring) {
|
for (auto& point : ring) {
|
||||||
if (polygonContainsPoint(polygon, point)) return true;
|
if (polygonIntersectsBufferedPoint(polygon, point, radius)) return true;
|
||||||
if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates&, const Geome
|
|||||||
bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius);
|
bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius);
|
||||||
bool polygonIntersectsPolygon(const GeometryCoordinates&, const GeometryCoordinates&);
|
bool polygonIntersectsPolygon(const GeometryCoordinates&, const GeometryCoordinates&);
|
||||||
bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&);
|
bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&);
|
||||||
|
bool polygonIntersectsBufferedPoint(const GeometryCoordinates& polygon, const GeometryCoordinate& point, float radius);
|
||||||
|
|
||||||
} // namespace util
|
} // namespace util
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
Reference in New Issue
Block a user