summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2018-03-26 21:33:52 +0300
committerIvo van Dongen <ivovandongen@users.noreply.github.com>2018-08-20 22:49:01 +0300
commit4fedcf8d061d835e71df80dbc20a32ee4ec8fd21 (patch)
treed0e52c0017075867aae09726ff334e56bc97a0c2
parentfae099933b23a36176dcc8c4a91c37816fa9b7fe (diff)
downloadqtlocation-mapboxgl-4fedcf8d061d835e71df80dbc20a32ee4ec8fd21.tar.gz
[android] arbitrary offline region geometries
-rw-r--r--platform/android/MapboxGLAndroidSDK/build.gradle1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineGeometryRegionDefinition.java128
-rwxr-xr-xplatform/android/src/jni.cpp1
-rw-r--r--platform/android/src/offline/offline_manager.cpp6
-rw-r--r--platform/android/src/offline/offline_region.cpp9
-rw-r--r--platform/android/src/offline/offline_region_definition.cpp68
-rw-r--r--platform/android/src/offline/offline_region_definition.hpp17
7 files changed, 223 insertions, 7 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/build.gradle b/platform/android/MapboxGLAndroidSDK/build.gradle
index 0529489783..5a505af959 100644
--- a/platform/android/MapboxGLAndroidSDK/build.gradle
+++ b/platform/android/MapboxGLAndroidSDK/build.gradle
@@ -10,6 +10,7 @@ dependencies {
api (dependenciesList.mapboxAndroidGestures) {
exclude group: 'com.android.support', module: 'appcompat-v7'
}
+ implementation dependenciesList.mapboxJavaTurf
implementation dependenciesList.supportAnnotations
implementation dependenciesList.supportFragmentV4
implementation dependenciesList.timber
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineGeometryRegionDefinition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineGeometryRegionDefinition.java
new file mode 100644
index 0000000000..0db3ee3202
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineGeometryRegionDefinition.java
@@ -0,0 +1,128 @@
+package com.mapbox.mapboxsdk.offline;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.mapbox.geojson.Feature;
+import com.mapbox.geojson.Geometry;
+import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.turf.TurfMeasurement;
+
+/**
+ * An offline region defined by a style URL, geometry, zoom range, and
+ * device pixel ratio.
+ * <p>
+ * Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom.
+ * <p>
+ * maxZoom may be ∞, in which case for each tile source, the region will include
+ * tiles from minZoom up to the maximum zoom level provided by that source.
+ * <p>
+ * pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0.
+ */
+public class OfflineGeometryRegionDefinition implements OfflineRegionDefinition, Parcelable {
+
+ private String styleURL;
+ private Geometry geometry;
+ private double minZoom;
+ private double maxZoom;
+ private float pixelRatio;
+
+ /**
+ * Constructor to create an OfflineGeometryRegionDefinition from parameters.
+ *
+ * @param styleURL the style
+ * @param geometry the geometry
+ * @param minZoom min zoom
+ * @param maxZoom max zoom
+ * @param pixelRatio pixel ratio of the device
+ */
+ public OfflineGeometryRegionDefinition(
+ String styleURL, Geometry geometry, double minZoom, double maxZoom, float pixelRatio) {
+ // Note: Also used in JNI
+ this.styleURL = styleURL;
+ this.geometry = geometry;
+ this.minZoom = minZoom;
+ this.maxZoom = maxZoom;
+ this.pixelRatio = pixelRatio;
+ }
+
+ /**
+ * Constructor to create an OfflineGeometryRegionDefinition from a Parcel.
+ *
+ * @param parcel the parcel to create the OfflineGeometryRegionDefinition from
+ */
+ public OfflineGeometryRegionDefinition(Parcel parcel) {
+ this.styleURL = parcel.readString();
+ this.geometry = Feature.fromJson(parcel.readString()).geometry();
+ this.minZoom = parcel.readDouble();
+ this.maxZoom = parcel.readDouble();
+ this.pixelRatio = parcel.readFloat();
+ }
+
+ /*
+ * Getters
+ */
+
+ public String getStyleURL() {
+ return styleURL;
+ }
+
+ public Geometry getGeometry() {
+ return geometry;
+ }
+
+ /**
+ * Calculates the bounding box for the Geometry it contains
+ * to retain backwards compatibility
+ * @return the {@link LatLngBounds} or null
+ */
+ @Override
+ public LatLngBounds getBounds() {
+ if (geometry == null) {
+ return null;
+ }
+
+ double[] bbox = TurfMeasurement.bbox(geometry);
+ return LatLngBounds.from(bbox[3], bbox[2], bbox[1], bbox[0]);
+ }
+
+ public double getMinZoom() {
+ return minZoom;
+ }
+
+ public double getMaxZoom() {
+ return maxZoom;
+ }
+
+ public float getPixelRatio() {
+ return pixelRatio;
+ }
+
+ /*
+ * Parceable
+ */
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(styleURL);
+ dest.writeString(Feature.fromGeometry(geometry).toJson());
+ dest.writeDouble(minZoom);
+ dest.writeDouble(maxZoom);
+ dest.writeFloat(pixelRatio);
+ }
+
+ public static final Creator CREATOR = new Creator() {
+ public OfflineGeometryRegionDefinition createFromParcel(Parcel in) {
+ return new OfflineGeometryRegionDefinition(in);
+ }
+
+ public OfflineGeometryRegionDefinition[] newArray(int size) {
+ return new OfflineGeometryRegionDefinition[size];
+ }
+ };
+}
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index beb2c14eb3..18b966e261 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -180,6 +180,7 @@ void registerNatives(JavaVM *vm) {
OfflineRegion::registerNative(env);
OfflineRegionDefinition::registerNative(env);
OfflineTilePyramidRegionDefinition::registerNative(env);
+ OfflineGeometryRegionDefinition::registerNative(env);
OfflineRegionError::registerNative(env);
OfflineRegionStatus::registerNative(env);
diff --git a/platform/android/src/offline/offline_manager.cpp b/platform/android/src/offline/offline_manager.cpp
index 4f94a1c3a5..e96ed7e4d2 100644
--- a/platform/android/src/offline/offline_manager.cpp
+++ b/platform/android/src/offline/offline_manager.cpp
@@ -48,9 +48,7 @@ void OfflineManager::createOfflineRegion(jni::JNIEnv& env_,
jni::Array<jni::jbyte> metadata_,
jni::Object<CreateOfflineRegionCallback> callback_) {
// Convert
-
- // XXX hardcoded cast for now as we only support OfflineTilePyramidRegionDefinition
- auto definition = OfflineTilePyramidRegionDefinition::getDefinition(env_, jni::Object<OfflineTilePyramidRegionDefinition>(*definition_));
+ auto definition = OfflineRegionDefinition::getDefinition(env_, definition_);
mbgl::OfflineRegionMetadata metadata;
if (metadata_) {
@@ -152,7 +150,7 @@ void OfflineManager::CreateOfflineRegionCallback::onCreate(jni::JNIEnv& env,
jni::Object<FileSource> jFileSource,
jni::Object<OfflineManager::CreateOfflineRegionCallback> callback,
mbgl::optional<mbgl::OfflineRegion> region) {
- //Convert the region to java peer object
+ // Convert the region to java peer object
auto jregion = OfflineRegion::New(env, jFileSource, std::move(*region));
// Trigger callback
diff --git a/platform/android/src/offline/offline_region.cpp b/platform/android/src/offline/offline_region.cpp
index fe4dbecf14..5ed37eda73 100644
--- a/platform/android/src/offline/offline_region.cpp
+++ b/platform/android/src/offline/offline_region.cpp
@@ -159,7 +159,14 @@ void OfflineRegion::updateOfflineRegionMetadata(jni::JNIEnv& env_, jni::Array<jn
jni::Object<OfflineRegion> OfflineRegion::New(jni::JNIEnv& env, jni::Object<FileSource> jFileSource, mbgl::OfflineRegion region) {
// Definition
- auto definition = jni::Object<OfflineRegionDefinition>(*OfflineTilePyramidRegionDefinition::New(env, region.getDefinition()));
+ auto definition = region.getDefinition().match(
+ [&](const mbgl::OfflineTilePyramidRegionDefinition def) {
+ return jni::Object<OfflineRegionDefinition>(
+ *OfflineTilePyramidRegionDefinition::New(env, def));
+ }, [&](const mbgl::OfflineGeometryRegionDefinition def) {
+ return jni::Object<OfflineRegionDefinition>(
+ *OfflineGeometryRegionDefinition::New(env, def));
+ });
// Metadata
auto metadata = OfflineRegion::metadata(env, region.getMetadata());
diff --git a/platform/android/src/offline/offline_region_definition.cpp b/platform/android/src/offline/offline_region_definition.cpp
index 66a9bdf99d..a856672902 100644
--- a/platform/android/src/offline/offline_region_definition.cpp
+++ b/platform/android/src/offline/offline_region_definition.cpp
@@ -1,6 +1,9 @@
#include "offline_region_definition.hpp"
#include "../geometry/lat_lng_bounds.hpp"
+#include "../geojson/geometry.hpp"
+
+#include <exception>
namespace mbgl {
namespace android {
@@ -13,9 +16,21 @@ void OfflineRegionDefinition::registerNative(jni::JNIEnv& env) {
javaClass = *jni::Class<OfflineRegionDefinition>::Find(env).NewGlobalRef(env).release();
}
+mbgl::OfflineRegionDefinition OfflineRegionDefinition::getDefinition(JNIEnv& env,
+ jni::Object<OfflineRegionDefinition> jDefinition) {
+
+ if (jDefinition.IsInstanceOf(env, OfflineTilePyramidRegionDefinition::javaClass)) {
+ return OfflineTilePyramidRegionDefinition::getDefinition(env, jni::Object<OfflineTilePyramidRegionDefinition>(*jDefinition));
+ } else if (jDefinition.IsInstanceOf(env, OfflineGeometryRegionDefinition::javaClass)) {
+ return OfflineGeometryRegionDefinition::getDefinition(env, jni::Object<OfflineGeometryRegionDefinition>(*jDefinition));
+ }
+
+ throw std::runtime_error("Unknown offline region definition java class");
+}
+
// OfflineTilePyramidRegionDefinition //
-jni::Object<OfflineTilePyramidRegionDefinition> OfflineTilePyramidRegionDefinition::New(jni::JNIEnv& env, mbgl::OfflineTilePyramidRegionDefinition definition) {
+jni::Object<OfflineTilePyramidRegionDefinition> OfflineTilePyramidRegionDefinition::New(jni::JNIEnv& env, const mbgl::OfflineTilePyramidRegionDefinition& definition) {
//Convert objects
auto styleURL = jni::Make<jni::String>(env, definition.styleURL);
@@ -65,5 +80,56 @@ void OfflineTilePyramidRegionDefinition::registerNative(jni::JNIEnv& env) {
javaClass = *jni::Class<OfflineTilePyramidRegionDefinition>::Find(env).NewGlobalRef(env).release();
}
+// OfflineGeometryRegionDefinition //
+
+jni::Object<OfflineGeometryRegionDefinition> OfflineGeometryRegionDefinition::New(jni::JNIEnv& env, const mbgl::OfflineGeometryRegionDefinition& definition) {
+ //Convert objects
+ auto styleURL = jni::Make<jni::String>(env, definition.styleURL);
+ auto geometry = geojson::Geometry::New(env, definition.geometry);
+
+ static auto constructor = javaClass.GetConstructor<jni::String, jni::Object<geojson::Geometry>, jni::jdouble, jni::jdouble, jni::jfloat>(env);
+ auto jdefinition = javaClass.New(env, constructor, styleURL, geometry, definition.minZoom, definition.maxZoom, definition.pixelRatio);
+
+ //Delete References
+ jni::DeleteLocalRef(env, styleURL);
+ jni::DeleteLocalRef(env, geometry);
+
+ return jdefinition;
+}
+
+mbgl::OfflineGeometryRegionDefinition OfflineGeometryRegionDefinition::getDefinition(jni::JNIEnv& env, jni::Object<OfflineGeometryRegionDefinition> jDefinition) {
+ // Field references
+ static auto styleURLF = javaClass.GetField<jni::String>(env, "styleURL");
+ static auto geometryF = javaClass.GetField<jni::Object<geojson::Geometry>>(env, "geometry");
+ static auto minZoomF = javaClass.GetField<jni::jdouble>(env, "minZoom");
+ static auto maxZoomF = javaClass.GetField<jni::jdouble>(env, "maxZoom");
+ static auto pixelRatioF = javaClass.GetField<jni::jfloat>(env, "pixelRatio");
+
+ // Get objects
+ auto jStyleURL = jDefinition.Get(env, styleURLF);
+ auto jGeometry = jDefinition.Get(env, geometryF);
+
+ // Create definition
+ mbgl::OfflineGeometryRegionDefinition definition(
+ jni::Make<std::string>(env, jStyleURL),
+ geojson::Geometry::convert(env, jGeometry),
+ jDefinition.Get(env, minZoomF),
+ jDefinition.Get(env, maxZoomF),
+ jDefinition.Get(env, pixelRatioF)
+ );
+
+ // Delete references
+ jni::DeleteLocalRef(env, jStyleURL);
+ jni::DeleteLocalRef(env, jGeometry);
+
+ return definition;
+}
+
+jni::Class<OfflineGeometryRegionDefinition> OfflineGeometryRegionDefinition::javaClass;
+
+void OfflineGeometryRegionDefinition::registerNative(jni::JNIEnv& env) {
+ javaClass = *jni::Class<OfflineGeometryRegionDefinition>::Find(env).NewGlobalRef(env).release();
+}
+
} // namespace android
} // namespace mbgl
diff --git a/platform/android/src/offline/offline_region_definition.hpp b/platform/android/src/offline/offline_region_definition.hpp
index 2ca82a4d96..a9dfb54634 100644
--- a/platform/android/src/offline/offline_region_definition.hpp
+++ b/platform/android/src/offline/offline_region_definition.hpp
@@ -14,13 +14,14 @@ public:
static void registerNative(jni::JNIEnv&);
+ static mbgl::OfflineRegionDefinition getDefinition(JNIEnv& env, jni::Object<OfflineRegionDefinition> jDefinition);
};
class OfflineTilePyramidRegionDefinition: public OfflineRegionDefinition {
public:
static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition"; };
- static jni::Object<OfflineTilePyramidRegionDefinition> New(jni::JNIEnv&, mbgl::OfflineTilePyramidRegionDefinition);
+ static jni::Object<OfflineTilePyramidRegionDefinition> New(jni::JNIEnv&, const mbgl::OfflineTilePyramidRegionDefinition&);
static mbgl::OfflineTilePyramidRegionDefinition getDefinition(jni::JNIEnv&, jni::Object<OfflineTilePyramidRegionDefinition>);
@@ -30,5 +31,19 @@ public:
};
+class OfflineGeometryRegionDefinition: public OfflineRegionDefinition {
+public:
+ static constexpr auto Name() { return "com/mapbox/mapboxsdk/offline/OfflineGeometryRegionDefinition"; };
+
+ static jni::Object<OfflineGeometryRegionDefinition> New(jni::JNIEnv&, const mbgl::OfflineGeometryRegionDefinition&);
+
+ static mbgl::OfflineGeometryRegionDefinition getDefinition(jni::JNIEnv&, jni::Object<OfflineGeometryRegionDefinition>);
+
+ static jni::Class<OfflineGeometryRegionDefinition> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+
+};
+
} // namespace android
} // namespace mbgl