summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorŁukasz Paczos <lukasz.paczos@mapbox.com>2018-06-04 18:15:33 +0200
committerŁukasz Paczos <lukasz.paczos@mapbox.com>2018-06-05 12:28:42 +0200
commit6cc0d52fdc8f317e90e30937732272a355e53119 (patch)
tree49cbf13bc23c81afde2c3402a4671e2419bdba3f
parentd928908ec849097440fd028454c538f1c1632a1e (diff)
downloadqtlocation-mapboxgl-upstream/12044-android-query-test.tar.gz
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle2
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java82
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java14
-rw-r--r--platform/android/src/snapshotter/map_snapshotter.cpp56
-rw-r--r--platform/android/src/snapshotter/map_snapshotter.hpp7
-rw-r--r--platform/default/mbgl/map/map_snapshotter.cpp27
-rw-r--r--platform/default/mbgl/map/map_snapshotter.hpp9
8 files changed, 182 insertions, 22 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 86919d21bc..6ffd16962d 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -91,7 +91,7 @@ android {
if (abi != 'all') {
abiFilters abi.split(' ')
} else {
- abiFilters "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
+ abiFilters "armeabi-v7a"//, "x86", "arm64-v8a", "x86_64"
}
}
}
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 d72e1a74a9..eb88a18c7c 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
@@ -828,8 +828,11 @@ final class NativeMapView {
if (checkState("queryRenderedFeatures")) {
return new ArrayList<>();
}
- Feature[] features = nativeQueryRenderedFeaturesForPoint(coordinates.x / pixelRatio,
- coordinates.y / pixelRatio, layerIds, filter != null ? filter.toArray() : null);
+ Feature[] features = nativeQueryRenderedFeaturesForPoint(
+ coordinates.x / pixelRatio,
+ coordinates.y / pixelRatio,
+ layerIds,
+ filter != null ? filter.toArray() : null);
return features != null ? Arrays.asList(features) : new ArrayList<Feature>();
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
index a2c7ed5dfd..fe7677b22b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/snapshotter/MapSnapshotter.java
@@ -6,6 +6,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
+import android.graphics.RectF;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
@@ -16,6 +17,8 @@ import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+
+import com.mapbox.geojson.Feature;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.attribution.AttributionLayout;
import com.mapbox.mapboxsdk.attribution.AttributionMeasure;
@@ -24,7 +27,13 @@ import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.storage.FileSource;
+import com.mapbox.mapboxsdk.style.expressions.Expression;
import com.mapbox.mapboxsdk.utils.ThreadUtils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import timber.log.Timber;
/**
@@ -52,6 +61,19 @@ public class MapSnapshotter {
}
/**
+ * Get notified on features query completion.
+ */
+ public interface FeaturesQueryCallback {
+
+ /**
+ * Called when feature query is complete.
+ *
+ * @param features th features
+ */
+ void onFeaturesQueryReady(List<Feature> features);
+ }
+
+ /**
* Can be used to get notified of errors
* in snapshot generation
*
@@ -74,7 +96,9 @@ public class MapSnapshotter {
private long nativePtr = 0;
private final Context context;
- private SnapshotReadyCallback callback;
+ private final float pixelRatio;
+ private SnapshotReadyCallback snapshotCallback;
+ private FeaturesQueryCallback featuresQueryCallback;
private ErrorHandler errorHandler;
/**
@@ -214,6 +238,7 @@ public class MapSnapshotter {
public MapSnapshotter(@NonNull Context context, @NonNull Options options) {
checkThread();
this.context = context.getApplicationContext();
+ pixelRatio = context.getResources().getDisplayMetrics().density;
FileSource fileSource = FileSource.getInstance(context);
String programCacheDir = context.getCacheDir().getAbsolutePath();
@@ -223,10 +248,10 @@ public class MapSnapshotter {
}
/**
- * Starts loading and rendering the snapshot. The callback will be fired
+ * Starts loading and rendering the snapshot. The snapshotCallback will be fired
* on the calling thread.
*
- * @param callback the callback to use when the snapshot is ready
+ * @param callback the snapshotCallback to use when the snapshot is ready
*/
public void start(@NonNull SnapshotReadyCallback callback) {
this.start(callback, null);
@@ -236,19 +261,34 @@ public class MapSnapshotter {
* Starts loading and rendering the snapshot. The callbacks will be fired
* on the calling thread.
*
- * @param callback the callback to use when the snapshot is ready
+ * @param callback the snapshotCallback to use when the snapshot is ready
* @param errorHandler the error handler to use on snapshot errors
*/
public void start(@NonNull SnapshotReadyCallback callback, ErrorHandler errorHandler) {
- if (this.callback != null) {
+ if (this.snapshotCallback != null) {
throw new IllegalStateException("Snapshotter was already started");
}
checkThread();
- this.callback = callback;
+ this.snapshotCallback = callback;
this.errorHandler = errorHandler;
nativeStart();
}
+ // TODO: 04/06/2018 query docs
+ public void queryFeatures(@NonNull FeaturesQueryCallback callback, @NonNull RectF coordinates,
+ @Nullable String[] layerIds,
+ @Nullable Expression filter) {
+ checkThread();
+ this.featuresQueryCallback = callback;
+ nativeQueryFeatures(
+ coordinates.left / pixelRatio,
+ coordinates.top / pixelRatio,
+ coordinates.right / pixelRatio,
+ coordinates.bottom / pixelRatio,
+ layerIds,
+ filter != null ? filter.toArray() : null);
+ }
+
/**
* Updates the snapshotter with a new size
*
@@ -450,9 +490,9 @@ public class MapSnapshotter {
new Handler().post(new Runnable() {
@Override
public void run() {
- if (callback != null) {
+ if (snapshotCallback != null) {
addOverlay(snapshot);
- callback.onSnapshotReady(snapshot);
+ snapshotCallback.onSnapshotReady(snapshot);
reset();
}
}
@@ -460,6 +500,24 @@ public class MapSnapshotter {
}
/**
+ * Called by JNI peer when queried features are ready.
+ * Always called on the origin (main) thread.
+ *
+ * @param features the queried features
+ */
+ protected void onQueryFeaturesReady(final Feature[] features) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ if (featuresQueryCallback != null) {
+ featuresQueryCallback.onFeaturesQueryReady(
+ features != null ? Arrays.asList(features) : new ArrayList<Feature>());
+ }
+ }
+ });
+ }
+
+ /**
* Called by JNI peer when snapshot has failed.
* Always called on the origin (main) thread.
*
@@ -477,7 +535,8 @@ public class MapSnapshotter {
}
protected void reset() {
- callback = null;
+ snapshotCallback = null;
+ featuresQueryCallback = null;
errorHandler = null;
}
@@ -489,6 +548,11 @@ public class MapSnapshotter {
protected native void nativeStart();
+ protected native void nativeQueryFeatures(float left, float top,
+ float right, float bottom,
+ String[] layerIds,
+ Object[] filter);
+
protected native void nativeCancel();
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java
index 11d1df008a..4125c4e3bf 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java
@@ -4,12 +4,14 @@ import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.PointF;
+import android.graphics.RectF;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
+import com.mapbox.geojson.Feature;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -17,13 +19,15 @@ import com.mapbox.mapboxsdk.snapshotter.MapSnapshot;
import com.mapbox.mapboxsdk.snapshotter.MapSnapshotter;
import com.mapbox.mapboxsdk.testapp.R;
+import java.util.List;
+
import timber.log.Timber;
/**
* Test activity showing how to use a the {@link MapSnapshotter} and overlay
* {@link android.graphics.Bitmap}s on top.
*/
-public class MapSnapshotterMarkerActivity extends AppCompatActivity implements MapSnapshotter.SnapshotReadyCallback {
+public class MapSnapshotterMarkerActivity extends AppCompatActivity implements MapSnapshotter.SnapshotReadyCallback, MapSnapshotter.FeaturesQueryCallback {
private MapSnapshotter mapSnapshotter;
@@ -49,7 +53,9 @@ public class MapSnapshotterMarkerActivity extends AppCompatActivity implements M
.withStyle(Style.OUTDOORS)
.withCameraPosition(new CameraPosition.Builder().target(new LatLng(52.090737, 5.121420)).zoom(15).build())
);
- mapSnapshotter.start(MapSnapshotterMarkerActivity.this);
+ mapSnapshotter.queryFeatures(MapSnapshotterMarkerActivity.this,
+ new RectF(0, 0, Math.min(container.getMeasuredWidth(), 1024), Math.min(container.getMeasuredHeight(), 1024)),
+ null, null);
}
});
}
@@ -83,4 +89,8 @@ public class MapSnapshotterMarkerActivity extends AppCompatActivity implements M
return snapshot.getBitmap();
}
+ @Override
+ public void onFeaturesQueryReady(List<Feature> features) {
+ Timber.d("FEATURES %s", features);
+ }
}
diff --git a/platform/android/src/snapshotter/map_snapshotter.cpp b/platform/android/src/snapshotter/map_snapshotter.cpp
index 155fdf81fb..8e0faf5cde 100644
--- a/platform/android/src/snapshotter/map_snapshotter.cpp
+++ b/platform/android/src/snapshotter/map_snapshotter.cpp
@@ -7,6 +7,15 @@
#include <mbgl/util/string.hpp>
#include <mbgl/actor/scheduler.hpp>
+#include "../style/android_conversion.hpp"
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/filter.hpp>
+
+#include "../conversion/conversion.hpp"
+#include "../conversion/collection.hpp"
+#include "../style/conversion/filter.hpp"
+#include "../geojson/conversion/feature.hpp"
+
#include "../attach_env.hpp"
#include "map_snapshot.hpp"
@@ -75,7 +84,7 @@ void MapSnapshotter::start(JNIEnv& env) {
MBGL_VERIFY_THREAD(tid);
activateFilesource(env);
- snapshotCallback = std::make_unique<Actor<mbgl::MapSnapshotter::Callback>>(
+ snapshotCallback = std::make_unique<Actor<mbgl::MapSnapshotter::SnapshotCallback>>(
*Scheduler::GetCurrent(),
[this](std::exception_ptr err, PremultipliedImage image, std::vector<std::string> attributions, mbgl::MapSnapshotter::PointForFn pointForFn) {
MBGL_VERIFY_THREAD(tid);
@@ -102,6 +111,50 @@ void MapSnapshotter::start(JNIEnv& env) {
snapshotter->snapshot(snapshotCallback->self());
}
+void MapSnapshotter::queryFeatures(JNIEnv& env, jni::jfloat left, jni::jfloat top,
+ jni::jfloat right, jni::jfloat bottom, jni::Array<jni::String> layerIds,
+ jni::Array<jni::Object<>> jfilter) {
+ MBGL_VERIFY_THREAD(tid);
+ activateFilesource(env);
+
+ using namespace mbgl::android::conversion;
+ using namespace mbgl::android::geojson;
+
+ queryFeaturesCallback = std::make_unique<Actor<mbgl::MapSnapshotter::QueryFeaturesCallback>>(
+ *Scheduler::GetCurrent(),
+ [this](std::exception_ptr err, const std::vector<mbgl::Feature> features) {
+ MBGL_VERIFY_THREAD(tid);
+ android::UniqueEnv _env = android::AttachEnv();
+
+ using namespace mbgl::android::conversion;
+ using namespace mbgl::android::geojson;
+
+ // todo add error handling
+ if (!err) {
+ // invoke callback
+ static auto onQueryFeaturesReady = javaClass.GetMethod<void (jni::Array<jni::Object<geojson::Feature>>)>(*_env, "onQueryFeaturesReady");
+ jni::Array<jni::Object<geojson::Feature>> featureArray =
+ *convert<jni::Array<jni::Object<geojson::Feature>>, std::vector<mbgl::Feature>>(*_env, features);
+
+ javaPeer->Call(*_env,
+ onQueryFeaturesReady,
+ featureArray);
+ }
+ }
+ );
+
+ mbgl::optional<std::vector<std::string>> layers;
+ if (layerIds != nullptr && layerIds.Length(env) > 0) {
+ layers = toVector(env, layerIds);
+ }
+ mapbox::geometry::box<double> box = {
+ mapbox::geometry::point<double>{ left, top},
+ mapbox::geometry::point<double>{ right, bottom }
+ };
+
+ snapshotter->queryFeatures(queryFeaturesCallback->self(), box, { layers, toFilter(env, jfilter) });
+}
+
void MapSnapshotter::cancel(JNIEnv& env) {
MBGL_VERIFY_THREAD(tid);
snapshotCallback.reset();
@@ -168,6 +221,7 @@ void MapSnapshotter::registerNative(jni::JNIEnv& env) {
METHOD(&MapSnapshotter::setCameraPosition, "setCameraPosition"),
METHOD(&MapSnapshotter::setRegion, "setRegion"),
METHOD(&MapSnapshotter::start, "nativeStart"),
+ METHOD(&MapSnapshotter::queryFeatures, "nativeQueryFeatures"),
METHOD(&MapSnapshotter::cancel, "nativeCancel")
);
}
diff --git a/platform/android/src/snapshotter/map_snapshotter.hpp b/platform/android/src/snapshotter/map_snapshotter.hpp
index 3be2cb4f6c..1cc4d23a9d 100644
--- a/platform/android/src/snapshotter/map_snapshotter.hpp
+++ b/platform/android/src/snapshotter/map_snapshotter.hpp
@@ -54,6 +54,10 @@ public:
void start(JNIEnv&);
+ void queryFeatures(JNIEnv&, jni::jfloat, jni::jfloat, jni::jfloat,
+ jni::jfloat, jni::Array<jni::String>,
+ jni::Array<jni::Object<>> jfilter);
+
void cancel(JNIEnv&);
private:
@@ -66,7 +70,8 @@ private:
bool showLogo;
std::shared_ptr<mbgl::ThreadPool> threadPool;
- std::unique_ptr<Actor<mbgl::MapSnapshotter::Callback>> snapshotCallback;
+ std::unique_ptr<Actor<mbgl::MapSnapshotter::SnapshotCallback>> snapshotCallback;
+ std::unique_ptr<Actor<mbgl::MapSnapshotter::QueryFeaturesCallback>> queryFeaturesCallback;
std::unique_ptr<mbgl::MapSnapshotter> snapshotter;
FileSource *jFileSource;
diff --git a/platform/default/mbgl/map/map_snapshotter.cpp b/platform/default/mbgl/map/map_snapshotter.cpp
index a909e3fe9b..9358d76a18 100644
--- a/platform/default/mbgl/map/map_snapshotter.cpp
+++ b/platform/default/mbgl/map/map_snapshotter.cpp
@@ -2,6 +2,7 @@
#include <mbgl/actor/actor_ref.hpp>
#include <mbgl/gl/headless_frontend.hpp>
+#include <mbgl/renderer/renderer.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/storage/file_source.hpp>
@@ -37,7 +38,9 @@ public:
void setRegion(LatLngBounds);
LatLngBounds getRegion() const;
- void snapshot(ActorRef<MapSnapshotter::Callback>);
+ void snapshot(ActorRef<MapSnapshotter::SnapshotCallback>);
+
+ void queryFeatures(ActorRef<MapSnapshotter::QueryFeaturesCallback>, const ScreenBox&, const RenderedQueryOptions&);
private:
HeadlessFrontend frontend;
@@ -71,7 +74,7 @@ MapSnapshotter::Impl::Impl(FileSource& fileSource,
}
}
-void MapSnapshotter::Impl::snapshot(ActorRef<MapSnapshotter::Callback> callback) {
+void MapSnapshotter::Impl::snapshot(ActorRef<MapSnapshotter::SnapshotCallback> callback) {
map.renderStill([this, callback = std::move(callback)] (std::exception_ptr error) mutable {
// Create lambda that captures the current transform state
@@ -96,7 +99,7 @@ void MapSnapshotter::Impl::snapshot(ActorRef<MapSnapshotter::Callback> callback)
// Invoke callback
callback.invoke(
- &MapSnapshotter::Callback::operator(),
+ &MapSnapshotter::SnapshotCallback::operator(),
error,
error ? PremultipliedImage() : frontend.readStillImage(),
std::move(attributions),
@@ -105,6 +108,17 @@ void MapSnapshotter::Impl::snapshot(ActorRef<MapSnapshotter::Callback> callback)
});
}
+void MapSnapshotter::Impl::queryFeatures(ActorRef<MapSnapshotter::QueryFeaturesCallback> callback,
+ const ScreenBox& box, const RenderedQueryOptions& options) {
+ map.renderStill([this, callback = std::move(callback), box, options] (std::exception_ptr error) mutable {
+ callback.invoke(
+ &MapSnapshotter::QueryFeaturesCallback::operator(),
+ error,
+ error ? std::vector<Feature>() : frontend.getRenderer()->queryRenderedFeatures(box, options)
+ );
+ });
+}
+
void MapSnapshotter::Impl::setStyleURL(std::string styleURL) {
map.getStyle().loadURL(styleURL);
}
@@ -162,10 +176,15 @@ MapSnapshotter::MapSnapshotter(FileSource& fileSource,
MapSnapshotter::~MapSnapshotter() = default;
-void MapSnapshotter::snapshot(ActorRef<MapSnapshotter::Callback> callback) {
+void MapSnapshotter::snapshot(ActorRef<MapSnapshotter::SnapshotCallback> callback) {
impl->actor().invoke(&Impl::snapshot, std::move(callback));
}
+void MapSnapshotter::queryFeatures(ActorRef<MapSnapshotter::QueryFeaturesCallback> callback,
+ const ScreenBox& box, const RenderedQueryOptions& options) {
+ impl->actor().invoke(&Impl::queryFeatures, std::move(callback), box, options);
+}
+
void MapSnapshotter::setStyleURL(const std::string& styleURL) {
impl->actor().invoke(&Impl::setStyleURL, styleURL);
}
diff --git a/platform/default/mbgl/map/map_snapshotter.hpp b/platform/default/mbgl/map/map_snapshotter.hpp
index b9e6307664..bc69a92a4f 100644
--- a/platform/default/mbgl/map/map_snapshotter.hpp
+++ b/platform/default/mbgl/map/map_snapshotter.hpp
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
#include <functional>
+#include <mbgl/renderer/query.hpp>
namespace mbgl {
@@ -53,8 +54,12 @@ public:
using PointForFn = std::function<ScreenCoordinate (const LatLng&)>;
using Attributions = std::vector<std::string>;
- using Callback = std::function<void (std::exception_ptr, PremultipliedImage, Attributions, PointForFn)>;
- void snapshot(ActorRef<Callback>);
+ using SnapshotCallback = std::function<void (std::exception_ptr, PremultipliedImage, Attributions, PointForFn)>;
+ void snapshot(ActorRef<SnapshotCallback>);
+
+ using Features = std::vector<Feature>;
+ using QueryFeaturesCallback = std::function<void (std::exception_ptr, Features)>;
+ void queryFeatures(ActorRef<QueryFeaturesCallback>, const ScreenBox& box, const RenderedQueryOptions& options);
private:
class Impl;