summaryrefslogtreecommitdiff
path: root/platform/android/src/native_map_view.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/src/native_map_view.cpp')
-rwxr-xr-xplatform/android/src/native_map_view.cpp1163
1 files changed, 930 insertions, 233 deletions
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp
index b36b477f2f..a0bd06345f 100755
--- a/platform/android/src/native_map_view.cpp
+++ b/platform/android/src/native_map_view.cpp
@@ -1,6 +1,4 @@
#include "native_map_view.hpp"
-#include "jni.hpp"
-#include "default_file_source.hpp"
#include <cstdlib>
#include <ctime>
@@ -11,90 +9,91 @@
#include <sys/system_properties.h>
-#include <mbgl/util/platform.hpp>
-#include <mbgl/util/event.hpp>
-#include <mbgl/util/logging.hpp>
-#include <mbgl/gl/extension.hpp>
+#include <EGL/egl.h>
+#include <android/native_window_jni.h>
+
+#include <jni/jni.hpp>
+
#include <mbgl/gl/context.hpp>
+#include <mbgl/gl/extension.hpp>
#include <mbgl/map/backend_scope.hpp>
#include <mbgl/util/constants.hpp>
+#include <mbgl/util/event.hpp>
+#include <mbgl/util/exception.hpp>
+#include <mbgl/util/geo.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/shared_thread_pool.hpp>
+#include <mbgl/util/logging.hpp>
+#include <mbgl/util/platform.hpp>
+#include <mbgl/sprite/sprite_image.hpp>
+
+#include "conversion/conversion.hpp"
+#include "conversion/collection.hpp"
+#include "geometry/conversion/feature.hpp"
+#include "jni.hpp"
+#include "attach_env.hpp"
#include "bitmap.hpp"
+#include "run_loop_impl.hpp"
+#include "java/util.hpp"
namespace mbgl {
namespace android {
-NativeMapView::NativeMapView(JNIEnv *env_, jobject obj_, float pixelRatio, int availableProcessors_, size_t totalMemory_)
- : env(env_),
- availableProcessors(availableProcessors_),
- totalMemory(totalMemory_),
- fileSource(defaultFileSource(mbgl::android::cachePath + "/mbgl-offline.db", mbgl::android::apkPath)),
- threadPool(sharedThreadPool()) {
-
- assert(env_ != nullptr);
- assert(obj_ != nullptr);
-
- if (env->GetJavaVM(&vm) < 0) {
- env->ExceptionDescribe();
- return;
- }
-
- obj = env->NewWeakGlobalRef(obj_);
- if (obj == nullptr) {
- env->ExceptionDescribe();
+NativeMapView::NativeMapView(jni::JNIEnv& _env, jni::Object<NativeMapView> _obj, jni::Object<FileSource> jFileSource,
+ jni::jfloat _pixelRatio, jni::jint _availableProcessors, jni::jlong _totalMemory) :
+ javaPeer(_obj.NewWeakGlobalRef(_env)),
+ pixelRatio(_pixelRatio),
+ availableProcessors(_availableProcessors),
+ totalMemory(_totalMemory),
+ threadPool(sharedThreadPool()) {
+
+ // Get a reference to the JavaVM for callbacks
+ if (_env.GetJavaVM(&vm) < 0) {
+ _env.ExceptionDescribe();
return;
}
+ // Create the core map
map = std::make_unique<mbgl::Map>(
*this, mbgl::Size{ static_cast<uint32_t>(width), static_cast<uint32_t>(height) },
- pixelRatio, fileSource, *threadPool, MapMode::Continuous);
+ pixelRatio, mbgl::android::FileSource::getDefaultFileSource(_env, jFileSource)
+ , *threadPool, MapMode::Continuous);
+ //Calculate a fitting cache size based on device parameters
float zoomFactor = map->getMaxZoom() - map->getMinZoom() + 1;
float cpuFactor = availableProcessors;
float memoryFactor = static_cast<float>(totalMemory) / 1000.0f / 1000.0f / 1000.0f;
float sizeFactor = (static_cast<float>(map->getSize().width) / mbgl::util::tileSize) *
- (static_cast<float>(map->getSize().height) / mbgl::util::tileSize);
+ (static_cast<float>(map->getSize().height) / mbgl::util::tileSize);
- size_t cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5f;
-
- map->setSourceTileCacheSize(cacheSize);
+ map->setSourceTileCacheSize(zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5f);
}
+/**
+ * Called through NativeMapView#destroy()
+ */
NativeMapView::~NativeMapView() {
- terminateContext();
- destroySurface();
- terminateDisplay();
-
- assert(vm != nullptr);
- assert(obj != nullptr);
+ _terminateContext();
+ _destroySurface();
+ _terminateDisplay();
map.reset();
- env->DeleteWeakGlobalRef(obj);
-
- obj = nullptr;
- env = nullptr;
vm = nullptr;
}
-mbgl::Size NativeMapView::getFramebufferSize() const {
- return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) };
-}
-
-void NativeMapView::updateViewBinding() {
- getContext().bindFramebuffer.setCurrentValue(0);
- assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue());
- getContext().viewport.setCurrentValue({ 0, 0, getFramebufferSize() });
- assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
-}
-
+/**
+ * From mbgl::View
+ */
void NativeMapView::bind() {
getContext().bindFramebuffer = 0;
getContext().viewport = { 0, 0, getFramebufferSize() };
}
+/**
+ * From mbgl::Backend.
+ */
void NativeMapView::activate() {
if (active++) {
return;
@@ -123,6 +122,9 @@ void NativeMapView::activate() {
}
}
+/**
+ * From mbgl::Backend.
+ */
void NativeMapView::deactivate() {
if (--active) {
return;
@@ -147,17 +149,57 @@ void NativeMapView::deactivate() {
}
}
+/**
+ * From mbgl::Backend. Callback to java NativeMapView#onInvalidate().
+ *
+ * May be called from any thread
+ */
void NativeMapView::invalidate() {
+ android::UniqueEnv _env = android::AttachEnv();
+ static auto onInvalidate = javaClass.GetMethod<void ()>(*_env, "onInvalidate");
+ javaPeer->Call(*_env, onInvalidate);
+}
+
+/**
+ * From mbgl::Backend. Callback to java NativeMapView#onMapChanged(int).
+ *
+ * May be called from any thread
+ */
+void NativeMapView::notifyMapChange(mbgl::MapChange change) {
assert(vm != nullptr);
- assert(obj != nullptr);
- env->CallVoidMethod(obj, onInvalidateId);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- }
+ android::UniqueEnv _env = android::AttachEnv();
+ static auto onMapChanged = javaClass.GetMethod<void (int)>(*_env, "onMapChanged");
+ javaPeer->Call(*_env, onMapChanged, (int) change);
+}
+
+// JNI Methods //
+
+void NativeMapView::initializeDisplay(jni::JNIEnv&) {
+ _initializeDisplay();
+}
+
+void NativeMapView::terminateDisplay(jni::JNIEnv&) {
+ _terminateDisplay();
+}
+
+void NativeMapView::initializeContext(jni::JNIEnv&) {
+ _initializeContext();
}
-void NativeMapView::render() {
+void NativeMapView::terminateContext(jni::JNIEnv&) {
+ _terminateContext();
+}
+
+void NativeMapView::createSurface(jni::JNIEnv& env, jni::Object<> _surface) {
+ _createSurface(ANativeWindow_fromSurface(&env, jni::Unwrap(*_surface)));
+}
+
+void NativeMapView::destroySurface(jni::JNIEnv&) {
+ _destroySurface();
+}
+
+void NativeMapView::render(jni::JNIEnv& env) {
BackendScope guard(*this);
if (framebufferSizeChanged) {
@@ -173,13 +215,12 @@ void NativeMapView::render() {
// take snapshot
auto image = getContext().readFramebuffer<mbgl::PremultipliedImage>(getFramebufferSize());
- auto bitmap = Bitmap::CreateBitmap(*env, std::move(image));
+ auto bitmap = Bitmap::CreateBitmap(env, std::move(image));
// invoke Mapview#OnSnapshotReady
- env->CallVoidMethod(obj, onSnapshotReadyId, jni::Unwrap(*bitmap));
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- }
+ android::UniqueEnv _env = android::AttachEnv();
+ static auto onSnapshotReady = javaClass.GetMethod<void (jni::Object<Bitmap>)>(*_env, "onSnapshotReady");
+ javaPeer->Call(*_env, onSnapshotReady, bitmap);
}
if ((display != EGL_NO_DISPLAY) && (surface != EGL_NO_SURFACE)) {
@@ -195,13 +236,611 @@ void NativeMapView::render() {
}
}
-mbgl::Map &NativeMapView::getMap() { return *map; }
+void NativeMapView::update(jni::JNIEnv&) {
+ invalidate();
+}
+
+void NativeMapView::resizeView(jni::JNIEnv&, int w, int h) {
+ width = w;
+ height = h;
+ map->setSize({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
+}
+
+void NativeMapView::resizeFramebuffer(jni::JNIEnv&, int w, int h) {
+ fbWidth = w;
+ fbHeight = h;
+ framebufferSizeChanged = true;
+ invalidate();
+}
+
+jni::String NativeMapView::getStyleUrl(jni::JNIEnv& env) {
+ return jni::Make<jni::String>(env, map->getStyleURL());
+}
+
+void NativeMapView::setStyleUrl(jni::JNIEnv& env, jni::String url) {
+ map->setStyleURL(jni::Make<std::string>(env, url));
+}
+
+jni::String NativeMapView::getStyleJson(jni::JNIEnv& env) {
+ return jni::Make<jni::String>(env, map->getStyleJSON());
+}
+
+void NativeMapView::setStyleJson(jni::JNIEnv& env, jni::String json) {
+ map->setStyleJSON(jni::Make<std::string>(env, json));
+}
+
+void NativeMapView::cancelTransitions(jni::JNIEnv&) {
+ map->cancelTransitions();
+}
+
+void NativeMapView::setGestureInProgress(jni::JNIEnv&, jni::jboolean inProgress) {
+ map->setGestureInProgress(inProgress);
+}
+
+void NativeMapView::moveBy(jni::JNIEnv&, jni::jdouble dx, jni::jdouble dy, jni::jlong duration) {
+ mbgl::AnimationOptions animationOptions;
+ if (duration > 0) {
+ animationOptions.duration.emplace(mbgl::Milliseconds(duration));
+ animationOptions.easing.emplace(mbgl::util::UnitBezier { 0, 0.3, 0.6, 1.0 });
+ }
+ map->moveBy({dx, dy}, animationOptions);
+}
+
+void NativeMapView::jumpTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jdouble pitch, jni::jdouble zoom) {
+ mbgl::CameraOptions options;
+ if (angle != -1) {
+ options.angle = (-angle * M_PI) / 180;
+ }
+ options.center = mbgl::LatLng(latitude, longitude);
+ options.padding = insets;
+ if (pitch != -1) {
+ options.pitch = pitch * M_PI / 180;
+ }
+ if (zoom != -1) {
+ options.zoom = zoom;
+ }
+
+ map->jumpTo(options);
+}
+
+void NativeMapView::easeTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom, jni::jboolean easing) {
+ mbgl::CameraOptions cameraOptions;
+ if (angle != -1) {
+ cameraOptions.angle = (-angle * M_PI) / 180;
+ }
+ cameraOptions.center = mbgl::LatLng(latitude, longitude);
+ cameraOptions.padding = insets;
+ if (pitch != -1) {
+ cameraOptions.pitch = pitch * M_PI / 180;
+ }
+ if (zoom != -1) {
+ cameraOptions.zoom = zoom;
+ }
+
+ mbgl::AnimationOptions animationOptions;
+ animationOptions.duration.emplace(mbgl::Duration(duration));
+ if (!easing) {
+ // add a linear interpolator instead of easing
+ animationOptions.easing.emplace(mbgl::util::UnitBezier { 0, 0, 1, 1 });
+ }
+
+ map->easeTo(cameraOptions, animationOptions);
+}
+
+void NativeMapView::flyTo(jni::JNIEnv&, jni::jdouble angle, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration, jni::jdouble pitch, jni::jdouble zoom) {
+ mbgl::CameraOptions cameraOptions;
+ if (angle != -1) {
+ cameraOptions.angle = (-angle * M_PI) / 180 ;
+ }
+ cameraOptions.center = mbgl::LatLng(latitude, longitude);
+ cameraOptions.padding = insets;
+ if (pitch != -1) {
+ cameraOptions.pitch = pitch * M_PI / 180;
+ }
+ if (zoom != -1) {
+ cameraOptions.zoom = zoom;
+ }
+
+ mbgl::AnimationOptions animationOptions;
+ animationOptions.duration.emplace(mbgl::Duration(duration));
+ map->flyTo(cameraOptions, animationOptions);
+}
+
+jni::Object<LatLng> NativeMapView::getLatLng(JNIEnv& env) {
+ mbgl::LatLng latLng = map->getLatLng(insets);
+ return LatLng::New(env, latLng.latitude, latLng.longitude);
+}
+
+void NativeMapView::setLatLng(jni::JNIEnv&, jni::jdouble latitude, jni::jdouble longitude, jni::jlong duration) {
+ map->setLatLng(mbgl::LatLng(latitude, longitude), insets, mbgl::Milliseconds(duration));
+}
+
+void NativeMapView::setReachability(jni::JNIEnv&, jni::jboolean reachable) {
+ if (reachable) {
+ mbgl::NetworkStatus::Reachable();
+ }
+}
+
+void NativeMapView::resetPosition(jni::JNIEnv&) {
+ map->resetPosition();
+}
+
+jni::jdouble NativeMapView::getPitch(jni::JNIEnv&) {
+ return map->getPitch();
+}
+
+void NativeMapView::setPitch(jni::JNIEnv&, jni::jdouble pitch, jni::jlong duration) {
+ map->setPitch(pitch, mbgl::Milliseconds(duration));
+}
+
+void NativeMapView::scaleBy(jni::JNIEnv&, jni::jdouble ds, jni::jdouble cx, jni::jdouble cy, jni::jlong duration) {
+ mbgl::ScreenCoordinate center(cx, cy);
+ map->scaleBy(ds, center, mbgl::Milliseconds(duration));
+}
+
+void NativeMapView::setScale(jni::JNIEnv&, jni::jdouble scale, jni::jdouble cx, jni::jdouble cy, jni::jlong duration) {
+ mbgl::ScreenCoordinate center(cx, cy);
+ map->setScale(scale, center, mbgl::Milliseconds(duration));
+}
+
+jni::jdouble NativeMapView::getScale(jni::JNIEnv&) {
+ return map->getScale();
+}
+
+void NativeMapView::setZoom(jni::JNIEnv&, jni::jdouble zoom, jni::jlong duration) {
+ map->setZoom(zoom, mbgl::Milliseconds(duration));
+}
+
+jni::jdouble NativeMapView::getZoom(jni::JNIEnv&) {
+ return map->getZoom();
+}
+
+void NativeMapView::resetZoom(jni::JNIEnv&) {
+ map->resetZoom();
+}
+
+void NativeMapView::setMinZoom(jni::JNIEnv&, jni::jdouble zoom) {
+ map->setMinZoom(zoom);
+}
+
+jni::jdouble NativeMapView::getMinZoom(jni::JNIEnv&) {
+ return map->getMinZoom();
+}
+
+void NativeMapView::setMaxZoom(jni::JNIEnv&, jni::jdouble zoom) {
+ map->setMaxZoom(zoom);
+}
+
+jni::jdouble NativeMapView::getMaxZoom(jni::JNIEnv&) {
+ return map->getMaxZoom();
+}
+
+void NativeMapView::rotateBy(jni::JNIEnv&, jni::jdouble sx, jni::jdouble sy, jni::jdouble ex, jni::jdouble ey, jni::jlong duration) {
+ mbgl::ScreenCoordinate first(sx, sy);
+ mbgl::ScreenCoordinate second(ex, ey);
+ map->rotateBy(first, second, mbgl::Milliseconds(duration));
+}
+
+void NativeMapView::setBearing(jni::JNIEnv&, jni::jdouble degrees, jni::jlong duration) {
+ map->setBearing(degrees, mbgl::Milliseconds(duration));
+}
+
+void NativeMapView::setBearingXY(jni::JNIEnv&, jni::jdouble degrees, jni::jdouble cx, jni::jdouble cy, jni::jlong duration) {
+ mbgl::ScreenCoordinate center(cx, cy);
+ map->setBearing(degrees, center, mbgl::Milliseconds(duration));
+}
+
+jni::jdouble NativeMapView::getBearing(jni::JNIEnv&) {
+ return map->getBearing();
+}
+
+void NativeMapView::resetNorth(jni::JNIEnv&) {
+ map->resetNorth();
+}
+
+void NativeMapView::setVisibleCoordinateBounds(JNIEnv& env, jni::Array<jni::Object<LatLng>> coordinates, jni::Object<RectF> padding, jdouble direction, jni::jlong duration) {
+ NullCheck(env, &coordinates);
+ std::size_t count = coordinates.Length(env);
+
+ std::vector<mbgl::LatLng> latLngs;
+ latLngs.reserve(count);
+
+ for (std::size_t i = 0; i < count; i++) {
+ auto latLng = coordinates.Get(env, i);
+ latLngs.push_back(LatLng::getLatLng(env, latLng));
+ jni::DeleteLocalRef(env, latLng);
+ }
+
+ mbgl::EdgeInsets mbglInsets = { RectF::getTop(env, padding), RectF::getLeft(env, padding), RectF::getBottom(env, padding), RectF::getRight(env, padding) };
+ mbgl::CameraOptions cameraOptions = map->cameraForLatLngs(latLngs, mbglInsets);
+ if (direction >= 0) {
+ // convert from degrees to radians
+ cameraOptions.angle = (-direction * M_PI) / 180;
+ }
+
+ mbgl::AnimationOptions animationOptions;
+ if (duration > 0) {
+ animationOptions.duration.emplace(mbgl::Milliseconds(duration));
+ // equivalent to kCAMediaTimingFunctionDefault in iOS
+ animationOptions.easing.emplace(mbgl::util::UnitBezier { 0.25, 0.1, 0.25, 0.1 });
+ }
+
+ map->easeTo(cameraOptions, animationOptions);
+}
+
+void NativeMapView::setContentPadding(JNIEnv&, double top, double left, double bottom, double right) {
+ insets = {top, left, bottom, right};
+}
+
+void NativeMapView::scheduleSnapshot(jni::JNIEnv&) {
+ snapshot = true;
+}
+
+void NativeMapView::enableFps(jni::JNIEnv&, jni::jboolean enable) {
+ fpsEnabled = enable;
+}
+
+jni::Array<jni::jdouble> NativeMapView::getCameraValues(jni::JNIEnv& env) {
+ //Create buffer with values
+ jdouble buf[5];
+ mbgl::LatLng latLng = map->getLatLng(insets);
+ buf[0] = latLng.latitude;
+ buf[1] = latLng.longitude;
+ buf[2] = -map->getBearing();
+ buf[3] = map->getPitch();
+ buf[4] = map->getZoom();
+
+ //Convert to Java array
+ auto output = jni::Array<jni::jdouble>::New(env, 5);
+ jni::SetArrayRegion(env, *output, 0, 5, buf);
+
+ return output;
+}
+
+void NativeMapView::updateMarker(jni::JNIEnv& env, jni::jlong markerId, jni::jdouble lat, jni::jdouble lon, jni::String jid) {
+ if (markerId == -1) {
+ return;
+ }
+
+ std::string iconId = jni::Make<std::string>(env, jid);
+ // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long.
+ map->updateAnnotation(markerId, mbgl::SymbolAnnotation { mbgl::Point<double>(lon, lat), iconId });
+}
+
+jni::Array<jni::jlong> NativeMapView::addMarkers(jni::JNIEnv& env, jni::Array<jni::Object<Marker>> jmarkers) {
+ jni::NullCheck(env, &jmarkers);
+ std::size_t len = jmarkers.Length(env);
+
+ std::vector<jni::jlong> ids;
+ ids.reserve(len);
+
+ for (std::size_t i = 0; i < len; i++) {
+ jni::Object<Marker> marker = jmarkers.Get(env, i);
+ ids.push_back(map->addAnnotation(mbgl::SymbolAnnotation {
+ Marker::getPosition(env, marker),
+ Marker::getIconId(env, marker)
+ }));
+
+ jni::DeleteLocalRef(env, marker);
+ }
+
+ auto result = jni::Array<jni::jlong>::New(env, len);
+ result.SetRegion<std::vector<jni::jlong>>(env, 0, ids);
+
+ return result;
+}
+
+void NativeMapView::onLowMemory(JNIEnv&) {
+ map->onLowMemory();
+}
+
+using DebugOptions = mbgl::MapDebugOptions;
+
+void NativeMapView::setDebug(JNIEnv&, jni::jboolean debug) {
+ DebugOptions debugOptions = debug ? DebugOptions::TileBorders | DebugOptions::ParseStatus | DebugOptions::Collision
+ : DebugOptions::NoDebug;
+ map->setDebug(debugOptions);
+ fpsEnabled = debug;
+}
+
+void NativeMapView::cycleDebugOptions(JNIEnv&) {
+ map->cycleDebugOptions();
+ fpsEnabled = map->getDebug() != DebugOptions::NoDebug;
+}
+
+jni::jboolean NativeMapView::getDebug(JNIEnv&) {
+ return map->getDebug() != DebugOptions::NoDebug;
+}
+
+jni::jboolean NativeMapView::isFullyLoaded(JNIEnv&) {
+ return map->isFullyLoaded();
+}
+
+jni::jdouble NativeMapView::getMetersPerPixelAtLatitude(JNIEnv&, jni::jdouble lat, jni::jdouble zoom) {
+ return map->getMetersPerPixelAtLatitude(lat, zoom);
+}
+
+jni::Object<ProjectedMeters> NativeMapView::projectedMetersForLatLng(JNIEnv& env, jni::jdouble latitude, jni::jdouble longitude) {
+ mbgl::ProjectedMeters projectedMeters = map->projectedMetersForLatLng(mbgl::LatLng(latitude, longitude));
+ return ProjectedMeters::New(env, projectedMeters.northing, projectedMeters.easting);
+}
+
+jni::Object<PointF> NativeMapView::pixelForLatLng(JNIEnv& env, jdouble latitude, jdouble longitude) {
+ mbgl::ScreenCoordinate pixel = map->pixelForLatLng(mbgl::LatLng(latitude, longitude));
+ return PointF::New(env, static_cast<float>(pixel.x), static_cast<float>(pixel.y));
+}
+
+jni::Object<LatLng> NativeMapView::latLngForProjectedMeters(JNIEnv& env, jdouble northing, jdouble easting) {
+ mbgl::LatLng latLng = map->latLngForProjectedMeters(mbgl::ProjectedMeters(northing, easting));
+ return LatLng::New(env, latLng.latitude, latLng.longitude);
+}
+
+jni::Object<LatLng> NativeMapView::latLngForPixel(JNIEnv& env, jfloat x, jfloat y) {
+ mbgl::LatLng latLng = map->latLngForPixel(mbgl::ScreenCoordinate(x, y));
+ return LatLng::New(env, latLng.latitude, latLng.longitude);
+}
+
+jni::Array<jlong> NativeMapView::addPolylines(JNIEnv& env, jni::Array<jni::Object<Polyline>> polylines) {
+ NullCheck(env, &polylines);
+ std::size_t len = polylines.Length(env);
+
+ std::vector<jni::jlong> ids;
+ ids.reserve(len);
+
+ for (std::size_t i = 0; i < len; i++) {
+ auto polyline = polylines.Get(env, i);
+
+ mbgl::LineAnnotation annotation = Polyline::toAnnotation(env, polyline);
+ ids.push_back(map->addAnnotation(annotation));
+
+ jni::DeleteLocalRef(env, polyline);
+ }
+
+ auto result = jni::Array<jni::jlong>::New(env, len);
+ result.SetRegion<std::vector<jni::jlong>>(env, 0, ids);
+
+ return result;
+}
+
+
+jni::Array<jlong> NativeMapView::addPolygons(JNIEnv& env, jni::Array<jni::Object<Polygon>> polygons) {
+ NullCheck(env, &polygons);
+ std::size_t len = polygons.Length(env);
+
+ std::vector<jni::jlong> ids;
+ ids.reserve(len);
+
+ for (std::size_t i = 0; i < len; i++) {
+ auto polygon = polygons.Get(env, i);
+
+ mbgl::FillAnnotation annotation = Polygon::toAnnotation(env, polygon);
+ ids.push_back(map->addAnnotation(annotation));
+
+ jni::DeleteLocalRef(env, polygon);
+ }
+
+ auto result = jni::Array<jni::jlong>::New(env, len);
+ result.SetRegion<std::vector<jni::jlong>>(env, 0, ids);
+
+ return result;
+}
+
+//TODO: Move to Polyline class and make native peer
+void NativeMapView::updatePolyline(JNIEnv& env, jlong polylineId, jni::Object<Polyline> polyline) {
+ mbgl::LineAnnotation annotation = Polyline::toAnnotation(env, polyline);
+ map->updateAnnotation(polylineId, annotation);
+}
+
+//TODO: Move to Polygon class and make native peer
+void NativeMapView::updatePolygon(JNIEnv& env, jlong polygonId, jni::Object<Polygon> polygon) {
+ mbgl::FillAnnotation annotation = Polygon::toAnnotation(env, polygon);
+ map->updateAnnotation(polygonId, annotation);
+}
+
+void NativeMapView::removeAnnotations(JNIEnv& env, jni::Array<jlong> ids) {
+ NullCheck(env, &ids);
+ std::size_t len = ids.Length(env);
+ auto elements = jni::GetArrayElements(env, *ids);
+ jlong* jids = std::get<0>(elements).get();
+
+ for (std::size_t i = 0; i < len; i++) {
+ if(jids[i] == -1L) {
+ continue;
+ }
+ map->removeAnnotation(jids[i]);
+ }
+}
+
+void NativeMapView::addAnnotationIcon(JNIEnv& env, jni::String symbol, jint w, jint h, jfloat scale, jni::Array<jbyte> jpixels) {
+ const std::string symbolName = jni::Make<std::string>(env, symbol);
+
+ NullCheck(env, &jpixels);
+ std::size_t size = jpixels.Length(env);
+
+ mbgl::PremultipliedImage premultipliedImage({ static_cast<uint32_t>(w), static_cast<uint32_t>(h) });
+ if (premultipliedImage.bytes() != uint32_t(size)) {
+ throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch");
+ }
+
+ jni::GetArrayRegion(env, *jpixels, 0, size, reinterpret_cast<jbyte*>(premultipliedImage.data.get()));
+ auto iconImage = std::make_shared<mbgl::SpriteImage>(std::move(premultipliedImage), float(scale));
+ map->addAnnotationIcon(symbolName, iconImage);
+}
+
+jdouble NativeMapView::getTopOffsetPixelsForAnnotationSymbol(JNIEnv& env, jni::String symbolName) {
+ return map->getTopOffsetPixelsForAnnotationIcon(jni::Make<std::string>(env, symbolName));
+}
+
+jlong NativeMapView::getTransitionDuration(JNIEnv&) {
+ const auto transitionOptions = map->getTransitionOptions();
+ return transitionOptions.duration.value_or(mbgl::Duration::zero()).count();
+}
+
+void NativeMapView::setTransitionDuration(JNIEnv&, jlong duration) {
+ auto transitionOptions = map->getTransitionOptions();
+ transitionOptions.duration = std::chrono::duration_cast<mbgl::Duration>(std::chrono::duration<jlong>(duration));
+ map->setTransitionOptions(transitionOptions);
+}
+
+jlong NativeMapView::getTransitionDelay(JNIEnv&) {
+ const auto transitionOptions = map->getTransitionOptions();
+ return transitionOptions.delay.value_or(mbgl::Duration::zero()).count();
+}
+
+void NativeMapView::setTransitionDelay(JNIEnv&, jlong delay) {
+ auto transitionOptions = map->getTransitionOptions();
+ transitionOptions.delay = std::chrono::duration_cast<mbgl::Duration>(std::chrono::duration<jlong>(delay));
+ map->setTransitionOptions(transitionOptions);
+}
+
+jni::Array<jlong> NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object<RectF> rect) {
+ // Convert input
+ mbgl::ScreenBox box = {
+ { RectF::getLeft(env, rect), RectF::getTop(env, rect) },
+ { RectF::getRight(env, rect), RectF::getBottom(env, rect) },
+ };
+
+ // Assume only points for now
+ mbgl::AnnotationIDs ids = map->queryPointAnnotations(box);
+
+ // Convert result
+ std::vector<jlong> longIds(ids.begin(), ids.end());
+ auto result = jni::Array<jni::jlong>::New(env, ids.size());
+ result.SetRegion<std::vector<jni::jlong>>(env, 0, longIds);
+
+ return result;
+}
+
+jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForPoint(JNIEnv& env, jni::jfloat x, jni::jfloat y, jni::Array<jni::String> layerIds) {
+ using namespace mbgl::android::conversion;
+ using namespace mapbox::geometry;
+
+ mbgl::optional<std::vector<std::string>> layers;
+ if (layerIds != nullptr && layerIds.Length(env) > 0) {
+ layers = toVector(env, layerIds);
+ }
+ point<double> point = {x, y};
+
+ return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, map->queryRenderedFeatures(point, layers));
+}
+
+jni::Array<jni::Object<Feature>> NativeMapView::queryRenderedFeaturesForBox(JNIEnv& env, jni::jfloat left, jni::jfloat top, jni::jfloat right, jni::jfloat bottom, jni::Array<jni::String> layerIds) {
+ using namespace mbgl::android::conversion;
+ using namespace mapbox::geometry;
+
+ mbgl::optional<std::vector<std::string>> layers;
+ if (layerIds != nullptr && layerIds.Length(env) > 0) {
+ layers = toVector(env, layerIds);
+ }
+ box<double> box = { point<double>{ left, top}, point<double>{ right, bottom } };
+
+ return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, map->queryRenderedFeatures(box, layers));
+}
+
+jni::Object<Layer> NativeMapView::getLayer(JNIEnv& env, jni::String layerId) {
+
+ // Find the layer
+ mbgl::style::Layer* coreLayer = map->getLayer(jni::Make<std::string>(env, layerId));
+ if (!coreLayer) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "No layer found");
+ return jni::Object<Layer>();
+ }
+
+ // Create and return the layer's native peer
+ return jni::Object<Layer>(createJavaLayerPeer(env, *map, *coreLayer));
+}
+
+void NativeMapView::addLayer(JNIEnv& env, jlong nativeLayerPtr, jni::String before) {
+ assert(nativeLayerPtr != 0);
+
+ Layer *layer = reinterpret_cast<Layer *>(nativeLayerPtr);
+ try {
+ layer->addToMap(*map, before ? mbgl::optional<std::string>(jni::Make<std::string>(env, before)) : mbgl::optional<std::string>());
+ } catch (const std::runtime_error& error) {
+ jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/layers/CannotAddLayerException"), error.what());
+ }
+}
+
+/**
+ * Remove by layer id. Ownership is not transferred back
+ */
+void NativeMapView::removeLayerById(JNIEnv& env, jni::String id) {
+ map->removeLayer(jni::Make<std::string>(env, id));
+}
+
+/**
+ * Remove with wrapper object id. Ownership is transferred back to the wrapper
+ */
+void NativeMapView::removeLayer(JNIEnv&, jlong layerPtr) {
+ assert(layerPtr != 0);
+
+ mbgl::android::Layer *layer = reinterpret_cast<mbgl::android::Layer *>(layerPtr);
+ std::unique_ptr<mbgl::style::Layer> coreLayer = map->removeLayer(layer->get().getID());
+ if (coreLayer) {
+ layer->setLayer(std::move(coreLayer));
+ }
+}
+
+
+jni::Object<Source> NativeMapView::getSource(JNIEnv& env, jni::String sourceId) {
+ // Find the source
+ mbgl::style::Source* coreSource = map->getSource(jni::Make<std::string>(env, sourceId));
+ if (!coreSource) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "No source found");
+ return jni::Object<Source>();
+ }
+
+ // Create and return the source's native peer
+ return jni::Object<Source>(createJavaSourcePeer(env, *map, *coreSource));
+}
+
+void NativeMapView::addSource(JNIEnv& env, jni::jlong sourcePtr) {
+ assert(sourcePtr != 0);
+
+ Source *source = reinterpret_cast<Source *>(sourcePtr);
+ try {
+ source->addToMap(*map);
+ } catch (const std::runtime_error& error) {
+ jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what());
+ }
+}
+
+void NativeMapView::removeSourceById(JNIEnv& env, jni::String id) {
+ map->removeSource(jni::Make<std::string>(env, id));
+}
+
+void NativeMapView::removeSource(JNIEnv&, jlong sourcePtr) {
+ assert(sourcePtr != 0);
+
+ mbgl::android::Source *source = reinterpret_cast<mbgl::android::Source *>(sourcePtr);
+ std::unique_ptr<mbgl::style::Source> coreSource = map->removeSource(source->get().getID());
+ if (coreSource) {
+ source->setSource(std::move(coreSource));
+ }
+}
+
+void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::jint w, jni::jint h, jni::jfloat scale, jni::Array<jbyte> pixels) {
+ jni::NullCheck(env, &pixels);
+ std::size_t size = pixels.Length(env);
+
+ mbgl::PremultipliedImage premultipliedImage({ static_cast<uint32_t>(w), static_cast<uint32_t>(h) });
+ if (premultipliedImage.bytes() != uint32_t(size)) {
+ throw mbgl::util::SpriteImageException("Sprite image pixel count mismatch");
+ }
-mbgl::DefaultFileSource& NativeMapView::getFileSource() {
- return fileSource;
+ jni::GetArrayRegion(env, *pixels, 0, size, reinterpret_cast<jbyte*>(premultipliedImage.data.get()));
+ auto spriteImage = std::make_unique<mbgl::SpriteImage>(std::move(premultipliedImage), float(scale));
+
+ map->addImage(jni::Make<std::string>(env, name), std::move(spriteImage));
+}
+
+void NativeMapView::removeImage(JNIEnv& env, jni::String name) {
+ map->removeImage(jni::Make<std::string>(env, name));
}
-void NativeMapView::initializeDisplay() {
+// Private methods //
+
+void NativeMapView::_initializeDisplay() {
assert(display == EGL_NO_DISPLAY);
assert(config == nullptr);
assert(format < 0);
@@ -286,145 +925,6 @@ void NativeMapView::initializeDisplay() {
}
}
-void NativeMapView::terminateDisplay() {
- if (display != EGL_NO_DISPLAY) {
- // Destroy the surface first, if it still exists. This call needs a valid surface.
- if (surface != EGL_NO_SURFACE) {
- if (!eglDestroySurface(display, surface)) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglDestroySurface() returned error %d",
- eglGetError());
- throw std::runtime_error("eglDestroySurface() failed");
- }
- surface = EGL_NO_SURFACE;
- }
-
- if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
- mbgl::Log::Error(mbgl::Event::OpenGL,
- "eglMakeCurrent(EGL_NO_CONTEXT) returned error %d", eglGetError());
- throw std::runtime_error("eglMakeCurrent() failed");
- }
-
- if (!eglTerminate(display)) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglTerminate() returned error %d",
- eglGetError());
- throw std::runtime_error("eglTerminate() failed");
- }
- }
-
- display = EGL_NO_DISPLAY;
- config = nullptr;
- format = -1;
-}
-
-void NativeMapView::initializeContext() {
- assert(display != EGL_NO_DISPLAY);
- assert(context == EGL_NO_CONTEXT);
- assert(config != nullptr);
-
- const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
- context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
- if (context == EGL_NO_CONTEXT) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglCreateContext() returned error %d",
- eglGetError());
- throw std::runtime_error("eglCreateContext() failed");
- }
-}
-
-void NativeMapView::terminateContext() {
- if (display != EGL_NO_DISPLAY) {
-
- if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
- mbgl::Log::Error(mbgl::Event::OpenGL,
- "eglMakeCurrent(EGL_NO_CONTEXT) returned error %d", eglGetError());
- throw std::runtime_error("eglMakeCurrent() failed");
- }
-
- if (context != EGL_NO_CONTEXT) {
- if (!eglDestroyContext(display, context)) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglDestroyContext() returned error %d",
- eglGetError());
- throw std::runtime_error("eglDestroyContext() failed");
- }
- }
- }
-
- context = EGL_NO_CONTEXT;
-}
-
-void NativeMapView::createSurface(ANativeWindow *window_) {
- assert(window == nullptr);
- assert(window_ != nullptr);
- window = window_;
-
- assert(display != EGL_NO_DISPLAY);
- assert(surface == EGL_NO_SURFACE);
- assert(config != nullptr);
- assert(format >= 0);
-
- ANativeWindow_setBuffersGeometry(window, 0, 0, format);
-
- const EGLint surfaceAttribs[] = {EGL_NONE};
- surface = eglCreateWindowSurface(display, config, window, surfaceAttribs);
- if (surface == EGL_NO_SURFACE) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglCreateWindowSurface() returned error %d",
- eglGetError());
- throw std::runtime_error("eglCreateWindowSurface() failed");
- }
-
- if (!firstTime) {
- firstTime = true;
-
- BackendScope guard(*this);
-
- if (!eglMakeCurrent(display, surface, surface, context)) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglMakeCurrent() returned error %d",
- eglGetError());
- throw std::runtime_error("eglMakeCurrent() failed");
- }
-
- mbgl::gl::InitializeExtensions([] (const char * name) {
- return reinterpret_cast<mbgl::gl::glProc>(eglGetProcAddress(name));
- });
- }
-}
-
-void NativeMapView::destroySurface() {
- if (surface != EGL_NO_SURFACE) {
- if (!eglDestroySurface(display, surface)) {
- mbgl::Log::Error(mbgl::Event::OpenGL, "eglDestroySurface() returned error %d",
- eglGetError());
- throw std::runtime_error("eglDestroySurface() failed");
- }
- }
-
- surface = EGL_NO_SURFACE;
-
- if (window != nullptr) {
- ANativeWindow_release(window);
- window = nullptr;
- }
-}
-
-void NativeMapView::scheduleTakeSnapshot() {
- snapshot = true;
-}
-
-// Speed
-/*
-typedef enum {
- Format16Bit = 0,
- Format32BitNoAlpha = 1,
- Format32BitAlpha = 2,
- Format24Bit = 3,
- Unknown = 4
-} BufferFormat;
-
-typedef enum {
- Format16Depth8Stencil = 0,
- Format24Depth8Stencil = 1,
-} DepthStencilFormat;
-*/
-
// Quality
typedef enum {
Format16Bit = 3,
@@ -589,18 +1089,134 @@ EGLConfig NativeMapView::chooseConfig(const EGLConfig configs[], EGLint numConfi
return configId;
}
-void NativeMapView::notifyMapChange(mbgl::MapChange change) {
- assert(vm != nullptr);
- assert(obj != nullptr);
+void NativeMapView::_terminateDisplay() {
+ if (display != EGL_NO_DISPLAY) {
+ // Destroy the surface first, if it still exists. This call needs a valid surface.
+ if (surface != EGL_NO_SURFACE) {
+ if (!eglDestroySurface(display, surface)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglDestroySurface() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglDestroySurface() failed");
+ }
+ surface = EGL_NO_SURFACE;
+ }
- env->CallVoidMethod(obj, onMapChangedId, change);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
+ if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL,
+ "eglMakeCurrent(EGL_NO_CONTEXT) returned error %d", eglGetError());
+ throw std::runtime_error("eglMakeCurrent() failed");
+ }
+
+ if (!eglTerminate(display)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglTerminate() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglTerminate() failed");
+ }
}
+
+ display = EGL_NO_DISPLAY;
+ config = nullptr;
+ format = -1;
}
-void NativeMapView::enableFps(bool enable) {
- fpsEnabled = enable;
+void NativeMapView::_initializeContext() {
+ assert(display != EGL_NO_DISPLAY);
+ assert(context == EGL_NO_CONTEXT);
+ assert(config != nullptr);
+
+ const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+ context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+ if (context == EGL_NO_CONTEXT) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglCreateContext() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglCreateContext() failed");
+ }
+}
+
+void NativeMapView::_terminateContext() {
+ if (display != EGL_NO_DISPLAY) {
+
+ if (!eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL,
+ "eglMakeCurrent(EGL_NO_CONTEXT) returned error %d", eglGetError());
+ throw std::runtime_error("eglMakeCurrent() failed");
+ }
+
+ if (context != EGL_NO_CONTEXT) {
+ if (!eglDestroyContext(display, context)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglDestroyContext() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglDestroyContext() failed");
+ }
+ }
+ }
+
+ context = EGL_NO_CONTEXT;
+}
+
+void NativeMapView::_createSurface(ANativeWindow *window_) {
+ assert(window == nullptr);
+ assert(window_ != nullptr);
+ window = window_;
+
+ assert(display != EGL_NO_DISPLAY);
+ assert(surface == EGL_NO_SURFACE);
+ assert(config != nullptr);
+ assert(format >= 0);
+
+ ANativeWindow_setBuffersGeometry(window, 0, 0, format);
+
+ const EGLint surfaceAttribs[] = {EGL_NONE};
+ surface = eglCreateWindowSurface(display, config, window, surfaceAttribs);
+ if (surface == EGL_NO_SURFACE) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglCreateWindowSurface() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglCreateWindowSurface() failed");
+ }
+
+ if (firstRender) {
+ firstRender = false;
+
+ BackendScope guard(*this);
+
+ if (!eglMakeCurrent(display, surface, surface, context)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglMakeCurrent() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglMakeCurrent() failed");
+ }
+
+ mbgl::gl::InitializeExtensions([] (const char * name) {
+ return reinterpret_cast<mbgl::gl::glProc>(eglGetProcAddress(name));
+ });
+ }
+}
+
+void NativeMapView::_destroySurface() {
+ if (surface != EGL_NO_SURFACE) {
+ if (!eglDestroySurface(display, surface)) {
+ mbgl::Log::Error(mbgl::Event::OpenGL, "eglDestroySurface() returned error %d",
+ eglGetError());
+ throw std::runtime_error("eglDestroySurface() failed");
+ }
+ }
+
+ surface = EGL_NO_SURFACE;
+
+ if (window != nullptr) {
+ ANativeWindow_release(window);
+ window = nullptr;
+ }
+}
+
+mbgl::Size NativeMapView::getFramebufferSize() const {
+ return { static_cast<uint32_t>(fbWidth), static_cast<uint32_t>(fbHeight) };
+}
+
+void NativeMapView::updateViewBinding() {
+ getContext().bindFramebuffer.setCurrentValue(0);
+ assert(mbgl::gl::value::BindFramebuffer::Get() == getContext().bindFramebuffer.getCurrentValue());
+ getContext().viewport.setCurrentValue({ 0, 0, getFramebufferSize() });
+ assert(mbgl::gl::value::Viewport::Get() == getContext().viewport.getCurrentValue());
}
void NativeMapView::updateFps() {
@@ -618,35 +1234,116 @@ void NativeMapView::updateFps() {
if (currentTime - timeElapsed >= 1) {
fps = frames / ((currentTime - timeElapsed) / 1E9);
- mbgl::Log::Debug(mbgl::Event::Render, "FPS: %4.2f", fps);
+ mbgl::Log::Info(mbgl::Event::Render, "FPS: %4.2f", fps);
timeElapsed = currentTime;
frames = 0;
}
assert(vm != nullptr);
- assert(obj != nullptr);
- env->CallVoidMethod(obj, onFpsChangedId, fps);
- if (env->ExceptionCheck()) {
- env->ExceptionDescribe();
- }
-}
-
-void NativeMapView::resizeView(int w, int h) {
- width = w;
- height = h;
- map->setSize({ static_cast<uint32_t>(width), static_cast<uint32_t>(height) });
-}
-
-void NativeMapView::resizeFramebuffer(int w, int h) {
- fbWidth = w;
- fbHeight = h;
- framebufferSizeChanged = true;
- invalidate();
+ android::UniqueEnv _env = android::AttachEnv();
+ static auto onFpsChanged = javaClass.GetMethod<void (double)>(*_env, "onFpsChanged");
+ javaPeer->Call(*_env, onFpsChanged, fps);
}
-void NativeMapView::setInsets(mbgl::EdgeInsets insets_) {
- insets = insets_;
+// Static methods //
+
+jni::Class<NativeMapView> NativeMapView::javaClass;
+
+void NativeMapView::registerNative(jni::JNIEnv& env) {
+ // Lookup the class
+ NativeMapView::javaClass = *jni::Class<NativeMapView>::Find(env).NewGlobalRef(env).release();
+
+ #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
+
+ // Register the peer
+ jni::RegisterNativePeer<NativeMapView>(env, NativeMapView::javaClass, "nativePtr",
+ std::make_unique<NativeMapView, JNIEnv&, jni::Object<NativeMapView>, jni::Object<FileSource>, jni::jfloat, jni::jint, jni::jlong>,
+ "nativeInitialize",
+ "nativeDestroy",
+ METHOD(&NativeMapView::render, "nativeRender"),
+ METHOD(&NativeMapView::update, "nativeUpdate"),
+ METHOD(&NativeMapView::resizeView, "nativeResizeView"),
+ METHOD(&NativeMapView::resizeFramebuffer, "nativeResizeFramebuffer"),
+ METHOD(&NativeMapView::initializeDisplay, "nativeInitializeDisplay"),
+ METHOD(&NativeMapView::terminateDisplay, "nativeTerminateDisplay"),
+ METHOD(&NativeMapView::initializeContext, "nativeInitializeContext"),
+ METHOD(&NativeMapView::terminateContext, "nativeTerminateContext"),
+ METHOD(&NativeMapView::createSurface, "nativeCreateSurface"),
+ METHOD(&NativeMapView::destroySurface, "nativeDestroySurface"),
+ METHOD(&NativeMapView::getStyleUrl, "nativeGetStyleUrl"),
+ METHOD(&NativeMapView::setStyleUrl, "nativeSetStyleUrl"),
+ METHOD(&NativeMapView::getStyleJson, "nativeGetStyleJson"),
+ METHOD(&NativeMapView::setStyleJson, "nativeSetStyleJson"),
+ METHOD(&NativeMapView::cancelTransitions, "nativeCancelTransitions"),
+ METHOD(&NativeMapView::setGestureInProgress, "nativeSetGestureInProgress"),
+ METHOD(&NativeMapView::moveBy, "nativeMoveBy"),
+ METHOD(&NativeMapView::jumpTo, "nativeJumpTo"),
+ METHOD(&NativeMapView::easeTo, "nativeEaseTo"),
+ METHOD(&NativeMapView::flyTo, "nativeFlyTo"),
+ METHOD(&NativeMapView::getLatLng, "nativeGetLatLng"),
+ METHOD(&NativeMapView::setLatLng, "nativeSetLatLng"),
+ METHOD(&NativeMapView::setReachability, "nativeSetReachability"),
+ METHOD(&NativeMapView::resetPosition, "nativeResetPosition"),
+ METHOD(&NativeMapView::getPitch, "nativeGetPitch"),
+ METHOD(&NativeMapView::setPitch, "nativeSetPitch"),
+ METHOD(&NativeMapView::scaleBy, "nativeScaleBy"),
+ METHOD(&NativeMapView::getScale, "nativeGetScale"),
+ METHOD(&NativeMapView::setScale, "nativeSetScale"),
+ METHOD(&NativeMapView::getZoom, "nativeGetZoom"),
+ METHOD(&NativeMapView::setZoom, "nativeSetZoom"),
+ METHOD(&NativeMapView::resetZoom, "nativeResetZoom"),
+ METHOD(&NativeMapView::setMinZoom, "nativeSetMinZoom"),
+ METHOD(&NativeMapView::getMinZoom, "nativeGetMinZoom"),
+ METHOD(&NativeMapView::setMaxZoom, "nativeSetMaxZoom"),
+ METHOD(&NativeMapView::getMaxZoom, "nativeGetMaxZoom"),
+ METHOD(&NativeMapView::rotateBy, "nativeRotateBy"),
+ METHOD(&NativeMapView::setBearing, "nativeSetBearing"),
+ METHOD(&NativeMapView::setBearingXY, "nativeSetBearingXY"),
+ METHOD(&NativeMapView::getBearing, "nativeGetBearing"),
+ METHOD(&NativeMapView::resetNorth, "nativeResetNorth"),
+ METHOD(&NativeMapView::setVisibleCoordinateBounds, "nativeSetVisibleCoordinateBounds"),
+ METHOD(&NativeMapView::setContentPadding, "nativeSetContentPadding"),
+ METHOD(&NativeMapView::scheduleSnapshot, "nativeTakeSnapshot"),
+ METHOD(&NativeMapView::enableFps, "nativeSetEnableFps"),
+ METHOD(&NativeMapView::getCameraValues, "nativeGetCameraValues"),
+ METHOD(&NativeMapView::updateMarker, "nativeUpdateMarker"),
+ METHOD(&NativeMapView::addMarkers, "nativeAddMarkers"),
+ METHOD(&NativeMapView::setDebug, "nativeSetDebug"),
+ METHOD(&NativeMapView::cycleDebugOptions, "nativeCycleDebugOptions"),
+ METHOD(&NativeMapView::getDebug, "nativeGetDebug"),
+ METHOD(&NativeMapView::isFullyLoaded, "nativeIsFullyLoaded"),
+ METHOD(&NativeMapView::onLowMemory, "nativeOnLowMemory"),
+ METHOD(&NativeMapView::getMetersPerPixelAtLatitude, "nativeGetMetersPerPixelAtLatitude"),
+ METHOD(&NativeMapView::projectedMetersForLatLng, "nativeProjectedMetersForLatLng"),
+ METHOD(&NativeMapView::pixelForLatLng, "nativePixelForLatLng"),
+ METHOD(&NativeMapView::latLngForProjectedMeters, "nativeLatLngForProjectedMeters"),
+ METHOD(&NativeMapView::latLngForPixel, "nativeLatLngForPixel"),
+ METHOD(&NativeMapView::addPolylines, "nativeAddPolylines"),
+ METHOD(&NativeMapView::addPolygons, "nativeAddPolygons"),
+ METHOD(&NativeMapView::updatePolyline, "nativeUpdatePolyline"),
+ METHOD(&NativeMapView::updatePolygon, "nativeUpdatePolygon"),
+ METHOD(&NativeMapView::removeAnnotations, "nativeRemoveAnnotations"),
+ METHOD(&NativeMapView::addAnnotationIcon, "nativeAddAnnotationIcon"),
+ METHOD(&NativeMapView::getTopOffsetPixelsForAnnotationSymbol, "nativeGetTopOffsetPixelsForAnnotationSymbol"),
+ METHOD(&NativeMapView::getTransitionDuration, "nativeGetTransitionDuration"),
+ METHOD(&NativeMapView::setTransitionDuration, "nativeSetTransitionDuration"),
+ METHOD(&NativeMapView::getTransitionDelay, "nativeGetTransitionDelay"),
+ METHOD(&NativeMapView::setTransitionDelay, "nativeSetTransitionDelay"),
+ METHOD(&NativeMapView::queryPointAnnotations, "nativeQueryPointAnnotations"),
+ METHOD(&NativeMapView::queryRenderedFeaturesForPoint, "nativeQueryRenderedFeaturesForPoint"),
+ METHOD(&NativeMapView::queryRenderedFeaturesForBox, "nativeQueryRenderedFeaturesForBox"),
+ METHOD(&NativeMapView::getLayer, "nativeGetLayer"),
+ METHOD(&NativeMapView::addLayer, "nativeAddLayer"),
+ METHOD(&NativeMapView::removeLayerById, "nativeRemoveLayerById"),
+ METHOD(&NativeMapView::removeLayer, "nativeRemoveLayer"),
+ METHOD(&NativeMapView::getSource, "nativeGetSource"),
+ METHOD(&NativeMapView::addSource, "nativeAddSource"),
+ METHOD(&NativeMapView::removeSourceById, "nativeRemoveSourceById"),
+ METHOD(&NativeMapView::removeSource, "nativeRemoveSource"),
+ METHOD(&NativeMapView::addImage, "nativeAddImage"),
+ METHOD(&NativeMapView::removeImage, "nativeRemoveImage")
+ );
}
}