Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[android] Add support for queryRenderedFeatures filter
Browse files Browse the repository at this point in the history
  • Loading branch information
ivovandongen committed Mar 4, 2017
1 parent 161ae80 commit b5d0a66
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1674,7 +1675,23 @@ public void snapshot(@NonNull SnapshotReadyCallback callback) {
@NonNull
public List<Feature> 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<Feature> queryRenderedFeatures(@NonNull PointF coordinates,
@Nullable Filter.Statement filter,
@Nullable String... layerIds) {
return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter);
}

/**
Expand All @@ -1686,9 +1703,25 @@ public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates, @Nullabl
*/
@UiThread
@NonNull
public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String...
layerIds) {
return nativeMapView.queryRenderedFeatures(coordinates, layerIds);
public List<Feature> 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<Feature> queryRenderedFeatures(@NonNull RectF coordinates,
@Nullable Filter.Statement filter,
@Nullable String... layerIds) {
return nativeMapView.queryRenderedFeatures(coordinates, layerIds, filter);
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -881,27 +882,31 @@ public void removeImage(String name) {
// Feature querying

@NonNull
public List<Feature> queryRenderedFeatures(PointF coordinates, String... layerIds) {
public List<Feature> 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<Feature>();
}

@NonNull
public List<Feature> queryRenderedFeatures(RectF coordinates, String... layerIds) {
public List<Feature> 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<Feature>();
}

Expand Down Expand Up @@ -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("")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Feature> features = mapboxMap.queryRenderedFeatures(box, "building");
List<Feature> features = mapboxMap.queryRenderedFeatures(box, Filter.lt("height", 10), "building");

// Show count
Toast.makeText(
Expand Down
40 changes: 35 additions & 5 deletions platform/android/src/native_map_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@
#include <mbgl/util/logging.hpp>
#include <mbgl/util/platform.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/style/filter.hpp>

// Java -> C++ conversion
#include "style/android_conversion.hpp"
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/filter.hpp>

// C++ -> Java conversion
#include "conversion/conversion.hpp"
#include "conversion/collection.hpp"
#include "geometry/conversion/feature.hpp"
Expand Down Expand Up @@ -694,6 +701,9 @@ void NativeMapView::setTransitionDelay(JNIEnv&, jlong delay) {
}

jni::Array<jlong> NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object<RectF> rect) {
using namespace mbgl::style;
using namespace mbgl::style::conversion;

// Convert input
mbgl::ScreenBox box = {
{ RectF::getLeft(env, rect), RectF::getTop(env, rect) },
Expand All @@ -711,20 +721,40 @@ jni::Array<jlong> NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object<
return result;
}

jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y, jni::Array<jni::String> layerIds) {
static inline optional<mbgl::style::Filter> toFilter(jni::JNIEnv& env, jni::Array<jni::Object<>> jfilter) {
using namespace mbgl::style;
using namespace mbgl::style::conversion;

mbgl::optional<Filter> filter;
if (jfilter) {
Value filterValue(env, jfilter);
auto converted = convert<Filter>(filterValue);
if (!converted) {
mbgl::Log::Error(mbgl::Event::JNI, "Error setting filter: " + converted.error().message);
}
filter = std::move(*converted);
}
return filter;
}

jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y,
jni::Array<jni::String> layerIds,
jni::Array<jni::Object<>> jfilter) {
using namespace mbgl::android::conversion;
using namespace mapbox::geometry;

mbgl::optional<std::vector<std::string>> layers;
if (layerIds != nullptr && layerIds.Length(env) > 0) {
layers = toVector(env, layerIds);
layers = android::conversion::toVector(env, layerIds);
}
point<double> point = {x, y};

return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, map->queryRenderedFeatures(point, { layers, {} }));
return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, map->queryRenderedFeatures(point, { layers, toFilter(env, jfilter) }));
}

jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, jni::jfloat right, jni::jfloat bottom, jni::Array<jni::String> layerIds) {
jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top,
jni::jfloat right, jni::jfloat bottom, jni::Array<jni::String> layerIds,
jni::Array<jni::Object<>> jfilter) {
using namespace mbgl::android::conversion;
using namespace mapbox::geometry;

Expand All @@ -734,7 +764,7 @@ jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForBox(JNIE
}
box<double> box = { point<double>{ left, top}, point<double>{ right, bottom } };

return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, map->queryRenderedFeatures(box, { layers, {} }));
return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, map->queryRenderedFeatures(box, { layers, toFilter(env, jfilter) }));
}

jni::Array<jni::Object<Layer>> NativeMapView::getLayers(JNIEnv& env) {
Expand Down
8 changes: 6 additions & 2 deletions platform/android/src/native_map_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,13 @@ class NativeMapView : public View, public Backend {

jni::Array<jlong> queryPointAnnotations(JNIEnv&, jni::Object<RectF>);

jni::Array<jni::Object<Feature>> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat, jni::Array<jni::String>);
jni::Array<jni::Object<Feature>> queryRenderedFeaturesForPoint(JNIEnv&, jni::jfloat, jni::jfloat,
jni::Array<jni::String>,
jni::Array<jni::Object<>> jfilter);

jni::Array<jni::Object<Feature>> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat, jni::jfloat, jni::Array<jni::String>);
jni::Array<jni::Object<Feature>> queryRenderedFeaturesForBox(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat,
jni::jfloat, jni::Array<jni::String>,
jni::Array<jni::Object<>> jfilter);

jni::Array<jni::Object<Layer>> getLayers(JNIEnv&);

Expand Down

0 comments on commit b5d0a66

Please sign in to comment.