diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index 85022dbc0..eee6bd8f6 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -42,6 +42,12 @@ 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 markerClass = nullptr; jmethodID markerConstructorId = nullptr; jfieldID markerPositionId = nullptr; @@ -65,13 +71,6 @@ jfieldID polygonStrokeWidthId = nullptr; jfieldID polygonPointsId = nullptr; jfieldID polygonHolesId = nullptr; - -jclass latLngZoomClass = nullptr; -jmethodID latLngZoomConstructorId = nullptr; -jfieldID latLngZoomLatitudeId = nullptr; -jfieldID latLngZoomLongitudeId = nullptr; -jfieldID latLngZoomZoomId = nullptr; - jclass runtimeExceptionClass = nullptr; jclass nullPointerExceptionClass = nullptr; @@ -156,21 +155,21 @@ std::vector std_vector_string_from_jobject(JNIEnv *env, jobject jli return vector; } - jobjectArray array = + jobjectArray jarray = reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (array == nullptr)) { + if (env->ExceptionCheck() || (jarray == nullptr)) { env->ExceptionDescribe(); return vector; } - jsize len = env->GetArrayLength(array); + jsize len = env->GetArrayLength(jarray); if (len < 0) { env->ExceptionDescribe(); return vector; } for (jsize i = 0; i < len; i++) { - jstring jstr = reinterpret_cast(env->GetObjectArrayElement(array, i)); + jstring jstr = reinterpret_cast(env->GetObjectArrayElement(jarray, i)); if (jstr == nullptr) { env->ExceptionDescribe(); return vector; @@ -179,61 +178,12 @@ std::vector std_vector_string_from_jobject(JNIEnv *env, jobject jli vector.push_back(std_string_from_jstring(env, jstr)); } + env->DeleteLocalRef(jarray); + jarray = nullptr; + return vector; } -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 array = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (array == nullptr)) { - env->ExceptionDescribe(); - return segment; - } - - jsize len = env->GetArrayLength(array); - if (len < 0) { - env->ExceptionDescribe(); - return segment; - } - - segment.reserve(len); - - for (jsize i = 0; i < len; i++) { - jobject latLng = reinterpret_cast(env->GetObjectArrayElement(array, 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(array); - return segment; -} - jobject std_vector_string_to_jobject(JNIEnv *env, std::vector vector) { jobject jlist = env->NewObject(arrayListClass, arrayListConstructorId); if (jlist == nullptr) { @@ -273,6 +223,91 @@ jlongArray std_vector_uint_to_jobject(JNIEnv *env, std::vector vector) 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(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(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 annotation_std_pair_from_polygon_jobject(JNIEnv *env, jobject polygon) { + jfloat alpha = env->GetFloatField(polygon, polygonAlphaId); + //jboolean visible = env->GetBooleanField(polygon, polygonVisibleId); + 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::StyleProperties shapeProperties; + mbgl::FillProperties fillProperties; + fillProperties.opacity = alpha; + fillProperties.stroke_color = {{ static_cast(rS) / 255.0f, static_cast(gS) / 255.0f, static_cast(bS) / 255.0f, static_cast(aS) / 255.0f }}; + fillProperties.fill_color = {{ static_cast(rF) / 255.0f, static_cast(gF) / 255.0f, static_cast(bF) / 255.0f, static_cast(aF) / 255.0f }}; + shapeProperties.set(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); +} + } } @@ -530,271 +565,6 @@ void JNICALL nativeSetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, j nativeMapView->getMap().setLatLng(mbgl::LatLng(latitude, longitude), std::chrono::milliseconds(duration)); } -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(nativeMapViewPtr); - - const std::string symbolName = std_string_from_jstring(env, symbol); - - jbyte* pixelData = env->GetByteArrayElements(jpixels, nullptr); - std::string pixels((char*)pixelData, width * height * 4); - env->ReleaseByteArrayElements(jpixels, pixelData, JNI_ABORT); - - auto spriteImage = std::make_shared( - uint16_t(width), - uint16_t(height), - float(scale), - std::move(pixels)); - - nativeMapView->getMap().setSprite(symbolName, spriteImage); -} - -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(nativeMapViewPtr); - - jobject position = env->GetObjectField(marker, markerPositionId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - - jstring jsprite = (jstring)env->GetObjectField(marker, markerSpriteId); - std::string sprite = std_string_from_jstring(env, jsprite); - - 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 (jlong) nativeMapView->getMap().addPointAnnotation(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), sprite)); -} - -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(nativeMapViewPtr); - - // ***** Java fields ***** // - // float alpha; - // boolean visible; - // int color - // float width - // List points - - jfloat alpha = env->GetFloatField(polyline, polylineAlphaId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - - jboolean visible = env->GetBooleanField(polyline, polylineVisibleId); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - visible = JNI_TRUE; - - 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::StyleProperties shapeProperties; - mbgl::LineProperties lineProperties; - lineProperties.opacity = alpha; - lineProperties.color = {{ (float)r / 255.0f, (float)g / 255.0f, (float)b / 255.0f, (float)a / 255.0f }}; - lineProperties.width = width; - shapeProperties.set(lineProperties); - - jobject points = env->GetObjectField(polyline, polylinePointsId); - mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); - - std::vector shapes; - shapes.emplace_back(mbgl::AnnotationSegments {{ segment }}, shapeProperties); - - std::vector shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); - uint32_t id = shapeAnnotationIDs.at(0); - return (jlong) id; -} - - -std::pair readPolygon(JNIEnv *env, jobject polygon) { - // ***** Java fields ***** // - // float alpha; - // boolean visible; - // int fillColor - // int strokeColor - // float strokeWidth - // List points - // List> holes - - jfloat alpha = env->GetFloatField(polygon, polygonAlphaId); - jboolean visible = env->GetBooleanField(polygon, polygonVisibleId); - visible = JNI_TRUE; - 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; - - // jfloat strokeWidth = env->GetFloatField(polygon, polygonStrokeWidthId); - // if (env->ExceptionCheck()) { - // env->ExceptionDescribe(); - // return -1; - // } - - mbgl::StyleProperties shapeProperties; - mbgl::FillProperties fillProperties; - fillProperties.opacity = alpha; - fillProperties.stroke_color = {{ (float)rS / 255.0f, (float)gS / 255.0f, (float)bS / 255.0f, (float)aS / 255.0f }}; - fillProperties.fill_color = {{ (float)rF / 255.0f, (float)gF / 255.0f, (float)bF / 255.0f, (float)aF / 255.0f }}; - shapeProperties.set(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); -} - -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(nativeMapViewPtr); - - std::vector shapes; - std::pair segment = readPolygon(env, polygon); - - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return -1; - } - - shapes.emplace_back(mbgl::AnnotationSegments {{ segment.first }}, segment.second); - - std::vector shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); - uint32_t id = shapeAnnotationIDs.at(0); - return (jlong) 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(nativeMapViewPtr); - - std::vector shapes; - - if (jlist == nullptr) { - if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { - env->ExceptionDescribe(); - return nullptr; - } - return nullptr; - } - - jobjectArray array = - reinterpret_cast(env->CallObjectMethod(jlist, listToArrayId)); - if (env->ExceptionCheck() || (array == nullptr)) { - env->ExceptionDescribe(); - return nullptr; - } - - jsize len = env->GetArrayLength(array); - if (len < 0) { - env->ExceptionDescribe(); - return nullptr; - } - - shapes.reserve(len); - - for (jsize i = 0; i < len; i++) { - jobject polygon = reinterpret_cast(env->GetObjectArrayElement(array, i)); - - std::pair segment = readPolygon(env, polygon); - if (env->ExceptionCheck()) { - env->ExceptionDescribe(); - return nullptr; - } - - shapes.emplace_back(mbgl::AnnotationSegments {{ segment.first }}, segment.second); - - env->DeleteLocalRef(polygon); - } - - std::vector 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(nativeMapViewPtr); - nativeMapView->getMap().removeAnnotation((uint32_t)annotationId); -} - -void JNICALL nativeRemoveAnnotations(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jlongArray array) { - mbgl::Log::Debug(mbgl::Event::JNI, "nativeRemoveAnnotations"); - assert(nativeMapViewPtr != 0); - NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - - std::vector ids; - - if (env->ExceptionCheck() || (array == nullptr)) { - env->ExceptionDescribe(); - return; - } - - jsize len = env->GetArrayLength(array); - if (len < 0) { - env->ExceptionDescribe(); - return; - } - - ids.reserve(len); - jlong* jids = env->GetLongArrayElements(array, nullptr); - - for (jsize i = 0; i < len; i++) { - if(jids[i] == -1L) - continue; - ids.push_back((uint32_t) jids[i]); - } - - env->ReleaseLongArrayElements(array, jids, JNI_ABORT); - - nativeMapView->getMap().removeAnnotations(ids); -} - jobject JNICALL nativeGetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetLatLng"); assert(nativeMapViewPtr != 0); @@ -956,6 +726,219 @@ void JNICALL nativeResetNorth(JNIEnv *env, jobject obj, jlong 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(nativeMapViewPtr); + + jobject position = env->GetObjectField(marker, markerPositionId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + jstring jsprite = reinterpret_cast(env->GetObjectField(marker, markerSpriteId)); + std::string sprite = std_string_from_jstring(env, jsprite); + + 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), sprite)); +} + +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(nativeMapViewPtr); + + jfloat alpha = env->GetFloatField(polyline, polylineAlphaId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return -1; + } + + /*jboolean visible = env->GetBooleanField(polyline, polylineVisibleId); + 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::StyleProperties shapeProperties; + mbgl::LineProperties lineProperties; + lineProperties.opacity = alpha; + lineProperties.color = {{ static_cast(r) / 255.0f, static_cast(g) / 255.0f, static_cast(b) / 255.0f, static_cast(a) / 255.0f }}; + lineProperties.width = width; + shapeProperties.set(lineProperties); + + jobject points = env->GetObjectField(polyline, polylinePointsId); + mbgl::AnnotationSegment segment = annotation_segment_from_latlng_jlist(env, points); + + std::vector shapes; + shapes.emplace_back(mbgl::AnnotationSegments { segment }, shapeProperties); + + std::vector shapeAnnotationIDs = nativeMapView->getMap().addShapeAnnotations(shapes); + uint32_t id = shapeAnnotationIDs.at(0); + + return id; +} + +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(nativeMapViewPtr); + + std::vector shapes; + std::pair 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 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(nativeMapViewPtr); + + std::vector shapes; + + if (jlist == nullptr) { + if (env->ThrowNew(nullPointerExceptionClass, "List cannot be null.") < 0) { + env->ExceptionDescribe(); + return nullptr; + } + return nullptr; + } + + jobjectArray jarray = + reinterpret_cast(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(env->GetObjectArrayElement(jarray, i)); + + std::pair 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 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(nativeMapViewPtr); + nativeMapView->getMap().removeAnnotation(static_cast(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(nativeMapViewPtr); + + std::vector 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(jids[i])); + } + + env->ReleaseLongArrayElements(jarray, jids, JNI_ABORT); + + nativeMapView->getMap().removeAnnotations(ids); +} + +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(nativeMapViewPtr); + + const std::string symbolName = std_string_from_jstring(env, symbol); + + jbyte* pixelData = env->GetByteArrayElements(jpixels, nullptr); + std::string pixels(reinterpret_cast(pixelData), width * height * 4); + env->ReleaseByteArrayElements(jpixels, pixelData, JNI_ABORT); + + auto spriteImage = std::make_shared( + uint16_t(width), + uint16_t(height), + float(scale), + std::move(pixels)); + + nativeMapView->getMap().setSprite(symbolName, spriteImage); +} + void JNICALL nativeOnLowMemory(JNIEnv *env, jobject obj, jlong nativeMapViewPtr) { mbgl::Log::Debug(mbgl::Event::JNI, "nativeOnLowMemory"); assert(nativeMapViewPtr != 0); @@ -1179,6 +1162,36 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } + latLngZoomClass = env->FindClass("com/mapbox/mapboxgl/geometry/LatLngZoom"); + if (latLngZoomClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + latLngZoomConstructorId = env->GetMethodID(latLngZoomClass, "", "(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; + } + markerClass = env->FindClass("com/mapbox/mapboxgl/annotations/Marker"); if (markerClass == nullptr) { env->ExceptionDescribe(); @@ -1299,36 +1312,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } - latLngZoomClass = env->FindClass("com/mapbox/mapboxgl/geometry/LatLngZoom"); - if (latLngZoomClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngZoomConstructorId = env->GetMethodID(latLngZoomClass, "", "(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; - } - jclass nativeMapViewClass = env->FindClass("com/mapbox/mapboxgl/views/NativeMapView"); if (nativeMapViewClass == nullptr) { env->ExceptionDescribe(); @@ -1492,17 +1475,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { {"nativeMoveBy", "(JDDJ)V", reinterpret_cast(&nativeMoveBy)}, {"nativeSetLatLng", "(JLcom/mapbox/mapboxgl/geometry/LatLng;J)V", reinterpret_cast(&nativeSetLatLng)}, - {"nativeSetSprite", "(JLjava/lang/String;IIF[B)V", reinterpret_cast(&nativeSetSprite)}, - {"nativeAddMarker", "(JLcom/mapbox/mapboxgl/annotations/Marker;)J", - reinterpret_cast(&nativeAddMarker)}, - {"nativeAddPolyline", "(JLcom/mapbox/mapboxgl/annotations/Polyline;)J", - reinterpret_cast(&nativeAddPolyline)}, - {"nativeAddPolygon", "(JLcom/mapbox/mapboxgl/annotations/Polygon;)J", - reinterpret_cast(&nativeAddPolygon)}, - {"nativeAddPolygons", "(JLjava/util/List;)[J", - reinterpret_cast(&nativeAddPolygons)}, - {"nativeRemoveAnnotation", "(JJ)V", reinterpret_cast(&nativeRemoveAnnotation)}, - {"nativeRemoveAnnotations", "(J[J)V", reinterpret_cast(&nativeRemoveAnnotations)}, {"nativeGetLatLng", "(J)Lcom/mapbox/mapboxgl/geometry/LatLng;", reinterpret_cast(&nativeGetLatLng)}, {"nativeResetPosition", "(J)V", reinterpret_cast(&nativeResetPosition)}, @@ -1529,6 +1501,17 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { &nativeSetBearing))}, {"nativeGetBearing", "(J)D", reinterpret_cast(&nativeGetBearing)}, {"nativeResetNorth", "(J)V", reinterpret_cast(&nativeResetNorth)}, + {"nativeAddMarker", "(JLcom/mapbox/mapboxgl/annotations/Marker;)J", + reinterpret_cast(&nativeAddMarker)}, + {"nativeAddPolyline", "(JLcom/mapbox/mapboxgl/annotations/Polyline;)J", + reinterpret_cast(&nativeAddPolyline)}, + {"nativeAddPolygon", "(JLcom/mapbox/mapboxgl/annotations/Polygon;)J", + reinterpret_cast(&nativeAddPolygon)}, + {"nativeAddPolygons", "(JLjava/util/List;)[J", + reinterpret_cast(&nativeAddPolygons)}, + {"nativeRemoveAnnotation", "(JJ)V", reinterpret_cast(&nativeRemoveAnnotation)}, + {"nativeRemoveAnnotations", "(J[J)V", reinterpret_cast(&nativeRemoveAnnotations)}, + {"nativeSetSprite", "(JLjava/lang/String;IIF[B)V", reinterpret_cast(&nativeSetSprite)}, {"nativeOnLowMemory", "(J)V", reinterpret_cast(&nativeOnLowMemory)}, {"nativeSetDebug", "(JZ)V", reinterpret_cast(&nativeSetDebug)}, {"nativeToggleDebug", "(J)V", reinterpret_cast(&nativeToggleDebug)}, @@ -1558,28 +1541,37 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } + latLngZoomClass = reinterpret_cast(env->NewGlobalRef(latLngZoomClass)); + if (latLngZoomClass == nullptr) { + env->ExceptionDescribe(); + env->DeleteGlobalRef(latLngClass); + return JNI_ERR; + } + markerClass = reinterpret_cast(env->NewGlobalRef(markerClass)); if (markerClass == nullptr) { env->ExceptionDescribe(); + env->DeleteGlobalRef(latLngClass); + env->DeleteGlobalRef(latLngZoomClass); return JNI_ERR; } polylineClass = reinterpret_cast(env->NewGlobalRef(polylineClass)); if (polylineClass == nullptr) { env->ExceptionDescribe(); + env->DeleteGlobalRef(latLngClass); + env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(markerClass); return JNI_ERR; } polygonClass = reinterpret_cast(env->NewGlobalRef(polygonClass)); if (polygonClass == nullptr) { - env->ExceptionDescribe(); - return JNI_ERR; - } - - latLngZoomClass = reinterpret_cast(env->NewGlobalRef(latLngZoomClass)); - if (latLngZoomClass == nullptr) { env->ExceptionDescribe(); env->DeleteGlobalRef(latLngClass); + env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(markerClass); + env->DeleteGlobalRef(polylineClass); return JNI_ERR; } @@ -1588,6 +1580,9 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { env->ExceptionDescribe(); env->DeleteGlobalRef(latLngClass); env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(markerClass); + env->DeleteGlobalRef(polylineClass); + env->DeleteGlobalRef(polygonClass); return JNI_ERR; } @@ -1597,6 +1592,9 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { env->ExceptionDescribe(); env->DeleteGlobalRef(latLngClass); env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(markerClass); + env->DeleteGlobalRef(polylineClass); + env->DeleteGlobalRef(polygonClass); env->DeleteGlobalRef(runtimeExceptionClass); return JNI_ERR; } @@ -1606,6 +1604,9 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { env->ExceptionDescribe(); env->DeleteGlobalRef(latLngClass); env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(markerClass); + env->DeleteGlobalRef(polylineClass); + env->DeleteGlobalRef(polygonClass); env->DeleteGlobalRef(runtimeExceptionClass); env->DeleteGlobalRef(nullPointerExceptionClass); return JNI_ERR; @@ -1616,18 +1617,23 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { env->ExceptionDescribe(); env->DeleteGlobalRef(latLngClass); env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(markerClass); + env->DeleteGlobalRef(polylineClass); + env->DeleteGlobalRef(polygonClass); env->DeleteGlobalRef(runtimeExceptionClass); env->DeleteGlobalRef(nullPointerExceptionClass); env->DeleteGlobalRef(arrayListClass); return JNI_ERR; } - pointFClass = reinterpret_cast(env->NewGlobalRef(pointFClass)); if (pointFClass == nullptr) { env->ExceptionDescribe(); env->DeleteGlobalRef(latLngClass); + env->DeleteGlobalRef(markerClass); env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(polylineClass); + env->DeleteGlobalRef(polygonClass); env->DeleteGlobalRef(runtimeExceptionClass); env->DeleteGlobalRef(nullPointerExceptionClass); env->DeleteGlobalRef(arrayListClass); @@ -1635,7 +1641,6 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } - char release[PROP_VALUE_MAX] = ""; __system_property_get("ro.build.version.release", release); androidRelease = std::string(release); @@ -1659,6 +1664,13 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { latLngLongitudeId = nullptr; latLngLatitudeId = nullptr; + env->DeleteGlobalRef(latLngZoomClass); + latLngZoomClass = nullptr; + latLngZoomConstructorId = nullptr; + latLngZoomLongitudeId = nullptr; + latLngZoomLatitudeId = nullptr; + latLngZoomZoomId = nullptr; + env->DeleteGlobalRef(markerClass); markerClass = nullptr; markerConstructorId = nullptr; @@ -1685,14 +1697,6 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { polygonPointsId = nullptr; polygonHolesId = nullptr; - - env->DeleteGlobalRef(latLngZoomClass); - latLngZoomClass = nullptr; - latLngZoomConstructorId = nullptr; - latLngZoomLongitudeId = nullptr; - latLngZoomLatitudeId = nullptr; - latLngZoomZoomId = nullptr; - onInvalidateId = nullptr; onMapChangedId = nullptr; onFpsChangedId = nullptr; diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java index 6feb733f0..4f172c6e2 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/annotations/Annotation.java @@ -10,20 +10,19 @@ public abstract class Annotation { * * Internal C++ id is stored as unsigned int. */ - protected Long id; // null unless added to a MapView + protected long id = -1; // -1 unless added to a MapView private MapView mapView; - float alpha = 1; + float alpha = 1.0f; boolean visible = true; - public Annotation() {} public float getAlpha() { return alpha; } - public Long getId() { + public long getId() { return id; } @@ -40,7 +39,7 @@ public abstract class Annotation { this.alpha = alpha; } - public void setId(Long id) { + public void setId(long id) { this.id = id; } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java index bc4b823c0..473f33a1a 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/views/MapView.java @@ -241,7 +241,7 @@ public class MapView extends SurfaceView { public Marker addMarker(MarkerOptions markerOptions) { Marker marker = markerOptions.getMarker(); - Long id = mNativeMapView.addMarker(marker); + long id = mNativeMapView.addMarker(marker); marker.setId(id); // the annotation needs to know its id marker.setMapView(this); // the annotation needs to know which map view it is in annotations.add(marker); @@ -250,7 +250,7 @@ public class MapView extends SurfaceView { public Polyline addPolyline(PolylineOptions polylineOptions) { Polyline polyline = polylineOptions.getPolyline(); - Long id = mNativeMapView.addPolyline(polyline); + long id = mNativeMapView.addPolyline(polyline); polyline.setId(id); polyline.setMapView(this); annotations.add(polyline); @@ -259,7 +259,7 @@ public class MapView extends SurfaceView { public Polygon addPolygon(PolygonOptions polygonOptions) { Polygon polygon = polygonOptions.getPolygon(); - Long id = mNativeMapView.addPolygon(polygon); + long id = mNativeMapView.addPolygon(polygon); polygon.setId(id); polygon.setMapView(this); annotations.add(polygon); @@ -274,7 +274,7 @@ public class MapView extends SurfaceView { long[] ids = mNativeMapView.addPolygons(polygons); - for(int i=0; i polygon) { - // NH TODO Throw exception if returns -1 - return nativeAddPolygons(mNativeMapViewPtr, polygon); - } - - public void removeAnnotation(long id) { - nativeRemoveAnnotation(mNativeMapViewPtr, id); - } - - public void removeAnnotations(long[] ids) { - nativeRemoveAnnotations(mNativeMapViewPtr, ids); - } - public LatLng getLatLng() { return nativeGetLatLng(mNativeMapViewPtr); } @@ -356,6 +325,34 @@ class NativeMapView { nativeResetNorth(mNativeMapViewPtr); } + public long addMarker(Marker marker) { + return nativeAddMarker(mNativeMapViewPtr, marker); + } + + public long addPolyline(Polyline polyline) { + return nativeAddPolyline(mNativeMapViewPtr, polyline); + } + + public long addPolygon(Polygon polygon) { + return nativeAddPolygon(mNativeMapViewPtr, polygon); + } + + public long[] addPolygons(List polygon) { + return nativeAddPolygons(mNativeMapViewPtr, polygon); + } + + public void removeAnnotation(long id) { + nativeRemoveAnnotation(mNativeMapViewPtr, id); + } + + public void removeAnnotations(long[] ids) { + nativeRemoveAnnotations(mNativeMapViewPtr, ids); + } + + public void setSprite(String symbol, int width, int height, float scale, byte[] pixels) { + nativeSetSprite(mNativeMapViewPtr, symbol, width, height, scale, pixels); + } + public void onLowMemory() { nativeOnLowMemory(mNativeMapViewPtr); } @@ -392,7 +389,7 @@ class NativeMapView { nativeSetReachability(mNativeMapViewPtr, status); } - //public void getWorldBoundsMeters(); + //public void (); //public void getWorldBoundsLatLng(); @@ -507,21 +504,6 @@ class NativeMapView { private native void nativeSetLatLng(long nativeMapViewPtr, LatLng latLng, long duration); - private native void nativeSetSprite(long nativeMapViewPtr, String symbol, - int width, int height, float scale, byte[] pixels); - - private native long nativeAddMarker(long nativeMapViewPtr, Marker marker); - - private native long nativeAddPolyline(long nativeMapViewPtr, Polyline polyline); - - private native long nativeAddPolygon(long mNativeMapViewPtr, Polygon polygon); - - private native long[] nativeAddPolygons(long mNativeMapViewPtr, List polygon); - - private native void nativeRemoveAnnotation(long nativeMapViewPtr, long id); - - private native void nativeRemoveAnnotations(long nativeMapViewPtr, long[] id); - private native LatLng nativeGetLatLng(long nativeMapViewPtr); private native void nativeResetPosition(long nativeMapViewPtr); @@ -563,6 +545,21 @@ class NativeMapView { private native void nativeResetNorth(long nativeMapViewPtr); + private native long nativeAddMarker(long nativeMapViewPtr, Marker marker); + + private native long nativeAddPolyline(long nativeMapViewPtr, Polyline polyline); + + private native long nativeAddPolygon(long mNativeMapViewPtr, Polygon polygon); + + private native long[] nativeAddPolygons(long mNativeMapViewPtr, List polygon); + + private native void nativeRemoveAnnotation(long nativeMapViewPtr, long id); + + private native void nativeRemoveAnnotations(long nativeMapViewPtr, long[] id); + + private native void nativeSetSprite(long nativeMapViewPtr, String symbol, + int width, int height, float scale, byte[] pixels); + private native void nativeOnLowMemory(long nativeMapViewPtr); private native void nativeSetDebug(long nativeMapViewPtr, boolean debug); diff --git a/include/mbgl/android/jni.hpp b/include/mbgl/android/jni.hpp index 48e2740b0..f27c8c844 100644 --- a/include/mbgl/android/jni.hpp +++ b/include/mbgl/android/jni.hpp @@ -31,6 +31,29 @@ extern jfieldID latLngZoomLatitudeId; extern jfieldID latLngZoomLongitudeId; extern jfieldID latLngZoomZoomId; +extern jclass markerClass; +extern jmethodID markerConstructorId; +extern jfieldID markerPositionId; +extern jfieldID markerSpriteId; + +extern jclass polylineClass; +extern jmethodID polylineConstructorId; +extern jfieldID polylineAlphaId; +extern jfieldID polylineVisibleId; +extern jfieldID polylineColorId; +extern jfieldID polylineWidthId; +extern jfieldID polylinePointsId; + +extern jclass polygonClass; +extern jmethodID polygonConstructorId; +extern jfieldID polygonAlphaId; +extern jfieldID polygonVisibleId; +extern jfieldID polygonFillColorId; +extern jfieldID polygonStrokeColorId; +extern jfieldID polygonStrokeWidthId; +extern jfieldID polygonPointsId; +extern jfieldID polygonHolesId; + extern jclass runtimeExceptionClass; extern jclass nullPointerExceptionClass;