diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-05-17 13:21:19 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-05-18 17:29:16 -0700 |
commit | 5864c8fc4cc0e42b2c13f57845492ac20f6980dd (patch) | |
tree | d5b20a57cad4d18d7b165f8ca43652417fc0c792 /src | |
parent | 1b1df9e354f6a26d1410627c1c4c57ea8e7a00af (diff) | |
download | qtlocation-mapboxgl-5864c8fc4cc0e42b2c13f57845492ac20f6980dd.tar.gz |
[core] Include geometry in queryRenderedFeatures results
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/geometry/feature_index.cpp | 21 | ||||
-rw-r--r-- | src/mbgl/geometry/feature_index.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.cpp | 81 | ||||
-rw-r--r-- | src/mbgl/tile/geometry_tile.hpp | 5 | ||||
-rw-r--r-- | src/mbgl/tile/vector_tile_data.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/util/geometry.hpp | 3 |
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); |