diff options
author | Langston Smith <langston.smith@mapbox.com> | 2018-03-05 17:56:29 -0800 |
---|---|---|
committer | Langston Smith <langston.smith@mapbox.com> | 2018-03-05 17:56:29 -0800 |
commit | aab4b971509f6f76943e2578cb13addc13ae079b (patch) | |
tree | f671cbf3dc5c7d5078423704df165eeb070f4d0f /platform/android/src | |
parent | 6996e2d81abb8ea2ad23a6efe1502809bbe7e882 (diff) | |
parent | 136e536159a1e22aa4a92c4e6463893600b809d0 (diff) | |
download | qtlocation-mapboxgl-aab4b971509f6f76943e2578cb13addc13ae079b.tar.gz |
Merge branch 'master' into ls-android-readme-snapshot-dependency-line-cleanup
Diffstat (limited to 'platform/android/src')
39 files changed, 585 insertions, 271 deletions
diff --git a/platform/android/src/android_renderer_frontend.cpp b/platform/android/src/android_renderer_frontend.cpp index afdb08a10e..2a03d9de9e 100644 --- a/platform/android/src/android_renderer_frontend.cpp +++ b/platform/android/src/android_renderer_frontend.cpp @@ -77,8 +77,8 @@ void AndroidRendererFrontend::update(std::shared_ptr<UpdateParameters> params) { mapRenderer.requestRender(); } -void AndroidRendererFrontend::onLowMemory() { - mapRenderer.actor().invoke(&Renderer::onLowMemory); +void AndroidRendererFrontend::reduceMemoryUse() { + mapRenderer.actor().invoke(&Renderer::reduceMemoryUse); } std::vector<Feature> AndroidRendererFrontend::querySourceFeatures(const std::string& sourceID, diff --git a/platform/android/src/android_renderer_frontend.hpp b/platform/android/src/android_renderer_frontend.hpp index 178870c452..b61904e388 100644 --- a/platform/android/src/android_renderer_frontend.hpp +++ b/platform/android/src/android_renderer_frontend.hpp @@ -39,7 +39,7 @@ public: AnnotationIDs queryShapeAnnotations(const ScreenBox& box) const; // Memory - void onLowMemory(); + void reduceMemoryUse(); private: MapRenderer& mapRenderer; diff --git a/platform/android/src/conversion/collection.hpp b/platform/android/src/conversion/collection.hpp index 549121c7ef..2b953e73f4 100644 --- a/platform/android/src/conversion/collection.hpp +++ b/platform/android/src/conversion/collection.hpp @@ -28,6 +28,7 @@ inline jni::jobject* toArrayList(JNIEnv& env, jni::jarray<T>& array) { inline std::vector<std::string> toVector(JNIEnv& env, jni::jarray<jni::jobject>& array) { std::vector<std::string> vector; std::size_t len = jni::GetArrayLength(env, array); + vector.reserve(len); for (std::size_t i = 0; i < len; i++) { jni::jstring* jstr = reinterpret_cast<jni::jstring*>(jni::GetObjectArrayElement(env, array, i)); diff --git a/platform/android/src/example_custom_layer.cpp b/platform/android/src/example_custom_layer.cpp index 1ed68d0835..f7b425c40a 100644 --- a/platform/android/src/example_custom_layer.cpp +++ b/platform/android/src/example_custom_layer.cpp @@ -1,17 +1,121 @@ #include <jni.h> #include <GLES2/gl2.h> +#include <sstream> +#include <android/log.h> +#include <mbgl/style/layers/custom_layer.hpp> -#include <mbgl/util/logging.hpp> +// DEBUGGING -#include <mbgl/style/layers/custom_layer.hpp> +const char* LOG_TAG = "Custom Layer Example"; + +const char* stringFromError(GLenum err) { + switch (err) { + case GL_INVALID_ENUM: + return "GL_INVALID_ENUM"; + + case GL_INVALID_VALUE: + return "GL_INVALID_VALUE"; + + case GL_INVALID_OPERATION: + return "GL_INVALID_OPERATION"; + + case GL_INVALID_FRAMEBUFFER_OPERATION: + return "GL_INVALID_FRAMEBUFFER_OPERATION"; + + case GL_OUT_OF_MEMORY: + return "GL_OUT_OF_MEMORY"; + +#ifdef GL_TABLE_TOO_LARGE + case GL_TABLE_TOO_LARGE: + return "GL_TABLE_TOO_LARGE"; +#endif + +#ifdef GL_STACK_OVERFLOW + case GL_STACK_OVERFLOW: + return "GL_STACK_OVERFLOW"; +#endif + +#ifdef GL_STACK_UNDERFLOW + case GL_STACK_UNDERFLOW: + return "GL_STACK_UNDERFLOW"; +#endif + +#ifdef GL_CONTEXT_LOST + case GL_CONTEXT_LOST: + return "GL_CONTEXT_LOST"; +#endif + + default: + return "GL_UNKNOWN"; + } +} + +struct Error : std::runtime_error { + using std::runtime_error::runtime_error; +}; + +void checkError(const char *cmd, const char *file, int line) { + + GLenum err = GL_NO_ERROR; + if ((err = glGetError()) != GL_NO_ERROR) { + std::ostringstream message; + message << cmd << ": Error " << stringFromError(err); + + // Check for further errors + while ((err = glGetError()) != GL_NO_ERROR) { + message << ", " << stringFromError(err); + } + + message << " at " << file << ":" << line; + __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, message.str().c_str()); + throw Error(message.str()); + } +} + +#ifndef NDEBUG +#define GL_CHECK_ERROR(cmd) ([&]() { struct __MBGL_C_E { ~__MBGL_C_E() noexcept(false) { checkError(#cmd, __FILE__, __LINE__); } } __MBGL_C_E; return cmd; }()) +#else +#define GL_CHECK_ERROR(cmd) (cmd) +#endif + +void checkLinkStatus(GLuint program) { + GLint isLinked = 0; + glGetProgramiv(program, GL_LINK_STATUS, &isLinked); + if (isLinked == GL_FALSE) { + GLint maxLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength); + GLchar infoLog[maxLength]; + glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]); + __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, &infoLog[0]); + throw Error(infoLog); + } + +} + +void checkCompileStatus(GLuint shader) { + GLint isCompiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled); + if (isCompiled == GL_FALSE) { + GLint maxLength = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength); + + // The maxLength includes the NULL character + GLchar errorLog[maxLength]; + glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]); + __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, &errorLog[0]); + throw Error(errorLog); + } +} + +// /DEBUGGING static const GLchar * vertexShaderSource = "attribute vec2 a_pos; void main() { gl_Position = vec4(a_pos, 0, 1); }"; -static const GLchar * fragmentShaderSource = "uniform vec4 fill_color; void main() { gl_FragColor = fill_color; }"; +static const GLchar * fragmentShaderSource = "uniform highp vec4 fill_color; void main() { gl_FragColor = fill_color; }"; class ExampleCustomLayer { public: ~ExampleCustomLayer() { - mbgl::Log::Info(mbgl::Event::General, "~ExampleCustomLayer"); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "~ExampleCustomLayer"); if (program) { glDeleteBuffers(1, &buffer); glDetachShader(program, vertexShader); @@ -23,38 +127,49 @@ public: } void initialize() { - mbgl::Log::Info(mbgl::Event::General, "Initialize"); - program = glCreateProgram(); - vertexShader = glCreateShader(GL_VERTEX_SHADER); - fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - - glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr); - glCompileShader(vertexShader); - glAttachShader(program, vertexShader); - glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr); - glCompileShader(fragmentShader); - glAttachShader(program, fragmentShader); - glLinkProgram(program); - a_pos = glGetAttribLocation(program, "a_pos"); - fill_color = glGetUniformLocation(program, "fill_color"); - - GLfloat background[] = { -1,-1, 1,-1, -1,1, 1,1 }; - glGenBuffers(1, &buffer); - glBindBuffer(GL_ARRAY_BUFFER, buffer); - glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "Initialize"); + + // Debug info + int maxAttrib; + GL_CHECK_ERROR(glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxAttrib)); + __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "Max vertex attributes: %i", maxAttrib); + + program = GL_CHECK_ERROR(glCreateProgram()); + vertexShader = GL_CHECK_ERROR(glCreateShader(GL_VERTEX_SHADER)); + fragmentShader = GL_CHECK_ERROR(glCreateShader(GL_FRAGMENT_SHADER)); + + GL_CHECK_ERROR(glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr)); + GL_CHECK_ERROR(glCompileShader(vertexShader)); + checkCompileStatus(vertexShader); + GL_CHECK_ERROR(glAttachShader(program, vertexShader)); + GL_CHECK_ERROR(glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr)); + GL_CHECK_ERROR(glCompileShader(fragmentShader)); + checkCompileStatus(fragmentShader); + GL_CHECK_ERROR(glAttachShader(program, fragmentShader)); + GL_CHECK_ERROR(glLinkProgram(program)); + checkLinkStatus(program); + + a_pos = GL_CHECK_ERROR(glGetAttribLocation(program, "a_pos")); + fill_color = GL_CHECK_ERROR(glGetUniformLocation(program, "fill_color")); + + GLfloat background[] = { -1, -1, 1, -1, -1, 1, 1, 1 }; + GL_CHECK_ERROR(glGenBuffers(1, &buffer)); + GL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer)); + GL_CHECK_ERROR(glBufferData(GL_ARRAY_BUFFER, 8 * sizeof(GLfloat), background, GL_STATIC_DRAW)); } void render() { - mbgl::Log::Info(mbgl::Event::General, "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); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "Render"); + + GL_CHECK_ERROR(glUseProgram(program)); + GL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, buffer)); + GL_CHECK_ERROR(glEnableVertexAttribArray(a_pos)); + GL_CHECK_ERROR(glVertexAttribPointer(a_pos, 2, GL_FLOAT, GL_FALSE, 0, NULL)); + GL_CHECK_ERROR(glDisable(GL_STENCIL_TEST)); + GL_CHECK_ERROR(glDisable(GL_DEPTH_TEST)); + GL_CHECK_ERROR(glUniform4fv(fill_color, 1, color)); + GL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)); + } GLuint program = 0; @@ -70,12 +185,12 @@ public: GLfloat ExampleCustomLayer::color[] = { 0.0f, 1.0f, 0.0f, 1.0f }; jlong JNICALL nativeCreateContext(JNIEnv*, jobject) { - mbgl::Log::Info(mbgl::Event::General, "nativeCreateContext"); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeCreateContext"); return reinterpret_cast<jlong>(new ExampleCustomLayer()); } void JNICALL nativeSetColor(JNIEnv*, jobject, jfloat red, jfloat green, jfloat blue, jfloat alpha) { - mbgl::Log::Info(mbgl::Event::General, "nativeSetColor: %.2f, %.2f, %.2f, %.2f", red, green, blue, alpha); + __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "nativeSetColor: %.2f, %.2f, %.2f, %.2f", red, green, blue, alpha); ExampleCustomLayer::color[0] = red; ExampleCustomLayer::color[1] = green; ExampleCustomLayer::color[2] = blue; @@ -83,26 +198,27 @@ void JNICALL nativeSetColor(JNIEnv*, jobject, jfloat red, jfloat green, jfloat b } void nativeInitialize(void *context) { - mbgl::Log::Info(mbgl::Event::General, "nativeInitialize"); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeInitialize"); reinterpret_cast<ExampleCustomLayer*>(context)->initialize(); } void nativeRender(void *context, const mbgl::style::CustomLayerRenderParameters& /*parameters*/) { - mbgl::Log::Info(mbgl::Event::General, "nativeRender"); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeRender"); reinterpret_cast<ExampleCustomLayer*>(context)->render(); } void nativeContextLost(void */*context*/) { - mbgl::Log::Info(mbgl::Event::General, "nativeContextLost"); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "nativeContextLost"); } -void nativeDenitialize(void *context) { - mbgl::Log::Info(mbgl::Event::General, "nativeDeinitialize"); +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 *) { - mbgl::Log::Info(mbgl::Event::General, "OnLoad"); + __android_log_write(ANDROID_LOG_INFO, LOG_TAG, "OnLoad"); + JNIEnv *env = nullptr; vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6); @@ -132,7 +248,7 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { env->SetStaticLongField(customLayerClass, env->GetStaticFieldID(customLayerClass, "DeinitializeFunction", "J"), - reinterpret_cast<jlong>(nativeDenitialize)); + 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 6a9d7badb0..42c03b0974 100644 --- a/platform/android/src/file_source.cpp +++ b/platform/android/src/file_source.cpp @@ -81,6 +81,13 @@ void FileSource::pause(jni::JNIEnv&) { } } +jni::jboolean FileSource::isResumed(jni::JNIEnv&) { + if (activationCounter) { + return (jboolean) (activationCounter > 0); + } + return (jboolean) false; +} + jni::Class<FileSource> FileSource::javaClass; FileSource* FileSource::getNativePeer(jni::JNIEnv& env, jni::Object<FileSource> jFileSource) { @@ -112,7 +119,8 @@ void FileSource::registerNative(jni::JNIEnv& env) { METHOD(&FileSource::setAPIBaseUrl, "setApiBaseUrl"), METHOD(&FileSource::setResourceTransform, "setResourceTransform"), METHOD(&FileSource::resume, "activate"), - METHOD(&FileSource::pause, "deactivate") + METHOD(&FileSource::pause, "deactivate"), + METHOD(&FileSource::isResumed, "isActivated") ); } @@ -124,8 +132,11 @@ jni::Class<FileSource::ResourceTransformCallback> FileSource::ResourceTransformC std::string FileSource::ResourceTransformCallback::onURL(jni::JNIEnv& env, jni::Object<FileSource::ResourceTransformCallback> callback, int kind, std::string url_) { static auto method = FileSource::ResourceTransformCallback::javaClass.GetMethod<jni::String (jni::jint, jni::String)>(env, "onURL"); auto url = jni::Make<jni::String>(env, url_); + url = callback.Call(env, method, kind, url); - return jni::Make<std::string>(env, url); + auto urlStr = jni::Make<std::string>(env, url); + jni::DeleteLocalRef(env, url); + return urlStr; } } // namespace android diff --git a/platform/android/src/file_source.hpp b/platform/android/src/file_source.hpp index 194f784622..e4295e1b84 100644 --- a/platform/android/src/file_source.hpp +++ b/platform/android/src/file_source.hpp @@ -45,6 +45,8 @@ public: void pause(jni::JNIEnv&); + jni::jboolean isResumed(jni::JNIEnv&); + static jni::Class<FileSource> javaClass; static FileSource* getNativePeer(jni::JNIEnv&, jni::Object<FileSource>); diff --git a/platform/android/src/geojson/conversion/geometry.hpp b/platform/android/src/geojson/conversion/geometry.hpp index 2ca63e2c11..5d2aab4c2d 100644 --- a/platform/android/src/geojson/conversion/geometry.hpp +++ b/platform/android/src/geojson/conversion/geometry.hpp @@ -21,88 +21,91 @@ public: jni::JNIEnv& env; /** - * Point (double[]) + * 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/services/commons/geojson/Point")).release(); - static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([D)Lcom/mapbox/services/commons/geojson/Point;"); + 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;"); - // Create Point - jni::LocalObject<jni::jarray<jni::jdouble>> position = jni::NewLocalObject(env, toGeoJsonPosition(env, geometry.x, geometry.y)); - return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, position.get())); + return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLat, geometry.x, geometry.y)); } /** - * LineString (double[][]) + * 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/services/commons/geojson/LineString")).release(); - static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[D)Lcom/mapbox/services/commons/geojson/LineString;"); + 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::jarray<jni::jobject>> coordinates = jni::NewLocalObject(env, toGeoJsonCoordinates(env, geometry)); - return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, coordinates.get())); + 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())); } /** - * MultiPoint (double[][]) + * 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/services/commons/geojson/MultiPoint")).release(); - static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[D)Lcom/mapbox/services/commons/geojson/MultiPoint;"); + 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::jarray<jni::jobject>> coordinates = jni::NewLocalObject(env, toGeoJsonCoordinates(env, geometry)); - return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, coordinates.get())); + 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())); } /** - * Polygon (double[][][]) + * 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/services/commons/geojson/Polygon")).release(); - static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[[D)Lcom/mapbox/services/commons/geojson/Polygon;"); + 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::jarray<jni::jobject>> shape = jni::NewLocalObject(env, toShape<>(env, geometry)); - return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, shape.get())); + 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())); } /** - * MultiLineString (double[][][]) + * 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/services/commons/geojson/MultiLineString")).release(); - static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[[D)Lcom/mapbox/services/commons/geojson/MultiLineString;"); + 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::jarray<jni::jobject>> shape = jni::NewLocalObject(env, toShape<>(env, geometry)); - return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, shape.get())); + 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 { - static jni::jclass* listClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[[[D")).release(); - jni::LocalObject<jni::jarray<jni::jobject>> jarray = jni::NewLocalObject(env, &jni::NewObjectArray(env, geometry.size(), *listClass)); + // 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::jarray<jni::jobject>> shape = jni::NewLocalObject(env, toShape<>(env, geometry.at(i))); - jni::SetObjectArrayElement(env, *jarray, i, shape.get()); + 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/services/commons/geojson/MultiPolygon")).release(); - static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[[[D)Lcom/mapbox/services/commons/geojson/MultiPolygon;"); - return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromGeometries, jarray.get())); + 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/services/commons/geojson/Geometry")).release(); + 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) { @@ -112,8 +115,8 @@ public: } // Turn into array list and create the GeometryCollection - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/GeometryCollection")).release(); - static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromGeometries", "(Ljava/util/List;)Lcom/mapbox/services/commons/geojson/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())); @@ -122,47 +125,50 @@ public: private: /** - * x, y -> jarray<jdouble> ([x,y]) - */ - static jni::jarray<jni::jdouble>* toGeoJsonPosition(JNIEnv& env, double x, double y) { - jni::jarray<jni::jdouble>& jarray = jni::NewArray<jni::jdouble>(env, 2); - jni::jdouble array[] = {x, y}; - jni::SetArrayRegion(env, jarray, 0, 2, array); - return &jarray; - } + * vector<point<T>> -> List<Point> + */ + static jni::jobject* toGeoJsonListOfPoints(JNIEnv& env, std::vector<mapbox::geometry::point<T>> points) { - /** - * vector<point<T>> -> jarray<jobject> (double[][]) -> [D + Object array == [[D - */ - static jni::jarray<jni::jobject>* toGeoJsonCoordinates(JNIEnv& env, std::vector<mapbox::geometry::point<T>> points) { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[D")).release(); - jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, points.size(), *javaClass); + // 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::jarray<jni::jdouble>> position = jni::NewLocalObject(env, toGeoJsonPosition(env, point.x, point.y)); - jni::SetObjectArrayElement(env, jarray, i, position.get()); + 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 &jarray; + return arrayList; } /** - * polygon<T> - * multi_line_string<T> - * -> jarray<jobject> (double[][][]) -> [[D + Object array == [[[D + * geometry -> List<List<Point>> */ template <class SHAPE> - static jni::jarray<jni::jobject>* toShape(JNIEnv& env, SHAPE value) { - static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[[D")).release(); - jni::jarray<jni::jobject>& jarray = jni::NewObjectArray(env, value.size(), *javaClass); + 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::jarray<jni::jobject>> coordinates = jni::NewLocalObject(env, toGeoJsonCoordinates(env, value.at(i))); - jni::SetObjectArrayElement(env, jarray, i, coordinates.get()); + jni::LocalObject<jni::jobject> listOfPoints = jni::NewLocalObject(env, toGeoJsonListOfPoints(env, value.at(i))); + jni::CallMethod<void>(env, arrayList, *add, i, listOfPoints.get()); } - return &jarray; + return arrayList; } }; diff --git a/platform/android/src/geojson/feature.cpp b/platform/android/src/geojson/feature.cpp index a6b387cd15..d8a4e829e2 100644 --- a/platform/android/src/geojson/feature.cpp +++ b/platform/android/src/geojson/feature.cpp @@ -8,11 +8,11 @@ namespace geojson { mbgl::Feature Feature::convert(jni::JNIEnv& env, jni::Object<Feature> jFeature) { // Convert - auto jGeometry = getGeometry(env, jFeature); - auto jProperties = Feature::getProperties(env, jFeature); + auto jGeometry = geometry(env, jFeature); + auto jProperties = Feature::properties(env, jFeature); std::experimental::optional<mapbox::geometry::identifier> id; - auto jId = Feature::getId(env, jFeature); + auto jId = Feature::id(env, jFeature); if (jId) { id = { jni::Make<std::string>(env, jId) }; } @@ -31,18 +31,18 @@ mbgl::Feature Feature::convert(jni::JNIEnv& env, jni::Object<Feature> jFeature) return feature; } -jni::Object<Geometry> Feature::getGeometry(jni::JNIEnv& env, jni::Object<Feature> jFeature) { - static auto method = Feature::javaClass.GetMethod<jni::Object<Geometry> ()>(env, "getGeometry"); +jni::Object<Geometry> Feature::geometry(jni::JNIEnv& env, jni::Object<Feature> jFeature) { + static auto method = Feature::javaClass.GetMethod<jni::Object<Geometry> ()>(env, "geometry"); return jFeature.Call(env, method); } -jni::Object<gson::JsonObject> Feature::getProperties(jni::JNIEnv& env, jni::Object<Feature> jFeature) { - static auto method = Feature::javaClass.GetMethod<jni::Object<gson::JsonObject> ()>(env, "getProperties"); +jni::Object<gson::JsonObject> Feature::properties(jni::JNIEnv& env, jni::Object<Feature> jFeature) { + static auto method = Feature::javaClass.GetMethod<jni::Object<gson::JsonObject> ()>(env, "properties"); return jFeature.Call(env, method); } -jni::String Feature::getId(jni::JNIEnv& env, jni::Object<Feature> jFeature) { - static auto method = Feature::javaClass.GetMethod<jni::String ()>(env, "getId"); +jni::String Feature::id(jni::JNIEnv& env, jni::Object<Feature> jFeature) { + static auto method = Feature::javaClass.GetMethod<jni::String ()>(env, "id"); return jFeature.Call(env, method); } diff --git a/platform/android/src/geojson/feature.hpp b/platform/android/src/geojson/feature.hpp index b5d856cc42..ab59d783e5 100644 --- a/platform/android/src/geojson/feature.hpp +++ b/platform/android/src/geojson/feature.hpp @@ -16,17 +16,17 @@ namespace geojson { class Feature : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/Feature"; }; + static constexpr auto Name() { return "com/mapbox/geojson/Feature"; }; static jni::Object<Feature> fromGeometry(jni::JNIEnv&, jni::Object<Geometry>, jni::Object<gson::JsonObject>, jni::String); static mbgl::Feature convert(jni::JNIEnv&, jni::Object<Feature>); - static jni::Object<Geometry> getGeometry(jni::JNIEnv&, jni::Object<Feature>); + static jni::Object<Geometry> geometry(jni::JNIEnv&, jni::Object<Feature>); - static jni::String getId(jni::JNIEnv&, jni::Object<Feature>); + static jni::String id(jni::JNIEnv&, jni::Object<Feature>); - static jni::Object<gson::JsonObject> getProperties(jni::JNIEnv&, jni::Object<Feature>); + static jni::Object<gson::JsonObject> properties(jni::JNIEnv&, jni::Object<Feature>); static jni::Class<Feature> javaClass; diff --git a/platform/android/src/geojson/feature_collection.cpp b/platform/android/src/geojson/feature_collection.cpp index 2f156532ae..18a41d48fa 100644 --- a/platform/android/src/geojson/feature_collection.cpp +++ b/platform/android/src/geojson/feature_collection.cpp @@ -7,24 +7,28 @@ namespace android { namespace geojson { mbgl::FeatureCollection FeatureCollection::convert(jni::JNIEnv& env, jni::Object<FeatureCollection> jCollection) { - auto jFeatureList = FeatureCollection::getFeatures(env, jCollection); - auto jFeatures = java::util::List::toArray<Feature>(env, jFeatureList); - auto size = size_t(jFeatures.Length(env)); - auto collection = mbgl::FeatureCollection(); - collection.reserve(size); - for (size_t i = 0; i < size; i++) { - auto jFeature = jFeatures.Get(env, i); - collection.push_back(Feature::convert(env, jFeature)); - jni::DeleteLocalRef(env, jFeature); - } + if (jCollection) { + auto jFeatureList = FeatureCollection::features(env, jCollection); + auto jFeatures = java::util::List::toArray<Feature>(env, jFeatureList); + auto size = size_t(jFeatures.Length(env)); + collection.reserve(size); + for (size_t i = 0; i < size; i++) { + auto jFeature = jFeatures.Get(env, i); + collection.push_back(Feature::convert(env, jFeature)); + jni::DeleteLocalRef(env, jFeature); + } + + jni::DeleteLocalRef(env, jFeatures); + jni::DeleteLocalRef(env, jFeatureList); + } return collection; } -jni::Object<java::util::List> FeatureCollection::getFeatures(jni::JNIEnv& env, jni::Object<FeatureCollection> jCollection) { - static auto method = FeatureCollection::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getFeatures"); +jni::Object<java::util::List> FeatureCollection::features(jni::JNIEnv& env, jni::Object<FeatureCollection> jCollection) { + static auto method = FeatureCollection::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "features"); return jCollection.Call(env, method); } diff --git a/platform/android/src/geojson/feature_collection.hpp b/platform/android/src/geojson/feature_collection.hpp index 8e9717e82b..259ffab370 100644 --- a/platform/android/src/geojson/feature_collection.hpp +++ b/platform/android/src/geojson/feature_collection.hpp @@ -13,11 +13,11 @@ namespace geojson { class FeatureCollection : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/FeatureCollection"; }; + static constexpr auto Name() { return "com/mapbox/geojson/FeatureCollection"; }; static mbgl::FeatureCollection convert(jni::JNIEnv&, jni::Object<FeatureCollection>); - static jni::Object<java::util::List> getFeatures(jni::JNIEnv&, jni::Object<FeatureCollection>); + static jni::Object<java::util::List> features(jni::JNIEnv&, jni::Object<FeatureCollection>); static jni::Class<FeatureCollection> javaClass; diff --git a/platform/android/src/geojson/geometry.cpp b/platform/android/src/geojson/geometry.cpp index 33bb4ee3db..ca19d8fb03 100644 --- a/platform/android/src/geojson/geometry.cpp +++ b/platform/android/src/geojson/geometry.cpp @@ -33,7 +33,7 @@ mapbox::geojson::geometry Geometry::convert(jni::JNIEnv &env, jni::Object<Geomet } std::string Geometry::getType(jni::JNIEnv &env, jni::Object<Geometry> jGeometry) { - static auto method = Geometry::javaClass.GetMethod<jni::String ()>(env, "getType"); + static auto method = Geometry::javaClass.GetMethod<jni::String ()>(env, "type"); auto jType = jGeometry.Call(env, method); auto type = jni::Make<std::string>(env, jType); jni::DeleteLocalRef(env, jType); diff --git a/platform/android/src/geojson/geometry.hpp b/platform/android/src/geojson/geometry.hpp index bdcff6bb3e..b7f8909f6f 100644 --- a/platform/android/src/geojson/geometry.hpp +++ b/platform/android/src/geojson/geometry.hpp @@ -11,7 +11,7 @@ namespace geojson { class Geometry : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/Geometry"; }; + static constexpr auto Name() { return "com/mapbox/geojson/Geometry"; }; static mapbox::geojson::geometry convert(jni::JNIEnv&, jni::Object<Geometry>); diff --git a/platform/android/src/geojson/line_string.cpp b/platform/android/src/geojson/line_string.cpp index d0719f2538..8eebd53550 100644 --- a/platform/android/src/geojson/line_string.cpp +++ b/platform/android/src/geojson/line_string.cpp @@ -1,6 +1,6 @@ #include "line_string.hpp" -#include "position.hpp" +#include "point.hpp" namespace mbgl { namespace android { @@ -10,35 +10,36 @@ mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<L mapbox::geojson::line_string lineString; if (jLineString) { - auto jPositionList = LineString::getCoordinates(env, jLineString); - lineString = LineString::convert(env, jPositionList); - jni::DeleteLocalRef(env, jPositionList); + auto jPointList = LineString::coordinates(env, jLineString); + lineString = LineString::convert(env, jPointList); + jni::DeleteLocalRef(env, jPointList); } return lineString; } -mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<Position>*/> jPositionList) { +mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<Point>*/> jPointList) { mapbox::geojson::line_string lineString; - if (jPositionList) { - auto jPositionArray = java::util::List::toArray<Position>(env, jPositionList); + if (jPointList) { + auto jPointArray = java::util::List::toArray<Point>(env, jPointList); + auto size = jPointArray.Length(env); + lineString.reserve(size); - auto size = jPositionArray.Length(env); for (std::size_t i = 0; i < size; i++) { - auto jPosition = jPositionArray.Get(env, i); - lineString.push_back(Position::convert(env, jPosition)); - jni::DeleteLocalRef(env, jPosition); + auto jPoint = jPointArray.Get(env, i); + lineString.push_back(Point::convert(env, jPoint)); + jni::DeleteLocalRef(env, jPoint); } - jni::DeleteLocalRef(env, jPositionArray); + jni::DeleteLocalRef(env, jPointArray); } return lineString; } -jni::Object<java::util::List> LineString::getCoordinates(jni::JNIEnv &env, jni::Object<LineString> jLineString) { - static auto method = LineString::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +jni::Object<java::util::List> LineString::coordinates(jni::JNIEnv &env, jni::Object<LineString> jLineString) { + static auto method = LineString::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "coordinates"); return jLineString.Call(env, method); } diff --git a/platform/android/src/geojson/line_string.hpp b/platform/android/src/geojson/line_string.hpp index d3be68d0a5..86033c2e6a 100644 --- a/platform/android/src/geojson/line_string.hpp +++ b/platform/android/src/geojson/line_string.hpp @@ -14,15 +14,15 @@ namespace geojson { class LineString : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/LineString"; }; + static constexpr auto Name() { return "com/mapbox/geojson/LineString"; }; static constexpr auto Type() { return "LineString"; }; static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<LineString>); - static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<Position>*/>); + static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<Point>*/>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<LineString>); + static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<LineString>); static jni::Class<LineString> javaClass; diff --git a/platform/android/src/geojson/multi_line_string.cpp b/platform/android/src/geojson/multi_line_string.cpp index b676144bf5..c748d4786f 100644 --- a/platform/android/src/geojson/multi_line_string.cpp +++ b/platform/android/src/geojson/multi_line_string.cpp @@ -10,27 +10,27 @@ mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jn mapbox::geojson::multi_line_string multiLineString; if (jMultiLineString) { - auto jPositionListsList = MultiLineString::getCoordinates(env, jMultiLineString); - multiLineString = MultiLineString::convert(env, jPositionListsList); - jni::DeleteLocalRef(env, jPositionListsList); + auto jPointListsList = MultiLineString::coordinates(env, jMultiLineString); + multiLineString = MultiLineString::convert(env, jPointListsList); + jni::DeleteLocalRef(env, jPointListsList); } return multiLineString; } -mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<java::util::List<Position>>*/> jPositionListsList) { +mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<java::util::List<Point>>*/> jPointListsList) { mapbox::geojson::multi_line_string multiLineString; - if (jPositionListsList) { - auto jPositionListsArray = java::util::List::toArray<java::util::List>(env, jPositionListsList); + if (jPointListsList) { + auto jPositionListsArray = java::util::List::toArray<java::util::List>(env, jPointListsList); auto size = jPositionListsArray.Length(env); multiLineString.reserve(size); for (std::size_t i = 0; i < size; i++) { - auto jPositionList = jPositionListsArray.Get(env, i); - multiLineString.push_back(LineString::convert(env, jPositionList)); - jni::DeleteLocalRef(env, jPositionList); + auto jPointsList = jPositionListsArray.Get(env, i); + multiLineString.push_back(LineString::convert(env, jPointsList)); + jni::DeleteLocalRef(env, jPointsList); } jni::DeleteLocalRef(env, jPositionListsArray); @@ -39,8 +39,8 @@ mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jn return multiLineString; } -jni::Object<java::util::List> MultiLineString::getCoordinates(jni::JNIEnv &env, jni::Object<MultiLineString> jLineString) { - static auto method = MultiLineString::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +jni::Object<java::util::List> MultiLineString::coordinates(jni::JNIEnv &env, jni::Object<MultiLineString> jLineString) { + static auto method = MultiLineString::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "coordinates"); return jLineString.Call(env, method); } diff --git a/platform/android/src/geojson/multi_line_string.hpp b/platform/android/src/geojson/multi_line_string.hpp index af33fe72d6..358a6b5dda 100644 --- a/platform/android/src/geojson/multi_line_string.hpp +++ b/platform/android/src/geojson/multi_line_string.hpp @@ -13,15 +13,15 @@ namespace geojson { class MultiLineString : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/MultiLineString"; }; + static constexpr auto Name() { return "com/mapbox/geojson/MultiLineString"; }; static constexpr auto Type() { return "MultiLineString"; }; 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<Position>>*/>); + static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Point>>*/>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<MultiLineString>); + static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiLineString>); static jni::Class<MultiLineString> javaClass; diff --git a/platform/android/src/geojson/multi_point.cpp b/platform/android/src/geojson/multi_point.cpp index f3acdb1ea6..4f9ff596b2 100644 --- a/platform/android/src/geojson/multi_point.cpp +++ b/platform/android/src/geojson/multi_point.cpp @@ -12,16 +12,16 @@ mapbox::geojson::multi_point MultiPoint::convert(jni::JNIEnv &env, jni::Object<M mapbox::geojson::multi_point multiPoint; if (jMultiPoint) { - auto jPositionListsList = MultiPoint::getCoordinates(env, jMultiPoint); - multiPoint = convertExplicit<mapbox::geojson::multi_point>(LineString::convert(env, jPositionListsList)); - jni::DeleteLocalRef(env, jPositionListsList); + auto jPointListsList = MultiPoint::coordinates(env, jMultiPoint); + multiPoint = convertExplicit<mapbox::geojson::multi_point>(LineString::convert(env, jPointListsList)); + jni::DeleteLocalRef(env, jPointListsList); } return multiPoint; } -jni::Object<java::util::List> MultiPoint::getCoordinates(jni::JNIEnv &env, jni::Object<MultiPoint> jMultiPoint) { - static auto method = MultiPoint::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +jni::Object<java::util::List> MultiPoint::coordinates(jni::JNIEnv &env, jni::Object<MultiPoint> jMultiPoint) { + static auto method = MultiPoint::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "coordinates"); return jMultiPoint.Call(env, method); } diff --git a/platform/android/src/geojson/multi_point.hpp b/platform/android/src/geojson/multi_point.hpp index 7a698287eb..e893e879af 100644 --- a/platform/android/src/geojson/multi_point.hpp +++ b/platform/android/src/geojson/multi_point.hpp @@ -13,13 +13,13 @@ namespace geojson { class MultiPoint : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/MultiPoint"; }; + static constexpr auto Name() { return "com/mapbox/geojson/MultiPoint"; }; static constexpr auto Type() { return "MultiPoint"; }; static mapbox::geojson::multi_point convert(jni::JNIEnv&, jni::Object<MultiPoint>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<MultiPoint>); + static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiPoint>); static jni::Class<MultiPoint> javaClass; diff --git a/platform/android/src/geojson/multi_polygon.cpp b/platform/android/src/geojson/multi_polygon.cpp index a55884a110..aadba8c8a6 100644 --- a/platform/android/src/geojson/multi_polygon.cpp +++ b/platform/android/src/geojson/multi_polygon.cpp @@ -10,27 +10,27 @@ mapbox::geojson::multi_polygon MultiPolygon::convert(jni::JNIEnv &env, jni::Obje mapbox::geojson::multi_polygon multiPolygon; if (jMultiPolygon) { - auto jPositionListsListList = MultiPolygon::getCoordinates(env, jMultiPolygon); - auto jPositionListsListArray = java::util::List::toArray<java::util::List>(env, jPositionListsListList); + auto jPointListsListList = MultiPolygon::coordinates(env, jMultiPolygon); + auto jPointListsListArray = java::util::List::toArray<java::util::List>(env, jPointListsListList); - auto size = jPositionListsListArray.Length(env); + auto size = jPointListsListArray.Length(env); multiPolygon.reserve(size); for (size_t i = 0; i < size; i++) { - auto jPositionListsList = jPositionListsListArray.Get(env, i); + auto jPositionListsList = jPointListsListArray.Get(env, i); multiPolygon.push_back(Polygon::convert(env, jPositionListsList)); jni::DeleteLocalRef(env, jPositionListsList); } - jni::DeleteLocalRef(env, jPositionListsListList); - jni::DeleteLocalRef(env, jPositionListsListArray); + jni::DeleteLocalRef(env, jPointListsListArray); + jni::DeleteLocalRef(env, jPointListsListList); } return multiPolygon; } -jni::Object<java::util::List> MultiPolygon::getCoordinates(jni::JNIEnv &env, jni::Object<MultiPolygon> jPolygon) { - static auto method = MultiPolygon::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +jni::Object<java::util::List> MultiPolygon::coordinates(jni::JNIEnv &env, jni::Object<MultiPolygon> jPolygon) { + static auto method = MultiPolygon::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "coordinates"); return jPolygon.Call(env, method); } diff --git a/platform/android/src/geojson/multi_polygon.hpp b/platform/android/src/geojson/multi_polygon.hpp index 1f144cffd2..6e1dfacfc8 100644 --- a/platform/android/src/geojson/multi_polygon.hpp +++ b/platform/android/src/geojson/multi_polygon.hpp @@ -13,13 +13,13 @@ namespace geojson { class MultiPolygon : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/MultiPolygon"; }; + static constexpr auto Name() { return "com/mapbox/geojson/MultiPolygon"; }; static constexpr auto Type() { return "MultiPolygon"; }; static mapbox::geojson::multi_polygon convert(jni::JNIEnv&, jni::Object<MultiPolygon>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<MultiPolygon>); + static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiPolygon>); static jni::Class<MultiPolygon> javaClass; diff --git a/platform/android/src/geojson/point.cpp b/platform/android/src/geojson/point.cpp index 3d19a119d7..e95376cd2e 100644 --- a/platform/android/src/geojson/point.cpp +++ b/platform/android/src/geojson/point.cpp @@ -1,19 +1,48 @@ #include "point.hpp" +#include "../java/util.hpp" +#include "../java_types.hpp" +#include "../style/value.hpp" namespace mbgl { namespace android { namespace geojson { mapbox::geojson::point Point::convert(jni::JNIEnv &env, jni::Object<Point> jPoint) { - auto jPosition = Point::getPosition(env, jPoint); - auto point = Position::convert(env, jPosition); - jni::DeleteLocalRef(env, jPosition); + mapbox::geojson::point point; + + if (jPoint) { + auto jDoubleList = Point::coordinates(env, jPoint); + point = Point::convert(env, jDoubleList); + jni::DeleteLocalRef(env, jDoubleList); + } + + return point; +} + +mapbox::geojson::point Point::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<Double>*/> jDoubleList) { + mapbox::geojson::point point; + + if (jDoubleList) { + auto jDoubleArray = java::util::List::toArray<jobject>(env, jDoubleList); + + auto lonObject = jDoubleArray.Get(env, 0); + auto latObject = jDoubleArray.Get(env, 1); + + point.x = jni::CallMethod<jni::jdouble>(env, lonObject, + *java::Number::doubleValueMethodId); + point.y = jni::CallMethod<jni::jdouble>(env, latObject, + *java::Number::doubleValueMethodId); + + jni::DeleteLocalRef(env, lonObject); + jni::DeleteLocalRef(env, latObject); + jni::DeleteLocalRef(env, jDoubleArray); + } return point; } -jni::Object<Position> Point::getPosition(JNIEnv& env, jni::Object<Point> jPoint) { - static auto method = Point::javaClass.GetMethod<jni::Object<Position> ()>(env, "getCoordinates"); - return jPoint.Call(env, method); +jni::Object<java::util::List> Point::coordinates(jni::JNIEnv &env, jni::Object<Point> jPoint) { + static auto method = Point::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "coordinates"); + return jPoint.Call(env, method); } void Point::registerNative(jni::JNIEnv &env) { diff --git a/platform/android/src/geojson/point.hpp b/platform/android/src/geojson/point.hpp index 64ac0af9cc..c6412299bf 100644 --- a/platform/android/src/geojson/point.hpp +++ b/platform/android/src/geojson/point.hpp @@ -3,23 +3,25 @@ #include <mbgl/util/geojson.hpp> #include <mbgl/util/noncopyable.hpp> -#include "position.hpp" - #include <jni/jni.hpp> +#include "../java/util.hpp" + namespace mbgl { namespace android { namespace geojson { class Point : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/Point"; }; + static constexpr auto Name() { return "com/mapbox/geojson/Point"; }; static constexpr auto Type() { return "Point"; }; static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<Point>); - static jni::Object<Position> getPosition(JNIEnv&, jni::Object<Point>); + static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<java::util::List/*<Double>*/>); + + static jni::Object<java::util::List> coordinates(JNIEnv&, jni::Object<Point>); static jni::Class<Point> javaClass; diff --git a/platform/android/src/geojson/polygon.cpp b/platform/android/src/geojson/polygon.cpp index ef00f9df3f..30ba996640 100644 --- a/platform/android/src/geojson/polygon.cpp +++ b/platform/android/src/geojson/polygon.cpp @@ -12,7 +12,7 @@ mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<Polygon> mapbox::geojson::polygon polygon; if (jPolygon) { - auto jPositionListsList = Polygon::getCoordinates(env, jPolygon); + auto jPositionListsList = Polygon::coordinates(env, jPolygon); polygon = Polygon::convert(env, jPositionListsList); jni::DeleteLocalRef(env, jPositionListsList); } @@ -20,11 +20,11 @@ mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<Polygon> return polygon; } -mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<java::util::List<Position>>*/> jPositionListsList) { +mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<java::util::List/*<java::util::List<Point>>*/> jPointListsList) { mapbox::geojson::polygon polygon; - if (jPositionListsList) { - auto multiLine = MultiLineString::convert(env, jPositionListsList); + if (jPointListsList) { + auto multiLine = MultiLineString::convert(env, jPointListsList); polygon.reserve(multiLine.size()); for (auto&& line : multiLine) { polygon.emplace_back(convertExplicit<mapbox::geojson::linear_ring>(std::move(line))); @@ -35,8 +35,8 @@ mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<java::ut } -jni::Object<java::util::List> Polygon::getCoordinates(jni::JNIEnv &env, jni::Object<Polygon> jPolygon) { - static auto method = Polygon::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getCoordinates"); +jni::Object<java::util::List> Polygon::coordinates(jni::JNIEnv &env, jni::Object<Polygon> jPolygon) { + static auto method = Polygon::javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "coordinates"); return jPolygon.Call(env, method); } diff --git a/platform/android/src/geojson/polygon.hpp b/platform/android/src/geojson/polygon.hpp index e5362cedf1..a8b2b93827 100644 --- a/platform/android/src/geojson/polygon.hpp +++ b/platform/android/src/geojson/polygon.hpp @@ -13,15 +13,15 @@ namespace geojson { class Polygon : private mbgl::util::noncopyable { public: - static constexpr auto Name() { return "com/mapbox/services/commons/geojson/Polygon"; }; + static constexpr auto Name() { return "com/mapbox/geojson/Polygon"; }; static constexpr auto Type() { return "Polygon"; }; 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<Position>>*/>); + static mapbox::geojson::polygon convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Point>>*/>); - static jni::Object<java::util::List> getCoordinates(jni::JNIEnv&, jni::Object<Polygon>); + static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<Polygon>); static jni::Class<Polygon> javaClass; diff --git a/platform/android/src/geojson/position.cpp b/platform/android/src/geojson/position.cpp deleted file mode 100644 index c0e6da3887..0000000000 --- a/platform/android/src/geojson/position.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "position.hpp" - -namespace mbgl { -namespace android { -namespace geojson { - -mapbox::geojson::point Position::convert(jni::JNIEnv &env, jni::Object<Position> jPosition) { - static auto method = Position::javaClass.GetMethod<jni::Array<jdouble> ()>(env, "getCoordinates"); - // Array with 0: longitude, 1: latitude (and optionally 2: altitude) - auto coordinates = jPosition.Call(env, method); - jdouble lngLat[2]; - coordinates.GetRegion(env, 0, lngLat); - mapbox::geojson::point point(lngLat[0], lngLat[1]); - jni::DeleteLocalRef(env, coordinates); - return point; -} - -void Position::registerNative(jni::JNIEnv &env) { - // Lookup the class - javaClass = *jni::Class<Position>::Find(env).NewGlobalRef(env).release(); -} - -jni::Class<Position> Position::javaClass; - -} // namespace geojson -} // namespace android -} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/geojson/position.hpp b/platform/android/src/geojson/position.hpp deleted file mode 100644 index 7017a8172a..0000000000 --- a/platform/android/src/geojson/position.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include <mbgl/util/geojson.hpp> -#include <mbgl/util/noncopyable.hpp> - -#include <jni/jni.hpp> - -namespace mbgl { -namespace android { -namespace geojson { - -class Position : private mbgl::util::noncopyable { -public: - static constexpr auto Name() { return "com/mapbox/services/commons/models/Position"; }; - - static constexpr auto Type() { return "Position"; }; - - static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<Position>); - - static jni::Class<Position> javaClass; - - static void registerNative(jni::JNIEnv&); -}; - -} // namespace geojson -} // namespace android -} // namespace mbgl
\ No newline at end of file diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 88ad0edb9e..c2fd1c95ad 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -20,7 +20,6 @@ #include "geojson/multi_polygon.hpp" #include "geojson/point.hpp" #include "geojson/polygon.hpp" -#include "geojson/position.hpp" #include "geometry/lat_lng.hpp" #include "geometry/lat_lng_bounds.hpp" #include "geometry/lat_lng_quad.hpp" @@ -128,7 +127,6 @@ void registerNatives(JavaVM *vm) { geojson::MultiPolygon::registerNative(env); geojson::Point::registerNative(env); geojson::Polygon::registerNative(env); - geojson::Position::registerNative(env); // Geometry LatLng::registerNative(env); diff --git a/platform/android/src/map/camera_position.cpp b/platform/android/src/map/camera_position.cpp index 1fc5f9789f..01ffc6530b 100644 --- a/platform/android/src/map/camera_position.cpp +++ b/platform/android/src/map/camera_position.cpp @@ -33,7 +33,9 @@ mbgl::CameraOptions CameraPosition::getCameraOptions(jni::JNIEnv& env, jni::Obje static auto tilt = CameraPosition::javaClass.GetField<jni::jdouble>(env, "tilt"); static auto zoom = CameraPosition::javaClass.GetField<jni::jdouble>(env, "zoom"); - auto center = LatLng::getLatLng(env, position.Get(env, target)); + auto jtarget = position.Get(env, target); + auto center = LatLng::getLatLng(env, jtarget); + jni::DeleteLocalRef(env, jtarget); return mbgl::CameraOptions { center, diff --git a/platform/android/src/map/image.cpp b/platform/android/src/map/image.cpp index 5f5c90eddd..52e0e0d255 100644 --- a/platform/android/src/map/image.cpp +++ b/platform/android/src/map/image.cpp @@ -16,7 +16,9 @@ mbgl::style::Image Image::getImage(jni::JNIEnv& env, jni::Object<Image> image) { auto width = image.Get(env, widthField); auto pixelRatio = image.Get(env, pixelRatioField); auto pixels = image.Get(env, bufferField); - auto name = jni::Make<std::string>(env, image.Get(env, nameField)); + auto jName = image.Get(env, nameField); + auto name = jni::Make<std::string>(env, jName); + jni::DeleteLocalRef(env, jName); jni::NullCheck(env, &pixels); std::size_t size = pixels.Length(env); diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 36a73fee35..67fc132204 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -450,7 +450,7 @@ jni::Array<jni::jlong> NativeMapView::addMarkers(jni::JNIEnv& env, jni::Array<jn } void NativeMapView::onLowMemory(JNIEnv&) { - rendererFrontend->onLowMemory(); + rendererFrontend->reduceMemoryUse(); } using DebugOptions = mbgl::MapDebugOptions; diff --git a/platform/android/src/run_loop.cpp b/platform/android/src/run_loop.cpp index 1d284a9e72..34366d836a 100644 --- a/platform/android/src/run_loop.cpp +++ b/platform/android/src/run_loop.cpp @@ -216,11 +216,8 @@ LOOP_HANDLE RunLoop::getLoopHandle() { return Get()->impl.get(); } -void RunLoop::push(std::shared_ptr<WorkTask> task) { - withMutex([&] { - queue.push(std::move(task)); - impl->wake(); - }); +void RunLoop::wake() { + impl->wake(); } void RunLoop::run() { diff --git a/platform/android/src/style/layers/heatmap_layer.cpp b/platform/android/src/style/layers/heatmap_layer.cpp new file mode 100644 index 0000000000..609499ec93 --- /dev/null +++ b/platform/android/src/style/layers/heatmap_layer.cpp @@ -0,0 +1,134 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#include "heatmap_layer.hpp" + +#include <string> + +#include "../conversion/property_value.hpp" +#include "../conversion/transition_options.hpp" + +namespace mbgl { +namespace android { + + /** + * Creates an owning peer object (for layers not attached to the map) from the JVM side + */ + HeatmapLayer::HeatmapLayer(jni::JNIEnv& env, jni::String layerId, jni::String sourceId) + : Layer(env, std::make_unique<mbgl::style::HeatmapLayer>(jni::Make<std::string>(env, layerId), jni::Make<std::string>(env, sourceId))) { + } + + /** + * Creates a non-owning peer object (for layers currently attached to the map) + */ + HeatmapLayer::HeatmapLayer(mbgl::Map& map, mbgl::style::HeatmapLayer& coreLayer) + : Layer(map, coreLayer) { + } + + /** + * Creates an owning peer object (for layers not attached to the map) + */ + HeatmapLayer::HeatmapLayer(mbgl::Map& map, std::unique_ptr<mbgl::style::HeatmapLayer> coreLayer) + : Layer(map, std::move(coreLayer)) { + } + + HeatmapLayer::~HeatmapLayer() = default; + + // Property getters + + jni::Object<jni::ObjectTag> HeatmapLayer::getHeatmapRadius(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapRadius()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HeatmapLayer::getHeatmapRadiusTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapRadiusTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HeatmapLayer::setHeatmapRadiusTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::setHeatmapRadiusTransition(options); + } + + jni::Object<jni::ObjectTag> HeatmapLayer::getHeatmapWeight(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapWeight()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<jni::ObjectTag> HeatmapLayer::getHeatmapIntensity(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + Result<jni::jobject*> converted = convert<jni::jobject*>(env, layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapIntensity()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HeatmapLayer::getHeatmapIntensityTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapIntensityTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HeatmapLayer::setHeatmapIntensityTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::setHeatmapIntensityTransition(options); + } + + 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()); + return jni::Object<jni::ObjectTag>(*converted); + } + + jni::Object<TransitionOptions> HeatmapLayer::getHeatmapOpacityTransition(jni::JNIEnv& env) { + using namespace mbgl::android::conversion; + mbgl::style::TransitionOptions options = layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::getHeatmapOpacityTransition(); + return *convert<jni::Object<TransitionOptions>>(env, options); + } + + void HeatmapLayer::setHeatmapOpacityTransition(jni::JNIEnv&, jlong duration, jlong delay) { + mbgl::style::TransitionOptions options; + options.duration.emplace(mbgl::Milliseconds(duration)); + options.delay.emplace(mbgl::Milliseconds(delay)); + layer.as<mbgl::style::HeatmapLayer>()->HeatmapLayer::setHeatmapOpacityTransition(options); + } + + + jni::Class<HeatmapLayer> HeatmapLayer::javaClass; + + jni::jobject* HeatmapLayer::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = HeatmapLayer::javaClass.template GetConstructor<jni::jlong>(env); + return HeatmapLayer::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)); + } + + void HeatmapLayer::registerNative(jni::JNIEnv& env) { + // Lookup the class + HeatmapLayer::javaClass = *jni::Class<HeatmapLayer>::Find(env).NewGlobalRef(env).release(); + + #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) + + // Register the peer + jni::RegisterNativePeer<HeatmapLayer>( + env, HeatmapLayer::javaClass, "nativePtr", + std::make_unique<HeatmapLayer, JNIEnv&, jni::String, jni::String>, + "initialize", + "finalize", + METHOD(&HeatmapLayer::getHeatmapRadiusTransition, "nativeGetHeatmapRadiusTransition"), + METHOD(&HeatmapLayer::setHeatmapRadiusTransition, "nativeSetHeatmapRadiusTransition"), + METHOD(&HeatmapLayer::getHeatmapRadius, "nativeGetHeatmapRadius"), + METHOD(&HeatmapLayer::getHeatmapWeight, "nativeGetHeatmapWeight"), + METHOD(&HeatmapLayer::getHeatmapIntensityTransition, "nativeGetHeatmapIntensityTransition"), + METHOD(&HeatmapLayer::setHeatmapIntensityTransition, "nativeSetHeatmapIntensityTransition"), + METHOD(&HeatmapLayer::getHeatmapIntensity, "nativeGetHeatmapIntensity"), + METHOD(&HeatmapLayer::getHeatmapOpacityTransition, "nativeGetHeatmapOpacityTransition"), + METHOD(&HeatmapLayer::setHeatmapOpacityTransition, "nativeSetHeatmapOpacityTransition"), + METHOD(&HeatmapLayer::getHeatmapOpacity, "nativeGetHeatmapOpacity")); + } + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/heatmap_layer.hpp b/platform/android/src/style/layers/heatmap_layer.hpp new file mode 100644 index 0000000000..85f9f0292e --- /dev/null +++ b/platform/android/src/style/layers/heatmap_layer.hpp @@ -0,0 +1,50 @@ +// This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + +#pragma once + +#include "layer.hpp" +#include "../transition_options.hpp" +#include <mbgl/style/layers/heatmap_layer.hpp> +#include <jni/jni.hpp> + +namespace mbgl { +namespace android { + +class HeatmapLayer : public Layer { +public: + + static constexpr auto Name() { return "com/mapbox/mapboxsdk/style/layers/HeatmapLayer"; }; + + static jni::Class<HeatmapLayer> javaClass; + + static void registerNative(jni::JNIEnv&); + + HeatmapLayer(jni::JNIEnv&, jni::String, jni::String); + + HeatmapLayer(mbgl::Map&, mbgl::style::HeatmapLayer&); + + HeatmapLayer(mbgl::Map&, std::unique_ptr<mbgl::style::HeatmapLayer>); + + ~HeatmapLayer(); + + // Properties + + jni::Object<jni::ObjectTag> getHeatmapRadius(jni::JNIEnv&); + void setHeatmapRadiusTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHeatmapRadiusTransition(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHeatmapWeight(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHeatmapIntensity(jni::JNIEnv&); + void setHeatmapIntensityTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHeatmapIntensityTransition(jni::JNIEnv&); + + jni::Object<jni::ObjectTag> getHeatmapOpacity(jni::JNIEnv&); + void setHeatmapOpacityTransition(jni::JNIEnv&, jlong duration, jlong delay); + jni::Object<TransitionOptions> getHeatmapOpacityTransition(jni::JNIEnv&); + jni::jobject* createJavaPeer(jni::JNIEnv&); + +}; // class HeatmapLayer + +} // namespace android +} // namespace mbgl diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index da1550bdb1..29530879a5 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -10,6 +10,7 @@ #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer.hpp> +#include <mbgl/style/layers/heatmap_layer.hpp> #include <mbgl/style/layers/hillshade_layer.hpp> #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> diff --git a/platform/android/src/style/layers/layers.cpp b/platform/android/src/style/layers/layers.cpp index 5d1d1bbcbf..5df689b45d 100644 --- a/platform/android/src/style/layers/layers.cpp +++ b/platform/android/src/style/layers/layers.cpp @@ -5,6 +5,7 @@ #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/fill_extrusion_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/layers/heatmap_layer.hpp> #include <mbgl/style/layers/hillshade_layer.hpp> #include <mbgl/style/layers/line_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> @@ -16,6 +17,7 @@ #include "custom_layer.hpp" #include "fill_extrusion_layer.hpp" #include "fill_layer.hpp" +#include "heatmap_layer.hpp" #include "hillshade_layer.hpp" #include "line_layer.hpp" #include "raster_layer.hpp" @@ -32,6 +34,7 @@ template <> struct PeerType<style::BackgroundLayer> { using Type = android::Back template <> struct PeerType<style::CircleLayer> { using Type = android::CircleLayer; }; template <> struct PeerType<style::FillExtrusionLayer> { using Type = android::FillExtrusionLayer; }; template <> struct PeerType<style::FillLayer> { using Type = android::FillLayer; }; +template <> struct PeerType<style::HeatmapLayer> { using Type = android::HeatmapLayer; }; template <> struct PeerType<style::HillshadeLayer> { using Type = android::HillshadeLayer; }; template <> struct PeerType<style::LineLayer> { using Type = android::LineLayer; }; template <> struct PeerType<style::RasterLayer> { using Type = android::RasterLayer; }; @@ -95,6 +98,7 @@ void registerNativeLayers(jni::JNIEnv& env) { CustomLayer::registerNative(env); FillExtrusionLayer::registerNative(env); FillLayer::registerNative(env); + HeatmapLayer::registerNative(env); HillshadeLayer::registerNative(env); LineLayer::registerNative(env); RasterLayer::registerNative(env); diff --git a/platform/android/src/style/sources/custom_geometry_source.cpp b/platform/android/src/style/sources/custom_geometry_source.cpp index a60b962e45..b38405a3b1 100644 --- a/platform/android/src/style/sources/custom_geometry_source.cpp +++ b/platform/android/src/style/sources/custom_geometry_source.cpp @@ -18,7 +18,7 @@ namespace mbgl { namespace android { // This conversion is expected not to fail because it's used only in contexts where - // the value was originally a GeoJsonOptions object on the Java side. If it fails + // the value was originally a CustomGeometrySourceOptions object on the Java side. If it fails // to convert, it's a bug in our serialization or Java-side static typing. static style::CustomGeometrySource::Options convertCustomGeometrySourceOptions(jni::JNIEnv& env, jni::Object<> options, diff --git a/platform/android/src/style/sources/image_source.cpp b/platform/android/src/style/sources/image_source.cpp index 0cd6995969..249387ea51 100644 --- a/platform/android/src/style/sources/image_source.cpp +++ b/platform/android/src/style/sources/image_source.cpp @@ -45,6 +45,11 @@ namespace android { source.as<mbgl::style::ImageSource>()->setImage(Bitmap::GetImage(env, bitmap)); } + void ImageSource::setCoordinates(jni::JNIEnv& env, jni::Object<LatLngQuad> coordinatesObject) { + source.as<mbgl::style::ImageSource>()->setCoordinates( + LatLngQuad::getLatLngArray(env, coordinatesObject)); + } + jni::Class<ImageSource> ImageSource::javaClass; jni::Object<Source> ImageSource::createJavaPeer(jni::JNIEnv& env) { @@ -66,7 +71,8 @@ namespace android { "finalize", METHOD(&ImageSource::setURL, "nativeSetUrl"), METHOD(&ImageSource::getURL, "nativeGetUrl"), - METHOD(&ImageSource::setImage, "nativeSetImage") + METHOD(&ImageSource::setImage, "nativeSetImage"), + METHOD(&ImageSource::setCoordinates, "nativeSetCoordinates") ); } diff --git a/platform/android/src/style/sources/image_source.hpp b/platform/android/src/style/sources/image_source.hpp index f0af28d357..6021a03dc3 100644 --- a/platform/android/src/style/sources/image_source.hpp +++ b/platform/android/src/style/sources/image_source.hpp @@ -30,6 +30,8 @@ public: void setImage(jni::JNIEnv&, jni::Object<Bitmap>); + void setCoordinates(jni::JNIEnv&, jni::Object<LatLngQuad>); + private: jni::Object<Source> createJavaPeer(jni::JNIEnv&); |