Files
MapLibreParticleLab/platform/android/jni.cpp
2015-11-27 17:47:02 +02:00

2264 lines
82 KiB
C++

#include <cstdint>
#include <cinttypes>
#include <cassert>
#include <string>
#include <locale>
#include <codecvt>
#include <array>
#include <vector>
#include <jni.h>
#include <android/native_window_jni.h>
#include <sys/system_properties.h>
#include <mbgl/android/jni.hpp>
#include <mbgl/android/native_map_view.hpp>
#include <mbgl/map/map.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/annotation/point_annotation.hpp>
#include <mbgl/annotation/shape_annotation.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/platform/event.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/storage/network_status.hpp>
#pragma clang diagnostic ignored "-Wunused-parameter"
namespace mbgl {
namespace android {
JavaVM* theJVM;
std::string cachePath;
std::string dataPath;
std::string apkPath;
std::string androidRelease;
jmethodID onInvalidateId = nullptr;
jmethodID onMapChangedId = nullptr;
jmethodID onFpsChangedId = nullptr;
jclass latLngClass = nullptr;
jmethodID latLngConstructorId = nullptr;
jfieldID latLngLatitudeId = nullptr;
jfieldID latLngLongitudeId = nullptr;
jclass latLngZoomClass = nullptr;
jmethodID latLngZoomConstructorId = nullptr;
jfieldID latLngZoomLatitudeId = nullptr;
jfieldID latLngZoomLongitudeId = nullptr;
jfieldID latLngZoomZoomId = nullptr;
jclass bboxClass = nullptr;
jmethodID bboxConstructorId = nullptr;
jfieldID bboxLatNorthId = nullptr;
jfieldID bboxLatSouthId = nullptr;
jfieldID bboxLonEastId = nullptr;
jfieldID bboxLonWestId = nullptr;
jclass spriteClass = nullptr;
jfieldID spriteIdId = nullptr;
jclass markerClass = nullptr;
jfieldID markerPositionId = nullptr;
jfieldID markerIconId = nullptr;
jclass polylineClass = nullptr;
jfieldID polylineAlphaId = nullptr;
jfieldID polylineColorId = nullptr;
jfieldID polylineWidthId = nullptr;
jfieldID polylinePointsId = nullptr;
jclass polygonClass = nullptr;
jfieldID polygonAlphaId = nullptr;
jfieldID polygonFillColorId = nullptr;
jfieldID polygonStrokeColorId = nullptr;
jfieldID polygonPointsId = nullptr;
jclass runtimeExceptionClass = nullptr;
jclass nullPointerExceptionClass = nullptr;
jmethodID listToArrayId = nullptr;
jclass arrayListClass = nullptr;
jmethodID arrayListConstructorId = nullptr;
jmethodID arrayListAddId = nullptr;
jclass projectedMetersClass = nullptr;
jmethodID projectedMetersConstructorId = nullptr;
jfieldID projectedMetersNorthingId = nullptr;
jfieldID projectedMetersEastingId = nullptr;
jclass pointFClass = nullptr;
jmethodID pointFConstructorId = nullptr;
jfieldID pointFXId = nullptr;
jfieldID pointFYId = nullptr;
jclass rectFClass = nullptr;
jmethodID rectFConstructorId = nullptr;
jfieldID rectFLeftId = nullptr;
jfieldID rectFTopId = nullptr;
jfieldID rectFRightId = nullptr;
jfieldID rectFBottomId = nullptr;
jclass httpContextClass = nullptr;
jmethodID httpContextGetInstanceId = nullptr;
jmethodID httpContextCreateRequestId = nullptr;
jclass httpRequestClass = nullptr;
jmethodID httpRequestStartId = nullptr;
jmethodID httpRequestCancelId = nullptr;
bool throw_jni_error(JNIEnv *env, const char *msg) {
if (env->ThrowNew(runtimeExceptionClass, msg) < 0) {
env->ExceptionDescribe();
return false;
}
return true;
}
bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName) {
assert(vm != nullptr);
assert(env != nullptr);
JavaVMAttachArgs args = {JNI_VERSION_1_2, threadName.c_str(), NULL};
jint ret;
*env = nullptr;
bool detach = false;
ret = vm->GetEnv(reinterpret_cast<void **>(env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
if (ret != JNI_EDETACHED) {
mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
throw new std::runtime_error("GetEnv() failed");
} else {
ret = vm->AttachCurrentThread(env, &args);
if (ret != JNI_OK) {
mbgl::Log::Error(mbgl::Event::JNI, "AttachCurrentThread() failed with %i", ret);
throw new std::runtime_error("AttachCurrentThread() failed");
}
detach = true;
}
}
return detach;
}
void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach) {
if (detach) {
assert(vm != nullptr);
assert(env != nullptr);
jint ret;
if ((ret = vm->DetachCurrentThread()) != JNI_OK) {
mbgl::Log::Error(mbgl::Event::JNI, "DetachCurrentThread() failed with %i", ret);
throw new std::runtime_error("DetachCurrentThread() failed");
}
}
*env = nullptr;
}
std::string std_string_from_jstring(JNIEnv *env, jstring jstr) {
std::string str;
if (jstr == nullptr) {
if (env->ThrowNew(nullPointerExceptionClass, "String cannot be null.") < 0) {
env->ExceptionDescribe();
return str;
}
return str;
}
jsize len = env->GetStringLength(jstr);
if (len < 0) {
env->ExceptionDescribe();
return str;
}
const jchar *chars = env->GetStringChars(jstr, nullptr);
if (chars == nullptr) {
env->ExceptionDescribe();
return str;
}
std::u16string ustr(reinterpret_cast<const char16_t *>(chars), len);
env->ReleaseStringChars(jstr, chars);
chars = nullptr;
str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().to_bytes(ustr);
return str;
}
jstring std_string_to_jstring(JNIEnv *env, std::string str) {
std::u16string ustr =
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().from_bytes(str);
jstring jstr = env->NewString(reinterpret_cast<const jchar *>(ustr.c_str()), ustr.size());
if (jstr == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return jstr;
}
std::vector<std::string> std_vector_string_from_jobject(JNIEnv *env, jobject jlist) {
std::vector<std::string> vector;
if (jlist == nullptr) {
if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) {
env->ExceptionDescribe();
return vector;
}
return vector;
}
jobjectArray jarray =
reinterpret_cast<jobjectArray>(env->CallObjectMethod(jlist, listToArrayId));
if (env->ExceptionCheck() || (jarray == nullptr)) {
env->ExceptionDescribe();
return vector;
}
jsize len = env->GetArrayLength(jarray);
if (len < 0) {
env->ExceptionDescribe();
return vector;
}
for (jsize i = 0; i < len; i++) {
jstring jstr = reinterpret_cast<jstring>(env->GetObjectArrayElement(jarray, i));
if (jstr == nullptr) {
env->ExceptionDescribe();
return vector;
}
vector.push_back(std_string_from_jstring(env, jstr));
}
env->DeleteLocalRef(jarray);
jarray = nullptr;
return vector;
}
jobject std_vector_string_to_jobject(JNIEnv *env, std::vector<std::string> vector) {
jobject jlist = env->NewObject(arrayListClass, arrayListConstructorId);
if (jlist == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
for (const auto& str : vector) {
env->CallBooleanMethod(jlist, arrayListAddId, std_string_to_jstring(env, str));
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
}
return jlist;
}
jlongArray std_vector_uint_to_jobject(JNIEnv *env, std::vector<uint32_t> vector) {
jlongArray jarray = env->NewLongArray(vector.size());
if (jarray == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
std::vector<jlong> v;
for (const uint32_t& id : vector) {
v.push_back((jlong)id);
}
env->SetLongArrayRegion(jarray, 0, v.size(), &(v[0]));
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
return jarray;
}
mbgl::AnnotationSegment annotation_segment_from_latlng_jlist(JNIEnv *env, jobject jlist) {
mbgl::AnnotationSegment segment;
if (jlist == nullptr) {
if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) {
env->ExceptionDescribe();
return segment;
}
return segment;
}
jobjectArray jarray =
reinterpret_cast<jobjectArray>(env->CallObjectMethod(jlist, listToArrayId));
if (env->ExceptionCheck() || (jarray == nullptr)) {
env->ExceptionDescribe();
return segment;
}
jsize len = env->GetArrayLength(jarray);
if (len < 0) {
env->ExceptionDescribe();
return segment;
}
segment.reserve(len);
for (jsize i = 0; i < len; i++) {
jobject latLng = reinterpret_cast<jobject>(env->GetObjectArrayElement(jarray, i));
if (latLng == nullptr) {
env->ExceptionDescribe();
return segment;
}
jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return segment;
}
jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return segment;
}
segment.push_back(mbgl::LatLng(latitude, longitude));
env->DeleteLocalRef(latLng);
}
env->DeleteLocalRef(jarray);
jarray = nullptr;
return segment;
}
std::pair<mbgl::AnnotationSegment, mbgl::ShapeAnnotation::Properties> annotation_std_pair_from_polygon_jobject(JNIEnv *env, jobject polygon) {
jfloat alpha = env->GetFloatField(polygon, polygonAlphaId);
jint fillColor = env->GetIntField(polygon, polygonFillColorId);
jint strokeColor = env->GetIntField(polygon, polygonStrokeColorId);
int rF = (fillColor >> 16) & 0xFF;
int gF = (fillColor >> 8) & 0xFF;
int bF = (fillColor) & 0xFF;
int aF = (fillColor >> 24) & 0xFF;
int rS = (strokeColor >> 16) & 0xFF;
int gS = (strokeColor >> 8) & 0xFF;
int bS = (strokeColor) & 0xFF;
int aS = (strokeColor >> 24) & 0xFF;
mbgl::ShapeAnnotation::Properties shapeProperties;
mbgl::FillAnnotationProperties fillProperties;
fillProperties.opacity = alpha;
fillProperties.outlineColor = {{ static_cast<float>(rS) / 255.0f, static_cast<float>(gS) / 255.0f, static_cast<float>(bS) / 255.0f, static_cast<float>(aS) / 255.0f }};
fillProperties.color = {{ static_cast<float>(rF) / 255.0f, static_cast<float>(gF) / 255.0f, static_cast<float>(bF) / 255.0f, static_cast<float>(aF) / 255.0f }};
shapeProperties.set<mbgl::FillAnnotationProperties>(fillProperties);
jobject points = env->GetObjectField(polygon, polygonPointsId);
mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points);
env->DeleteLocalRef(points);
return std::make_pair(segment, shapeProperties);
}
}
}
namespace {
using namespace mbgl::android;
using DebugOptions = mbgl::MapDebugOptions;
jlong JNICALL nativeCreate(JNIEnv *env, jobject obj, jstring cachePath_, jstring dataPath_, jstring apkPath_, jfloat pixelRatio, jint availableProcessors, jlong totalMemory) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreate");
cachePath = std_string_from_jstring(env, cachePath_);
dataPath = std_string_from_jstring(env, dataPath_);
apkPath = std_string_from_jstring(env, apkPath_);
NativeMapView *nativeMapView = new NativeMapView(env, obj, pixelRatio, availableProcessors, totalMemory);
jlong mapViewPtr = reinterpret_cast<jlong>(nativeMapView);
return mapViewPtr;
}
void JNICALL nativeDestroy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeDestroy");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
delete nativeMapView;
nativeMapView = nullptr;
}
void JNICALL nativeInitializeDisplay(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeInitializeDisplay");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
try
{
nativeMapView->initializeDisplay();
} catch(const std::exception& e) {
throw_jni_error(env, "Unable to initialize GL display.");
}
}
void JNICALL nativeTerminateDisplay(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeTerminateDisplay");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->terminateDisplay();
}
void JNICALL nativeInitializeContext(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeInitializeContext");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
try {
nativeMapView->initializeContext();
} catch(const std::exception& e) {
throw_jni_error(env, "Unable to initialize GL context.");
}
}
void JNICALL nativeTerminateContext(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeTerminateContext");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->terminateContext();
}
void JNICALL nativeCreateSurface(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject surface) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeCreateSurface");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
try {
nativeMapView->createSurface(ANativeWindow_fromSurface(env, surface));
} catch(const std::exception& e) {
throw_jni_error(env, "Unable to create GL surface.");
}
}
void JNICALL nativeDestroySurface(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeDestroySurface");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->destroySurface();
}
void JNICALL nativePause(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativePause");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->pause();
}
jboolean JNICALL nativeIsPaused(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeIsPaused");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().isPaused();
}
void JNICALL nativeResume(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeResume");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->resume();
}
void JNICALL nativeUpdate(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdate");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().update(mbgl::Update::Repaint);
}
void JNICALL nativeRenderSync(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeRenderSync");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().renderSync();
}
void JNICALL nativeViewResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint width, jint height) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeViewResize");
assert(nativeMapViewPtr != 0);
assert(width >= 0);
assert(height >= 0);
assert(width <= UINT16_MAX);
assert(height <= UINT16_MAX);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->resizeView(width, height);
}
void JNICALL nativeFramebufferResize(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jint fbWidth, jint fbHeight) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeFramebufferResize");
assert(nativeMapViewPtr != 0);
assert(fbWidth >= 0);
assert(fbHeight >= 0);
assert(fbWidth <= UINT16_MAX);
assert(fbHeight <= UINT16_MAX);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->resizeFramebuffer(fbWidth, fbHeight);
}
void JNICALL nativeRemoveClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveClass");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().removeClass(std_string_from_jstring(env, clazz));
}
jboolean JNICALL nativeHasClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeHasClass");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().hasClass(std_string_from_jstring(env, clazz));
}
void JNICALL nativeAddClass(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring clazz) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddClass");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().addClass(std_string_from_jstring(env, clazz));
}
void JNICALL nativeSetClasses(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject classes) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetClasses");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().setClasses(std_vector_string_from_jobject(env, classes));
}
jobject JNICALL nativeGetClasses(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetClasses");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return std_vector_string_to_jobject(env, nativeMapView->getMap().getClasses());
}
void JNICALL nativeSetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetDefaultTransitionDuration");
assert(nativeMapViewPtr != 0);
assert(duration >= 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().setDefaultTransitionDuration(std::chrono::milliseconds(duration));
}
jlong JNICALL nativeGetDefaultTransitionDuration(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetDefaultTransitionDuration");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return std::chrono::duration_cast<std::chrono::milliseconds>(nativeMapView->getMap().getDefaultTransitionDuration()).count();
}
void JNICALL nativeSetStyleURL(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring url) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetStyleURL");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().setStyleURL(std_string_from_jstring(env, url));
}
void JNICALL nativeSetStyleJSON(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
jstring newStyleJson, jstring base) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetStyleJSON");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().setStyleJSON(std_string_from_jstring(env, newStyleJson),
std_string_from_jstring(env, base));
}
jstring JNICALL nativeGetStyleJSON(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetStyleJSON");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return std_string_to_jstring(env, nativeMapView->getMap().getStyleJSON());
}
void JNICALL nativeSetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring accessToken) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetAccessToken");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getFileSource().setAccessToken(std_string_from_jstring(env, accessToken));
}
jstring JNICALL nativeGetAccessToken(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetAccessToken");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return std_string_to_jstring(env, nativeMapView->getFileSource().getAccessToken());
}
void JNICALL nativeCancelTransitions(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeCancelTransitions");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().cancelTransitions();
}
void JNICALL nativeSetGestureInProgress(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean inProgress) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetGestureInProgress");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().setGestureInProgress(inProgress);
}
void JNICALL nativeMoveBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble dx, jdouble dy,
jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeMoveBy");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::PrecisionPoint center(dx, dy);
nativeMapView->getMap().moveBy(center, std::chrono::milliseconds(duration));
}
void JNICALL nativeSetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng,
jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetLatLng");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
nativeMapView->getMap().setLatLng(mbgl::LatLng(latitude, longitude), mbgl::Duration(duration));
}
jobject JNICALL nativeGetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetLatLng");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::LatLng latLng = nativeMapView->getMap().getLatLng();
jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude);
if (ret == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return ret;
}
void JNICALL nativeResetPosition(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetPosition");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().resetPosition();
}
void JNICALL nativeScaleBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble ds, jdouble cx,
jdouble cy, jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeScaleBy");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::PrecisionPoint center(cx, cy);
nativeMapView->getMap().scaleBy(ds, center, std::chrono::milliseconds(duration));
}
void JNICALL nativeSetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble scale,
jdouble cx, jdouble cy, jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetScale");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::PrecisionPoint center(cx, cy);
nativeMapView->getMap().setScale(scale, center, std::chrono::milliseconds(duration));
}
jdouble JNICALL nativeGetScale(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetScale");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getScale();
}
void JNICALL nativeSetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble zoom, jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().setZoom(zoom, std::chrono::milliseconds(duration));
}
jdouble JNICALL nativeGetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getZoom();
}
void JNICALL nativeSetLatLngZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
jobject latLngZoom, jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetLatLngZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jdouble latitude = env->GetDoubleField(latLngZoom, latLngZoomLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jdouble longitude = env->GetDoubleField(latLngZoom, latLngZoomLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jdouble zoom = env->GetDoubleField(latLngZoom, latLngZoomZoomId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
nativeMapView->getMap().setLatLngZoom(mbgl::LatLng(latitude, longitude), zoom, std::chrono::milliseconds(duration));
}
jobject JNICALL nativeGetLatLngZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetLatLngZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::LatLng latLng = nativeMapView->getMap().getLatLng();
jdouble zoom = nativeMapView->getMap().getZoom();
jobject ret = env->NewObject(latLngZoomClass, latLngZoomConstructorId, latLng.longitude, latLng.latitude, zoom);
if (ret == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return ret;
}
void JNICALL nativeResetZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().resetZoom();
}
jdouble JNICALL nativeGetMinZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMinZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getMinZoom();
}
jdouble JNICALL nativeGetMaxZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMaxZoom");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getMaxZoom();
}
void JNICALL nativeRotateBy(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble sx,
jdouble sy, jdouble ex, jdouble ey, jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeRotateBy");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::PrecisionPoint first(sx, sy);
mbgl::PrecisionPoint second(ex, ey);
nativeMapView->getMap().rotateBy(first, second, std::chrono::milliseconds(duration));
}
void JNICALL nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble degrees,
jlong milliseconds) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetBearing");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::Duration duration((std::chrono::milliseconds(milliseconds)));
nativeMapView->getMap().setBearing(degrees, duration);
}
void JNICALL nativeSetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble degrees,
jdouble cx, jdouble cy) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetBearing");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
mbgl::PrecisionPoint center(cx, cy);
nativeMapView->getMap().setBearing(degrees, center);
}
jdouble JNICALL nativeGetBearing(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetBearing");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getBearing();
}
void JNICALL nativeResetNorth(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeResetNorth");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().resetNorth();
}
jlong JNICALL nativeAddMarker(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject marker) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarker");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jobject position = env->GetObjectField(marker, markerPositionId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
jobject icon = env->GetObjectField(marker, markerIconId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
jstring jid = reinterpret_cast<jstring>(env->GetObjectField(icon, spriteIdId));
std::string id = std_string_from_jstring(env, jid);
jdouble latitude = env->GetDoubleField(position, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
jdouble longitude = env->GetDoubleField(position, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
// Because Java only has int, not unsigned int, we need to bump the annotation id up to a long.
return nativeMapView->getMap().addPointAnnotation(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id));
}
jlongArray JNICALL nativeAddMarkers(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarkers");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
std::vector<mbgl::PointAnnotation> markers;
if (jlist == nullptr) {
if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) {
env->ExceptionDescribe();
return nullptr;
}
return nullptr;
}
jobjectArray jarray =
reinterpret_cast<jobjectArray>(env->CallObjectMethod(jlist, listToArrayId));
if (env->ExceptionCheck() || (jarray == nullptr)) {
env->ExceptionDescribe();
return nullptr;
}
jsize len = env->GetArrayLength(jarray);
if (len < 0) {
env->ExceptionDescribe();
return nullptr;
}
markers.reserve(len);
for (jsize i = 0; i < len; i++) {
jobject marker = reinterpret_cast<jobject>(env->GetObjectArrayElement(jarray, i));
jobject position = env->GetObjectField(marker, markerPositionId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jobject icon = env->GetObjectField(marker, markerIconId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
env->DeleteLocalRef(marker);
jstring jid = reinterpret_cast<jstring>(env->GetObjectField(icon, spriteIdId));
env->DeleteLocalRef(icon);
std::string id = std_string_from_jstring(env, jid);
env->DeleteLocalRef(jid);
jdouble latitude = env->GetDoubleField(position, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble longitude = env->GetDoubleField(position, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
env->DeleteLocalRef(position);
markers.emplace_back(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id));
}
env->DeleteLocalRef(jarray);
std::vector<uint32_t> pointAnnotationIDs = nativeMapView->getMap().addPointAnnotations(markers);
return std_vector_uint_to_jobject(env, pointAnnotationIDs);
}
jlong JNICALL nativeAddPolyline(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject polyline) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolyline");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jfloat alpha = env->GetFloatField(polyline, polylineAlphaId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
jint color = env->GetIntField(polyline, polylineColorId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color) & 0xFF;
int a = (color >> 24) & 0xFF;
jfloat width = env->GetFloatField(polyline, polylineWidthId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
mbgl::ShapeAnnotation::Properties shapeProperties;
mbgl::LineAnnotationProperties lineProperties;
lineProperties.opacity = alpha;
lineProperties.color = {{ static_cast<float>(r) / 255.0f, static_cast<float>(g) / 255.0f, static_cast<float>(b) / 255.0f, static_cast<float>(a) / 255.0f }};
lineProperties.width = width;
shapeProperties.set<mbgl::LineAnnotationProperties>(lineProperties);
jobject points = env->GetObjectField(polyline, polylinePointsId);
mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points);
std::vector<mbgl::ShapeAnnotation> shapes;
shapes.emplace_back(mbgl::AnnotationSegments { segment }, shapeProperties);
std::vector<uint32_t> shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes);
uint32_t id = shapeAnnotationIDs.at(0);
return id;
}
jlongArray JNICALL nativeAddPolylines(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolylines");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
std::vector<mbgl::ShapeAnnotation> shapes;
if (jlist == nullptr) {
if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) {
env->ExceptionDescribe();
return nullptr;
}
return nullptr;
}
jobjectArray jarray =
reinterpret_cast<jobjectArray>(env->CallObjectMethod(jlist, listToArrayId));
if (env->ExceptionCheck() || (jarray == nullptr)) {
env->ExceptionDescribe();
return nullptr;
}
jsize len = env->GetArrayLength(jarray);
if (len < 0) {
env->ExceptionDescribe();
return nullptr;
}
shapes.reserve(len);
for (jsize i = 0; i < len; i++) {
jobject polyline = reinterpret_cast<jobject>(env->GetObjectArrayElement(jarray, i));
jfloat alpha = env->GetFloatField(polyline, polylineAlphaId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jint color = env->GetIntField(polyline, polylineColorId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
int r = (color >> 16) & 0xFF;
int g = (color >> 8) & 0xFF;
int b = (color) & 0xFF;
int a = (color >> 24) & 0xFF;
jfloat width = env->GetFloatField(polyline, polylineWidthId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
mbgl::ShapeAnnotation::Properties shapeProperties;
mbgl::LineAnnotationProperties lineProperties;
lineProperties.opacity = alpha;
lineProperties.color = {{ static_cast<float>(r) / 255.0f, static_cast<float>(g) / 255.0f, static_cast<float>(b) / 255.0f, static_cast<float>(a) / 255.0f }};
lineProperties.width = width;
shapeProperties.set<mbgl::LineAnnotationProperties>(lineProperties);
jobject points = env->GetObjectField(polyline, polylinePointsId);
mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points);
shapes.emplace_back(mbgl::AnnotationSegments { segment }, shapeProperties);
env->DeleteLocalRef(polyline);
}
env->DeleteLocalRef(jarray);
std::vector<uint32_t> shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes);
return std_vector_uint_to_jobject(env, shapeAnnotationIDs);
}
jlong JNICALL nativeAddPolygon(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject polygon) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolygon");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
std::vector<mbgl::ShapeAnnotation> shapes;
std::pair<mbgl::AnnotationSegment, mbgl::ShapeAnnotation::Properties> segment = annotation_std_pair_from_polygon_jobject(env, polygon);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return -1;
}
shapes.emplace_back(mbgl::AnnotationSegments { segment.first }, segment.second);
std::vector<uint32_t> shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes);
uint32_t id = shapeAnnotationIDs.at(0);
return id;
}
jlongArray JNICALL nativeAddPolygons(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject jlist) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddPolygons");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
std::vector<mbgl::ShapeAnnotation> shapes;
if (jlist == nullptr) {
if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) {
env->ExceptionDescribe();
return nullptr;
}
return nullptr;
}
jobjectArray jarray =
reinterpret_cast<jobjectArray>(env->CallObjectMethod(jlist, listToArrayId));
if (env->ExceptionCheck() || (jarray == nullptr)) {
env->ExceptionDescribe();
return nullptr;
}
jsize len = env->GetArrayLength(jarray);
if (len < 0) {
env->ExceptionDescribe();
return nullptr;
}
shapes.reserve(len);
for (jsize i = 0; i < len; i++) {
jobject polygon = reinterpret_cast<jobject>(env->GetObjectArrayElement(jarray, i));
std::pair<mbgl::AnnotationSegment, mbgl::ShapeAnnotation::Properties> segment = annotation_std_pair_from_polygon_jobject(env, polygon);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
shapes.emplace_back(mbgl::AnnotationSegments { segment.first }, segment.second);
env->DeleteLocalRef(polygon);
}
env->DeleteLocalRef(jarray);
std::vector<uint32_t> shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes);
return std_vector_uint_to_jobject(env, shapeAnnotationIDs);
}
void JNICALL nativeRemoveAnnotation(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jlong annotationId) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveAnnotation");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().removeAnnotation(static_cast<uint32_t>(annotationId));
}
void JNICALL nativeRemoveAnnotations(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jlongArray jarray) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveAnnotations");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
std::vector<uint32_t> ids;
if (env->ExceptionCheck() || (jarray == nullptr)) {
env->ExceptionDescribe();
return;
}
jsize len = env->GetArrayLength(jarray);
if (len < 0) {
env->ExceptionDescribe();
return;
}
ids.reserve(len);
jlong* jids = env->GetLongArrayElements(jarray, nullptr);
for (jsize i = 0; i < len; i++) {
if(jids[i] == -1L)
continue;
ids.push_back(static_cast<uint32_t>(jids[i]));
}
env->ReleaseLongArrayElements(jarray, jids, JNI_ABORT);
nativeMapView->getMap().removeAnnotations(ids);
}
jlongArray JNICALL nativeGetAnnotationsInBounds(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject bbox) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetAnnotationsInBounds");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
if (env->ExceptionCheck() || (bbox == nullptr)) {
env->ExceptionDescribe();
return nullptr;
}
jdouble swLat = env->GetDoubleField(bbox, bboxLatSouthId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble swLon = env->GetDoubleField(bbox, bboxLonWestId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble neLat = env->GetDoubleField(bbox, bboxLatNorthId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble neLon = env->GetDoubleField(bbox, bboxLonEastId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
mbgl::LatLngBounds bounds({ swLat, swLon }, { neLat, neLon });
// assume only points for now
std::vector<uint32_t> annotations = nativeMapView->getMap().getPointAnnotationsInBounds(bounds);
return std_vector_uint_to_jobject(env, annotations);
}
void JNICALL nativeSetSprite(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
jstring symbol, jint width, jint height, jfloat scale, jbyteArray jpixels) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetSprite");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
const std::string symbolName = std_string_from_jstring(env, symbol);
jbyte* pixelData = env->GetByteArrayElements(jpixels, nullptr);
jsize size = env->GetArrayLength(jpixels);
std::string pixels(reinterpret_cast<char*>(pixelData), size);
env->ReleaseByteArrayElements(jpixels, pixelData, JNI_ABORT);
auto spriteImage = std::make_shared<mbgl::SpriteImage>(
uint16_t(width),
uint16_t(height),
float(scale),
std::move(pixels));
nativeMapView->getMap().setSprite(symbolName, spriteImage);
}
void JNICALL nativeSetVisibleCoordinateBounds(JNIEnv *env, jobject obj, jlong nativeMapViewPtr,
jobjectArray coordinates, jobject padding, jdouble direction, jlong duration) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetVisibleCoordinateBounds");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jfloat left = env->GetFloatField(padding, rectFLeftId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jfloat right = env->GetFloatField(padding, rectFRightId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jfloat top = env->GetFloatField(padding, rectFTopId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jfloat bottom = env->GetFloatField(padding, rectFBottomId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jsize count = env->GetArrayLength(coordinates);
mbgl::EdgeInsets mbglInsets = {top, left, bottom, right};
mbgl::AnnotationSegment segment;
segment.reserve(count);
for (int i = 0; i < count; i++) {
jobject latLng = reinterpret_cast<jobject>(env->GetObjectArrayElement(coordinates, i));
jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return;
}
segment.push_back(mbgl::LatLng(latitude, longitude));
}
mbgl::CameraOptions options = nativeMapView->getMap().cameraForLatLngs(segment, mbglInsets);
if (direction >= 0) {
// convert from degrees to radians
options.angle = (-direction * M_PI) / 180;
}
if (duration > 0) {
options.duration = std::chrono::milliseconds(duration);
// equivalent to kCAMediaTimingFunctionDefault in iOS
options.easing = {0.25, 0.1, 0.25, 0.1};
}
nativeMapView->getMap().easeTo(options);
}
void JNICALL nativeOnLowMemory(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnLowMemory");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().onLowMemory();
}
void JNICALL nativeSetDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean debug) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetDebug");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
DebugOptions debugOptions = debug ? DebugOptions::TileBorders | DebugOptions::ParseStatus | DebugOptions::Collision
: DebugOptions::NoDebug;
nativeMapView->getMap().setDebug(debugOptions);
nativeMapView->enableFps(debug);
}
void JNICALL nativeToggleDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeToggleDebug");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
nativeMapView->getMap().cycleDebugOptions();
nativeMapView->enableFps(nativeMapView->getMap().getDebug() != DebugOptions::NoDebug);
}
jboolean JNICALL nativeGetDebug(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetDebug");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getDebug() != DebugOptions::NoDebug;
}
jboolean JNICALL nativeIsFullyLoaded(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeIsFullyLoaded");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().isFullyLoaded();
}
void JNICALL nativeSetReachability(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean status) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeSetReachability");
assert(nativeMapViewPtr != 0);
if (status) {
mbgl::NetworkStatus::Reachable();
}
}
jdouble JNICALL nativeGetMetersPerPixelAtLatitude(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble lat, jdouble zoom) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMetersPerPixelAtLatitude");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getMetersPerPixelAtLatitude(lat, zoom);
}
jobject JNICALL nativeProjectedMetersForLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeProjectedMetersForLatLng");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
mbgl::ProjectedMeters projectedMeters = nativeMapView->getMap().projectedMetersForLatLng(mbgl::LatLng(latitude, longitude));
jobject ret = env->NewObject(projectedMetersClass, projectedMetersConstructorId, projectedMeters.northing, projectedMeters.easting);
if (ret == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return ret;
}
jobject JNICALL nativeLatLngForProjectedMeters(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject projectedMeters) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeLatLngForProjectedMeters");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jdouble northing = env->GetDoubleField(projectedMeters, projectedMetersNorthingId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble easting = env->GetDoubleField(projectedMeters, projectedMetersEastingId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
mbgl::LatLng latLng = nativeMapView->getMap().latLngForProjectedMeters(mbgl::ProjectedMeters(northing, easting));
jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude);
if (ret == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return ret;
}
jobject JNICALL nativePixelForLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativePixelForLatLng");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
mbgl::vec2<double> pixel = nativeMapView->getMap().pixelForLatLng(mbgl::LatLng(latitude, longitude));
jobject ret = env->NewObject(pointFClass, pointFConstructorId, static_cast<jfloat>(pixel.x), static_cast<jfloat>(pixel.y));
if (ret == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return ret;
}
jobject JNICALL nativeLatLngForPixel(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject pixel) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeLatLngForPixel");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
jfloat x = env->GetFloatField(pixel, pointFXId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
jfloat y = env->GetFloatField(pixel, pointFYId);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
return nullptr;
}
mbgl::LatLng latLng = nativeMapView->getMap().latLngForPixel(mbgl::PrecisionPoint(x, y));
jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude);
if (ret == nullptr) {
env->ExceptionDescribe();
return nullptr;
}
return ret;
}
jdouble JNICALL nativeGetTopOffsetPixelsForAnnotationSymbol(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jstring symbolName) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetTopOffsetPixelsForAnnotationSymbol");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
return nativeMapView->getMap().getTopOffsetPixelsForAnnotationSymbol(std_string_from_jstring(env, symbolName));
}
}
extern "C" {
extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
mbgl::Log::Debug(mbgl::Event::JNI, "JNI_OnLoad");
theJVM = vm;
JNIEnv *env = nullptr;
jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
return JNI_ERR;
}
latLngClass = env->FindClass("com/mapbox/mapboxsdk/geometry/LatLng");
if (latLngClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngConstructorId = env->GetMethodID(latLngClass, "<init>", "(DD)V");
if (latLngConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngLatitudeId = env->GetFieldID(latLngClass, "latitude", "D");
if (latLngLatitudeId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngLongitudeId = env->GetFieldID(latLngClass, "longitude", "D");
if (latLngLongitudeId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngZoomClass = env->FindClass("com/mapbox/mapboxsdk/geometry/LatLngZoom");
if (latLngZoomClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngZoomConstructorId = env->GetMethodID(latLngZoomClass, "<init>", "(DDD)V");
if (latLngZoomConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngZoomLatitudeId = env->GetFieldID(latLngZoomClass, "latitude", "D");
if (latLngZoomLatitudeId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngZoomLongitudeId = env->GetFieldID(latLngZoomClass, "longitude", "D");
if (latLngZoomLongitudeId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngZoomZoomId = env->GetFieldID(latLngZoomClass, "zoom", "D");
if (latLngZoomZoomId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
bboxClass = env->FindClass("com/mapbox/mapboxsdk/geometry/BoundingBox");
if (bboxClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
bboxConstructorId = env->GetMethodID(bboxClass, "<init>", "(DDDD)V");
if (bboxConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
bboxLatNorthId = env->GetFieldID(bboxClass, "mLatNorth", "D");
if (bboxLatNorthId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
bboxLatSouthId = env->GetFieldID(bboxClass, "mLatSouth", "D");
if (bboxLatSouthId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
bboxLonEastId = env->GetFieldID(bboxClass, "mLonEast", "D");
if (bboxLonEastId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
bboxLonWestId = env->GetFieldID(bboxClass, "mLonWest", "D");
if (bboxLonWestId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
spriteClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Sprite");
if (spriteClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
spriteIdId = env->GetFieldID(spriteClass, "mId", "Ljava/lang/String;");
if (spriteIdId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
markerClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Marker");
if (markerClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
markerPositionId = env->GetFieldID(markerClass, "position", "Lcom/mapbox/mapboxsdk/geometry/LatLng;");
if (markerPositionId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
markerIconId = env->GetFieldID(markerClass, "icon", "Lcom/mapbox/mapboxsdk/annotations/Sprite;");
if (markerIconId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polylineClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Polyline");
if (polylineClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polylineAlphaId = env->GetFieldID(polylineClass, "alpha", "F");
if (polylineAlphaId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polylineColorId = env->GetFieldID(polylineClass, "color", "I");
if (polylineColorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polylineWidthId = env->GetFieldID(polylineClass, "width", "F");
if (polylineWidthId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polylinePointsId = env->GetFieldID(polylineClass, "points", "Ljava/util/List;");
if (polylineWidthId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polygonClass = env->FindClass("com/mapbox/mapboxsdk/annotations/Polygon");
if (polygonClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polygonAlphaId = env->GetFieldID(polygonClass, "alpha", "F");
if (polygonAlphaId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polygonFillColorId = env->GetFieldID(polygonClass, "fillColor", "I");
if (polygonFillColorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polygonStrokeColorId = env->GetFieldID(polygonClass, "strokeColor", "I");
if (polygonStrokeColorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
polygonPointsId = env->GetFieldID(polygonClass, "points", "Ljava/util/List;");
if (polygonPointsId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
jclass nativeMapViewClass = env->FindClass("com/mapbox/mapboxsdk/views/NativeMapView");
if (nativeMapViewClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
onInvalidateId = env->GetMethodID(nativeMapViewClass, "onInvalidate", "()V");
if (onInvalidateId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
onMapChangedId = env->GetMethodID(nativeMapViewClass, "onMapChanged", "(I)V");
if (onMapChangedId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
onFpsChangedId = env->GetMethodID(nativeMapViewClass, "onFpsChanged", "(D)V");
if (onFpsChangedId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
runtimeExceptionClass = env->FindClass("java/lang/RuntimeException");
if (runtimeExceptionClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
nullPointerExceptionClass = env->FindClass("java/lang/NullPointerException");
if (nullPointerExceptionClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
jclass listClass = env->FindClass("java/util/List");
if (listClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
listToArrayId = env->GetMethodID(listClass, "toArray", "()[Ljava/lang/Object;");
if (listToArrayId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
arrayListClass = env->FindClass("java/util/ArrayList");
if (arrayListClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
arrayListConstructorId = env->GetMethodID(arrayListClass, "<init>", "()V");
if (arrayListConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
arrayListAddId = env->GetMethodID(arrayListClass, "add", "(Ljava/lang/Object;)Z");
if (arrayListAddId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
projectedMetersClass = env->FindClass("com/mapbox/mapboxsdk/geometry/ProjectedMeters");
if (projectedMetersClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
projectedMetersConstructorId = env->GetMethodID(projectedMetersClass, "<init>", "(DD)V");
if (projectedMetersConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
projectedMetersNorthingId = env->GetFieldID(projectedMetersClass, "northing", "D");
if (projectedMetersNorthingId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
projectedMetersEastingId = env->GetFieldID(projectedMetersClass, "easting", "D");
if (projectedMetersEastingId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
pointFClass = env->FindClass("android/graphics/PointF");
if (pointFClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
pointFConstructorId = env->GetMethodID(pointFClass, "<init>", "(FF)V");
if (pointFConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
pointFXId = env->GetFieldID(pointFClass, "x", "F");
if (pointFXId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
pointFYId = env->GetFieldID(pointFClass, "y", "F");
if (pointFYId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
rectFClass = env->FindClass("android/graphics/RectF");
if (rectFClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
rectFConstructorId = env->GetMethodID(rectFClass, "<init>", "()V");
if (rectFConstructorId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
rectFLeftId = env->GetFieldID(rectFClass, "left", "F");
if (rectFLeftId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
rectFRightId = env->GetFieldID(rectFClass, "right", "F");
if (rectFRightId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
rectFTopId = env->GetFieldID(rectFClass, "top", "F");
if (rectFTopId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
rectFBottomId = env->GetFieldID(rectFClass, "bottom", "F");
if (rectFBottomId == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
httpContextClass = env->FindClass("com/mapbox/mapboxsdk/http/HTTPContext");
if (httpContextClass == nullptr) {
env->ExceptionDescribe();
}
httpContextGetInstanceId = env->GetStaticMethodID(httpContextClass, "getInstance", "()Lcom/mapbox/mapboxsdk/http/HTTPContext;");
if (httpContextGetInstanceId == nullptr) {
env->ExceptionDescribe();
}
httpContextCreateRequestId = env->GetMethodID(httpContextClass, "createRequest", "(JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lcom/mapbox/mapboxsdk/http/HTTPContext$HTTPRequest;");
if (httpContextCreateRequestId == nullptr) {
env->ExceptionDescribe();
}
httpRequestClass = env->FindClass("com/mapbox/mapboxsdk/http/HTTPContext$HTTPRequest");
if (httpRequestClass == nullptr) {
env->ExceptionDescribe();
}
httpRequestStartId = env->GetMethodID(httpRequestClass, "start", "()V");
if (httpRequestStartId == nullptr) {
env->ExceptionDescribe();
}
httpRequestCancelId = env->GetMethodID(httpRequestClass, "cancel", "()V");
if (httpRequestCancelId == nullptr) {
env->ExceptionDescribe();
}
const std::vector<JNINativeMethod> methods = {
{"nativeCreate", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;FIJ)J",
reinterpret_cast<void *>(&nativeCreate)},
{"nativeDestroy", "(J)V", reinterpret_cast<void *>(&nativeDestroy)},
{"nativeInitializeDisplay", "(J)V", reinterpret_cast<void *>(&nativeInitializeDisplay)},
{"nativeTerminateDisplay", "(J)V", reinterpret_cast<void *>(&nativeTerminateDisplay)},
{"nativeInitializeContext", "(J)V", reinterpret_cast<void *>(&nativeInitializeContext)},
{"nativeTerminateContext", "(J)V", reinterpret_cast<void *>(&nativeTerminateContext)},
{"nativeCreateSurface", "(JLandroid/view/Surface;)V",
reinterpret_cast<void *>(&nativeCreateSurface)},
{"nativeDestroySurface", "(J)V", reinterpret_cast<void *>(&nativeDestroySurface)},
{"nativePause", "(J)V", reinterpret_cast<void *>(&nativePause)},
{"nativeIsPaused", "(J)Z", reinterpret_cast<void *>(&nativeIsPaused)},
{"nativeResume", "(J)V", reinterpret_cast<void *>(&nativeResume)},
{"nativeUpdate", "(J)V", reinterpret_cast<void *>(&nativeUpdate)},
{"nativeRenderSync", "(J)V", reinterpret_cast<void *>(&nativeRenderSync)},
{"nativeViewResize", "(JII)V",
reinterpret_cast<void *>(static_cast<void JNICALL (
*)(JNIEnv *, jobject, jlong, jint, jint)>(&nativeViewResize))},
{"nativeFramebufferResize", "(JII)V",
reinterpret_cast<void *>(static_cast<void JNICALL (
*)(JNIEnv *, jobject, jlong, jint, jint)>(&nativeFramebufferResize))},
{"nativeAddClass", "(JLjava/lang/String;)V",
reinterpret_cast<void *>(&nativeAddClass)},
{"nativeRemoveClass", "(JLjava/lang/String;)V",
reinterpret_cast<void *>(&nativeRemoveClass)},
{"nativeHasClass", "(JLjava/lang/String;)Z",
reinterpret_cast<void *>(&nativeHasClass)},
{"nativeSetClasses", "(JLjava/util/List;)V",
reinterpret_cast<void *>(&nativeSetClasses)},
{"nativeGetClasses", "(J)Ljava/util/List;",
reinterpret_cast<void *>(&nativeGetClasses)},
{"nativeSetDefaultTransitionDuration", "(JJ)V",
reinterpret_cast<void *>(&nativeSetDefaultTransitionDuration)},
{"nativeGetDefaultTransitionDuration", "(J)J",
reinterpret_cast<void *>(&nativeGetDefaultTransitionDuration)},
{"nativeSetStyleUrl", "(JLjava/lang/String;)V",
reinterpret_cast<void *>(&nativeSetStyleURL)},
{"nativeSetStyleJson", "(JLjava/lang/String;Ljava/lang/String;)V",
reinterpret_cast<void *>(&nativeSetStyleJSON)},
{"nativeGetStyleJson", "(J)Ljava/lang/String;",
reinterpret_cast<void *>(&nativeGetStyleJSON)},
{"nativeSetAccessToken", "(JLjava/lang/String;)V",
reinterpret_cast<void *>(&nativeSetAccessToken)},
{"nativeGetAccessToken", "(J)Ljava/lang/String;",
reinterpret_cast<void *>(&nativeGetAccessToken)},
{"nativeCancelTransitions", "(J)V", reinterpret_cast<void *>(&nativeCancelTransitions)},
{"nativeSetGestureInProgress", "(JZ)V", reinterpret_cast<void *>(&nativeSetGestureInProgress)},
{"nativeMoveBy", "(JDDJ)V", reinterpret_cast<void *>(&nativeMoveBy)},
{"nativeSetLatLng", "(JLcom/mapbox/mapboxsdk/geometry/LatLng;J)V",
reinterpret_cast<void *>(&nativeSetLatLng)},
{"nativeGetLatLng", "(J)Lcom/mapbox/mapboxsdk/geometry/LatLng;",
reinterpret_cast<void *>(&nativeGetLatLng)},
{"nativeResetPosition", "(J)V", reinterpret_cast<void *>(&nativeResetPosition)},
{"nativeScaleBy", "(JDDDJ)V", reinterpret_cast<void *>(&nativeScaleBy)},
{"nativeSetScale", "(JDDDJ)V", reinterpret_cast<void *>(&nativeSetScale)},
{"nativeGetScale", "(J)D", reinterpret_cast<void *>(&nativeGetScale)},
{"nativeSetZoom", "(JDJ)V", reinterpret_cast<void *>(&nativeSetZoom)},
{"nativeGetZoom", "(J)D", reinterpret_cast<void *>(&nativeGetZoom)},
{"nativeSetLatLngZoom", "(JLcom/mapbox/mapboxsdk/geometry/LatLngZoom;J)V",
reinterpret_cast<void *>(&nativeSetLatLngZoom)},
{"nativeGetLatLngZoom", "(J)Lcom/mapbox/mapboxsdk/geometry/LatLngZoom;",
reinterpret_cast<void *>(&nativeGetLatLngZoom)},
{"nativeResetZoom", "(J)V", reinterpret_cast<void *>(&nativeResetZoom)},
{"nativeGetMinZoom", "(J)D", reinterpret_cast<void *>(&nativeGetMinZoom)},
{"nativeGetMaxZoom", "(J)D", reinterpret_cast<void *>(&nativeGetMaxZoom)},
{"nativeRotateBy", "(JDDDDJ)V", reinterpret_cast<void *>(&nativeRotateBy)},
{"nativeSetBearing", "(JDJ)V",
reinterpret_cast<void *>(
static_cast<void JNICALL (*)(JNIEnv *, jobject, jlong, jdouble, jlong)>(
&nativeSetBearing))},
{"nativeSetBearing", "(JDDD)V",
reinterpret_cast<void *>(
static_cast<void JNICALL (*)(JNIEnv *, jobject, jlong, jdouble, jdouble, jdouble)>(
&nativeSetBearing))},
{"nativeGetBearing", "(J)D", reinterpret_cast<void *>(&nativeGetBearing)},
{"nativeResetNorth", "(J)V", reinterpret_cast<void *>(&nativeResetNorth)},
{"nativeAddMarker", "(JLcom/mapbox/mapboxsdk/annotations/Marker;)J",
reinterpret_cast<void *>(&nativeAddMarker)},
{"nativeAddMarkers", "(JLjava/util/List;)[J",
reinterpret_cast<void *>(&nativeAddMarkers)},
{"nativeAddPolyline", "(JLcom/mapbox/mapboxsdk/annotations/Polyline;)J",
reinterpret_cast<void *>(&nativeAddPolyline)},
{"nativeAddPolylines", "(JLjava/util/List;)[J",
reinterpret_cast<void *>(&nativeAddPolylines)},
{"nativeAddPolygon", "(JLcom/mapbox/mapboxsdk/annotations/Polygon;)J",
reinterpret_cast<void *>(&nativeAddPolygon)},
{"nativeAddPolygons", "(JLjava/util/List;)[J",
reinterpret_cast<void *>(&nativeAddPolygons)},
{"nativeRemoveAnnotation", "(JJ)V", reinterpret_cast<void *>(&nativeRemoveAnnotation)},
{"nativeRemoveAnnotations", "(J[J)V", reinterpret_cast<void *>(&nativeRemoveAnnotations)},
{"nativeGetAnnotationsInBounds", "(JLcom/mapbox/mapboxsdk/geometry/BoundingBox;)[J",
reinterpret_cast<void *>(&nativeGetAnnotationsInBounds)},
{"nativeSetSprite", "(JLjava/lang/String;IIF[B)V", reinterpret_cast<void *>(&nativeSetSprite)},
{"nativeSetVisibleCoordinateBounds", "(J[Lcom/mapbox/mapboxsdk/geometry/LatLng;Landroid/graphics/RectF;DJ)V",
reinterpret_cast<void *>(&nativeSetVisibleCoordinateBounds)},
{"nativeOnLowMemory", "(J)V", reinterpret_cast<void *>(&nativeOnLowMemory)},
{"nativeSetDebug", "(JZ)V", reinterpret_cast<void *>(&nativeSetDebug)},
{"nativeToggleDebug", "(J)V", reinterpret_cast<void *>(&nativeToggleDebug)},
{"nativeGetDebug", "(J)Z", reinterpret_cast<void *>(&nativeGetDebug)},
{"nativeIsFullyLoaded", "(J)Z", reinterpret_cast<void *>(&nativeIsFullyLoaded)},
{"nativeSetReachability", "(JZ)V", reinterpret_cast<void *>(&nativeSetReachability)},
{"nativeGetMetersPerPixelAtLatitude", "(JDD)D", reinterpret_cast<void *>(&nativeGetMetersPerPixelAtLatitude)},
{"nativeProjectedMetersForLatLng",
"(JLcom/mapbox/mapboxsdk/geometry/LatLng;)Lcom/mapbox/mapboxsdk/geometry/ProjectedMeters;",
reinterpret_cast<void *>(&nativeProjectedMetersForLatLng)},
{"nativeLatLngForProjectedMeters",
"(JLcom/mapbox/mapboxsdk/geometry/ProjectedMeters;)Lcom/mapbox/mapboxsdk/geometry/LatLng;",
reinterpret_cast<void *>(&nativeLatLngForProjectedMeters)},
{"nativePixelForLatLng", "(JLcom/mapbox/mapboxsdk/geometry/LatLng;)Landroid/graphics/PointF;",
reinterpret_cast<void *>(&nativePixelForLatLng)},
{"nativeLatLngForPixel", "(JLandroid/graphics/PointF;)Lcom/mapbox/mapboxsdk/geometry/LatLng;",
reinterpret_cast<void *>(&nativeLatLngForPixel)},
{"nativeGetTopOffsetPixelsForAnnotationSymbol", "(JLjava/lang/String;)D",
reinterpret_cast<void *>(&nativeGetTopOffsetPixelsForAnnotationSymbol)},
};
if (env->RegisterNatives(nativeMapViewClass, methods.data(), methods.size()) < 0) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngClass = reinterpret_cast<jclass>(env->NewGlobalRef(latLngClass));
if (latLngClass == nullptr) {
env->ExceptionDescribe();
return JNI_ERR;
}
latLngZoomClass = reinterpret_cast<jclass>(env->NewGlobalRef(latLngZoomClass));
if (latLngZoomClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
return JNI_ERR;
}
bboxClass = reinterpret_cast<jclass>(env->NewGlobalRef(bboxClass));
if (bboxClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
return JNI_ERR;
}
spriteClass = reinterpret_cast<jclass>(env->NewGlobalRef(spriteClass));
if (spriteClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
return JNI_ERR;
}
markerClass = reinterpret_cast<jclass>(env->NewGlobalRef(markerClass));
if (markerClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
return JNI_ERR;
}
polylineClass = reinterpret_cast<jclass>(env->NewGlobalRef(polylineClass));
if (polylineClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
return JNI_ERR;
}
polygonClass = reinterpret_cast<jclass>(env->NewGlobalRef(polygonClass));
if (polygonClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
return JNI_ERR;
}
runtimeExceptionClass = reinterpret_cast<jclass>(env->NewGlobalRef(runtimeExceptionClass));
if (runtimeExceptionClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
return JNI_ERR;
}
nullPointerExceptionClass =
reinterpret_cast<jclass>(env->NewGlobalRef(nullPointerExceptionClass));
if (nullPointerExceptionClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
return JNI_ERR;
}
arrayListClass = reinterpret_cast<jclass>(env->NewGlobalRef(arrayListClass));
if (arrayListClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
return JNI_ERR;
}
projectedMetersClass = reinterpret_cast<jclass>(env->NewGlobalRef(projectedMetersClass));
if (projectedMetersClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
return JNI_ERR;
}
pointFClass = reinterpret_cast<jclass>(env->NewGlobalRef(pointFClass));
if (pointFClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
env->DeleteGlobalRef(projectedMetersClass);
return JNI_ERR;
}
rectFClass = reinterpret_cast<jclass>(env->NewGlobalRef(rectFClass));
if (rectFClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
return JNI_ERR;
}
httpContextClass = reinterpret_cast<jclass>(env->NewGlobalRef(httpContextClass));
if (httpContextClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
}
httpRequestClass = reinterpret_cast<jclass>(env->NewGlobalRef(httpRequestClass));
if (httpRequestClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngZoomClass);
env->DeleteGlobalRef(bboxClass);
env->DeleteGlobalRef(spriteClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
env->DeleteGlobalRef(httpContextClass);
}
char release[PROP_VALUE_MAX] = "";
__system_property_get("ro.build.version.release", release);
androidRelease = std::string(release);
return JNI_VERSION_1_6;
}
extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
mbgl::Log::Debug(mbgl::Event::JNI, "JNI_OnUnload");
theJVM = vm;
JNIEnv *env = nullptr;
jint ret = vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
if (ret != JNI_OK) {
mbgl::Log::Error(mbgl::Event::JNI, "GetEnv() failed with %i", ret);
throw new std::runtime_error("GetEnv() failed");
}
env->DeleteGlobalRef(latLngClass);
latLngClass = nullptr;
latLngConstructorId = nullptr;
latLngLongitudeId = nullptr;
latLngLatitudeId = nullptr;
env->DeleteGlobalRef(latLngZoomClass);
latLngZoomClass = nullptr;
latLngZoomConstructorId = nullptr;
latLngZoomLongitudeId = nullptr;
latLngZoomLatitudeId = nullptr;
latLngZoomZoomId = nullptr;
env->DeleteGlobalRef(bboxClass);
bboxClass = nullptr;
bboxConstructorId = nullptr;
bboxLatNorthId = nullptr;
bboxLatSouthId = nullptr;
bboxLonEastId = nullptr;
bboxLonWestId = nullptr;
env->DeleteGlobalRef(spriteClass);
spriteClass = nullptr;
spriteIdId = nullptr;
env->DeleteGlobalRef(markerClass);
markerClass = nullptr;
markerPositionId = nullptr;
markerIconId = nullptr;
env->DeleteGlobalRef(polylineClass);
polylineClass = nullptr;
polylineAlphaId = nullptr;
polylineColorId = nullptr;
polylineWidthId = nullptr;
polylinePointsId = nullptr;
env->DeleteGlobalRef(polygonClass);
polygonClass = nullptr;
polygonAlphaId = nullptr;
polygonFillColorId = nullptr;
polygonStrokeColorId = nullptr;
polygonPointsId = nullptr;
onInvalidateId = nullptr;
onMapChangedId = nullptr;
onFpsChangedId = nullptr;
env->DeleteGlobalRef(runtimeExceptionClass);
runtimeExceptionClass = nullptr;
env->DeleteGlobalRef(nullPointerExceptionClass);
nullPointerExceptionClass = nullptr;
listToArrayId = nullptr;
env->DeleteGlobalRef(arrayListClass);
arrayListClass = nullptr;
arrayListConstructorId = nullptr;
arrayListAddId = nullptr;
env->DeleteGlobalRef(projectedMetersClass);
projectedMetersClass = nullptr;
projectedMetersConstructorId = nullptr;
projectedMetersNorthingId = nullptr;
projectedMetersEastingId = nullptr;
env->DeleteGlobalRef(pointFClass);
pointFClass = nullptr;
pointFConstructorId = nullptr;
pointFXId = nullptr;
pointFYId = nullptr;
env->DeleteGlobalRef(rectFClass);
rectFClass = nullptr;
rectFConstructorId = nullptr;
rectFLeftId = nullptr;
rectFTopId = nullptr;
rectFRightId = nullptr;
rectFBottomId = nullptr;
env->DeleteGlobalRef(httpContextClass);
httpContextGetInstanceId = nullptr;
httpContextCreateRequestId = nullptr;
env->DeleteGlobalRef(httpRequestClass);
httpRequestStartId = nullptr;
httpRequestCancelId = nullptr;
theJVM = nullptr;
}
}