summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2017-03-04 18:44:33 -0800
committerJesse Bounds <jesse@rebounds.net>2017-03-10 11:08:32 -0800
commit517659b1b44a4e31e1035d4da9c444380454ad58 (patch)
tree45777ce2cf3ca4cb4d22ab42c6a82c6b4118b530
parent4d325879b89323439e9c2955ba5271d03c910490 (diff)
downloadqtlocation-mapboxgl-517659b1b44a4e31e1035d4da9c444380454ad58.tar.gz
[core] query source features
-rw-r--r--cmake/core-files.cmake1
-rw-r--r--include/mbgl/map/query.hpp5
-rw-r--r--include/mbgl/style/query.hpp24
-rw-r--r--include/mbgl/style/source.hpp5
-rw-r--r--src/mbgl/style/source.cpp4
-rw-r--r--src/mbgl/style/source_impl.cpp18
-rw-r--r--src/mbgl/style/source_impl.hpp3
-rw-r--r--src/mbgl/tile/geojson_tile.cpp23
-rw-r--r--src/mbgl/tile/geojson_tile.hpp4
-rw-r--r--src/mbgl/tile/geometry_tile.cpp36
-rw-r--r--src/mbgl/tile/geometry_tile.hpp10
-rw-r--r--src/mbgl/tile/tile.cpp5
-rw-r--r--src/mbgl/tile/tile.hpp5
-rw-r--r--test/api/query.test.cpp41
-rw-r--r--test/fixtures/api/query_style.json9
15 files changed, 191 insertions, 2 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index b5baff264c..d2a77aa3aa 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -245,6 +245,7 @@ set(MBGL_CORE_FILES
include/mbgl/style/filter_evaluator.hpp
include/mbgl/style/layer.hpp
include/mbgl/style/property_value.hpp
+ include/mbgl/style/query.hpp
include/mbgl/style/source.hpp
include/mbgl/style/transition_options.hpp
include/mbgl/style/types.hpp
diff --git a/include/mbgl/map/query.hpp b/include/mbgl/map/query.hpp
index 201484cd84..827424d21d 100644
--- a/include/mbgl/map/query.hpp
+++ b/include/mbgl/map/query.hpp
@@ -3,6 +3,9 @@
#include <mbgl/util/optional.hpp>
#include <mbgl/style/filter.hpp>
+#include <string>
+#include <vector>
+
namespace mbgl {
/**
@@ -12,7 +15,7 @@ class RenderedQueryOptions {
public:
/** layerIDs to include in the query */
optional<std::vector<std::string>> layerIDs;
-
+
optional<style::Filter> filter;
};
diff --git a/include/mbgl/style/query.hpp b/include/mbgl/style/query.hpp
new file mode 100644
index 0000000000..8cb2545ab4
--- /dev/null
+++ b/include/mbgl/style/query.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <mbgl/util/optional.hpp>
+#include <mbgl/style/filter.hpp>
+
+#include <string>
+#include <vector>
+
+namespace mbgl {
+namespace style {
+
+/**
+ * Options for query source features
+ */
+class SourceQueryOptions {
+public:
+ // Required for VectorSource, ignored for GeoJSONSource
+ optional<std::vector<std::string>> sourceLayers;
+
+ optional<style::Filter> filter;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/include/mbgl/style/source.hpp b/include/mbgl/style/source.hpp
index 870c81fda6..0901bb1954 100644
--- a/include/mbgl/style/source.hpp
+++ b/include/mbgl/style/source.hpp
@@ -1,11 +1,14 @@
#pragma once
+#include <mbgl/util/feature.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/style/types.hpp>
+#include <mbgl/style/query.hpp>
#include <memory>
#include <string>
+#include <vector>
namespace mbgl {
namespace style {
@@ -52,6 +55,8 @@ public:
std::unique_ptr<Source> copy(const std::string& id) const;
optional<std::string> getAttribution() const;
+
+ std::vector<Feature> querySourceFeatures(const SourceQueryOptions& options = {});
// Private implementation
class Impl;
diff --git a/src/mbgl/style/source.cpp b/src/mbgl/style/source.cpp
index cfb268006b..25c06024d6 100644
--- a/src/mbgl/style/source.cpp
+++ b/src/mbgl/style/source.cpp
@@ -17,6 +17,10 @@ const std::string& Source::getID() const {
optional<std::string> Source::getAttribution() const {
return baseImpl->getAttribution();
}
+
+std::vector<Feature> Source::querySourceFeatures(const SourceQueryOptions& options) {
+ return baseImpl->querySourceFeatures(options);
+}
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/source_impl.cpp b/src/mbgl/style/source_impl.cpp
index f83579d0d0..1f8301629f 100644
--- a/src/mbgl/style/source_impl.cpp
+++ b/src/mbgl/style/source_impl.cpp
@@ -10,6 +10,7 @@
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/util/enum.hpp>
#include <mbgl/map/query.hpp>
+#include <mbgl/style/query.hpp>
#include <mbgl/algorithm/update_renderables.hpp>
#include <mbgl/algorithm/generate_clip_ids.hpp>
@@ -258,6 +259,23 @@ std::unordered_map<std::string, std::vector<Feature>> Source::Impl::queryRendere
return result;
}
+std::vector<Feature> Source::Impl::querySourceFeatures(const SourceQueryOptions& options) {
+
+ // Only VectorSource and GeoJSON source supported
+ if (type != SourceType::GeoJSON && type != SourceType::Vector) {
+ Log::Warning(Event::General, "Source type not supported");
+ return {};
+ }
+
+ std::vector<Feature> result;
+
+ for (const auto& pair : tiles) {
+ pair.second->querySourceFeatures(result, options);
+ }
+
+ return result;
+}
+
void Source::Impl::setCacheSize(size_t size) {
cache.setSize(size);
}
diff --git a/src/mbgl/style/source_impl.hpp b/src/mbgl/style/source_impl.hpp
index 6e16a31e5a..b9707edaa7 100644
--- a/src/mbgl/style/source_impl.hpp
+++ b/src/mbgl/style/source_impl.hpp
@@ -7,6 +7,7 @@
#include <mbgl/tile/tile.hpp>
#include <mbgl/tile/tile_cache.hpp>
#include <mbgl/style/types.hpp>
+#include <mbgl/style/query.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/mat4.hpp>
@@ -70,6 +71,8 @@ public:
const TransformState& transformState,
const RenderedQueryOptions& options) const;
+ std::vector<Feature> querySourceFeatures(const SourceQueryOptions&);
+
void setCacheSize(size_t);
void onLowMemory();
diff --git a/src/mbgl/tile/geojson_tile.cpp b/src/mbgl/tile/geojson_tile.cpp
index 85d8b75619..5a2a72f50b 100644
--- a/src/mbgl/tile/geojson_tile.cpp
+++ b/src/mbgl/tile/geojson_tile.cpp
@@ -1,5 +1,6 @@
#include <mbgl/tile/geojson_tile.hpp>
#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/style/query.hpp>
#include <mapbox/geojsonvt.hpp>
#include <supercluster.hpp>
@@ -90,5 +91,27 @@ void GeoJSONTile::updateData(const mapbox::geometry::feature_collection<int16_t>
}
void GeoJSONTile::setNecessity(Necessity) {}
+
+void GeoJSONTile::querySourceFeatures(
+ std::vector<Feature>& result,
+ const style::SourceQueryOptions& options) {
+
+ // Ignore the sourceLayer, there is only one
+ auto layer = getData()->getLayer({});
+
+ if (layer) {
+ auto featureCount = layer->featureCount();
+ for (std::size_t i = 0; i < featureCount; i++) {
+ auto feature = layer->getFeature(i);
+
+ // Apply filter, if any
+ if (options.filter && !(*options.filter)(*feature)) {
+ continue;
+ }
+
+ result.push_back(convertFeature(*feature, id.canonical));
+ }
+ }
+}
} // namespace mbgl
diff --git a/src/mbgl/tile/geojson_tile.hpp b/src/mbgl/tile/geojson_tile.hpp
index 6ddc6ea482..e1d269a9a7 100644
--- a/src/mbgl/tile/geojson_tile.hpp
+++ b/src/mbgl/tile/geojson_tile.hpp
@@ -18,6 +18,10 @@ public:
void updateData(const mapbox::geometry::feature_collection<int16_t>&);
void setNecessity(Necessity) final;
+
+ void querySourceFeatures(
+ std::vector<Feature>& result,
+ const style::SourceQueryOptions&) override;
};
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp
index 01f054bdf4..37787df9ea 100644
--- a/src/mbgl/tile/geometry_tile.cpp
+++ b/src/mbgl/tile/geometry_tile.cpp
@@ -12,8 +12,11 @@
#include <mbgl/geometry/feature_index.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/map/transform_state.hpp>
-#include <mbgl/util/run_loop.hpp>
#include <mbgl/map/query.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/style/filter_evaluator.hpp>
+#include <mbgl/style/query.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
@@ -158,4 +161,35 @@ void GeometryTile::queryRenderedFeatures(
collisionTile.get());
}
+void GeometryTile::querySourceFeatures(
+ std::vector<Feature>& result,
+ const style::SourceQueryOptions& options) {
+
+ // No source layers, specified, nothing to do
+ if (!options.sourceLayers) {
+ Log::Warning(Event::General, "At least one sourceLayer required");
+ return;
+ }
+
+ for (auto sourceLayer : *options.sourceLayers) {
+ // Go throught all sourceLayers, if any
+ // to gather all the features
+ auto layer = data->getLayer(sourceLayer);
+
+ if (layer) {
+ auto featureCount = layer->featureCount();
+ for (std::size_t i = 0; i < featureCount; i++) {
+ auto feature = layer->getFeature(i);
+
+ // Apply filter, if any
+ if (options.filter && !(*options.filter)(*feature)) {
+ continue;
+ }
+
+ result.push_back(convertFeature(*feature, id.canonical));
+ }
+ }
+ }
+}
+
} // namespace mbgl
diff --git a/src/mbgl/tile/geometry_tile.hpp b/src/mbgl/tile/geometry_tile.hpp
index 538ea4fbd2..cabe193467 100644
--- a/src/mbgl/tile/geometry_tile.hpp
+++ b/src/mbgl/tile/geometry_tile.hpp
@@ -21,6 +21,7 @@ namespace style {
class Style;
class Layer;
class UpdateParameters;
+class SourceQueryOptions;
} // namespace style
class GeometryTile : public Tile {
@@ -46,6 +47,10 @@ public:
const TransformState&,
const RenderedQueryOptions& options) override;
+ void querySourceFeatures(
+ std::vector<Feature>& result,
+ const style::SourceQueryOptions&) override;
+
void cancel() override;
class LayoutResult {
@@ -66,6 +71,11 @@ public:
void onPlacement(PlacementResult);
void onError(std::exception_ptr);
+
+protected:
+ const GeometryTileData* getData() {
+ return data.get();
+ }
private:
const std::string sourceID;
diff --git a/src/mbgl/tile/tile.cpp b/src/mbgl/tile/tile.cpp
index 2f347fb950..4fb8331aeb 100644
--- a/src/mbgl/tile/tile.cpp
+++ b/src/mbgl/tile/tile.cpp
@@ -4,6 +4,7 @@
#include <mbgl/util/string.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/map/query.hpp>
+#include <mbgl/style/query.hpp>
namespace mbgl {
@@ -35,4 +36,8 @@ void Tile::queryRenderedFeatures(
const TransformState&,
const RenderedQueryOptions&) {}
+void Tile::querySourceFeatures(
+ std::vector<Feature>&,
+ const style::SourceQueryOptions&) {}
+
} // namespace mbgl
diff --git a/src/mbgl/tile/tile.hpp b/src/mbgl/tile/tile.hpp
index b335d1a5d5..613b15f36c 100644
--- a/src/mbgl/tile/tile.hpp
+++ b/src/mbgl/tile/tile.hpp
@@ -25,6 +25,7 @@ class RenderedQueryOptions;
namespace style {
class Layer;
+class SourceQueryOptions;
} // namespace style
class Tile : private util::noncopyable {
@@ -58,6 +59,10 @@ public:
const TransformState&,
const RenderedQueryOptions& options);
+ virtual void querySourceFeatures(
+ std::vector<Feature>& result,
+ const style::SourceQueryOptions&);
+
void setTriedOptional();
// Returns true when the tile source has received a first response, regardless of whether a load
diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp
index b42046fb48..45e6b19268 100644
--- a/test/api/query.test.cpp
+++ b/test/api/query.test.cpp
@@ -8,6 +8,7 @@
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
+#include <mbgl/style/source.hpp>
using namespace mbgl;
using namespace mbgl::style;
@@ -81,3 +82,43 @@ TEST(Query, QueryRenderedFeaturesFilter) {
auto features3 = test.map.queryRenderedFeatures(zz, {{ }, { gtFilter }});
EXPECT_EQ(features3.size(), 1u);
}
+
+TEST(Query, QuerySourceFeatures) {
+ QueryTest test;
+
+ auto features1 = test.map.getSource("source3")->querySourceFeatures();
+ EXPECT_EQ(features1.size(), 1u);
+}
+
+TEST(Query, QuerySourceFeaturesOptionValidation) {
+ QueryTest test;
+
+ // GeoJSONSource, doesn't require a layer id
+ auto features = test.map.getSource("source3")->querySourceFeatures();
+ ASSERT_EQ(features.size(), 1u);
+
+ // VectorSource, requires a layer id
+ features = test.map.getSource("source5")->querySourceFeatures();
+ ASSERT_EQ(features.size(), 0u);
+
+ // RasterSource, not supported
+ features = test.map.getSource("source6")->querySourceFeatures();
+ ASSERT_EQ(features.size(), 0u);
+}
+
+TEST(Query, QuerySourceFeaturesFilter) {
+ QueryTest test;
+
+ const EqualsFilter eqFilter = { "key1", std::string("value1") };
+ auto features1 = test.map.getSource("source4")->querySourceFeatures({{}, { eqFilter }});
+ EXPECT_EQ(features1.size(), 1u);
+
+ const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") };
+ auto features2 = test.map.getSource("source4")->querySourceFeatures({{}, { idNotEqFilter }});
+ EXPECT_EQ(features2.size(), 0u);
+
+ const GreaterThanFilter gtFilter = { "key2", 1.0 };
+ auto features3 = test.map.getSource("source4")->querySourceFeatures({{}, { gtFilter }});
+ EXPECT_EQ(features3.size(), 1u);
+}
+
diff --git a/test/fixtures/api/query_style.json b/test/fixtures/api/query_style.json
index 4e11921775..97f1d04432 100644
--- a/test/fixtures/api/query_style.json
+++ b/test/fixtures/api/query_style.json
@@ -50,6 +50,15 @@
"key4": 0.5
}
}
+ },
+ "source5": {
+ "type": "vector",
+ "url": "mapbox://mapbox.mapbox-streets-v6"
+ },
+ "source6": {
+ "type": "raster",
+ "url": "mapbox://mapbox.satellite",
+ "tileSize": 256
}
},
"layers": [