[core] No need for feature querying to support multipolygons

This commit is contained in:
John Firebaugh
2016-10-07 11:49:22 -07:00
committed by Bruno de Oliveira Abinader
parent 61d8ecefda
commit 38e78e25df
12 changed files with 46 additions and 57 deletions

View File

@@ -52,7 +52,7 @@ static bool topDownSymbols(const IndexedSubfeature& a, const IndexedSubfeature&
void FeatureIndex::query(
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const float bearing,
const double tileSize,
const double scale,
@@ -93,7 +93,7 @@ void FeatureIndex::query(
void FeatureIndex::addFeature(
std::unordered_map<std::string, std::vector<Feature>>& result,
const IndexedSubfeature& indexedFeature,
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTileData& geometryTileData,
const CanonicalTileID& tileID,
@@ -128,8 +128,8 @@ void FeatureIndex::addFeature(
}
}
optional<GeometryCollection> FeatureIndex::translateQueryGeometry(
const GeometryCollection& queryGeometry,
optional<GeometryCoordinates> FeatureIndex::translateQueryGeometry(
const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType anchorType,
const float bearing,
@@ -143,13 +143,9 @@ optional<GeometryCollection> FeatureIndex::translateQueryGeometry(
translateVec = util::rotate(translateVec, -bearing);
}
GeometryCollection translated;
for (const auto& ring : queryGeometry) {
translated.emplace_back();
auto& translatedRing = translated.back();
for (const auto& p : ring) {
translatedRing.push_back(p - translateVec);
}
GeometryCoordinates translated;
for (const auto& p : queryGeometry) {
translated.push_back(p - translateVec);
}
return translated;
}

View File

@@ -35,7 +35,7 @@ public:
void query(
std::unordered_map<std::string, std::vector<Feature>>& result,
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const float bearing,
const double tileSize,
const double scale,
@@ -44,8 +44,8 @@ public:
const CanonicalTileID&,
const style::Style&) const;
static optional<GeometryCollection> translateQueryGeometry(
const GeometryCollection& queryGeometry,
static optional<GeometryCoordinates> translateQueryGeometry(
const GeometryCoordinates& queryGeometry,
const std::array<float, 2>& translate,
const style::TranslateAnchorType,
const float bearing,
@@ -59,7 +59,7 @@ private:
void addFeature(
std::unordered_map<std::string, std::vector<Feature>>& result,
const IndexedSubfeature&,
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTileData&,
const CanonicalTileID&,

View File

@@ -69,7 +69,7 @@ public:
virtual float getQueryRadius() const { return 0; }
virtual bool queryIntersectsGeometry(
const GeometryCollection&,
const GeometryCoordinates&,
const GeometryCollection&,
const float,
const float) const { return false; };

View File

@@ -40,7 +40,7 @@ float CircleLayer::Impl::getQueryRadius() const {
}
bool CircleLayer::Impl::queryIntersectsGeometry(
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -50,7 +50,7 @@ bool CircleLayer::Impl::queryIntersectsGeometry(
auto circleRadius = paint.circleRadius * pixelsToTileUnits;
return util::multiPolygonIntersectsBufferedMultiPoint(
return util::polygonIntersectsBufferedMultiPoint(
translatedQueryGeometry.value_or(queryGeometry), geometry, circleRadius);
}

View File

@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;

View File

@@ -49,7 +49,7 @@ float FillLayer::Impl::getQueryRadius() const {
}
bool FillLayer::Impl::queryIntersectsGeometry(
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -57,7 +57,7 @@ bool FillLayer::Impl::queryIntersectsGeometry(
auto translatedQueryGeometry = FeatureIndex::translateQueryGeometry(
queryGeometry, paint.fillTranslate, paint.fillTranslateAnchor, bearing, pixelsToTileUnits);
return util::multiPolygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
return util::polygonIntersectsMultiPolygon(translatedQueryGeometry.value_or(queryGeometry), geometry);
}
} // namespace style

View File

@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;

View File

@@ -87,7 +87,7 @@ float LineLayer::Impl::getQueryRadius() const {
}
bool LineLayer::Impl::queryIntersectsGeometry(
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const {
@@ -98,7 +98,7 @@ bool LineLayer::Impl::queryIntersectsGeometry(
queryGeometry, paint.lineTranslate, paint.lineTranslateAnchor, bearing, pixelsToTileUnits);
auto offsetGeometry = offsetLine(geometry, paint.lineOffset * pixelsToTileUnits);
return util::multiPolygonIntersectsBufferedMultiLine(
return util::polygonIntersectsBufferedMultiLine(
translatedQueryGeometry.value_or(queryGeometry),
offsetGeometry.value_or(geometry),
halfWidth);

View File

@@ -19,7 +19,7 @@ public:
float getQueryRadius() const override;
bool queryIntersectsGeometry(
const GeometryCollection& queryGeometry,
const GeometryCoordinates& queryGeometry,
const GeometryCollection& geometry,
const float bearing,
const float pixelsToTileUnits) const override;

View File

@@ -136,7 +136,7 @@ void GeometryTile::queryRenderedFeatures(
if (!featureIndex || !data) return;
featureIndex->query(result,
{ queryGeometry },
queryGeometry,
transformState.getAngle(),
util::tileSize * id.overscaleFactor(),
std::pow(2, transformState.getZoom() - id.overscaledZ),

View File

@@ -90,54 +90,47 @@ bool lineIntersectsBufferedLine(const GeometryCoordinates& lineA, const Geometry
return false;
}
bool multiPolygonIntersectsBufferedMultiPoint(const GeometryCollection& multiPolygon, const GeometryCollection& rings, float radius) {
for (auto& polygon : multiPolygon) {
for (auto& ring : rings) {
for (auto& point : ring) {
if (polygonContainsPoint(polygon, point)) return true;
if (pointIntersectsBufferedLine(point, polygon, radius)) return true;
}
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;
}
}
return false;
}
bool multiPolygonIntersectsBufferedMultiLine(const GeometryCollection& multiPolygon, const GeometryCollection& multiLine, float radius) {
bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates& polygon, const GeometryCollection& multiLine, float radius) {
for (auto& line : multiLine) {
for (auto& polygon : multiPolygon) {
if (polygon.size() >= 3) {
for (auto& p : line) {
if (polygonContainsPoint(polygon, p)) return true;
}
if (polygon.size() >= 3) {
for (auto& p : line) {
if (polygonContainsPoint(polygon, p)) return true;
}
if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
}
if (lineIntersectsBufferedLine(polygon, line, radius)) return true;
}
return false;
}
bool multiPolygonIntersectsMultiPolygon(const GeometryCollection& multiPolygonA, const GeometryCollection& multiPolygonB) {
if (multiPolygonA.size() == 1 && multiPolygonA.at(0).size() == 1) {
return multiPolygonContainsPoint(multiPolygonB, multiPolygonA.at(0).at(0));
bool polygonIntersectsMultiPolygon(const GeometryCoordinates& polygon, const GeometryCollection& multiPolygon) {
if (polygon.size() == 1) {
return multiPolygonContainsPoint(multiPolygon, polygon.at(0));
}
for (auto& ring : multiPolygonB) {
for (auto& ring : multiPolygon) {
for (auto& p : ring) {
if (multiPolygonContainsPoint(multiPolygonA, p)) return true;
if (polygonContainsPoint(polygon, p)) return true;
}
}
for (auto& polygon : multiPolygonA) {
for (auto& p : polygon) {
if (multiPolygonContainsPoint(multiPolygonB, p)) return true;
}
for (auto& p : polygon) {
if (multiPolygonContainsPoint(multiPolygon, p)) return true;
}
for (auto& polygonB : multiPolygonB) {
if (lineIntersectsLine(polygon, polygonB)) return true;
}
for (auto& polygonB : multiPolygon) {
if (lineIntersectsLine(polygon, polygonB)) return true;
}
return false;

View File

@@ -5,9 +5,9 @@
namespace mbgl {
namespace util {
bool multiPolygonIntersectsBufferedMultiPoint(const GeometryCollection&, const GeometryCollection&, float radius);
bool multiPolygonIntersectsBufferedMultiLine(const GeometryCollection&, const GeometryCollection&, float radius);
bool multiPolygonIntersectsMultiPolygon(const GeometryCollection&, const GeometryCollection&);
bool polygonIntersectsBufferedMultiPoint(const GeometryCoordinates&, const GeometryCollection&, float radius);
bool polygonIntersectsBufferedMultiLine(const GeometryCoordinates&, const GeometryCollection&, float radius);
bool polygonIntersectsMultiPolygon(const GeometryCoordinates&, const GeometryCollection&);
} // namespace util
} // namespace mbgl