diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-10-31 11:45:19 -0700 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-11-22 13:56:38 -0800 |
commit | eb6de2c434d6cbd5060a9a19cf4f13ec8a792c3b (patch) | |
tree | c8e234957f92ff5f347576fa259f0e120aab743e /platform/android/src/style/sources/custom_geometry_source.cpp | |
parent | 7c6ede6bb33c6ce3f82b33a9b83dd39dcc31b9ec (diff) | |
download | qtlocation-mapboxgl-eb6de2c434d6cbd5060a9a19cf4f13ec8a792c3b.tar.gz |
[android] Bindings for Custom Geometry Sources
Diffstat (limited to 'platform/android/src/style/sources/custom_geometry_source.cpp')
-rw-r--r-- | platform/android/src/style/sources/custom_geometry_source.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/platform/android/src/style/sources/custom_geometry_source.cpp b/platform/android/src/style/sources/custom_geometry_source.cpp new file mode 100644 index 0000000000..e647975e4d --- /dev/null +++ b/platform/android/src/style/sources/custom_geometry_source.cpp @@ -0,0 +1,122 @@ +#include "custom_geometry_source.hpp" + +#include <mbgl/renderer/query.hpp> + +// Java -> C++ conversion +#include "../android_conversion.hpp" +#include "../conversion/filter.hpp" +//#include "../conversion/geojson.hpp" + +// C++ -> Java conversion +#include "../../conversion/conversion.hpp" +#include "../../conversion/collection.hpp" +#include "../../geojson/conversion/feature.hpp" +#include <mbgl/style/conversion/custom_geometry_source_options.hpp> + +#include <string> + +namespace mbgl { +namespace android { + + // This conversion is expected not to fail because it's used only in contexts where + // the value was originally a GeoJsonOptions object on the Java side. If it fails + // to convert, it's a bug in our serialization or Java-side static typing. + static style::CustomGeometrySource::Options convertCustomGeometrySourceOptions(jni::JNIEnv& env, jni::Object<> options, style::TileFunction fetchFn, style::TileFunction cancelFn) { + using namespace mbgl::style::conversion; + if (!options) { + return style::CustomGeometrySource::Options(); + } + Error error; + optional<style::CustomGeometrySource::Options> result = convert<style::CustomGeometrySource::Options>(Value(env, options), error); + if (!result) { + throw std::logic_error(error.message); + } + result->fetchTileFunction = fetchFn; + result->cancelTileFunction = cancelFn; + return *result; + } + + CustomGeometrySource::CustomGeometrySource(jni::JNIEnv& env, jni::Object<CustomGeometrySource> _obj, jni::String sourceId, jni::Object<> options) + : Source(env, std::make_unique<mbgl::style::CustomGeometrySource>( + jni::Make<std::string>(env, sourceId), + convertCustomGeometrySourceOptions(env, + options, + std::bind(&CustomGeometrySource::fetchTile, this, std::placeholders::_1), + std::bind(&CustomGeometrySource::cancelTile, this, std::placeholders::_1))) ), + javaPeer(_obj.NewGlobalRef(env)) { + } + + CustomGeometrySource::~CustomGeometrySource() = default; + + void CustomGeometrySource::fetchTile (const mbgl::CanonicalTileID& tileID) { + android::UniqueEnv _env = android::AttachEnv(); + static auto fetchTile = javaClass.GetMethod<void (jni::jint, jni::jint, jni::jint)>(*_env, "fetchTile"); + assert(javaPeer); + javaPeer->Call(*_env, fetchTile, (int)tileID.z, (int)tileID.x, (int)tileID.y); + }; + + void CustomGeometrySource::cancelTile(const mbgl::CanonicalTileID& tileID) { + android::UniqueEnv _env = android::AttachEnv(); + static auto cancelTile = javaClass.GetMethod<void (jni::jint, jni::jint, jni::jint)>(*_env, "cancelTile"); + assert(javaPeer); + javaPeer->Call(*_env, cancelTile, (int)tileID.z, (int)tileID.x, (int)tileID.y); + }; + + void CustomGeometrySource::setTileData(jni::JNIEnv& env, jni::jint z, jni::jint x, jni::jint y, jni::Object<geojson::FeatureCollection> jFeatures) { + using namespace mbgl::android::geojson; + + // Convert the jni object + auto geometry = geojson::FeatureCollection::convert(env, jFeatures); + + // Update the core source + source.as<mbgl::style::CustomGeometrySource>()->CustomGeometrySource::setTileData(CanonicalTileID(z, x, y), GeoJSON(geometry)); + } + + void CustomGeometrySource::invalidateTile(jni::JNIEnv&, jni::jint z, jni::jint x, jni::jint y) { + source.as<mbgl::style::CustomGeometrySource>()->CustomGeometrySource::invalidateTile(CanonicalTileID(z, x, y)); + } + void CustomGeometrySource::invalidateBounds(jni::JNIEnv& env, jni::Object<LatLngBounds> jBounds) { + auto bounds = LatLngBounds::getLatLngBounds(env, jBounds); + source.as<mbgl::style::CustomGeometrySource>()->CustomGeometrySource::invalidateRegion(bounds); + } + + jni::Array<jni::Object<geojson::Feature>> CustomGeometrySource::querySourceFeatures(jni::JNIEnv& env, + jni::Array<jni::Object<>> jfilter) { + using namespace mbgl::android::conversion; + using namespace mbgl::android::geojson; + + std::vector<mbgl::Feature> features; + if (rendererFrontend) { + features = rendererFrontend->querySourceFeatures(source.getID(), { {}, toFilter(env, jfilter) }); + } + return *convert<jni::Array<jni::Object<Feature>>, std::vector<mbgl::Feature>>(env, features); + } + + jni::Class<CustomGeometrySource> CustomGeometrySource::javaClass; + + jni::jobject* CustomGeometrySource::createJavaPeer(jni::JNIEnv& env) { + static auto constructor = CustomGeometrySource::javaClass.template GetConstructor<jni::jlong>(env); + return CustomGeometrySource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)); + } + + void CustomGeometrySource::registerNative(jni::JNIEnv& env) { + // Lookup the class + CustomGeometrySource::javaClass = *jni::Class<CustomGeometrySource>::Find(env).NewGlobalRef(env).release(); + + #define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name) + + // Register the peer + jni::RegisterNativePeer<CustomGeometrySource>( + env, CustomGeometrySource::javaClass, "nativePtr", + std::make_unique<CustomGeometrySource, JNIEnv&, jni::Object<CustomGeometrySource>, jni::String, jni::Object<>>, + "initialize", + "finalize", + METHOD(&CustomGeometrySource::querySourceFeatures, "querySourceFeatures"), + METHOD(&CustomGeometrySource::setTileData, "nativeSetTileData"), + METHOD(&CustomGeometrySource::invalidateTile, "nativeInvalidateTile"), + METHOD(&CustomGeometrySource::invalidateBounds, "nativeInvalidateBounds") + ); + } + +} // namespace android +} // namespace mbgl |