summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAsheem Mamoowala <asheem.mamoowala@mapbox.com>2017-05-25 14:36:05 -0700
committerAsheem Mamoowala <asheem.mamoowala@mapbox.com>2017-06-19 09:50:08 -0700
commitb7c7d3fdab283d7bf03d8acf68b9cfd478d6973f (patch)
treed0e2d24300e5b28fe3a5f91d37456ffcb988d287
parentab5b310a9eb7c88935cc457da1af81349fbe8d41 (diff)
downloadqtlocation-mapboxgl-b7c7d3fdab283d7bf03d8acf68b9cfd478d6973f.tar.gz
[android] Add ImageSource bindings
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngQuad.java87
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java137
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml11
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java132
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_0.pngbin0 -> 172489 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_1.pngbin0 -> 177163 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_2.pngbin0 -> 179236 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_3.pngbin0 -> 177074 bytes
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_image_source.xml29
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml2
-rw-r--r--platform/android/config.cmake4
-rw-r--r--platform/android/src/geometry/lat_lng_quad.cpp39
-rw-r--r--platform/android/src/geometry/lat_lng_quad.hpp30
-rwxr-xr-xplatform/android/src/jni.cpp2
-rw-r--r--platform/android/src/style/conversion/latlngquad.hpp24
-rw-r--r--platform/android/src/style/sources/image_source.cpp48
-rw-r--r--platform/android/src/style/sources/image_source.hpp7
-rw-r--r--platform/android/src/style/sources/sources.cpp5
18 files changed, 528 insertions, 29 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngQuad.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngQuad.java
new file mode 100644
index 0000000000..e374eee8f3
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngQuad.java
@@ -0,0 +1,87 @@
+package com.mapbox.mapboxsdk.geometry;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * A geographical area representing a non-aligned quadrilateral
+ * <p>
+ * This class does not wrap values to the world bounds
+ * </p>
+ */
+public class LatLngQuad implements Parcelable {
+
+ private final LatLng topLeft;
+ private final LatLng topRight;
+ private final LatLng bottomRight;
+ private final LatLng bottomLeft;
+
+ /**
+ * Construct a new LatLngQuad based on its corners,
+ * in order top left, top right, bottom left, bottom right
+ */
+ public LatLngQuad(final LatLng topLeft, final LatLng topRight, final LatLng bottomRight, final LatLng bottomLeft) {
+ this.topLeft = topLeft;
+ this.topRight = topRight;
+ this.bottomRight = bottomRight;
+ this.bottomLeft = bottomLeft;
+ }
+
+ public LatLng getTopLeft() {
+ return this.topLeft;
+ }
+
+ public LatLng getTopRight() {
+ return this.topRight;
+ }
+
+ public LatLng getBottomRight() {
+ return this.bottomRight;
+ }
+
+ public LatLng getBottomLeft() {
+ return this.bottomLeft;
+ }
+
+ public static final Parcelable.Creator<LatLngQuad> CREATOR = new Parcelable.Creator<LatLngQuad>() {
+ @Override
+ public LatLngQuad createFromParcel(final Parcel in) {
+ return readFromParcel(in);
+ }
+
+ @Override
+ public LatLngQuad[] newArray(final int size) {
+ return new LatLngQuad[size];
+ }
+ };
+
+ @Override
+ public int hashCode() {
+ int code = topLeft.hashCode();
+ code = (code ^ code >>> 31) + topRight.hashCode();
+ code = (code ^ code >>> 31) + bottomRight.hashCode();
+ code = (code ^ code >>> 31) + bottomLeft.hashCode();
+ return code;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(final Parcel out, final int arg1) {
+ topLeft.writeToParcel(out, arg1);
+ topRight.writeToParcel(out, arg1);
+ bottomRight.writeToParcel(out, arg1);
+ bottomLeft.writeToParcel(out, arg1);
+ }
+
+ private static LatLngQuad readFromParcel(final Parcel in) {
+ final LatLng topLeft = new LatLng(in);
+ final LatLng topRight = new LatLng(in);
+ final LatLng bottomRight = new LatLng(in);
+ final LatLng bottomLeft = new LatLng(in);
+ return new LatLngQuad(topLeft, topRight, bottomRight, bottomLeft);
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java
new file mode 100644
index 0000000000..84e5e96fa4
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/ImageSource.java
@@ -0,0 +1,137 @@
+package com.mapbox.mapboxsdk.style.sources;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.support.annotation.DrawableRes;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.UiThread;
+import android.support.v4.content.ContextCompat;
+
+import com.mapbox.mapboxsdk.Mapbox;
+import com.mapbox.mapboxsdk.geometry.LatLngQuad;
+
+import java.net.URL;
+
+
+/**
+ * Image source, allows a georeferenced raster image to be shown on the map.
+ * <p>
+ * The georeferenced image scales and rotates as the user zooms and rotates the map.
+ * The geographic location of the raster image content, supplied with `LatLngQuad`,
+ * can be non-axis aligned.
+ * </p>
+ * * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-image">the style specification</a>
+ */
+@UiThread
+public class ImageSource extends Source {
+
+ /**
+ * Internal use
+ *
+ * @param nativePtr - pointer to native peer
+ */
+ public ImageSource(long nativePtr) {
+ super(nativePtr);
+ }
+
+ /**
+ * Create an ImageSource from coordinates and an image URL
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param url remote json file
+ */
+ public ImageSource(String id, LatLngQuad coordinates, URL url) {
+ initialize(id, coordinates);
+ setUrl(url);
+ }
+
+ /**
+ * Create an ImageSource from coordinates and a bitmap image
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param bitmap A Bitmap image
+ */
+ public ImageSource(String id, LatLngQuad coordinates, @NonNull android.graphics.Bitmap bitmap) {
+ initialize(id, coordinates);
+ setImage(bitmap);
+ }
+
+ /**
+ * Create an ImageSource from coordinates and a bitmap image resource
+ *
+ * @param id The source id
+ * @param coordinates The Latitude and Longitude of the four corners of the image
+ * @param resourceId The resource ID of a Bitmap image
+ */
+ public ImageSource(String id, LatLngQuad coordinates, @DrawableRes int resourceId) {
+ initialize(id, coordinates);
+ setImage(resourceId);
+ }
+
+ /**
+ * Updates the source image url
+ *
+ * @param url An Image url
+ */
+ public void setUrl(URL url) {
+ setUrl(url.toExternalForm());
+ }
+
+ /**
+ * Updates the source image url
+ *
+ * @param url An image url
+ */
+ public void setUrl(String url) {
+ nativeSetUrl(url);
+ }
+
+ /**
+ * Updates the source image to a bitmap
+ *
+ * @param bitmap A Bitmap image
+ */
+ public void setImage(@NonNull android.graphics.Bitmap bitmap) {
+ nativeSetImage(bitmap);
+ }
+
+ /**
+ * Updates the source image to a bitmap image resource
+ *
+ * @param resourceId The resource ID of a Bitmap image
+ */
+ public void setImage(@DrawableRes int resourceId) throws IllegalArgumentException {
+ Context context = Mapbox.getApplicationContext();
+ Drawable drawable = ContextCompat.getDrawable(context, resourceId);
+ if (drawable instanceof BitmapDrawable) {
+ BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
+ nativeSetImage(bitmapDrawable.getBitmap());
+ } else {
+ throw new IllegalArgumentException("Failed to decode image. The resource provided must be a Bitmap.");
+ }
+ }
+
+ /**
+ * @return The url or null
+ */
+ @Nullable
+ public String getUrl() {
+ return nativeGetUrl();
+ }
+
+ protected native void initialize(String layerId, LatLngQuad payload);
+
+ protected native void nativeSetUrl(String url);
+
+ protected native String nativeGetUrl();
+
+ protected native void nativeSetImage(Bitmap bitmap);
+
+ @Override
+ protected native void finalize() throws Throwable;
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
index 1a70e4548a..d57136755f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/AndroidManifest.xml
@@ -535,6 +535,17 @@
android:name="android.support.PARENT_ACTIVITY"
android:value=".activity.FeatureOverviewActivity"/>
</activity>
+ <activity
+ android:name=".activity.style.AnimatedImageSourceActivity"
+ android:label="@string/activity_animated_image_source"
+ android:description="@string/description_animated_image_source">
+ <meta-data
+ android:name="@string/category"
+ android:value="@string/category_style"/>
+ <meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".activity.FeatureOverviewActivity"/>
+ </activity>
<!-- Features -->
<activity
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java
new file mode 100644
index 0000000000..aeb6751b99
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/AnimatedImageSourceActivity.java
@@ -0,0 +1,132 @@
+package com.mapbox.mapboxsdk.testapp.activity.style;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.support.annotation.NonNull;
+import android.support.v7.app.AppCompatActivity;
+
+import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.geometry.LatLngQuad;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
+import com.mapbox.mapboxsdk.style.layers.RasterLayer;
+import com.mapbox.mapboxsdk.style.sources.ImageSource;
+
+import com.mapbox.mapboxsdk.testapp.R;
+
+/**
+ * Test activity showing how to use a series of images to create an animation
+ * with an ImageSource
+ * <p>
+ * GL-native equivalent of https://www.mapbox.com/mapbox-gl-js/example/animate-images/
+ * </p>
+ */
+public class AnimatedImageSourceActivity extends AppCompatActivity implements OnMapReadyCallback {
+
+ private static final String ID_IMAGE_SOURCE = "animated_image_source";
+ private static final String ID_IMAGE_LAYER = "animated_image_layer";
+
+ private MapView mapView;
+ private MapboxMap mapboxMap;
+
+ private Handler handler;
+ private Runnable runnable;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_animated_image_source);
+
+ mapView = (MapView) findViewById(R.id.mapView);
+ mapView.onCreate(savedInstanceState);
+ mapView.getMapAsync(this);
+ }
+
+ @Override
+ public void onMapReady(@NonNull final MapboxMap map) {
+ mapboxMap = map;
+
+ // add source
+ LatLngQuad quad = new LatLngQuad(
+ new LatLng(46.437, -80.425),
+ new LatLng(46.437, -71.516),
+ new LatLng(37.936, -71.516),
+ new LatLng(37.936, -80.425));
+ mapboxMap.addSource(new ImageSource(ID_IMAGE_SOURCE, quad, R.drawable.southeast_radar_0));
+
+ // add layer
+ RasterLayer layer = new RasterLayer(ID_IMAGE_LAYER, ID_IMAGE_SOURCE);
+ mapboxMap.addLayer(layer);
+
+ // loop refresh geojson
+ handler = new Handler();
+ runnable = new RefreshImageRunnable(mapboxMap, handler);
+ handler.postDelayed(runnable, 100);
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mapView.onStart();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ mapView.onResume();
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ mapView.onPause();
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ mapView.onStop();
+ handler.removeCallbacks(runnable);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ mapView.onDestroy();
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mapView.onSaveInstanceState(outState);
+ }
+
+ private static class RefreshImageRunnable implements Runnable {
+
+ private MapboxMap mapboxMap;
+ private Handler handler;
+ private int[] drawables;
+ private int drawableIndex;
+
+ RefreshImageRunnable(MapboxMap mapboxMap, Handler handler) {
+ this.mapboxMap = mapboxMap;
+ this.handler = handler;
+ drawables = new int[4];
+ drawables[0] = R.drawable.southeast_radar_0;
+ drawables[1] = R.drawable.southeast_radar_1;
+ drawables[2] = R.drawable.southeast_radar_2;
+ drawables[3] = R.drawable.southeast_radar_3;
+ drawableIndex = 1;
+ }
+
+ @Override
+ public void run() {
+ ((ImageSource) mapboxMap.getSource(ID_IMAGE_SOURCE)).setImage(drawables[drawableIndex++]);
+ if (drawableIndex > 3) {
+ drawableIndex = 0;
+ }
+ handler.postDelayed(this, 1000);
+ }
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_0.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_0.png
new file mode 100644
index 0000000000..c304b619c4
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_0.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_1.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_1.png
new file mode 100644
index 0000000000..ed09fffbe1
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_1.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_2.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_2.png
new file mode 100644
index 0000000000..fee630f863
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_2.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_3.png b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_3.png
new file mode 100644
index 0000000000..c4c7146afa
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/southeast_radar_3.png
Binary files differ
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_image_source.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_image_source.xml
new file mode 100644
index 0000000000..ac1f08e821
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_animated_image_source.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+<com.mapbox.mapboxsdk.maps.MapView
+ android:id="@id/mapView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:mapbox_cameraTargetLat="46.437"
+ app:mapbox_cameraTargetLng="-80.425"
+ app:mapbox_cameraZoom="3"
+ app:mapbox_styleUrl="@string/mapbox_style_mapbox_streets"/>
+
+<android.support.design.widget.FloatingActionButton
+ android:id="@+id/fabStartStop"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ android:layout_alignParentEnd="true"
+ android:layout_alignParentRight="true"
+ android:layout_marginBottom="@dimen/fab_margin"
+ android:layout_marginRight="@dimen/fab_margin"
+ android:src="@android:drawable/ic_media_play"
+ app:backgroundTint="@color/primary"/>
+
+</RelativeLayout>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 5b6cbb8c42..0dd0b343fb 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -59,6 +59,7 @@
<string name="activity_restricted_bounds">Restrict camera to a bounds</string>
<string name="activity_fill_extrusion_layer">Fill extrusions</string>
<string name="activity_building_fill_extrusion_layer">Building layer</string>
+ <string name="activity_animated_image_source">Animated Image Source</string>
<!--Description-->
<string name="description_user_location_tracking">Tracks the location of the user</string>
@@ -117,6 +118,7 @@
<string name="description_restricted_bounds">Limit viewport to Iceland</string>
<string name="description_fill_extrusion_layer">Shows how to add 3D extruded shapes</string>
<string name="description_building_fill_extrusion_layer">Shows how to show 3D extruded buildings</string>
+ <string name="description_animated_image_source">Shows how to animate georeferenced images</string>
<!--Categories-->
<string name="category">category</string>
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 84591d644b..a7370da5fd 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -158,6 +158,8 @@ add_library(mbgl-android STATIC
platform/android/src/style/sources/unknown_source.hpp
platform/android/src/style/sources/vector_source.cpp
platform/android/src/style/sources/vector_source.hpp
+ platform/android/src/style/sources/image_source.hpp
+ platform/android/src/style/sources/image_source.cpp
platform/android/src/style/functions/stop.cpp
platform/android/src/style/functions/stop.hpp
platform/android/src/style/functions/categorical_stops.cpp
@@ -222,6 +224,8 @@ add_library(mbgl-android STATIC
platform/android/src/geometry/lat_lng.hpp
platform/android/src/geometry/lat_lng_bounds.cpp
platform/android/src/geometry/lat_lng_bounds.hpp
+ platform/android/src/geometry/lat_lng_quad.cpp
+ platform/android/src/geometry/lat_lng_quad.hpp
platform/android/src/geometry/projected_meters.cpp
platform/android/src/geometry/projected_meters.hpp
diff --git a/platform/android/src/geometry/lat_lng_quad.cpp b/platform/android/src/geometry/lat_lng_quad.cpp
new file mode 100644
index 0000000000..2b36139e18
--- /dev/null
+++ b/platform/android/src/geometry/lat_lng_quad.cpp
@@ -0,0 +1,39 @@
+#include "lat_lng_quad.hpp"
+#include "lat_lng.hpp"
+
+namespace mbgl {
+namespace android {
+
+jni::Object<LatLngQuad> LatLngQuad::New(jni::JNIEnv& env, std::array<mbgl::LatLng, 4> coordinates) {
+ static auto quadConstructor = LatLngQuad::javaClass.GetConstructor<jni::Object<LatLng>, jni::Object<LatLng>, jni::Object<LatLng>, jni::Object<LatLng>>(env);
+ return LatLngQuad::javaClass.New(env, quadConstructor,
+ LatLng::New(env, coordinates[0]),
+ LatLng::New(env, coordinates[1]),
+ LatLng::New(env, coordinates[2]),
+ LatLng::New(env, coordinates[3]));
+}
+
+std::array<mbgl::LatLng, 4> LatLngQuad::getLatLngArray(jni::JNIEnv& env, jni::Object<LatLngQuad> quad) {
+ static auto topLeftField = LatLngQuad::javaClass.GetField <jni::Object<LatLng>>(env, "topLeft");
+ static auto topRightField = LatLngQuad::javaClass.GetField <jni::Object<LatLng>>(env, "topRight");
+ static auto bottomRightField = LatLngQuad::javaClass.GetField <jni::Object<LatLng>>(env, "bottomRight");
+ static auto bottomLeftField = LatLngQuad::javaClass.GetField <jni::Object<LatLng>>(env, "bottomLeft");
+
+ return std::array < mbgl::LatLng, 4 > {{
+ LatLng::getLatLng(env, quad.Get(env, topLeftField)),
+ LatLng::getLatLng(env, quad.Get(env, topRightField)),
+ LatLng::getLatLng(env, quad.Get(env, bottomRightField)),
+ LatLng::getLatLng(env, quad.Get(env, bottomLeftField))
+ }};
+}
+
+void LatLngQuad::registerNative(jni::JNIEnv& env) {
+ // Lookup the class
+ LatLngQuad::javaClass = *jni::Class<LatLngQuad>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<LatLngQuad> LatLngQuad::javaClass;
+
+
+} // namespace android
+} // namespace mbgl \ No newline at end of file
diff --git a/platform/android/src/geometry/lat_lng_quad.hpp b/platform/android/src/geometry/lat_lng_quad.hpp
new file mode 100644
index 0000000000..8f8c9abeef
--- /dev/null
+++ b/platform/android/src/geometry/lat_lng_quad.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <mbgl/util/noncopyable.hpp>
+#include <mbgl/util/geo.hpp>
+#include <mbgl/util/geometry.hpp>
+
+#include <jni/jni.hpp>
+#include <array>
+
+namespace mbgl {
+namespace android {
+
+class LatLngQuad : private mbgl::util::noncopyable {
+public:
+
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/geometry/LatLngQuad"; };
+
+ static jni::Object<LatLngQuad> New(jni::JNIEnv&, std::array<mbgl::LatLng, 4>);
+
+ static std::array<mbgl::LatLng, 4> getLatLngArray(jni::JNIEnv&, jni::Object<LatLngQuad>);
+
+ static jni::Class<LatLngQuad> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+
+};
+
+
+} // namespace android
+} // namespace mbgl \ No newline at end of file
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 6c490fad5c..db8dd1dbdf 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -23,6 +23,7 @@
#include "geojson/position.hpp"
#include "geometry/lat_lng.hpp"
#include "geometry/lat_lng_bounds.hpp"
+#include "geometry/lat_lng_quad.hpp"
#include "geometry/projected_meters.hpp"
#include "graphics/pointf.hpp"
#include "graphics/rectf.hpp"
@@ -127,6 +128,7 @@ void registerNatives(JavaVM *vm) {
// Geometry
LatLng::registerNative(env);
LatLngBounds::registerNative(env);
+ LatLngQuad::registerNative(env);
ProjectedMeters::registerNative(env);
// GSon
diff --git a/platform/android/src/style/conversion/latlngquad.hpp b/platform/android/src/style/conversion/latlngquad.hpp
new file mode 100644
index 0000000000..9d1a83e164
--- /dev/null
+++ b/platform/android/src/style/conversion/latlngquad.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <mapbox/geojson.hpp>
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/conversion/geojson.hpp>
+#include <jni/jni.hpp>
+
+namespace mbgl {
+namespace style {
+namespace conversion {
+
+template <>
+optional<std::array<LatLng, 4>> Converter<std::array<LatLng, 4>>::operator()(const mbgl::android::Value& value, Error& error) const {
+ if (value.isNull() || !value.isArray()) {
+ error = { "value cannot be converted to LatLng array" };
+ return {};
+ }
+
+ return convert<GeoJSON>(value.toString(), error);
+}
+
+} // namespace conversion
+} // namespace style
+} // namespace mbgl
diff --git a/platform/android/src/style/sources/image_source.cpp b/platform/android/src/style/sources/image_source.cpp
index 9909675f44..cc7e1e7404 100644
--- a/platform/android/src/style/sources/image_source.cpp
+++ b/platform/android/src/style/sources/image_source.cpp
@@ -6,15 +6,19 @@
// C++ -> Java conversion
#include "../../conversion/conversion.hpp"
#include <mbgl/style/conversion.hpp>
+#include <mbgl/util/premultiply.hpp>
+#include "../../bitmap.hpp"
#include <string>
+#include <array>
namespace mbgl {
namespace android {
- ImageSource::ImageSource(jni::JNIEnv& env, jni::String sourceId)
+ ImageSource::ImageSource(jni::JNIEnv& env, jni::String sourceId, jni::Object<LatLngQuad> coordinatesObject)
: Source(env, std::make_unique<mbgl::style::ImageSource>(
- jni::Make<std::string>(env, sourceId)
+ jni::Make<std::string>(env, sourceId),
+ LatLngQuad::getLatLngArray(env, coordinatesObject)
)
) {
}
@@ -25,31 +29,20 @@ namespace android {
ImageSource::~ImageSource() = default;
- void GeoJSONSource::setGeoJSONString(jni::JNIEnv& env, jni::String json) {
- using namespace mbgl::style::conversion;
-
- // Convert the jni object
- Error error;
- optional<GeoJSON> converted = convert<GeoJSON>(Value(env, json), error);
- if(!converted) {
- mbgl::Log::Error(mbgl::Event::JNI, "Error setting geo json: " + error.message);
- return;
- }
-
- // Update the core source
- source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::setGeoJSON(*converted);
- }
-
void ImageSource::setURL(jni::JNIEnv& env, jni::String url) {
// Update the core source
- source.as<mbgl::style::GeoJSONSource>()->GeoJSONSource::setURL(jni::Make<std::string>(env, url));
+ source.as<mbgl::style::ImageSource>()->ImageSource::setURL(jni::Make<std::string>(env, url));
}
jni::String ImageSource::getURL(jni::JNIEnv& env) {
- std::string url = source.as<mbgl::style::ImageSource>()->ImageSource::getURL();
- return !url.empty() ? jni::Make<jni::String>(env, url) : jni::String();
+ optional<std::string> url = source.as<mbgl::style::ImageSource>()->ImageSource::getURL();
+ return url ? jni::Make<jni::String>(env, *url) : jni::String();
}
+ void ImageSource::setImage(jni::JNIEnv& env, jni::Object<Bitmap> bitmap) {
+ UnassociatedImage image = util::unpremultiply(Bitmap::GetImage(env, bitmap));
+ source.as<mbgl::style::ImageSource>()->setImage(std:: move(image));
+ }
jni::Class<ImageSource> ImageSource::javaClass;
@@ -66,14 +59,13 @@ namespace android {
// Register the peer
jni::RegisterNativePeer<ImageSource>(
- env, ImageSource::javaClass, "nativePtr",
- std::make_unique<ImageSource, JNIEnv&, jni::String, jni::Object<>>,
- "initialize",
- "finalize",
- METHOD(&ImageSource::setGeoJSONString, "nativeSetGeoJsonString"),
- METHOD(&ImageSource::setURL, "nativeSetUrl"),
- METHOD(&ImageSource::getURL, "nativeGetUrl"),
- METHOD(&ImageSource::getURL, "nativeGetUrl"),
+ env, ImageSource::javaClass, "nativePtr",
+ std::make_unique<ImageSource, JNIEnv&, jni::String, jni::Object<LatLngQuad>>,
+ "initialize",
+ "finalize",
+ METHOD(&ImageSource::setURL, "nativeSetUrl"),
+ METHOD(&ImageSource::getURL, "nativeGetUrl"),
+ METHOD(&ImageSource::setImage, "nativeSetImage")
);
}
diff --git a/platform/android/src/style/sources/image_source.hpp b/platform/android/src/style/sources/image_source.hpp
index d5802ed5a1..309d17a299 100644
--- a/platform/android/src/style/sources/image_source.hpp
+++ b/platform/android/src/style/sources/image_source.hpp
@@ -1,12 +1,15 @@
#pragma once
#include "source.hpp"
+#include "../../geometry/lat_lng_quad.hpp"
#include <mbgl/style/sources/image_source.hpp>
#include <jni/jni.hpp>
namespace mbgl {
namespace android {
+class Bitmap;
+
class ImageSource : public Source {
public:
@@ -16,7 +19,7 @@ public:
static void registerNative(jni::JNIEnv&);
- ImageSource(jni::JNIEnv&, jni::String, jni::Object<>);
+ ImageSource(jni::JNIEnv&, jni::String, jni::Object<LatLngQuad>);
ImageSource(mbgl::Map&, mbgl::style::ImageSource&);
@@ -25,6 +28,8 @@ public:
void setURL(jni::JNIEnv&, jni::String);
jni::String getURL(jni::JNIEnv&);
+ void setImage(jni::JNIEnv&, jni::Object<Bitmap>);
+
jni::jobject* createJavaPeer(jni::JNIEnv&);
}; // class ImageSource
diff --git a/platform/android/src/style/sources/sources.cpp b/platform/android/src/style/sources/sources.cpp
index b4e70202b4..7ca6328e71 100644
--- a/platform/android/src/style/sources/sources.cpp
+++ b/platform/android/src/style/sources/sources.cpp
@@ -2,11 +2,13 @@
#include <mbgl/style/source.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
+#include <mbgl/style/sources/image_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
#include "source.hpp"
#include "geojson_source.hpp"
+#include "image_source.hpp"
#include "raster_source.hpp"
#include "unknown_source.hpp"
#include "vector_source.hpp"
@@ -22,6 +24,8 @@ Source* initializeSourcePeer(mbgl::Map& map, mbgl::style::Source& coreSource) {
source = new RasterSource(map, *coreSource.as<mbgl::style::RasterSource>());
} else if (coreSource.is<mbgl::style::GeoJSONSource>()) {
source = new GeoJSONSource(map, *coreSource.as<mbgl::style::GeoJSONSource>());
+ } else if (coreSource.is<mbgl::style::ImageSource>()) {
+ source = new ImageSource(map, *coreSource.as<mbgl::style::ImageSource>());
} else {
source = new UnknownSource(map, coreSource);
}
@@ -39,6 +43,7 @@ jni::jobject* createJavaSourcePeer(jni::JNIEnv& env, mbgl::Map& map, mbgl::style
void registerNativeSources(jni::JNIEnv& env) {
Source::registerNative(env);
GeoJSONSource::registerNative(env);
+ ImageSource::registerNative(env);
RasterSource::registerNative(env);
UnknownSource::registerNative(env);
VectorSource::registerNative(env);