summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-05-17 13:21:19 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-05-18 17:29:16 -0700
commit5864c8fc4cc0e42b2c13f57845492ac20f6980dd (patch)
treed5b20a57cad4d18d7b165f8ca43652417fc0c792 /src
parent1b1df9e354f6a26d1410627c1c4c57ea8e7a00af (diff)
downloadqtlocation-mapboxgl-5864c8fc4cc0e42b2c13f57845492ac20f6980dd.tar.gz
[core] Include geometry in queryRenderedFeatures results
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/geometry/feature_index.cpp21
-rw-r--r--src/mbgl/geometry/feature_index.hpp3
-rw-r--r--src/mbgl/tile/geometry_tile.cpp81
-rw-r--r--src/mbgl/tile/geometry_tile.hpp5
-rw-r--r--src/mbgl/tile/vector_tile_data.cpp1
-rw-r--r--src/mbgl/util/geometry.hpp3
6 files changed, 101 insertions, 13 deletions
diff --git a/src/mbgl/geometry/feature_index.cpp b/src/mbgl/geometry/feature_index.cpp
index fb68b572b1..ab451bcd6a 100644
--- a/src/mbgl/geometry/feature_index.cpp
+++ b/src/mbgl/geometry/feature_index.cpp
@@ -57,6 +57,7 @@ void FeatureIndex::query(
const double scale,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTile& geometryTile,
+ const CanonicalTileID& tileID,
const Style& style) const {
mapbox::geometry::box<int16_t> box = mapbox::geometry::envelope(queryGeometry);
@@ -73,7 +74,7 @@ void FeatureIndex::query(
if (indexedFeature.sortIndex == previousSortIndex) continue;
previousSortIndex = indexedFeature.sortIndex;
- addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTile, style, bearing, pixelsToTileUnits);
+ addFeature(result, indexedFeature, queryGeometry, filterLayerIDs, geometryTile, tileID, style, bearing, pixelsToTileUnits);
}
// query symbol features
@@ -81,7 +82,7 @@ void FeatureIndex::query(
std::vector<IndexedSubfeature> symbolFeatures = collisionTile->queryRenderedSymbols(box, scale);
std::sort(symbolFeatures.begin(), symbolFeatures.end(), topDownSymbols);
for (const auto& symbolFeature : symbolFeatures) {
- addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTile, style, bearing, pixelsToTileUnits);
+ addFeature(result, symbolFeature, queryGeometry, filterLayerIDs, geometryTile, tileID, style, bearing, pixelsToTileUnits);
}
}
@@ -91,6 +92,7 @@ void FeatureIndex::addFeature(
const GeometryCollection& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTile& geometryTile,
+ const CanonicalTileID& tileID,
const Style& style,
const float bearing,
const float pixelsToTileUnits) const {
@@ -112,20 +114,13 @@ void FeatureIndex::addFeature(
}
auto styleLayer = style.getLayer(layerID);
- if (!styleLayer) {
+ if (!styleLayer ||
+ (!styleLayer->is<SymbolLayer>() &&
+ !styleLayer->queryIntersectsGeometry(queryGeometry, geometryTileFeature->getGeometries(), bearing, pixelsToTileUnits))) {
continue;
}
- if (!styleLayer->is<SymbolLayer>()) {
- auto geometries = geometryTileFeature->getGeometries();
- if (!styleLayer->queryIntersectsGeometry(queryGeometry, geometries, bearing, pixelsToTileUnits)) continue;
- }
-
- Feature feature { mapbox::geometry::point<double>() };
- feature.properties = geometryTileFeature->getProperties();
- feature.id = geometryTileFeature->getID();
-
- result[layerID].push_back(std::move(feature));
+ result[layerID].push_back(convertFeature(*geometryTileFeature, tileID));
}
}
diff --git a/src/mbgl/geometry/feature_index.hpp b/src/mbgl/geometry/feature_index.hpp
index 0cb9a891d7..a0afbb885a 100644
--- a/src/mbgl/geometry/feature_index.hpp
+++ b/src/mbgl/geometry/feature_index.hpp
@@ -14,6 +14,7 @@ namespace mbgl {
class Style;
class CollisionTile;
enum class TranslateAnchorType : bool;
+class CanonicalTileID;
class IndexedSubfeature {
public:
@@ -38,6 +39,7 @@ public:
const double scale,
const optional<std::vector<std::string>>& layerIDs,
const GeometryTile&,
+ const CanonicalTileID&,
const Style&) const;
static optional<GeometryCollection> translateQueryGeometry(
@@ -58,6 +60,7 @@ private:
const GeometryCollection& queryGeometry,
const optional<std::vector<std::string>>& filterLayerIDs,
const GeometryTile&,
+ const CanonicalTileID&,
const Style&,
const float bearing,
const float pixelsToTileUnits) const;
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 9f57c7ab6f..2e3d0576db 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -51,4 +51,85 @@ std::vector<GeometryCollection> classifyRings(const GeometryCollection& rings) {
return polygons;
}
+static Feature::geometry_type convertGeometry(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
+ const double size = util::EXTENT * std::pow(2, tileID.z);
+ const double x0 = util::EXTENT * tileID.x;
+ const double y0 = util::EXTENT * tileID.y;
+
+ auto tileCoordinatesToLatLng = [&] (const Point<int16_t>& p) {
+ double y2 = 180 - (p.y + y0) * 360 / size;
+ return Point<double>(
+ (p.x + x0) * 360 / size - 180,
+ 360.0 / M_PI * std::atan(std::exp(y2 * M_PI / 180)) - 90.0
+ );
+ };
+
+ GeometryCollection geometries = geometryTileFeature.getGeometries();
+
+ switch (geometryTileFeature.getType()) {
+ case FeatureType::Unknown: {
+ assert(false);
+ return Point<double>(NAN, NAN);
+ }
+
+ case FeatureType::Point: {
+ MultiPoint<double> multiPoint;
+ for (const auto& p : geometries.at(0)) {
+ multiPoint.push_back(tileCoordinatesToLatLng(p));
+ }
+ if (multiPoint.size() == 1) {
+ return multiPoint[0];
+ } else {
+ return multiPoint;
+ }
+ }
+
+ case FeatureType::LineString: {
+ MultiLineString<double> multiLineString;
+ for (const auto& g : geometries) {
+ LineString<double> lineString;
+ for (const auto& p : g) {
+ lineString.push_back(tileCoordinatesToLatLng(p));
+ }
+ multiLineString.push_back(std::move(lineString));
+ }
+ if (multiLineString.size() == 1) {
+ return multiLineString[0];
+ } else {
+ return multiLineString;
+ }
+ }
+
+ case FeatureType::Polygon: {
+ MultiPolygon<double> multiPolygon;
+ for (const auto& pg : classifyRings(geometries)) {
+ Polygon<double> polygon;
+ for (const auto& r : pg) {
+ LinearRing<double> linearRing;
+ for (const auto& p : r) {
+ linearRing.push_back(tileCoordinatesToLatLng(p));
+ }
+ polygon.push_back(std::move(linearRing));
+ }
+ multiPolygon.push_back(std::move(polygon));
+ }
+ if (multiPolygon.size() == 1) {
+ return multiPolygon[0];
+ } else {
+ return multiPolygon;
+ }
+ }
+ }
+
+ // Unreachable, but placate GCC.
+ return Point<double>();
+}
+
+Feature convertFeature(const GeometryTileFeature& geometryTileFeature, const CanonicalTileID& tileID) {
+ Feature feature { convertGeometry(geometryTileFeature, tileID) };
+ feature.properties = geometryTileFeature.getProperties();
+ feature.id = geometryTileFeature.getID();
+ return feature;
+}
+
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index edbe91b6c9..d98e1b3b0c 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -25,6 +25,8 @@ enum class FeatureType : uint8_t {
Polygon = 3
};
+class CanonicalTileID;
+
// Normalized vector tile coordinates.
// Each geometry coordinate represents a point in a bidimensional space,
// varying from -V...0...+V, where V is the maximum extent applicable.
@@ -90,6 +92,9 @@ public:
// classifies an array of rings into polygons with outer rings and holes
std::vector<GeometryCollection> classifyRings(const GeometryCollection&);
+// convert from GeometryTileFeature to Feature (eventually we should eliminate GeometryTileFeature)
+Feature convertFeature(const GeometryTileFeature&, const CanonicalTileID&);
+
} // namespace mbgl
#endif
diff --git a/src/mbgl/tile/vector_tile_data.cpp b/src/mbgl/tile/vector_tile_data.cpp
index 457ffd4171..10b5bae182 100644
--- a/src/mbgl/tile/vector_tile_data.cpp
+++ b/src/mbgl/tile/vector_tile_data.cpp
@@ -206,6 +206,7 @@ void VectorTileData::queryRenderedFeatures(
std::pow(2, transformState.getZoom() - id.overscaledZ),
layerIDs,
*geometryTile,
+ id.canonical,
style);
}
diff --git a/src/mbgl/util/geometry.hpp b/src/mbgl/util/geometry.hpp
index bf44d5ce93..f9b91bcb39 100644
--- a/src/mbgl/util/geometry.hpp
+++ b/src/mbgl/util/geometry.hpp
@@ -23,6 +23,9 @@ using MultiLineString = mapbox::geometry::multi_line_string<T>;
template <class T>
using MultiPolygon = mapbox::geometry::multi_polygon<T>;
+template <class T>
+using LinearRing = mapbox::geometry::linear_ring<T>;
+
template <class S, class T>
Point<S> convertPoint(const Point<T>& p) {
return Point<S>(p.x, p.y);