diff options
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 |
commit | 6cc0d52fdc8f317e90e30937732272a355e53119 (patch) | |
tree | 49cbf13bc23c81afde2c3402a4671e2419bdba3f | |
parent | d928908ec849097440fd028454c538f1c1632a1e (diff) | |
download | qtlocation-mapboxgl-upstream/12044-android-query-test.tar.gz |
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; |