summaryrefslogtreecommitdiff
path: root/platform/android/src
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/src')
-rw-r--r--platform/android/src/bitmap.cpp10
-rw-r--r--platform/android/src/bitmap.hpp1
-rw-r--r--platform/android/src/example_custom_layer.cpp75
-rw-r--r--platform/android/src/file_source.cpp10
-rw-r--r--platform/android/src/geojson/conversion/feature.hpp2
-rw-r--r--platform/android/src/geojson/conversion/geometry.hpp182
-rw-r--r--platform/android/src/geojson/geometry.cpp47
-rw-r--r--platform/android/src/geojson/geometry.hpp8
-rw-r--r--platform/android/src/geojson/geometry_collection.cpp63
-rw-r--r--platform/android/src/geojson/geometry_collection.hpp28
-rw-r--r--platform/android/src/geojson/line_string.cpp13
-rw-r--r--platform/android/src/geojson/line_string.hpp10
-rw-r--r--platform/android/src/geojson/multi_line_string.cpp11
-rw-r--r--platform/android/src/geojson/multi_line_string.hpp9
-rw-r--r--platform/android/src/geojson/multi_point.cpp10
-rw-r--r--platform/android/src/geojson/multi_point.hpp10
-rw-r--r--platform/android/src/geojson/multi_polygon.cpp23
-rw-r--r--platform/android/src/geojson/multi_polygon.hpp9
-rw-r--r--platform/android/src/geojson/point.cpp7
-rw-r--r--platform/android/src/geojson/point.hpp9
-rw-r--r--platform/android/src/geojson/polygon.cpp10
-rw-r--r--platform/android/src/geojson/polygon.hpp8
-rw-r--r--platform/android/src/geojson/util.hpp38
-rw-r--r--platform/android/src/gson/json_array.cpp19
-rw-r--r--platform/android/src/gson/json_array.hpp2
-rw-r--r--platform/android/src/gson/json_element.cpp28
-rw-r--r--platform/android/src/gson/json_element.hpp2
-rw-r--r--platform/android/src/gson/json_object.cpp17
-rw-r--r--platform/android/src/gson/json_object.hpp2
-rw-r--r--platform/android/src/gson/json_primitive.cpp80
-rw-r--r--platform/android/src/gson/json_primitive.hpp2
-rw-r--r--platform/android/src/http_file_source.cpp2
-rw-r--r--platform/android/src/image.cpp7
-rw-r--r--platform/android/src/java/lang.cpp76
-rw-r--r--platform/android/src/java/lang.hpp50
-rw-r--r--platform/android/src/java/util.cpp2
-rw-r--r--platform/android/src/java/util.hpp15
-rwxr-xr-xplatform/android/src/jni.cpp18
-rw-r--r--platform/android/src/map/image.cpp2
-rw-r--r--platform/android/src/map_renderer.cpp16
-rw-r--r--platform/android/src/map_renderer.hpp5
-rwxr-xr-xplatform/android/src/native_map_view.cpp23
-rwxr-xr-xplatform/android/src/native_map_view.hpp7
-rw-r--r--platform/android/src/offline/offline_manager.cpp8
-rw-r--r--platform/android/src/offline/offline_region.cpp12
-rw-r--r--platform/android/src/snapshotter/map_snapshotter.cpp4
-rw-r--r--platform/android/src/style/conversion/function.hpp208
-rw-r--r--platform/android/src/style/conversion/property_value.hpp19
-rw-r--r--platform/android/src/style/functions/categorical_stops.cpp18
-rw-r--r--platform/android/src/style/functions/categorical_stops.hpp23
-rw-r--r--platform/android/src/style/functions/exponential_stops.cpp18
-rw-r--r--platform/android/src/style/functions/exponential_stops.hpp24
-rw-r--r--platform/android/src/style/functions/identity_stops.cpp18
-rw-r--r--platform/android/src/style/functions/identity_stops.hpp21
-rw-r--r--platform/android/src/style/functions/interval_stops.cpp18
-rw-r--r--platform/android/src/style/functions/interval_stops.hpp23
-rw-r--r--platform/android/src/style/functions/stop.cpp21
-rw-r--r--platform/android/src/style/functions/stop.hpp36
-rw-r--r--platform/android/src/style/layers/custom_layer.cpp10
-rw-r--r--platform/android/src/style/layers/custom_layer.hpp2
-rw-r--r--platform/android/src/style/layers/heatmap_layer.cpp11
-rw-r--r--platform/android/src/style/layers/heatmap_layer.hpp2
-rw-r--r--platform/android/src/style/layers/layer.cpp34
-rw-r--r--platform/android/src/style/layers/layer.cpp.ejs13
-rw-r--r--platform/android/src/style/layers/layer.hpp5
-rw-r--r--platform/android/src/text/local_glyph_rasterizer.cpp1
66 files changed, 800 insertions, 717 deletions
diff --git a/platform/android/src/bitmap.cpp b/platform/android/src/bitmap.cpp
index 50088116f4..46e7253050 100644
--- a/platform/android/src/bitmap.cpp
+++ b/platform/android/src/bitmap.cpp
@@ -110,8 +110,7 @@ PremultipliedImage Bitmap::GetImage(jni::JNIEnv& env, jni::Object<Bitmap> bitmap
}
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
- // TODO: convert
- throw std::runtime_error("bitmap decoding: bitmap format invalid");
+ bitmap = Bitmap::Copy(env, bitmap);
}
const PixelGuard guard(env, bitmap);
@@ -128,5 +127,12 @@ PremultipliedImage Bitmap::GetImage(jni::JNIEnv& env, jni::Object<Bitmap> bitmap
return { Size{ info.width, info.height }, std::move(pixels) };
}
+jni::Object<Bitmap> Bitmap::Copy(jni::JNIEnv& env, jni::Object<Bitmap> bitmap) {
+ using Signature = jni::Object<Bitmap>(jni::Object<Config>, jni::jboolean);
+ auto static method = _class.GetMethod<Signature>(env, "copy");
+ auto config = Bitmap::Config::Create(env, Bitmap::Config::Value::ARGB_8888);
+ return bitmap.Call(env, method, config, (jni::jboolean) false);
+}
+
} // namespace android
} // namespace mbgl
diff --git a/platform/android/src/bitmap.hpp b/platform/android/src/bitmap.hpp
index f64f42ae87..c4e41db1e0 100644
--- a/platform/android/src/bitmap.hpp
+++ b/platform/android/src/bitmap.hpp
@@ -43,6 +43,7 @@ public:
static PremultipliedImage GetImage(jni::JNIEnv&, jni::Object<Bitmap>);
static jni::Object<Bitmap> CreateBitmap(jni::JNIEnv&, const PremultipliedImage&);
+ static jni::Object<Bitmap> Copy(jni::JNIEnv&, jni::Object<Bitmap>);
private:
static jni::Class<Bitmap> _class;
diff --git a/platform/android/src/example_custom_layer.cpp b/platform/android/src/example_custom_layer.cpp
index f7b425c40a..e805532541 100644
--- a/platform/android/src/example_custom_layer.cpp
+++ b/platform/android/src/example_custom_layer.cpp
@@ -112,18 +112,9 @@ void checkCompileStatus(GLuint shader) {
static const GLchar * vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }";
static const GLchar * fragmentShaderSource = "uniform highp vec4 fill_color; void main() { gl_FragColor = fill_color; }";
-class ExampleCustomLayer {
+class ExampleCustomLayer: mbgl::style::CustomLayerHost {
public:
~ExampleCustomLayer() {
- __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "~ExampleCustomLayer");
- if (program) {
- glDeleteBuffers(1, &buffer);
- glDetachShader(program, vertexShader);
- glDetachShader(program, fragmentShader);
- glDeleteShader(vertexShader);
- glDeleteShader(fragmentShader);
- glDeleteProgram(program);
- }
}
void initialize() {
@@ -158,8 +149,15 @@ public:
GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW));
}
- void render() {
+ void render(const mbgl::style::CustomLayerRenderParameters&) {
__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "Render");
+ glUseProgram(program);
+ glBindBuffer(GL_ARRAY_BUFFER, buffer);
+ glEnableVertexAttribArray(a_pos);
+ glVertexAttribPointer(a_pos, 2, GL_FLOAT, GL_FALSE, 0, NULL);
+ glDisable(GL_STENCIL_TEST);
+ glDisable(GL_DEPTH_TEST);
+ glUniform4fv(fill_color, 1, color);
GL_CHECK_ERROR(glUseProgram(program));
GL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer));
@@ -172,6 +170,23 @@ public:
}
+ void contextLost() {
+ __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "ContextLost");
+ program = 0;
+ }
+
+ void deinitialize() {
+ __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "DeInitialize");
+ if (program) {
+ glDeleteBuffers(1, &buffer);
+ glDetachShader(program, vertexShader);
+ glDetachShader(program, fragmentShader);
+ glDeleteShader(vertexShader);
+ glDeleteShader(fragmentShader);
+ glDeleteProgram(program);
+ }
+ }
+
GLuint program = 0;
GLuint vertexShader = 0;
GLuint fragmentShader = 0;
@@ -186,7 +201,8 @@ GLfloat ExampleCustomLayer::color[] = { 0.0f, 1.0f, 0.0f, 1.0f };
jlong JNICALL nativeCreateContext(JNIEnv*, jobject) {
__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeCreateContext");
- return reinterpret_cast<jlong>(new ExampleCustomLayer());
+ auto exampleCustomLayer = std::make_unique<ExampleCustomLayer>();
+ return reinterpret_cast<jlong>(exampleCustomLayer.release());
}
void JNICALL nativeSetColor(JNIEnv*, jobject, jfloat red, jfloat green, jfloat blue, jfloat alpha) {
@@ -197,25 +213,6 @@ void JNICALL nativeSetColor(JNIEnv*, jobject, jfloat red, jfloat green, jfloat b
ExampleCustomLayer::color[3] = alpha;
}
-void nativeInitialize(void *context) {
- __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeInitialize");
- reinterpret_cast<ExampleCustomLayer*>(context)->initialize();
-}
-
-void nativeRender(void *context, const mbgl::style::CustomLayerRenderParameters& /*parameters*/) {
- __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeRender");
- reinterpret_cast<ExampleCustomLayer*>(context)->render();
-}
-
-void nativeContextLost(void */*context*/) {
- __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeContextLost");
-}
-
-void nativeDeinitialize(void *context) {
- __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeDeinitialize");
- delete reinterpret_cast<ExampleCustomLayer*>(context);
-}
-
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
__android_log_write(ANDROID_LOG_INFO, LOG_TAG, "OnLoad");
@@ -234,22 +231,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return JNI_ERR;
}
- env->SetStaticLongField(customLayerClass,
- env->GetStaticFieldID(customLayerClass, "InitializeFunction", "J"),
- reinterpret_cast<jlong>(nativeInitialize));
-
- env->SetStaticLongField(customLayerClass,
- env->GetStaticFieldID(customLayerClass, "RenderFunction", "J"),
- reinterpret_cast<jlong>(nativeRender));
-
- env->SetStaticLongField(customLayerClass,
- env->GetStaticFieldID(customLayerClass, "ContextLostFunction", "J"),
- reinterpret_cast<jlong>(nativeContextLost));
-
- env->SetStaticLongField(customLayerClass,
- env->GetStaticFieldID(customLayerClass, "DeinitializeFunction", "J"),
- reinterpret_cast<jlong>(nativeDeinitialize));
-
return JNI_VERSION_1_6;
}
diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp
index 42c03b0974..58a91f6cf0 100644
--- a/platform/android/src/file_source.cpp
+++ b/platform/android/src/file_source.cpp
@@ -70,14 +70,16 @@ void FileSource::resume(jni::JNIEnv&) {
activationCounter.value()++;
if (activationCounter == 1) {
- fileSource->resume();
+ fileSource->resume();
}
}
void FileSource::pause(jni::JNIEnv&) {
- activationCounter.value()--;
- if (activationCounter == 0) {
- fileSource->pause();
+ if (activationCounter) {
+ activationCounter.value()--;
+ if (activationCounter == 0) {
+ fileSource->pause();
+ }
}
}
diff --git a/platform/android/src/geojson/conversion/feature.hpp b/platform/android/src/geojson/conversion/feature.hpp
index 86aa5fc03c..8fc62a2789 100644
--- a/platform/android/src/geojson/conversion/feature.hpp
+++ b/platform/android/src/geojson/conversion/feature.hpp
@@ -182,7 +182,7 @@ struct Converter<jni::Object<android::geojson::Feature>, mbgl::Feature> {
auto properties = jni::Object<gson::JsonObject>(*convert<jni::jobject*>(env, value.properties));
// Convert geometry
- auto geometry = jni::Object<android::geojson::Geometry>(*convert<jni::jobject*>(env, value.geometry));
+ auto geometry = *convert<jni::Object<android::geojson::Geometry>>(env, value.geometry);
// Create feature
auto feature = android::geojson::Feature::fromGeometry(env, geometry, properties, jid);
diff --git a/platform/android/src/geojson/conversion/geometry.hpp b/platform/android/src/geojson/conversion/geometry.hpp
index 5d2aab4c2d..242a68df02 100644
--- a/platform/android/src/geojson/conversion/geometry.hpp
+++ b/platform/android/src/geojson/conversion/geometry.hpp
@@ -1,190 +1,24 @@
#pragma once
-#include "../../conversion/constant.hpp"
-#include "../../conversion/collection.hpp"
-
#include <mapbox/geometry.hpp>
+#include "../geometry.hpp"
#include <jni/jni.hpp>
-#include "../../jni/local_object.hpp"
namespace mbgl {
namespace android {
namespace conversion {
/**
- * Turn mapbox::geometry type into Java GeoJson Geometries
- */
-template <typename T>
-class GeometryEvaluator {
-public:
-
- jni::JNIEnv& env;
-
- /**
- * static Point fromLngLat(double longitude,double latitude)
- */
- jni::jobject* operator()(const mapbox::geometry::point<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Point")).release();
- static jni::jmethodID* fromLngLat = &jni::GetStaticMethodID(env, *javaClass, "fromLngLat", "(DD)Lcom/mapbox/geojson/Point;");
-
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLat, geometry.x, geometry.y));
- }
-
- /**
- * static LineString fromLngLats(List<Point> points)
- */
- jni::jobject* operator()(const mapbox::geometry::line_string<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/LineString")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "(Ljava/util/List;)Lcom/mapbox/geojson/LineString;");
-
- // Create
- jni::LocalObject<jni::jobject> listOfPoints = jni::NewLocalObject(env, toGeoJsonListOfPoints(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, listOfPoints.get()));
- }
-
- /**
- * static MultiPoint fromLngLats(List<Point> points)
- */
- jni::jobject* operator()(const mapbox::geometry::multi_point<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/MultiPoint")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "(Ljava/util/List;)Lcom/mapbox/geojson/MultiPoint;");
-
- // Create
- jni::LocalObject<jni::jobject> coordinates = jni::NewLocalObject(env, toGeoJsonListOfPoints(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, coordinates.get()));
- }
-
- /**
- * static Polygon fromLngLats(List<List<Point>> coordinates)
- */
- jni::jobject* operator()(const mapbox::geometry::polygon<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Polygon")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "(Ljava/util/List;)Lcom/mapbox/geojson/Polygon;");
-
- // Create
- jni::LocalObject<jni::jobject> shape = jni::NewLocalObject(env, toShape<>(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, shape.get()));
- }
-
- /**
- * static MultiLineString fromLngLats(List<List<Point>> points)
- */
- jni::jobject* operator()(const mapbox::geometry::multi_line_string<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/MultiLineString")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "(Ljava/util/List;)Lcom/mapbox/geojson/MultiLineString;");
-
- // Create
- jni::LocalObject<jni::jobject> shape = jni::NewLocalObject(env, toShape<>(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, shape.get()));
- }
-
- /**
- * MultiPolygon (double[][][][]) -> [[[D + Object array == [[[[D
- *
- * static MultiPolygon fromLngLats(List<List<List<Point>>> points)
- */
- jni::jobject* operator()(const mapbox::geometry::multi_polygon<T> &geometry) const {
- // ArrayList
- static jni::jclass* arrayListClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/util/ArrayList")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *arrayListClass, "<init>", "(I)V");
- static jni::jmethodID* add = &jni::GetMethodID(env, *arrayListClass, "add", "(ILjava/lang/Object;)V");
- jni::jobject* arrayList = &jni::NewObject(env, *arrayListClass, *constructor, geometry.size());
-
- for(size_t i = 0; i < geometry.size(); i = i + 1) {
- jni::LocalObject<jni::jobject> shape = jni::NewLocalObject(env, toShape<>(env, geometry.at(i)));
- jni::CallMethod<void>(env, arrayList, *add, i, shape.get());
- }
-
- // Create the MultiPolygon
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/MultiPolygon")).release();
- static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "(Ljava/util/List;)Lcom/mapbox/geojson/MultiPolygon;");
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromGeometries, arrayList));
- }
-
- /**
- * GeometryCollection
- */
- jni::jobject* operator()(const mapbox::geometry::geometry_collection<T> &collection) const {
- static jni::jclass* geometryClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Geometry")).release();
- jni::LocalObject<jni::jarray<jni::jobject>> jarray = jni::NewLocalObject(env, &jni::NewObjectArray(env, collection.size(), *geometryClass));
-
- for(size_t i = 0; i < collection.size(); i = i + 1) {
- auto& geometry = collection.at(i);
- jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, mapbox::geometry::geometry<T>::visit(geometry, *this));
- jni::SetObjectArrayElement(env, *jarray, i, converted.get());
- }
-
- // Turn into array list and create the GeometryCollection
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/GeometryCollection")).release();
- static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromGeometries", "(Ljava/util/List;)Lcom/mapbox/geojson/GeometryCollection;");
-
- jni::LocalObject<jni::jobject> list = jni::NewLocalObject(env, toArrayList<>(env, *jarray));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromGeometries, list.get()));
- }
-
-private:
-
- /**
- * vector<point<T>> -> List<Point>
- */
- static jni::jobject* toGeoJsonListOfPoints(JNIEnv& env, std::vector<mapbox::geometry::point<T>> points) {
-
- // ArrayList
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/util/ArrayList")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(I)V");
- static jni::jmethodID* add = &jni::GetMethodID(env, *javaClass, "add", "(ILjava/lang/Object;)V");
- jni::jobject* arrayList = &jni::NewObject(env, *javaClass, *constructor, points.size());
-
-
- // Point
- static jni::jclass* pointJavaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Point")).release();
- static jni::jmethodID* fromLngLat = &jni::GetStaticMethodID(env, *pointJavaClass, "fromLngLat", "(DD)Lcom/mapbox/geojson/Point;");
-
- for(size_t i = 0; i < points.size(); i = i + 1) {
- mapbox::geometry::point<T> point = points.at(i);
- jni::LocalObject<jni::jobject> pointObject =
- jni::NewLocalObject(env, jni::CallStaticMethod<jni::jobject*>(env, *pointJavaClass, *fromLngLat, point.x, point.y));
- jni::CallMethod<void>(env, arrayList, *add, i, pointObject.get());
- }
-
- return arrayList;
- }
-
- /**
- * geometry -> List<List<Point>>
- */
- template <class SHAPE>
- static jni::jobject* toShape(JNIEnv& env, SHAPE value) {
-
- // ArrayList
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "java/util/ArrayList")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(I)V");
- static jni::jmethodID* add = &jni::GetMethodID(env, *javaClass, "add", "(ILjava/lang/Object;)V");
- jni::jobject* arrayList = &jni::NewObject(env, *javaClass, *constructor, value.size());
-
-
- for(size_t i = 0; i < value.size(); i = i + 1) {
- jni::LocalObject<jni::jobject> listOfPoints = jni::NewLocalObject(env, toGeoJsonListOfPoints(env, value.at(i)));
- jni::CallMethod<void>(env, arrayList, *add, i, listOfPoints.get());
- }
-
- return arrayList;
- }
-};
-
-/**
- * mapbox::geometry::geometry<T> -> Java GeoJson Geometry<>
+ * mapbox::geometry::geometry<T> -> Java GeoJson Geometry
*/
template <class T>
-struct Converter<jni::jobject*, mapbox::geometry::geometry<T>> {
- Result<jni::jobject*> operator()(jni::JNIEnv& env, const mapbox::geometry::geometry<T>& value) const {
- GeometryEvaluator<double> evaluator { env } ;
- jni::jobject* converted = mapbox::geometry::geometry<double>::visit(value, evaluator);
- return {converted};
+struct Converter<jni::Object<android::geojson::Geometry>, mapbox::geometry::geometry<T>> {
+ Result<jni::Object<android::geojson::Geometry>> operator()(jni::JNIEnv& env, const mapbox::geometry::geometry<T>& value) const {
+ return { android::geojson::Geometry::New(env, value) };
}
};
-}
-}
-}
+} // conversion
+} // android
+} // mbgl
diff --git a/platform/android/src/geojson/geometry.cpp b/platform/android/src/geojson/geometry.cpp
index ca19d8fb03..5635b5a0f5 100644
--- a/platform/android/src/geojson/geometry.cpp
+++ b/platform/android/src/geojson/geometry.cpp
@@ -6,6 +6,7 @@
#include "multi_line_string.hpp"
#include "polygon.hpp"
#include "multi_polygon.hpp"
+#include "geometry_collection.hpp"
#include <string>
@@ -13,7 +14,49 @@ namespace mbgl {
namespace android {
namespace geojson {
-mapbox::geojson::geometry Geometry::convert(jni::JNIEnv &env, jni::Object<Geometry> jGeometry) {
+/**
+ * Turn mapbox::geometry type into Java GeoJson Geometries
+ */
+class GeometryEvaluator {
+public:
+
+ jni::JNIEnv& env;
+
+ jni::Object<Geometry> operator()(const mbgl::Point<double> &geometry) const {
+ return jni::Cast(env, Point::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::LineString<double> &geometry) const {
+ return jni::Cast(env, LineString::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::MultiLineString<double> &geometry) const {
+ return jni::Cast(env, MultiLineString::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::MultiPoint<double> &geometry) const {
+ return jni::Cast(env, MultiPoint::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::Polygon<double> &geometry) const {
+ return jni::Cast(env, Polygon::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::MultiPolygon<double> &geometry) const {
+ return jni::Cast(env, MultiPolygon::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mapbox::geometry::geometry_collection<double> &geometry) const {
+ return jni::Cast(env, GeometryCollection::New(env, geometry), Geometry::javaClass);
+ }
+};
+
+jni::Object<Geometry> Geometry::New(jni::JNIEnv& env, mbgl::Geometry<double> geometry) {
+ GeometryEvaluator evaluator { env } ;
+ return mbgl::Geometry<double>::visit(geometry, evaluator);
+}
+
+mbgl::Geometry<double> Geometry::convert(jni::JNIEnv &env, jni::Object<Geometry> jGeometry) {
auto type = Geometry::getType(env, jGeometry);
if (type == Point::Type()) {
return { Point::convert(env, jni::Object<Point>(jGeometry.Get())) };
@@ -27,6 +70,8 @@ mapbox::geojson::geometry Geometry::convert(jni::JNIEnv &env, jni::Object<Geomet
return { Polygon::convert(env, jni::Object<Polygon>(jGeometry.Get())) };
} else if (type == MultiPolygon::Type()) {
return { MultiPolygon::convert(env, jni::Object<MultiPolygon>(jGeometry.Get())) };
+ } else if (type == GeometryCollection::Type()) {
+ return { GeometryCollection::convert(env, jni::Object<GeometryCollection>(jGeometry.Get())) };
}
throw std::runtime_error(std::string {"Unsupported GeoJSON type: " } + type);
diff --git a/platform/android/src/geojson/geometry.hpp b/platform/android/src/geojson/geometry.hpp
index b7f8909f6f..a1bb886683 100644
--- a/platform/android/src/geojson/geometry.hpp
+++ b/platform/android/src/geojson/geometry.hpp
@@ -1,8 +1,10 @@
#pragma once
-#include <mbgl/util/geojson.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include "../java/util.hpp"
+
#include <jni/jni.hpp>
namespace mbgl {
@@ -13,7 +15,9 @@ class Geometry : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "com/mapbox/geojson/Geometry"; };
- static mapbox::geojson::geometry convert(jni::JNIEnv&, jni::Object<Geometry>);
+ static jni::Object<Geometry> New(jni::JNIEnv&, mbgl::Geometry<double>);
+
+ static mbgl::Geometry<double> convert(jni::JNIEnv&, jni::Object<Geometry>);
static std::string getType(jni::JNIEnv&, jni::Object<Geometry>);
diff --git a/platform/android/src/geojson/geometry_collection.cpp b/platform/android/src/geojson/geometry_collection.cpp
new file mode 100644
index 0000000000..eb3a790404
--- /dev/null
+++ b/platform/android/src/geojson/geometry_collection.cpp
@@ -0,0 +1,63 @@
+#include "geometry_collection.hpp"
+#include "../java/util.hpp"
+
+namespace mbgl {
+namespace android {
+namespace geojson {
+
+jni::Object<GeometryCollection> GeometryCollection::New(jni::JNIEnv& env, const mapbox::geometry::geometry_collection<double>& collection) {
+ // Create an array of geometries
+ auto jarray = jni::Array<jni::Object<Geometry>>::New(env, collection.size(), Geometry::javaClass);
+
+ for (size_t i = 0; i < collection.size(); i++) {
+ auto& geometry = collection.at(i);
+ auto jGeometry = Geometry::New(env, geometry);
+ jarray.Set(env, i, jGeometry);
+ jni::DeleteLocalRef(env, jGeometry);
+ }
+
+ // Turn into array list
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+
+ // create the GeometryCollection
+ static auto method = javaClass.GetStaticMethod<jni::Object<GeometryCollection> (jni::Object<java::util::List>)>(env, "fromGeometries");
+ auto jCollection = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jCollection;
+}
+
+mapbox::geometry::geometry_collection<double> GeometryCollection::convert(jni::JNIEnv &env, jni::Object<GeometryCollection> jCollection) {
+ // Get geometries
+ static auto getGeometries = javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getGeometries");
+ auto jList = jCollection.Call(env, getGeometries);
+
+ // Turn into array
+ auto jarray = java::util::List::toArray<Geometry>(env, jList);
+ jni::DeleteLocalRef(env, jList);
+
+ // Convert each geometry
+ mapbox::geometry::geometry_collection<double> collection{};
+
+ auto size = jarray.Length(env);
+ for (jni::jsize i = 0; i < size; i++) {
+ auto element = jarray.Get(env, i);
+ collection.push_back(Geometry::convert(env, element));
+ jni::DeleteLocalRef(env, element);
+ }
+
+ jni::DeleteLocalRef(env, jarray);
+ return collection;
+}
+
+void GeometryCollection::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<GeometryCollection>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<GeometryCollection> GeometryCollection::javaClass;
+
+} // namespace geojson
+} // namespace android
+} // namespace mbgl \ No newline at end of file
diff --git a/platform/android/src/geojson/geometry_collection.hpp b/platform/android/src/geojson/geometry_collection.hpp
new file mode 100644
index 0000000000..9ed9953b0d
--- /dev/null
+++ b/platform/android/src/geojson/geometry_collection.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
+
+namespace mbgl {
+namespace android {
+namespace geojson {
+
+class GeometryCollection : public Geometry {
+public:
+ static constexpr auto Name() { return "com/mapbox/geojson/GeometryCollection"; };
+
+ static constexpr auto Type() { return "GeometryCollection"; };
+
+ static jni::Object<GeometryCollection> New(jni::JNIEnv&, const mapbox::geometry::geometry_collection<double>&);
+
+ static mapbox::geometry::geometry_collection<double> convert(jni::JNIEnv&, jni::Object<GeometryCollection>);
+
+ static jni::Class<GeometryCollection> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+} // namespace geojson
+} // namespace android
+} // namespace mbgl \ No newline at end of file
diff --git a/platform/android/src/geojson/line_string.cpp b/platform/android/src/geojson/line_string.cpp
index 8eebd53550..a5f1a468ce 100644
--- a/platform/android/src/geojson/line_string.cpp
+++ b/platform/android/src/geojson/line_string.cpp
@@ -1,11 +1,22 @@
#include "line_string.hpp"
-
#include "point.hpp"
+#include "util.hpp"
+#include "../java/util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<LineString> LineString::New(jni::JNIEnv& env, const mbgl::LineString<double>& lineString) {
+ auto jList = asPointsList(env, lineString);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<LineString>(jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jLineString = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jLineString;
+}
+
mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<LineString> jLineString) {
mapbox::geojson::line_string lineString;
diff --git a/platform/android/src/geojson/line_string.hpp b/platform/android/src/geojson/line_string.hpp
index 86033c2e6a..98dc414642 100644
--- a/platform/android/src/geojson/line_string.hpp
+++ b/platform/android/src/geojson/line_string.hpp
@@ -1,23 +1,27 @@
#pragma once
#include <mbgl/util/geojson.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
+#include "geometry.hpp"
#include "../java/util.hpp"
+#include <jni/jni.hpp>
+
namespace mbgl {
namespace android {
namespace geojson {
-class LineString : private mbgl::util::noncopyable {
+class LineString : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/LineString"; };
static constexpr auto Type() { return "LineString"; };
+ static jni::Object<LineString> New(jni::JNIEnv&, const mbgl::LineString<double>&);
+
static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<LineString>);
static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<Point>*/>);
diff --git a/platform/android/src/geojson/multi_line_string.cpp b/platform/android/src/geojson/multi_line_string.cpp
index c748d4786f..4a6ea37dd1 100644
--- a/platform/android/src/geojson/multi_line_string.cpp
+++ b/platform/android/src/geojson/multi_line_string.cpp
@@ -1,11 +1,22 @@
#include "multi_line_string.hpp"
#include "line_string.hpp"
+#include "util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<MultiLineString> MultiLineString::New(jni::JNIEnv& env, const mbgl::MultiLineString<double>& multiLineString) {
+ auto jList = asPointsListsList(env, multiLineString);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<MultiLineString> (jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jMultiLineString = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jMultiLineString;
+}
+
mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jni::Object<MultiLineString> jMultiLineString) {
mapbox::geojson::multi_line_string multiLineString;
diff --git a/platform/android/src/geojson/multi_line_string.hpp b/platform/android/src/geojson/multi_line_string.hpp
index 358a6b5dda..934a0cb6b5 100644
--- a/platform/android/src/geojson/multi_line_string.hpp
+++ b/platform/android/src/geojson/multi_line_string.hpp
@@ -3,20 +3,23 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
#include "../java/util.hpp"
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace geojson {
-class MultiLineString : private mbgl::util::noncopyable {
+class MultiLineString : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/MultiLineString"; };
static constexpr auto Type() { return "MultiLineString"; };
+ static jni::Object<MultiLineString> New(jni::JNIEnv&, const mbgl::MultiLineString<double>&);
+
static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<MultiLineString>);
static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Point>>*/>);
diff --git a/platform/android/src/geojson/multi_point.cpp b/platform/android/src/geojson/multi_point.cpp
index 4f9ff596b2..6f62541209 100644
--- a/platform/android/src/geojson/multi_point.cpp
+++ b/platform/android/src/geojson/multi_point.cpp
@@ -8,6 +8,16 @@ namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<MultiPoint> MultiPoint::New(JNIEnv& env, const mbgl::MultiPoint<double>& multiPoint) {
+ auto jList = asPointsList(env, multiPoint);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<MultiPoint>(jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jMultiPoint = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jMultiPoint;
+}
+
mapbox::geojson::multi_point MultiPoint::convert(jni::JNIEnv &env, jni::Object<MultiPoint> jMultiPoint) {
mapbox::geojson::multi_point multiPoint;
diff --git a/platform/android/src/geojson/multi_point.hpp b/platform/android/src/geojson/multi_point.hpp
index e893e879af..cfe80cd34c 100644
--- a/platform/android/src/geojson/multi_point.hpp
+++ b/platform/android/src/geojson/multi_point.hpp
@@ -1,22 +1,26 @@
#pragma once
#include <mbgl/util/geojson.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
+#include "geometry.hpp"
#include "../java/util.hpp"
+#include <jni/jni.hpp>
+
namespace mbgl {
namespace android {
namespace geojson {
-class MultiPoint : private mbgl::util::noncopyable {
+class MultiPoint : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/MultiPoint"; };
static constexpr auto Type() { return "MultiPoint"; };
+ static jni::Object<MultiPoint> New(jni::JNIEnv&, const mbgl::MultiPoint<double>&);
+
static mapbox::geojson::multi_point convert(jni::JNIEnv&, jni::Object<MultiPoint>);
static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiPoint>);
diff --git a/platform/android/src/geojson/multi_polygon.cpp b/platform/android/src/geojson/multi_polygon.cpp
index aadba8c8a6..cc872d4955 100644
--- a/platform/android/src/geojson/multi_polygon.cpp
+++ b/platform/android/src/geojson/multi_polygon.cpp
@@ -1,11 +1,34 @@
#include "multi_polygon.hpp"
#include "polygon.hpp"
+#include "util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<MultiPolygon> MultiPolygon::New(JNIEnv& env, const mbgl::MultiPolygon<double>& multiPolygon) {
+ auto jarray = jni::Array<jni::Object<java::util::List>>::New(env, multiPolygon.size(), java::util::List::javaClass);
+
+ for (size_t i = 0; i < multiPolygon.size(); i++) {
+ auto& geometry = multiPolygon.at(i);
+ auto jPolygon = asPointsListsList(env, geometry);
+ jarray.Set(env, i, jPolygon);
+ jni::DeleteLocalRef(env, jPolygon);
+ }
+
+ // Turn into array list
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+
+ // create the MultiPolygon
+ static auto method = javaClass.GetStaticMethod<jni::Object<MultiPolygon> (jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jMultiPolygon = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jMultiPolygon;
+}
+
mapbox::geojson::multi_polygon MultiPolygon::convert(jni::JNIEnv &env, jni::Object<MultiPolygon> jMultiPolygon) {
mapbox::geojson::multi_polygon multiPolygon;
diff --git a/platform/android/src/geojson/multi_polygon.hpp b/platform/android/src/geojson/multi_polygon.hpp
index 6e1dfacfc8..b4657af09d 100644
--- a/platform/android/src/geojson/multi_polygon.hpp
+++ b/platform/android/src/geojson/multi_polygon.hpp
@@ -3,20 +3,23 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
#include "../java/util.hpp"
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace geojson {
-class MultiPolygon : private mbgl::util::noncopyable {
+class MultiPolygon : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/MultiPolygon"; };
static constexpr auto Type() { return "MultiPolygon"; };
+ static jni::Object<MultiPolygon> New(jni::JNIEnv&, const mbgl::MultiPolygon<double>&);
+
static mapbox::geojson::multi_polygon convert(jni::JNIEnv&, jni::Object<MultiPolygon>);
static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiPolygon>);
diff --git a/platform/android/src/geojson/point.cpp b/platform/android/src/geojson/point.cpp
index e95376cd2e..8a9656ea14 100644
--- a/platform/android/src/geojson/point.cpp
+++ b/platform/android/src/geojson/point.cpp
@@ -7,6 +7,11 @@ namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<Point> Point::New(jni::JNIEnv& env, const mbgl::Point<double>& point) {
+ static auto method = javaClass.GetStaticMethod<jni::Object<Point> (jni::jdouble, jni::jdouble)>(env, "fromLngLat");
+ return javaClass.Call(env, method, point.x, point.y);
+}
+
mapbox::geojson::point Point::convert(jni::JNIEnv &env, jni::Object<Point> jPoint) {
mapbox::geojson::point point;
@@ -54,4 +59,4 @@ jni::Class<Point> Point::javaClass;
} // namespace geojson
} // namespace android
-} // namespace mbgl \ No newline at end of file
+} // namespace mbgl
diff --git a/platform/android/src/geojson/point.hpp b/platform/android/src/geojson/point.hpp
index c6412299bf..627bd1b649 100644
--- a/platform/android/src/geojson/point.hpp
+++ b/platform/android/src/geojson/point.hpp
@@ -3,20 +3,23 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
#include "../java/util.hpp"
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace geojson {
-class Point : private mbgl::util::noncopyable {
+class Point : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/Point"; };
static constexpr auto Type() { return "Point"; };
+ static jni::Object<Point> New(jni::JNIEnv&, const mbgl::Point<double>&);
+
static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<Point>);
static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<java::util::List/*<Double>*/>);
diff --git a/platform/android/src/geojson/polygon.cpp b/platform/android/src/geojson/polygon.cpp
index 30ba996640..96058b63b3 100644
--- a/platform/android/src/geojson/polygon.cpp
+++ b/platform/android/src/geojson/polygon.cpp
@@ -8,6 +8,16 @@ namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<Polygon> Polygon::New(jni::JNIEnv& env, const mbgl::Polygon<double>& polygon) {
+ auto jList = asPointsListsList(env, polygon);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<Polygon> (jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jPolygon = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jPolygon;
+}
+
mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<Polygon> jPolygon) {
mapbox::geojson::polygon polygon;
diff --git a/platform/android/src/geojson/polygon.hpp b/platform/android/src/geojson/polygon.hpp
index a8b2b93827..f3c23b4d7b 100644
--- a/platform/android/src/geojson/polygon.hpp
+++ b/platform/android/src/geojson/polygon.hpp
@@ -3,20 +3,24 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include "geometry.hpp"
+#include "../java/util.hpp"
+
#include <jni/jni.hpp>
-#include "../java/util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
-class Polygon : private mbgl::util::noncopyable {
+class Polygon : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/Polygon"; };
static constexpr auto Type() { return "Polygon"; };
+ static jni::Object<Polygon> New(jni::JNIEnv&, const mbgl::Polygon<double>&);
+
static mapbox::geojson::polygon convert(jni::JNIEnv &, jni::Object<Polygon>);
static mapbox::geojson::polygon convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Point>>*/>);
diff --git a/platform/android/src/geojson/util.hpp b/platform/android/src/geojson/util.hpp
index ece8e52433..5e6d90a953 100644
--- a/platform/android/src/geojson/util.hpp
+++ b/platform/android/src/geojson/util.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "point.hpp"
+
#include <type_traits>
namespace mbgl {
@@ -17,6 +19,42 @@ To convertExplicit(From&& src) {
return *reinterpret_cast<std::add_pointer_t<To>>(&src);
}
+/**
+ * Geometry -> List<Point>
+ */
+template <class T>
+static jni::Object<java::util::List> asPointsList(jni::JNIEnv& env, const T& pointsList) {
+ auto jarray = jni::Array<jni::Object<Point>>::New(env, pointsList.size(), Point::javaClass);
+
+ for (jni::jsize i = 0; i < pointsList.size(); i++) {
+ auto jPoint = Point::New(env, pointsList.at(i));
+ jarray.Set(env, i, jPoint);
+ jni::DeleteLocalRef(env, jPoint);
+ }
+
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+ return jList;
+}
+
+/**
+ * Geometry -> List<List<Point>>
+ */
+template <class SHAPE>
+static jni::Object<java::util::List> asPointsListsList(JNIEnv& env, SHAPE value) {
+ auto jarray = jni::Array<jni::Object<java::util::List>>::New(env, value.size(), java::util::List::javaClass);
+
+ for (size_t i = 0; i < value.size(); i = i + 1) {
+ auto pointsList = asPointsList(env, value[i]);
+ jarray.Set(env, i, pointsList);
+ jni::DeleteLocalRef(env, pointsList);
+ }
+
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+ return jList;
+}
+
} // namespace geojson
} // namespace android
} // namespace mbgl
diff --git a/platform/android/src/gson/json_array.cpp b/platform/android/src/gson/json_array.cpp
index d91e323ac9..e8852d77e9 100644
--- a/platform/android/src/gson/json_array.cpp
+++ b/platform/android/src/gson/json_array.cpp
@@ -6,7 +6,22 @@ namespace mbgl {
namespace android {
namespace gson {
-std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv &env, jni::Object<JsonArray> jsonArray) {
+jni::Object<JsonArray> JsonArray::New(jni::JNIEnv& env, const std::vector<mapbox::geometry::value>& values){
+ static auto constructor = JsonArray::javaClass.GetConstructor(env);
+ static auto addMethod = JsonArray::javaClass.GetMethod<void (jni::Object<JsonElement>)>(env, "add");
+
+ auto jsonArray = JsonArray::javaClass.New(env, constructor);
+
+ for (const auto &v : values) {
+ auto jsonElement = JsonElement::New(env, v);
+ jsonArray.Call(env, addMethod, jsonElement);
+ jni::DeleteLocalRef(env, jsonElement);
+ }
+
+ return jsonArray;
+}
+
+std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv& env, const jni::Object<JsonArray> jsonArray) {
std::vector<mapbox::geometry::value> values;
if (jsonArray) {
@@ -28,7 +43,7 @@ std::vector<mapbox::geometry::value> JsonArray::convert(jni::JNIEnv &env, jni::O
return values;
}
-void JsonArray::registerNative(jni::JNIEnv &env) {
+void JsonArray::registerNative(jni::JNIEnv& env) {
// Lookup the class
javaClass = *jni::Class<JsonArray>::Find(env).NewGlobalRef(env).release();
}
diff --git a/platform/android/src/gson/json_array.hpp b/platform/android/src/gson/json_array.hpp
index 8571ad5dba..c9ae98692f 100644
--- a/platform/android/src/gson/json_array.hpp
+++ b/platform/android/src/gson/json_array.hpp
@@ -13,6 +13,8 @@ class JsonArray : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "com/google/gson/JsonArray"; };
+ static jni::Object<JsonArray> New(jni::JNIEnv&, const std::vector<mapbox::geometry::value>&);
+
static std::vector<mapbox::geometry::value> convert(JNIEnv&, jni::Object<JsonArray>);
static jni::Class<JsonArray> javaClass;
diff --git a/platform/android/src/gson/json_element.cpp b/platform/android/src/gson/json_element.cpp
index 060b1e0fe2..5eaaf531f4 100644
--- a/platform/android/src/gson/json_element.cpp
+++ b/platform/android/src/gson/json_element.cpp
@@ -11,6 +11,34 @@ namespace mbgl {
namespace android {
namespace gson {
+/**
+ * Turn mapbox::geometry::value into Java Gson JsonElement
+ */
+class JsonElementEvaluator {
+public:
+
+ jni::JNIEnv& env;
+
+ jni::Object<JsonElement> operator()(const JsonPrimitive::value value) const {
+ return jni::Cast(env, JsonPrimitive::New(env, value), JsonElement::javaClass);
+ }
+
+ jni::Object<JsonElement> operator()(const std::vector<mapbox::geometry::value> &values) const {
+ return jni::Cast(env, JsonArray::New(env, values), JsonElement::javaClass);
+ }
+
+ jni::Object<JsonElement> operator()(const std::unordered_map<std::string, mapbox::geometry::value> &values) const {
+ return jni::Cast(env, JsonObject::New(env, values), JsonElement::javaClass);
+ }
+
+};
+
+
+jni::Object<JsonElement> JsonElement::New(jni::JNIEnv& env, const mapbox::geometry::value& value) {
+ JsonElementEvaluator evaluator { env } ;
+ return mapbox::geometry::value::visit(value, evaluator);
+}
+
mapbox::geometry::value JsonElement::convert(jni::JNIEnv &env, jni::Object<JsonElement> jsonElement) {
mapbox::geometry::value value;
diff --git a/platform/android/src/gson/json_element.hpp b/platform/android/src/gson/json_element.hpp
index 7619350617..d850caa526 100644
--- a/platform/android/src/gson/json_element.hpp
+++ b/platform/android/src/gson/json_element.hpp
@@ -13,6 +13,8 @@ class JsonElement : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "com/google/gson/JsonElement"; };
+ static jni::Object<JsonElement> New(jni::JNIEnv&, const mapbox::geometry::value&);
+
static mapbox::geometry::value convert(JNIEnv&, jni::Object<JsonElement>);
static bool isJsonObject(JNIEnv&, jni::Object<JsonElement>);
diff --git a/platform/android/src/gson/json_object.cpp b/platform/android/src/gson/json_object.cpp
index a704dae9dd..61b55f8b9e 100644
--- a/platform/android/src/gson/json_object.cpp
+++ b/platform/android/src/gson/json_object.cpp
@@ -9,6 +9,23 @@ namespace android {
namespace gson {
+jni::Object<JsonObject> JsonObject::New(jni::JNIEnv& env, const std::unordered_map<std::string, mapbox::geometry::value>& values) {
+ static auto constructor = JsonObject::javaClass.GetConstructor(env);
+ static auto addMethod = JsonObject::javaClass.GetMethod<void (jni::String, jni::Object<JsonElement>)>(env, "add");
+
+ jni::Object<JsonObject> jsonObject = JsonObject::javaClass.New(env, constructor);
+
+ for (auto &item : values) {
+ jni::Object<JsonElement> jsonElement = JsonElement::New(env, item.second);
+ jni::String key = jni::Make<jni::String>(env, item.first);
+ jsonObject.Call(env, addMethod, key, jsonElement);
+ jni::DeleteLocalRef(env, jsonElement);
+ jni::DeleteLocalRef(env, key);
+ }
+
+ return jsonObject;
+}
+
template <typename F> // void (jni::String, jni::Object<gson::JsonElement>)
static void iterateEntrySet(jni::JNIEnv& env, jni::Object<JsonObject> jsonObject, F callback) {
// Get Set<Map.Entry<String, JsonElement>>
diff --git a/platform/android/src/gson/json_object.hpp b/platform/android/src/gson/json_object.hpp
index aba8e40415..4bc61e51a2 100644
--- a/platform/android/src/gson/json_object.hpp
+++ b/platform/android/src/gson/json_object.hpp
@@ -13,6 +13,8 @@ class JsonObject : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "com/google/gson/JsonObject"; };
+ static jni::Object<JsonObject> New(jni::JNIEnv&, const std::unordered_map<std::string, mapbox::geometry::value>&);
+
static mapbox::geometry::property_map convert(JNIEnv&, jni::Object<JsonObject>);
static jni::Class<JsonObject> javaClass;
diff --git a/platform/android/src/gson/json_primitive.cpp b/platform/android/src/gson/json_primitive.cpp
index 58d0b45fe7..4e171c4845 100644
--- a/platform/android/src/gson/json_primitive.cpp
+++ b/platform/android/src/gson/json_primitive.cpp
@@ -1,9 +1,89 @@
#include "json_primitive.hpp"
+#include "../java/lang.hpp"
namespace mbgl {
namespace android {
namespace gson {
+/**
+ * Turn mapbox::geometry::value into Java Gson JsonPrimitives
+ */
+class JsonPrimitiveEvaluator {
+public:
+
+ jni::JNIEnv& env;
+
+ /**
+ * Create a null primitive
+ */
+ jni::Object<JsonPrimitive> operator()(const mapbox::geometry::null_value_t) const {
+ return jni::Object<JsonPrimitive>();
+ }
+
+ /**
+ * Create a primitive containing a string value
+ */
+ jni::Object<JsonPrimitive> operator()(const std::string value) const {
+ static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::String>(env);
+ auto jvalue = jni::Make<jni::String>(env, value);
+ auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, jvalue);
+ jni::DeleteLocalRef(env, jvalue);
+ return jsonPrimitive;
+ }
+
+ /**
+ * Create a primitive containing a number value with type double
+ */
+ jni::Object<JsonPrimitive> operator()(const double value) const {
+ static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Number>>(env);
+ auto boxedValue = java::lang::Double::valueOf(env, value);
+ auto number = jni::Cast(env, boxedValue, java::lang::Number::javaClass);
+ auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, number);
+ jni::DeleteLocalRef(env, boxedValue);
+ return jsonPrimitive;
+ }
+
+ /**
+ * Create a primitive containing a number value with type long
+ */
+ jni::Object<JsonPrimitive> operator()(const int64_t value) const {
+ static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Number>>(env);
+ auto boxedValue = java::lang::Long::valueOf(env, value);
+ auto number = jni::Cast(env, boxedValue, java::lang::Number::javaClass);
+ auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, number);
+ jni::DeleteLocalRef(env, boxedValue);
+ return jsonPrimitive;
+ }
+
+ /**
+ * Create a primitive containing a number value with type long
+ */
+ jni::Object<JsonPrimitive> operator()(const uint64_t value) const {
+ static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Number>>(env);
+ auto boxedValue = java::lang::Long::valueOf(env, value);
+ auto number = jni::Cast(env, boxedValue, java::lang::Number::javaClass);
+ auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, number);
+ jni::DeleteLocalRef(env, boxedValue);
+ return jsonPrimitive;
+ }
+
+ /**
+ * Create a primitive containing a boolean value
+ */
+ jni::Object<JsonPrimitive> operator()(const bool value) const {
+ static auto constructor = JsonPrimitive::javaClass.GetConstructor<jni::Object<java::lang::Boolean>>(env);
+ auto boxedValue = java::lang::Boolean::valueOf(env, value);
+ auto jsonPrimitive = JsonPrimitive::javaClass.New(env, constructor, boxedValue);
+ jni::DeleteLocalRef(env, boxedValue);
+ return jsonPrimitive;
+ }
+};
+
+jni::Object<JsonPrimitive> JsonPrimitive::New(jni::JNIEnv &env, const value& value) {
+ JsonPrimitiveEvaluator evaluator { env };
+ return value::visit(value, evaluator);
+}
+
JsonPrimitive::value JsonPrimitive::convert(jni::JNIEnv &env, jni::Object<JsonPrimitive> jsonPrimitive) {
value value;
if (jsonPrimitive) {
diff --git a/platform/android/src/gson/json_primitive.hpp b/platform/android/src/gson/json_primitive.hpp
index 5fc8a2b485..c418e0ebe8 100644
--- a/platform/android/src/gson/json_primitive.hpp
+++ b/platform/android/src/gson/json_primitive.hpp
@@ -15,6 +15,8 @@ public:
static constexpr auto Name() { return "com/google/gson/JsonPrimitive"; };
+ static jni::Object<JsonPrimitive> New(jni::JNIEnv&, const value&);
+
static value convert(JNIEnv&, jni::Object<JsonPrimitive>);
static bool isBoolean(JNIEnv&, jni::Object<JsonPrimitive>);
diff --git a/platform/android/src/http_file_source.cpp b/platform/android/src/http_file_source.cpp
index 8eb9416e9d..cda84209ea 100644
--- a/platform/android/src/http_file_source.cpp
+++ b/platform/android/src/http_file_source.cpp
@@ -61,7 +61,7 @@ void RegisterNativeHTTPRequest(jni::JNIEnv& env) {
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
- jni::RegisterNativePeer<HTTPRequest>(env, HTTPRequest::javaClass, "mNativePtr",
+ jni::RegisterNativePeer<HTTPRequest>(env, HTTPRequest::javaClass, "nativePtr",
METHOD(&HTTPRequest::onFailure, "nativeOnFailure"),
METHOD(&HTTPRequest::onResponse, "nativeOnResponse"));
}
diff --git a/platform/android/src/image.cpp b/platform/android/src/image.cpp
index 2a33944b18..0456381578 100644
--- a/platform/android/src/image.cpp
+++ b/platform/android/src/image.cpp
@@ -16,7 +16,12 @@ PremultipliedImage decodeImage(const std::string& string) {
reinterpret_cast<const signed char*>(string.data()));
auto bitmap = android::BitmapFactory::DecodeByteArray(*env, array, 0, string.size());
- return android::Bitmap::GetImage(*env, bitmap);
+ jni::DeleteLocalRef(*env, array);
+
+ auto image = android::Bitmap::GetImage(*env, bitmap);
+ jni::DeleteLocalRef(*env, bitmap);
+
+ return image;
}
} // namespace mbgl
diff --git a/platform/android/src/java/lang.cpp b/platform/android/src/java/lang.cpp
new file mode 100644
index 0000000000..3c95737169
--- /dev/null
+++ b/platform/android/src/java/lang.cpp
@@ -0,0 +1,76 @@
+#include "lang.hpp"
+
+namespace mbgl {
+namespace android {
+namespace java {
+namespace lang {
+
+// Float
+
+jni::Object<Float> Float::valueOf(JNIEnv &env, jfloat value) {
+ static auto method = javaClass.GetStaticMethod<jni::Object<Float> (jni::jfloat)>(env, "valueOf");
+ return javaClass.Call(env, method, value);
+}
+
+void Float::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<Float>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<Float> Float::javaClass;
+
+// Long
+
+jni::Object<Long> Long::valueOf(JNIEnv &env, jlong value) {
+ static auto method = javaClass.GetStaticMethod<jni::Object<Long> (jni::jlong)>(env, "valueOf");
+ return javaClass.Call(env, method, value);
+}
+
+void Long::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<Long>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<Long> Long::javaClass;
+
+// Double
+
+jni::Object<Double> Double::valueOf(JNIEnv &env, jdouble value) {
+ static auto method = javaClass.GetStaticMethod<jni::Object<Double> (jni::jdouble)>(env, "valueOf");
+ return javaClass.Call(env, method, value);
+}
+
+void Double::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<Double>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<Double> Double::javaClass;
+
+// Boolean
+
+jni::Object<Boolean> Boolean::valueOf(JNIEnv &env, jboolean value) {
+ static auto method = javaClass.GetStaticMethod<jni::Object<Boolean> (jni::jboolean)>(env, "valueOf");
+ return javaClass.Call(env, method, value);
+}
+
+void Boolean::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<Boolean>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<Boolean> Boolean::javaClass;
+
+// Number
+
+void Number::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<Number>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<Number> Number::javaClass;
+
+} // namespace lang
+} // namespace java
+} // namespace android
+} // namespace mbgl
diff --git a/platform/android/src/java/lang.hpp b/platform/android/src/java/lang.hpp
index dcf81a9d0c..981e3b14b7 100644
--- a/platform/android/src/java/lang.hpp
+++ b/platform/android/src/java/lang.hpp
@@ -1,18 +1,64 @@
#pragma once
+#include <jni/jni.hpp>
+#include <mbgl/util/noncopyable.hpp>
+
namespace mbgl {
namespace android {
namespace java {
namespace lang {
-class Float {
+class Float : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "java/lang/Float"; };
+
+ static jni::Object<Float> valueOf(JNIEnv&, jfloat);
+
+ static jni::Class<Float> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+class Double : private mbgl::util::noncopyable {
+public:
+ static constexpr auto Name() { return "java/lang/Double"; };
+
+ static jni::Object<Double> valueOf(JNIEnv&, jdouble);
+
+ static jni::Class<Double> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+class Long : private mbgl::util::noncopyable {
+public:
+ static constexpr auto Name() { return "java/lang/Long"; };
+
+ static jni::Object<Long> valueOf(JNIEnv&, jlong);
+
+ static jni::Class<Long> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+class Boolean : private mbgl::util::noncopyable {
+public:
+ static constexpr auto Name() { return "java/lang/Boolean"; };
+
+ static jni::Object<Boolean> valueOf(JNIEnv&, jboolean);
+
+ static jni::Class<Boolean> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
};
-class Number {
+class Number : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "java/lang/Number"; };
+
+ static jni::Class<Number> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
};
} // namespace lang
diff --git a/platform/android/src/java/util.cpp b/platform/android/src/java/util.cpp
index effd2ae0d0..89c4c77794 100644
--- a/platform/android/src/java/util.cpp
+++ b/platform/android/src/java/util.cpp
@@ -5,12 +5,14 @@ namespace android {
namespace java {
namespace util {
+jni::Class<Arrays> Arrays::javaClass;
jni::Class<List> List::javaClass;
jni::Class<Set> Set::javaClass;
jni::Class<Map> Map::javaClass;
jni::Class<Map::Entry> Map::Entry::javaClass;
void registerNative(jni::JNIEnv& env) {
+ Arrays::javaClass = *jni::Class<Arrays>::Find(env).NewGlobalRef(env).release();
List::javaClass = *jni::Class<List>::Find(env).NewGlobalRef(env).release();
Set::javaClass = *jni::Class<Set>::Find(env).NewGlobalRef(env).release();
Map::javaClass = *jni::Class<Map>::Find(env).NewGlobalRef(env).release();
diff --git a/platform/android/src/java/util.hpp b/platform/android/src/java/util.hpp
index dedb8ac348..c6b07acac5 100644
--- a/platform/android/src/java/util.hpp
+++ b/platform/android/src/java/util.hpp
@@ -24,6 +24,21 @@ public:
};
+class Arrays : private mbgl::util::noncopyable {
+public:
+
+ static constexpr auto Name() { return "java/util/Arrays"; };
+
+ template <class T>
+ static jni::Object<List> asList(jni::JNIEnv& env, jni::Array<jni::Object<T>> array) {
+ static auto asList = Arrays::javaClass.GetStaticMethod<jni::Object<List>(jni::Array<jni::Object<>>)>(env, "asList");
+ return javaClass.Call(env, asList, (jni::Array<jni::Object<>>) array);
+ }
+
+ static jni::Class<Arrays> javaClass;
+
+};
+
class Set : private mbgl::util::noncopyable {
public:
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index c2fd1c95ad..2f6ed96ab0 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -14,6 +14,7 @@
#include "geojson/feature.hpp"
#include "geojson/feature_collection.hpp"
#include "geojson/geometry.hpp"
+#include "geojson/geometry_collection.hpp"
#include "geojson/line_string.hpp"
#include "geojson/multi_line_string.hpp"
#include "geojson/multi_point.hpp"
@@ -40,17 +41,13 @@
#include "offline/offline_region_error.hpp"
#include "offline/offline_region_status.hpp"
#include "style/transition_options.hpp"
-#include "style/functions/categorical_stops.hpp"
-#include "style/functions/exponential_stops.hpp"
-#include "style/functions/identity_stops.hpp"
-#include "style/functions/interval_stops.hpp"
-#include "style/functions/stop.hpp"
#include "style/layers/layers.hpp"
#include "style/sources/source.hpp"
#include "style/light.hpp"
#include "snapshotter/map_snapshotter.hpp"
#include "snapshotter/map_snapshot.hpp"
#include "text/local_glyph_rasterizer_jni.hpp"
+#include "java/lang.hpp"
namespace mbgl {
namespace android {
@@ -116,11 +113,17 @@ void registerNatives(JavaVM *vm) {
java::util::registerNative(env);
PointF::registerNative(env);
RectF::registerNative(env);
+ java::lang::Number::registerNative(env);
+ java::lang::Float::registerNative(env);
+ java::lang::Boolean::registerNative(env);
+ java::lang::Double::registerNative(env);
+ java::lang::Long::registerNative(env);
// GeoJSON
geojson::Feature::registerNative(env);
geojson::FeatureCollection::registerNative(env);
geojson::Geometry::registerNative(env);
+ geojson::GeometryCollection::registerNative(env);
geojson::LineString::registerNative(env);
geojson::MultiLineString::registerNative(env);
geojson::MultiPoint::registerNative(env);
@@ -163,11 +166,6 @@ void registerNatives(JavaVM *vm) {
Source::registerNative(env);
Light::registerNative(env);
Position::registerNative(env);
- Stop::registerNative(env);
- CategoricalStops::registerNative(env);
- ExponentialStops::registerNative(env);
- IdentityStops::registerNative(env);
- IntervalStops::registerNative(env);
// Map
CameraPosition::registerNative(env);
diff --git a/platform/android/src/map/image.cpp b/platform/android/src/map/image.cpp
index 52e0e0d255..c3b22b0054 100644
--- a/platform/android/src/map/image.cpp
+++ b/platform/android/src/map/image.cpp
@@ -29,7 +29,7 @@ mbgl::style::Image Image::getImage(jni::JNIEnv& env, jni::Object<Image> image) {
}
jni::GetArrayRegion(env, *pixels, 0, size, reinterpret_cast<jbyte*>(premultipliedImage.data.get()));
-
+ jni::DeleteLocalRef(env, pixels);
return mbgl::style::Image {name, std::move(premultipliedImage), pixelRatio};
}
diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp
index 2440ac93ef..f7e16b7091 100644
--- a/platform/android/src/map_renderer.cpp
+++ b/platform/android/src/map_renderer.cpp
@@ -136,7 +136,7 @@ void MapRenderer::render(JNIEnv&) {
renderer->render(*params);
// Deliver the snapshot if requested
- if (snapshotCallback) {
+ if (snapshotCallback && !paused) {
snapshotCallback->operator()(backend->readFramebuffer());
snapshotCallback.reset();
}
@@ -174,6 +174,14 @@ void MapRenderer::onSurfaceChanged(JNIEnv&, jint width, jint height) {
requestRender();
}
+void MapRenderer::onResume(JNIEnv&) {
+ paused = false;
+}
+
+void MapRenderer::onPause(JNIEnv&) {
+ paused = true;
+}
+
// Static methods //
jni::Class<MapRenderer> MapRenderer::javaClass;
@@ -192,7 +200,11 @@ void MapRenderer::registerNative(jni::JNIEnv& env) {
METHOD(&MapRenderer::onSurfaceCreated,
"nativeOnSurfaceCreated"),
METHOD(&MapRenderer::onSurfaceChanged,
- "nativeOnSurfaceChanged"));
+ "nativeOnSurfaceChanged"),
+ METHOD(&MapRenderer::onResume,
+ "nativeOnResume"),
+ METHOD(&MapRenderer::onPause,
+ "nativeOnPause"));
}
MapRenderer& MapRenderer::getNativePeer(JNIEnv& env, jni::Object<MapRenderer> jObject) {
diff --git a/platform/android/src/map_renderer.hpp b/platform/android/src/map_renderer.hpp
index c36357af7a..5fb5ef1a61 100644
--- a/platform/android/src/map_renderer.hpp
+++ b/platform/android/src/map_renderer.hpp
@@ -98,6 +98,10 @@ private:
void onSurfaceChanged(JNIEnv&, jint width, jint height);
+ void onResume(JNIEnv&);
+
+ void onPause(JNIEnv&);
+
private:
GenericUniqueWeakObject<MapRenderer> javaPeer;
@@ -120,6 +124,7 @@ private:
std::mutex updateMutex;
bool framebufferSizeChanged = false;
+ std::atomic<bool> paused {false};
std::unique_ptr<SnapshotCallback> snapshotCallback;
};
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index 67fc132204..eecb76213b 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -288,13 +288,15 @@ void NativeMapView::setLatLng(jni::JNIEnv&, jni::jdouble latitude, jni::jdouble
map->setLatLng(mbgl::LatLng(latitude, longitude), insets, mbgl::AnimationOptions{mbgl::Milliseconds(duration)});
}
-jni::Object<CameraPosition> NativeMapView::getCameraForLatLngBounds(jni::JNIEnv& env, jni::Object<LatLngBounds> jBounds) {
- return CameraPosition::New(env, map->cameraForLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds), insets));
+jni::Object<CameraPosition> NativeMapView::getCameraForLatLngBounds(jni::JNIEnv& env, jni::Object<LatLngBounds> jBounds, double top, double left, double bottom, double right) {
+ mbgl::EdgeInsets padding = {top, left, bottom, right};
+ return CameraPosition::New(env, map->cameraForLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds), padding));
}
-jni::Object<CameraPosition> NativeMapView::getCameraForGeometry(jni::JNIEnv& env, jni::Object<geojson::Geometry> jGeometry, double bearing) {
+jni::Object<CameraPosition> NativeMapView::getCameraForGeometry(jni::JNIEnv& env, jni::Object<geojson::Geometry> jGeometry, double bearing, double top, double left, double bottom, double right) {
auto geometry = geojson::Geometry::convert(env, jGeometry);
- return CameraPosition::New(env, map->cameraForGeometry(geometry, insets, bearing));
+ mbgl::EdgeInsets padding = {top, left, bottom, right};
+ return CameraPosition::New(env, map->cameraForGeometry(geometry, padding, bearing));
}
void NativeMapView::setReachability(jni::JNIEnv&, jni::jboolean reachable) {
@@ -893,16 +895,9 @@ void NativeMapView::removeSource(JNIEnv& env, jni::Object<Source> obj, jlong sou
source->removeFromMap(env, obj, *map);
}
-void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::jint w, jni::jint h, jni::jfloat scale, jni::Array<jbyte> pixels) {
- jni::NullCheck(env, &pixels);
- std::size_t size = pixels.Length(env);
-
- mbgl::PremultipliedImage premultipliedImage({ static_cast<uint32_t>(w), static_cast<uint32_t>(h) });
- if (premultipliedImage.bytes() != uint32_t(size)) {
- throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch");
- }
-
- jni::GetArrayRegion(env, *pixels, 0, size, reinterpret_cast<jbyte*>(premultipliedImage.data.get()));
+void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::Object<Bitmap> bitmap, jni::jfloat scale) {
+ jni::NullCheck(env, &bitmap);
+ mbgl::PremultipliedImage premultipliedImage = Bitmap::GetImage(env, bitmap);
map->getStyle().addImage(std::make_unique<mbgl::style::Image>(
jni::Make<std::string>(env, name),
diff --git a/platform/android/src/native_map_view.hpp b/platform/android/src/native_map_view.hpp
index 507d77ac5f..aff3b51c42 100755
--- a/platform/android/src/native_map_view.hpp
+++ b/platform/android/src/native_map_view.hpp
@@ -104,9 +104,9 @@ public:
void setLatLng(jni::JNIEnv&, jni::jdouble, jni::jdouble, jni::jlong);
- jni::Object<CameraPosition> getCameraForLatLngBounds(jni::JNIEnv&, jni::Object<mbgl::android::LatLngBounds>);
+ jni::Object<CameraPosition> getCameraForLatLngBounds(jni::JNIEnv&, jni::Object<mbgl::android::LatLngBounds>, double top, double left, double bottom, double right);
- jni::Object<CameraPosition> getCameraForGeometry(jni::JNIEnv&, jni::Object<geojson::Geometry>, double bearing);
+ jni::Object<CameraPosition> getCameraForGeometry(jni::JNIEnv&, jni::Object<geojson::Geometry>, double bearing, double top, double left, double bottom, double right);
void setReachability(jni::JNIEnv&, jni::jboolean);
@@ -236,7 +236,7 @@ public:
void removeSource(JNIEnv&, jni::Object<Source>, jlong nativePtr);
- void addImage(JNIEnv&, jni::String, jni::jint, jni::jint, jni::jfloat, jni::Array<jbyte>);
+ void addImage(JNIEnv&, jni::String, jni::Object<Bitmap> bitmap, jni::jfloat);
void addImages(JNIEnv&, jni::Array<jni::Object<mbgl::android::Image>>);
@@ -257,7 +257,6 @@ private:
MapRenderer& mapRenderer;
std::string styleUrl;
- std::string apiKey;
float pixelRatio;
diff --git a/platform/android/src/offline/offline_manager.cpp b/platform/android/src/offline/offline_manager.cpp
index 02871e7fdf..4960ae2845 100644
--- a/platform/android/src/offline/offline_manager.cpp
+++ b/platform/android/src/offline/offline_manager.cpp
@@ -102,7 +102,9 @@ void OfflineManager::ListOfflineRegionsCallback::onError(jni::JNIEnv& env,
std::exception_ptr error) {
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
std::string message = mbgl::util::toString(error);
- callback.Call(env, method, jni::Make<jni::String>(env, message));
+ auto jmessage = jni::Make<jni::String>(env, message);
+ callback.Call(env, method, jmessage);
+ jni::DeleteLocalRef(env, jmessage);
}
void OfflineManager::ListOfflineRegionsCallback::onList(jni::JNIEnv& env,
@@ -138,7 +140,9 @@ void OfflineManager::CreateOfflineRegionCallback::onError(jni::JNIEnv& env,
std::exception_ptr error) {
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
std::string message = mbgl::util::toString(error);
- callback.Call(env, method, jni::Make<jni::String>(env, message));
+ auto jmessage = jni::Make<jni::String>(env, message);
+ callback.Call(env, method, jmessage);
+ jni::DeleteLocalRef(env, jmessage);
}
void OfflineManager::CreateOfflineRegionCallback::onCreate(jni::JNIEnv& env,
diff --git a/platform/android/src/offline/offline_region.cpp b/platform/android/src/offline/offline_region.cpp
index 856434d266..27de76fb00 100644
--- a/platform/android/src/offline/offline_region.cpp
+++ b/platform/android/src/offline/offline_region.cpp
@@ -239,7 +239,9 @@ void OfflineRegion::OfflineRegionStatusCallback::onError(jni::JNIEnv& env,
std::exception_ptr error) {
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
std::string message = mbgl::util::toString(error);
- callback.Call(env, method, jni::Make<jni::String>(env, message));
+ auto jmessage = jni::Make<jni::String>(env, message);
+ callback.Call(env, method, jmessage);
+ jni::DeleteLocalRef(env, jmessage);
}
void OfflineRegion::OfflineRegionStatusCallback::onStatus(jni::JNIEnv& env,
@@ -267,7 +269,9 @@ void OfflineRegion::OfflineRegionDeleteCallback::onError(jni::JNIEnv& env,
std::exception_ptr error) {
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
std::string message = mbgl::util::toString(error);
- callback.Call(env, method, jni::Make<jni::String>(env, message));
+ auto jmessage = jni::Make<jni::String>(env, message);
+ callback.Call(env, method, jmessage);
+ jni::DeleteLocalRef(env, jmessage);
}
void OfflineRegion::OfflineRegionDeleteCallback::onDelete(jni::JNIEnv& env, jni::Object<OfflineRegion::OfflineRegionDeleteCallback> callback) {
@@ -289,7 +293,9 @@ void OfflineRegion::OfflineRegionUpdateMetadataCallback::onError(jni::JNIEnv& en
std::exception_ptr error) {
static auto method = javaClass.GetMethod<void (jni::String)>(env, "onError");
std::string message = mbgl::util::toString(error);
- callback.Call(env, method, jni::Make<jni::String>(env, message));
+ auto jmessage = jni::Make<jni::String>(env, message);
+ callback.Call(env, method, jmessage);
+ jni::DeleteLocalRef(env, jmessage);
}
void OfflineRegion::OfflineRegionUpdateMetadataCallback::onUpdate(jni::JNIEnv& env,
diff --git a/platform/android/src/snapshotter/map_snapshotter.cpp b/platform/android/src/snapshotter/map_snapshotter.cpp
index 71f8b4f4c0..a006953d36 100644
--- a/platform/android/src/snapshotter/map_snapshotter.cpp
+++ b/platform/android/src/snapshotter/map_snapshotter.cpp
@@ -71,7 +71,9 @@ void MapSnapshotter::start(JNIEnv& env) {
if (err) {
// error handler callback
static auto onSnapshotFailed = javaClass.GetMethod<void (jni::String)>(*_env, "onSnapshotFailed");
- javaPeer->Call(*_env, onSnapshotFailed, jni::Make<jni::String>(*_env, util::toString(err)));
+ auto message = jni::Make<jni::String>(*_env, util::toString(err));
+ javaPeer->Call(*_env, onSnapshotFailed, message);
+ jni::DeleteLocalRef(*_env, message);
} else {
// Create the wrapper
auto mapSnapshot = android::MapSnapshot::New(*_env, std::move(image), pixelRatio, attributions, showLogo, pointForFn);
diff --git a/platform/android/src/style/conversion/function.hpp b/platform/android/src/style/conversion/function.hpp
index ad01a7afc2..d6669b4508 100644
--- a/platform/android/src/style/conversion/function.hpp
+++ b/platform/android/src/style/conversion/function.hpp
@@ -5,13 +5,9 @@
#include "../../conversion/constant.hpp"
#include "types.hpp"
#include "../../java/lang.hpp"
-#include "../functions/stop.hpp"
-#include "../functions/categorical_stops.hpp"
-#include "../functions/exponential_stops.hpp"
-#include "../functions/identity_stops.hpp"
-#include "../functions/interval_stops.hpp"
#include <jni/jni.hpp>
+#include "../../gson/json_element.hpp"
#include <tuple>
#include <map>
@@ -20,205 +16,33 @@ namespace mbgl {
namespace android {
namespace conversion {
-/**
- * Conversion from core composite value to java type
- */
-class CategoricalValueEvaluator {
-public:
-
- CategoricalValueEvaluator(jni::JNIEnv& _env) : env(_env) {}
-
- template <class T>
- jni::jobject* operator()(const T &value) const {
- return *convert<jni::jobject*, T>(env, value);
- }
-
-private:
- jni::JNIEnv& env;
-};
-
-/**
- * Conversion from core composite value to java type
- */
-template <>
-struct Converter<jni::jobject*, mbgl::style::CategoricalValue> {
-
- Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::CategoricalValue& value) const {
- CategoricalValueEvaluator evaluator(env);
- return apply_visitor(evaluator, value);
- }
-};
-
-template <class I, class O>
-jni::Array<jni::Object<Stop>> toFunctionStopJavaArray(jni::JNIEnv& env, std::map<I, O> value) {
-
- auto jarray = jni::Array<jni::Object<Stop>>::New(env, value.size(), Stop::javaClass);
-
- size_t i = 0;
- for (auto const& stop : value) {
- jni::jobject* in = *convert<jni::jobject*, I>(env, stop.first);
- jni::jobject* out = *convert<jni::jobject*, O>(env, stop.second);
-
- auto jstop = Stop::New(env, jni::Object<>(in), jni::Object<>(out));
- jarray.Set(env, i, jstop);
-
- jni::DeleteLocalRef(env, in);
- jni::DeleteLocalRef(env, out);
- jni::DeleteLocalRef(env, jstop);
-
- i++;
- }
-
- return jarray;
-}
-
-template <class I, class O>
-jni::Array<jni::Object<Stop>> toFunctionStopJavaArray(jni::JNIEnv& env, std::map<float, std::map<I, O>> value) {
-
- auto jarray = jni::Array<jni::Object<Stop>>::New(env, value.size(), Stop::javaClass);
-
- for (auto const& zoomLevelMap : value) {
- size_t i = 0;
- for (auto const& stop: zoomLevelMap.second) {
- auto zoom = jni::Object<java::lang::Number>(*convert<jni::jobject*>(env, zoomLevelMap.first));
- auto in = jni::Object<>(*convert<jni::jobject*, I>(env, stop.first));
- auto out = jni::Object<>(*convert<jni::jobject*, O>(env, stop.second));
- auto compositeValue = Stop::CompositeValue::New(env, zoom, in);
-
- auto jstop = Stop::New(env, compositeValue, out);
- jarray.Set(env, i, jstop);
-
- jni::DeleteLocalRef(env, zoom);
- jni::DeleteLocalRef(env, in);
- jni::DeleteLocalRef(env, out);
- jni::DeleteLocalRef(env, compositeValue);
- jni::DeleteLocalRef(env, jstop);
-
- i++;
- }
- }
-
- return jarray;
-}
-
-template <class I, typename O>
-inline jni::jobject* convertCompositeStopsArray(jni::JNIEnv& env, std::map<float, std::map<I, O>> value) {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/mapboxsdk/style/functions/stops/Stop")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *javaClass, "<init>", "(Ljava/lang/Object;Ljava/lang/Object;)V");
-
- jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *javaClass);
-
- size_t i = 0;
- for (auto const& stop : value) {
- jni::jobject* in = *convert<jni::jobject*, I>(env, stop.first);
- jni::jobject* out = *convert<jni::jobject*, O>(env, stop.second);
- jni::SetObjectArrayElement(env, jarray, i, &jni::NewObject(env, *javaClass, *constructor, in, out));
- i++;
- jni::DeleteLocalRef(env, in);
- jni::DeleteLocalRef(env, out);
- }
-
- return &jarray;
-}
-
-/**
- * Conversion from core function stops to Stops java subclasses
- */
template <class T>
-class StopsEvaluator {
-public:
-
- StopsEvaluator(jni::JNIEnv& _env) : env(_env) {}
-
- jni::jobject* operator()(const mbgl::style::CategoricalStops<T> &value) const {
- return CategoricalStops::New(env, toFunctionStopJavaArray(env, value.stops)).Get();
- }
-
- jni::jobject* operator()(const mbgl::style::CompositeCategoricalStops<T> &value) const {
- return CategoricalStops::New(env, toFunctionStopJavaArray(env, value.stops)).Get();
- }
-
- jni::jobject* operator()(const mbgl::style::ExponentialStops<T> &value) const {
- return ExponentialStops::New(env, jni::Object<java::lang::Float>(*convert<jni::jobject*>(env, value.base)), toFunctionStopJavaArray(env, value.stops)).Get();
- }
+struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::CameraFunction<T>> {
- jni::jobject* operator()(const mbgl::style::CompositeExponentialStops<T> &value) const {
- return ExponentialStops::New(env, jni::Object<java::lang::Float>(*convert<jni::jobject*>(env, value.base)), toFunctionStopJavaArray(env, value.stops)).Get();
+ Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::CameraFunction<T>& value) const {
+ // Convert expressions
+ mbgl::Value expressionValue = value.getExpression().serialize();
+ return gson::JsonElement::New(env, expressionValue);
}
-
- jni::jobject* operator()(const mbgl::style::IdentityStops<T> &) const {
- return IdentityStops::New(env).Get();
- }
-
- jni::jobject* operator()(const mbgl::style::IntervalStops<T> &value) const {
- return IntervalStops::New(env, toFunctionStopJavaArray(env, value.stops)).Get();
- }
-
- jni::jobject* operator()(const mbgl::style::CompositeIntervalStops<T> &value) const {
- return IntervalStops::New(env, toFunctionStopJavaArray(env, value.stops)).Get();
- }
-
-private:
- jni::JNIEnv& env;
};
template <class T>
-struct Converter<jni::jobject*, mbgl::style::CameraFunction<T>> {
+struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::SourceFunction<T>> {
- Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::CameraFunction<T>& value) const {
- static jni::jclass* clazz = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/mapboxsdk/style/functions/CameraFunction")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *clazz, "<init>", "(Lcom/mapbox/mapboxsdk/style/functions/stops/Stops;)V");
-
- StopsEvaluator<T> evaluator(env);
- jni::jobject* stops = apply_visitor(evaluator, value.stops);
- jni::jobject* converted = &jni::NewObject(env, *clazz, *constructor, stops);
-
- return { converted };
- }
-};
-
-template <class T>
-struct Converter<jni::jobject*, mbgl::style::SourceFunction<T>> {
-
- Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::SourceFunction<T>& value) const {
- static jni::jclass* clazz = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/mapboxsdk/style/functions/SourceFunction")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *clazz, "<init>",
- "(Ljava/lang/Object;Ljava/lang/String;Lcom/mapbox/mapboxsdk/style/functions/stops/Stops;)V");
-
- // Convert stops
- StopsEvaluator<T> evaluator(env);
- jni::jobject* stops = apply_visitor(evaluator, value.stops);
-
- // Convert default value
- jni::jobject* defaultValue = nullptr;
- if (value.defaultValue) {
- defaultValue = *convert<jni::jobject*>(env, *value.defaultValue);
- }
-
- return { &jni::NewObject(env, *clazz, *constructor, defaultValue, jni::Make<jni::String>(env, value.property).Get(), stops) };
+ Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::SourceFunction<T>& value) const {
+ // Convert expressions
+ mbgl::Value expressionValue = value.getExpression().serialize();
+ return gson::JsonElement::New(env, expressionValue);
}
};
template <class T>
-struct Converter<jni::jobject*, mbgl::style::CompositeFunction<T>> {
-
- Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::CompositeFunction<T>& value) const {
- static jni::jclass* clazz = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/mapboxsdk/style/functions/CompositeFunction")).release();
- static jni::jmethodID* constructor = &jni::GetMethodID(env, *clazz, "<init>",
- "(Ljava/lang/Object;Ljava/lang/String;Lcom/mapbox/mapboxsdk/style/functions/stops/Stops;)V");
-
- // Convert stops
- StopsEvaluator<T> evaluator(env);
- jni::jobject* stops = apply_visitor(evaluator, value.stops);
-
-
- // Convert default value
- jni::jobject* defaultValue = nullptr;
- if (value.defaultValue) {
- defaultValue = *convert<jni::jobject*>(env, *value.defaultValue);
- }
+struct Converter<jni::Object<android::gson::JsonElement>, mbgl::style::CompositeFunction<T>> {
- return { &jni::NewObject(env, *clazz, *constructor, defaultValue, jni::Make<jni::String>(env, value.property).Get(), stops) };
+ Result<jni::Object<android::gson::JsonElement>> operator()(jni::JNIEnv& env, const mbgl::style::CompositeFunction<T>& value) const {
+ // Convert expressions
+ mbgl::Value expressionValue = value.getExpression().serialize();
+ return gson::JsonElement::New(env, expressionValue);
}
};
diff --git a/platform/android/src/style/conversion/property_value.hpp b/platform/android/src/style/conversion/property_value.hpp
index a58cf975a7..902d1e80b2 100644
--- a/platform/android/src/style/conversion/property_value.hpp
+++ b/platform/android/src/style/conversion/property_value.hpp
@@ -2,6 +2,7 @@
#include <mbgl/style/property_value.hpp>
#include <mbgl/style/data_driven_property_value.hpp>
+#include <mbgl/style/heatmap_color_property_value.hpp>
#include "../../conversion/conversion.hpp"
#include "../../conversion/constant.hpp"
#include "types.hpp"
@@ -30,15 +31,15 @@ public:
}
jni::jobject* operator()(const mbgl::style::CameraFunction<T> &value) const {
- return *convert<jni::jobject*, mbgl::style::CameraFunction<T>>(env, value);
+ return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::CameraFunction<T>>(env, value);
}
jni::jobject* operator()(const mbgl::style::SourceFunction<T> &value) const {
- return *convert<jni::jobject*, mbgl::style::SourceFunction<T>>(env, value);
+ return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::SourceFunction<T>>(env, value);
}
jni::jobject* operator()(const mbgl::style::CompositeFunction<T> &value) const {
- return *convert<jni::jobject*, mbgl::style::CompositeFunction<T>>(env, value);
+ return *convert<jni::Object<android::gson::JsonElement>, mbgl::style::CompositeFunction<T>>(env, value);
}
private:
@@ -70,6 +71,18 @@ struct Converter<jni::jobject*, mbgl::style::DataDrivenPropertyValue<T>> {
}
};
+/**
+ * Convert core heat map color property value to java
+ */
+template <>
+struct Converter<jni::jobject*, mbgl::style::HeatmapColorPropertyValue> {
+
+ Result<jni::jobject*> operator()(jni::JNIEnv& env, const mbgl::style::HeatmapColorPropertyValue value) const {
+ PropertyValueEvaluator<mbgl::style::HeatmapColorPropertyValue> evaluator(env);
+ return *convert<jni::jobject*>(env, value.evaluate(evaluator));
+ }
+};
+
} // namespace conversion
} // namespace android
} // namespace mbgl
diff --git a/platform/android/src/style/functions/categorical_stops.cpp b/platform/android/src/style/functions/categorical_stops.cpp
deleted file mode 100644
index 2aff9730a7..0000000000
--- a/platform/android/src/style/functions/categorical_stops.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "categorical_stops.hpp"
-
-namespace mbgl {
-namespace android {
-
-jni::Object<CategoricalStops> CategoricalStops::New(jni::JNIEnv& env, jni::Array<jni::Object<Stop>> stops) {
- static auto constructor = CategoricalStops::javaClass.GetConstructor<jni::Array<jni::Object<Stop>>>(env);
- return CategoricalStops::javaClass.New(env, constructor, stops);
-}
-
-jni::Class<CategoricalStops> CategoricalStops::javaClass;
-
-void CategoricalStops::registerNative(jni::JNIEnv& env) {
- CategoricalStops::javaClass = *jni::Class<CategoricalStops>::Find(env).NewGlobalRef(env).release();
-}
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/categorical_stops.hpp b/platform/android/src/style/functions/categorical_stops.hpp
deleted file mode 100644
index a198c8d5c9..0000000000
--- a/platform/android/src/style/functions/categorical_stops.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
-#include "stop.hpp"
-
-namespace mbgl {
-namespace android {
-
-class CategoricalStops : private mbgl::util::noncopyable {
-public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/CategoricalStops"; };
-
- static jni::Object<CategoricalStops> New(jni::JNIEnv&, jni::Array<jni::Object<Stop>>);
-
- static jni::Class<CategoricalStops> javaClass;
-
- static void registerNative(jni::JNIEnv&);
-};
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/exponential_stops.cpp b/platform/android/src/style/functions/exponential_stops.cpp
deleted file mode 100644
index 6390a0ec35..0000000000
--- a/platform/android/src/style/functions/exponential_stops.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "exponential_stops.hpp"
-
-namespace mbgl {
-namespace android {
-
-jni::Object<ExponentialStops> ExponentialStops::New(jni::JNIEnv& env, jni::Object<java::lang::Float> base, jni::Array<jni::Object<Stop>> stops) {
- static auto constructor = ExponentialStops::javaClass.GetConstructor<jni::Object<java::lang::Float>, jni::Array<jni::Object<Stop>>>(env);
- return ExponentialStops::javaClass.New(env, constructor, base, stops);
-}
-
-jni::Class<ExponentialStops> ExponentialStops::javaClass;
-
-void ExponentialStops::registerNative(jni::JNIEnv& env) {
- ExponentialStops::javaClass = *jni::Class<ExponentialStops>::Find(env).NewGlobalRef(env).release();
-}
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/exponential_stops.hpp b/platform/android/src/style/functions/exponential_stops.hpp
deleted file mode 100644
index 391d723cef..0000000000
--- a/platform/android/src/style/functions/exponential_stops.hpp
+++ /dev/null
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
-#include "../../java/lang.hpp"
-#include "stop.hpp"
-
-namespace mbgl {
-namespace android {
-
-class ExponentialStops : private mbgl::util::noncopyable {
-public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/ExponentialStops"; };
-
- static jni::Object<ExponentialStops> New(jni::JNIEnv&, jni::Object<java::lang::Float>, jni::Array<jni::Object<Stop>>);
-
- static jni::Class<ExponentialStops> javaClass;
-
- static void registerNative(jni::JNIEnv&);
-};
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/identity_stops.cpp b/platform/android/src/style/functions/identity_stops.cpp
deleted file mode 100644
index 239b0ddb88..0000000000
--- a/platform/android/src/style/functions/identity_stops.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "identity_stops.hpp"
-
-namespace mbgl {
-namespace android {
-
-jni::Object<IdentityStops> IdentityStops::New(jni::JNIEnv& env) {
- static auto constructor = IdentityStops::javaClass.GetConstructor<>(env);
- return IdentityStops::javaClass.New(env, constructor);
-}
-
-jni::Class<IdentityStops> IdentityStops::javaClass;
-
-void IdentityStops::registerNative(jni::JNIEnv& env) {
- IdentityStops::javaClass = *jni::Class<IdentityStops>::Find(env).NewGlobalRef(env).release();
-}
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/identity_stops.hpp b/platform/android/src/style/functions/identity_stops.hpp
deleted file mode 100644
index 150b2135f0..0000000000
--- a/platform/android/src/style/functions/identity_stops.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
-namespace mbgl {
-namespace android {
-
-class IdentityStops : private mbgl::util::noncopyable {
-public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/IdentityStops"; };
-
- static jni::Object<IdentityStops> New(jni::JNIEnv&);
-
- static jni::Class<IdentityStops> javaClass;
-
- static void registerNative(jni::JNIEnv&);
-};
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/interval_stops.cpp b/platform/android/src/style/functions/interval_stops.cpp
deleted file mode 100644
index c3d9b6513f..0000000000
--- a/platform/android/src/style/functions/interval_stops.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-#include "interval_stops.hpp"
-
-namespace mbgl {
-namespace android {
-
-jni::Object<IntervalStops> IntervalStops::New(jni::JNIEnv& env, jni::Array<jni::Object<Stop>> stops) {
- static auto constructor = IntervalStops::javaClass.GetConstructor<jni::Array<jni::Object<Stop>>>(env);
- return IntervalStops::javaClass.New(env, constructor, stops);
-}
-
-jni::Class<IntervalStops> IntervalStops::javaClass;
-
-void IntervalStops::registerNative(jni::JNIEnv& env) {
- IntervalStops::javaClass = *jni::Class<IntervalStops>::Find(env).NewGlobalRef(env).release();
-}
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/interval_stops.hpp b/platform/android/src/style/functions/interval_stops.hpp
deleted file mode 100644
index e3f75159cf..0000000000
--- a/platform/android/src/style/functions/interval_stops.hpp
+++ /dev/null
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
-#include "stop.hpp"
-
-namespace mbgl {
-namespace android {
-
-class IntervalStops : private mbgl::util::noncopyable {
-public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/IntervalStops"; };
-
- static jni::Object<IntervalStops> New(jni::JNIEnv&, jni::Array<jni::Object<Stop>>);
-
- static jni::Class<IntervalStops> javaClass;
-
- static void registerNative(jni::JNIEnv&);
-};
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/stop.cpp b/platform/android/src/style/functions/stop.cpp
deleted file mode 100644
index f9ed4b7368..0000000000
--- a/platform/android/src/style/functions/stop.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "interval_stops.hpp"
-
-namespace mbgl {
-namespace android {
-
-jni::Object<Stop::CompositeValue> Stop::CompositeValue::New(jni::JNIEnv& env, jni::Object<java::lang::Number> zoom, jni::Object<> value) {
- static auto constructor = Stop::CompositeValue::javaClass.GetConstructor<jni::Object<java::lang::Number>, jni::Object<>>(env);
- return Stop::CompositeValue::javaClass.New(env, constructor, zoom, value);
-}
-
-jni::Class<Stop> Stop::javaClass;
-
-jni::Class<Stop::CompositeValue> Stop::CompositeValue::javaClass;
-
-void Stop::registerNative(jni::JNIEnv& env) {
- Stop::javaClass = *jni::Class<Stop>::Find(env).NewGlobalRef(env).release();
- Stop::CompositeValue::javaClass = *jni::Class<Stop::CompositeValue>::Find(env).NewGlobalRef(env).release();
-}
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/functions/stop.hpp b/platform/android/src/style/functions/stop.hpp
deleted file mode 100644
index 7c697db65d..0000000000
--- a/platform/android/src/style/functions/stop.hpp
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
-#include "../../java/lang.hpp"
-
-namespace mbgl {
-namespace android {
-
-class Stop : private mbgl::util::noncopyable {
-public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/Stop"; };
-
- template<class I, class O>
- static jni::Object<Stop> New(jni::JNIEnv& env, jni::Object<I> in, jni::Object<O> out) {
- static auto constructor = Stop::javaClass.GetConstructor<jni::Object<>, jni::Object<>>(env);
- return Stop::javaClass.New(env, constructor, (jni::Object<>) in, (jni::Object<>) out);
- }
-
- static jni::Class<Stop> javaClass;
-
- static void registerNative(jni::JNIEnv&);
-
- class CompositeValue : private mbgl::util::noncopyable {
- public:
- static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/functions/stops/Stop$CompositeValue"; };
-
- static jni::Object<Stop::CompositeValue> New(jni::JNIEnv&, jni::Object<java::lang::Number>, jni::Object<>);
-
- static jni::Class<Stop::CompositeValue> javaClass;
- };
-};
-
-} // namespace android
-} // namespace mbgl
diff --git a/platform/android/src/style/layers/custom_layer.cpp b/platform/android/src/style/layers/custom_layer.cpp
index 51a48520bf..61e74a9cf5 100644
--- a/platform/android/src/style/layers/custom_layer.cpp
+++ b/platform/android/src/style/layers/custom_layer.cpp
@@ -7,14 +7,10 @@
namespace mbgl {
namespace android {
- CustomLayer::CustomLayer(jni::JNIEnv& env, jni::String layerId, jni::jlong initializeFunction, jni::jlong renderFunction, jni::jlong contextLostFunction, jni::jlong deinitializeFunction, jni::jlong context)
+ CustomLayer::CustomLayer(jni::JNIEnv& env, jni::String layerId, jni::jlong host)
: Layer(env, std::make_unique<mbgl::style::CustomLayer>(
jni::Make<std::string>(env, layerId),
- reinterpret_cast<mbgl::style::CustomLayerInitializeFunction>(initializeFunction),
- reinterpret_cast<mbgl::style::CustomLayerRenderFunction>(renderFunction),
- reinterpret_cast<mbgl::style::CustomLayerContextLostFunction>(contextLostFunction),
- reinterpret_cast<mbgl::style::CustomLayerDeinitializeFunction>(deinitializeFunction),
- reinterpret_cast<void*>(context))
+ std::unique_ptr<mbgl::style::CustomLayerHost>(reinterpret_cast<mbgl::style::CustomLayerHost*>(host)))
) {
}
@@ -53,7 +49,7 @@ namespace android {
// Register the peer
jni::RegisterNativePeer<CustomLayer>(
env, CustomLayer::javaClass, "nativePtr",
- std::make_unique<CustomLayer, JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong, jni::jlong>,
+ std::make_unique<CustomLayer, JNIEnv&, jni::String, jni::jlong>,
"initialize",
"finalize",
METHOD(&CustomLayer::update, "nativeUpdate"));
diff --git a/platform/android/src/style/layers/custom_layer.hpp b/platform/android/src/style/layers/custom_layer.hpp
index 9e079c1288..7eb649d923 100644
--- a/platform/android/src/style/layers/custom_layer.hpp
+++ b/platform/android/src/style/layers/custom_layer.hpp
@@ -16,7 +16,7 @@ public:
static void registerNative(jni::JNIEnv&);
- CustomLayer(jni::JNIEnv&, jni::String, jni::jlong, jni::jlong, jni::jlong, jni::jlong, jni::jlong);
+ CustomLayer(jni::JNIEnv&, jni::String, jni::jlong);
CustomLayer(mbgl::Map&, mbgl::style::CustomLayer&);
diff --git a/platform/android/src/style/layers/heatmap_layer.cpp b/platform/android/src/style/layers/heatmap_layer.cpp
index 609499ec93..b3d90faab7 100644
--- a/platform/android/src/style/layers/heatmap_layer.cpp
+++ b/platform/android/src/style/layers/heatmap_layer.cpp
@@ -79,6 +79,16 @@ namespace android {
layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::setHeatmapIntensityTransition(options);
}
+ jni::Object<jni::ObjectTag> HeatmapLayer::getHeatmapColor(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ auto propertyValue = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapColor();
+ if (propertyValue.isUndefined()) {
+ propertyValue = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getDefaultHeatmapColor();
+ }
+ Result<jni::jobject*> converted = convert<jni::jobject*>(env, propertyValue);
+ return jni::Object<jni::ObjectTag>(*converted);
+ }
+
jni::Object<jni::ObjectTag> HeatmapLayer::getHeatmapOpacity(jni::JNIEnv& env) {
using namespace mbgl::android::conversion;
Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapOpacity());
@@ -125,6 +135,7 @@ namespace android {
METHOD(&HeatmapLayer::getHeatmapIntensityTransition, "nativeGetHeatmapIntensityTransition"),
METHOD(&HeatmapLayer::setHeatmapIntensityTransition, "nativeSetHeatmapIntensityTransition"),
METHOD(&HeatmapLayer::getHeatmapIntensity, "nativeGetHeatmapIntensity"),
+ METHOD(&HeatmapLayer::getHeatmapColor, "nativeGetHeatmapColor"),
METHOD(&HeatmapLayer::getHeatmapOpacityTransition, "nativeGetHeatmapOpacityTransition"),
METHOD(&HeatmapLayer::setHeatmapOpacityTransition, "nativeSetHeatmapOpacityTransition"),
METHOD(&HeatmapLayer::getHeatmapOpacity, "nativeGetHeatmapOpacity"));
diff --git a/platform/android/src/style/layers/heatmap_layer.hpp b/platform/android/src/style/layers/heatmap_layer.hpp
index 85f9f0292e..9e8908b062 100644
--- a/platform/android/src/style/layers/heatmap_layer.hpp
+++ b/platform/android/src/style/layers/heatmap_layer.hpp
@@ -39,6 +39,8 @@ public:
void setHeatmapIntensityTransition(jni::JNIEnv&, jlong duration, jlong delay);
jni::Object<TransitionOptions> getHeatmapIntensityTransition(jni::JNIEnv&);
+ jni::Object<jni::ObjectTag> getHeatmapColor(jni::JNIEnv&);
+
jni::Object<jni::ObjectTag> getHeatmapOpacity(jni::JNIEnv&);
void setHeatmapOpacityTransition(jni::JNIEnv&, jlong duration, jlong delay);
jni::Object<TransitionOptions> getHeatmapOpacityTransition(jni::JNIEnv&);
diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp
index 29530879a5..6fe6e3cb29 100644
--- a/platform/android/src/style/layers/layer.cpp
+++ b/platform/android/src/style/layers/layer.cpp
@@ -25,6 +25,7 @@
// C++ -> Java conversion
#include "../conversion/property_value.hpp"
+#include <mbgl/style/filter.hpp>
#include <string>
@@ -134,6 +135,38 @@ namespace android {
layer.accept(SetFilterEvaluator {std::move(*converted)});
}
+ struct GetFilterEvaluator {
+ mbgl::style::Filter noop(std::string layerType) {
+ Log::Warning(mbgl::Event::JNI, "%s doesn't support filter", layerType.c_str());
+ return {};
+ }
+
+ mbgl::style::Filter operator()(style::BackgroundLayer&) { return noop("BackgroundLayer"); }
+ mbgl::style::Filter operator()(style::CustomLayer&) { return noop("CustomLayer"); }
+ mbgl::style::Filter operator()(style::RasterLayer&) { return noop("RasterLayer"); }
+ mbgl::style::Filter operator()(style::HillshadeLayer&) { return noop("HillshadeLayer"); }
+
+ template <class LayerType>
+ mbgl::style::Filter operator()(LayerType& layer) {
+ return layer.getFilter();
+ }
+ };
+
+ jni::Object<gson::JsonElement> Layer::getFilter(jni::JNIEnv& env) {
+ using namespace mbgl::style;
+ using namespace mbgl::style::conversion;
+
+ Filter filter = layer.accept(GetFilterEvaluator());
+
+ jni::Object<gson::JsonElement> converted;
+ if (filter.is<ExpressionFilter>()) {
+ ExpressionFilter filterExpression = filter.get<ExpressionFilter>();
+ mbgl::Value expressionValue = filterExpression.expression.get()->serialize();
+ converted = gson::JsonElement::New(env, expressionValue);
+ }
+ return converted;
+ }
+
struct SetSourceLayerEvaluator {
std::string sourceLayer;
@@ -208,6 +241,7 @@ namespace android {
METHOD(&Layer::setLayoutProperty, "nativeSetLayoutProperty"),
METHOD(&Layer::setPaintProperty, "nativeSetPaintProperty"),
METHOD(&Layer::setFilter, "nativeSetFilter"),
+ METHOD(&Layer::getFilter, "nativeGetFilter"),
METHOD(&Layer::setSourceLayer, "nativeSetSourceLayer"),
METHOD(&Layer::getSourceLayer, "nativeGetSourceLayer"),
METHOD(&Layer::getMinZoom, "nativeGetMinZoom"),
diff --git a/platform/android/src/style/layers/layer.cpp.ejs b/platform/android/src/style/layers/layer.cpp.ejs
index 1debb096a3..b08f0ec4dc 100644
--- a/platform/android/src/style/layers/layer.cpp.ejs
+++ b/platform/android/src/style/layers/layer.cpp.ejs
@@ -48,12 +48,25 @@ namespace android {
// Property getters
<% for (const property of properties) { -%>
+<% if (property.name != 'heatmap-color') { -%>
jni::Object<jni::ObjectTag> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>(jni::JNIEnv& env) {
using namespace mbgl::android::conversion;
Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::<%- camelize(type) %>Layer>()-><%- camelize(type) %>Layer::get<%- camelize(property.name) %>());
return jni::Object<jni::ObjectTag>(*converted);
}
+<% } else { -%>
+ jni::Object<jni::ObjectTag> HeatmapLayer::getHeatmapColor(jni::JNIEnv& env) {
+ using namespace mbgl::android::conversion;
+ auto propertyValue = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapColor();
+ if (propertyValue.isUndefined()) {
+ propertyValue = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getDefaultHeatmapColor();
+ }
+ Result<jni::jobject*> converted = convert<jni::jobject*>(env, propertyValue);
+ return jni::Object<jni::ObjectTag>(*converted);
+ }
+
+<% } -%>
<% if (property.transition) { -%>
jni::Object<TransitionOptions> <%- camelize(type) %>Layer::get<%- camelize(property.name) %>Transition(jni::JNIEnv& env) {
using namespace mbgl::android::conversion;
diff --git a/platform/android/src/style/layers/layer.hpp b/platform/android/src/style/layers/layer.hpp
index 78c3f80b48..2486b0dfa6 100644
--- a/platform/android/src/style/layers/layer.hpp
+++ b/platform/android/src/style/layers/layer.hpp
@@ -3,8 +3,9 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/style/layer.hpp>
-
+#include "../../gson/json_array.hpp"
#include "../value.hpp"
+#include "../../gson/json_element.hpp"
#include <jni/jni.hpp>
@@ -68,6 +69,8 @@ public:
void setFilter(jni::JNIEnv&, jni::Array<jni::Object<>>);
+ jni::Object<gson::JsonElement> getFilter(jni::JNIEnv&);
+
void setSourceLayer(jni::JNIEnv&, jni::String);
jni::String getSourceLayer(jni::JNIEnv&);
diff --git a/platform/android/src/text/local_glyph_rasterizer.cpp b/platform/android/src/text/local_glyph_rasterizer.cpp
index ce1b0fc8fd..d232058d15 100644
--- a/platform/android/src/text/local_glyph_rasterizer.cpp
+++ b/platform/android/src/text/local_glyph_rasterizer.cpp
@@ -46,6 +46,7 @@ PremultipliedImage LocalGlyphRasterizer::drawGlyphBitmap(const std::string& font
jniFontFamily,
static_cast<jni::jboolean>(bold),
static_cast<jni::jchar>(glyphID));
+ jni::DeleteLocalRef(*env, jniFontFamily);
PremultipliedImage result = Bitmap::GetImage(*env, javaBitmap);
jni::DeleteLocalRef(*env, javaBitmap);