diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index e3e33ec067e..46c5e269c03 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -37,6 +37,7 @@ import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; +import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.services.commons.geojson.Feature; @@ -1674,7 +1675,23 @@ public void snapshot(@NonNull SnapshotReadyCallback callback) { @NonNull public List queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String... layerIds) { - return nativeMapView.queryRenderedFeatures(coordinates, layerIds); + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, null); + } + + /** + * Queries the map for rendered features + * + * @param coordinates the point to query + * @param filter filters the returned features + * @param layerIds optionally - only query these layers + * @return the list of feature + */ + @UiThread + @NonNull + public List queryRenderedFeatures(@NonNull PointF coordinates, + @Nullable Filter.Statement filter, + @Nullable String... layerIds) { + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter); } /** @@ -1686,9 +1703,25 @@ public List queryRenderedFeatures(@NonNull PointF coordinates, @Nullabl */ @UiThread @NonNull - public List queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String... - layerIds) { - return nativeMapView.queryRenderedFeatures(coordinates, layerIds); + public List queryRenderedFeatures(@NonNull RectF coordinates, + @Nullable String... layerIds) { + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, null); + } + + /** + * Queries the map for rendered features + * + * @param coordinates the box to query + * @param filter filters the returned features + * @param layerIds optionally - only query these layers + * @return the list of feature + */ + @UiThread + @NonNull + public List queryRenderedFeatures(@NonNull RectF coordinates, + @Nullable Filter.Statement filter, + @Nullable String... layerIds) { + return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter); } // diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index e02a0f3d36e..7c68a48c4d1 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -22,6 +22,7 @@ import com.mapbox.mapboxsdk.geometry.ProjectedMeters; import com.mapbox.mapboxsdk.storage.FileSource; import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; +import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.layers.Layer; import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; import com.mapbox.mapboxsdk.style.sources.Source; @@ -881,27 +882,31 @@ public void removeImage(String name) { // Feature querying @NonNull - public List queryRenderedFeatures(PointF coordinates, String... layerIds) { + public List queryRenderedFeatures(@NonNull PointF coordinates, + @Nullable String[] layerIds, + @Nullable Filter.Statement filter) { if (isDestroyedOn("queryRenderedFeatures")) { return new ArrayList<>(); } Feature[] features = nativeQueryRenderedFeaturesForPoint(coordinates.x / pixelRatio, - coordinates.y / pixelRatio, layerIds); + coordinates.y / pixelRatio, layerIds, filter != null ? filter.toArray() : null); return features != null ? Arrays.asList(features) : new ArrayList(); } @NonNull - public List queryRenderedFeatures(RectF coordinates, String... layerIds) { + public List queryRenderedFeatures(@NonNull RectF coordinates, + @Nullable String[] layerIds, + @Nullable Filter.Statement filter) { if (isDestroyedOn("queryRenderedFeatures")) { return new ArrayList<>(); } Feature[] features = nativeQueryRenderedFeaturesForBox( - coordinates.left / pixelRatio, coordinates.top / pixelRatio, coordinates.right / pixelRatio, coordinates.bottom / pixelRatio, - layerIds); + layerIds, + filter != null ? filter.toArray() : null); return features != null ? Arrays.asList(features) : new ArrayList(); } @@ -1139,12 +1144,14 @@ private native void nativeAddImage(String name, int width, int height, float pix private native void nativeTakeSnapshot(); - private native Feature[] nativeQueryRenderedFeaturesForPoint(float x, float y, String[] - layerIds); + private native Feature[] nativeQueryRenderedFeaturesForPoint(float x, float y, + String[] layerIds, + Object[] filter); private native Feature[] nativeQueryRenderedFeaturesForBox(float left, float top, float right, float bottom, - String[] layerIds); + String[] layerIds, + Object[] filter); int getWidth() { if (isDestroyedOn("")) { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java index ca4fe4e4fdd..1d15efef84a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java @@ -11,6 +11,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; import com.mapbox.mapboxsdk.style.layers.FillLayer; +import com.mapbox.mapboxsdk.style.layers.Filter; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.services.commons.geojson.Feature; @@ -53,7 +54,7 @@ public void onClick(View view) { int left = selectionBox.getLeft() - mapView.getLeft(); RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight()); Timber.i(String.format("Querying box %s for buildings", box)); - List features = mapboxMap.queryRenderedFeatures(box, "building"); + List features = mapboxMap.queryRenderedFeatures(box, Filter.lt("height", 10), "building"); // Show count Toast.makeText( diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 73edc8e2989..c97bdbbfe34 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -26,7 +26,14 @@ #include #include #include +#include +// Java -> C++ conversion +#include "style/android_conversion.hpp" +#include +#include + +// C++ -> Java conversion #include "conversion/conversion.hpp" #include "conversion/collection.hpp" #include "geometry/conversion/feature.hpp" @@ -694,6 +701,9 @@ void NativeMapView::setTransitionDelay(JNIEnv&, jlong delay) { } jni::Array NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object rect) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + // Convert input mbgl::ScreenBox box = { { RectF::getLeft(env, rect), RectF::getTop(env, rect) }, @@ -711,20 +721,40 @@ jni::Array NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object< return result; } -jni::Array> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y, jni::Array layerIds) { +static inline optional toFilter(jni::JNIEnv& env, jni::Array> jfilter) { + using namespace mbgl::style; + using namespace mbgl::style::conversion; + + mbgl::optional filter; + if (jfilter) { + Value filterValue(env, jfilter); + auto converted = convert(filterValue); + if (!converted) { + mbgl::Log::Error(mbgl::Event::JNI, "Error setting filter: " + converted.error().message); + } + filter = std::move(*converted); + } + return filter; +} + +jni::Array> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y, + jni::Array layerIds, + jni::Array> jfilter) { using namespace mbgl::android::conversion; using namespace mapbox::geometry; mbgl::optional> layers; if (layerIds != nullptr && layerIds.Length(env) > 0) { - layers = toVector(env, layerIds); + layers = android::conversion::toVector(env, layerIds); } point point = {x, y}; - return *convert>, std::vector>(env, map->queryRenderedFeatures(point, { layers, {} })); + return *convert>, std::vector>(env, map->queryRenderedFeatures(point, { layers, toFilter(env, jfilter) })); } -jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, jni::jfloat right, jni::jfloat bottom, jni::Array layerIds) { +jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, + jni::jfloat right, jni::jfloat bottom, jni::Array layerIds, + jni::Array> jfilter) { using namespace mbgl::android::conversion; using namespace mapbox::geometry; @@ -734,7 +764,7 @@ jni::Array> NativeMapView::queryRenderedFeaturesForBox(JNIE } box box = { point{ left, top}, point{ right, bottom } }; - return *convert>, std::vector>(env, map->queryRenderedFeatures(box, { layers, {} })); + return *convert>, std::vector>(env, map->queryRenderedFeatures(box, { layers, toFilter(env, jfilter) })); } jni::Array> NativeMapView::getLayers(JNIEnv& env) { diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp index c38afd3e6cc..b7bf03402ed 100755 --- a/platform/android/src/native_map_view.hpp +++ b/platform/android/src/native_map_view.hpp @@ -197,9 +197,13 @@ class NativeMapView : public View, public Backend { jni::Array queryPointAnnotations(JNIEnv&, jni::Object); - jni::Array> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat, jni::Array); + jni::Array> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat, + jni::Array, + jni::Array> jfilter); - jni::Array> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat, jni::jfloat, jni::Array); + jni::Array> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat, + jni::jfloat, jni::Array, + jni::Array> jfilter); jni::Array> getLayers(JNIEnv&);