summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvo van Dongen <info@ivovandongen.nl>2018-03-13 12:31:56 +0200
committerIvo van Dongen <ivovandongen@users.noreply.github.com>2018-03-19 11:19:09 +0200
commit2464520da18f0f4cc7532adb3fb7b1f8f195304e (patch)
tree8a391da645a7a84fce5ba2e05a0ef2422474d0cd
parentf2fbe69b32d7683d489b1f259b6db49070736980 (diff)
downloadqtlocation-mapboxgl-2464520da18f0f4cc7532adb3fb7b1f8f195304e.tar.gz
[android] high-level jni bindings for geojson conversion
-rw-r--r--platform/android/config.cmake2
-rw-r--r--platform/android/src/geojson/conversion/feature.hpp2
-rw-r--r--platform/android/src/geojson/conversion/geometry.hpp184
-rw-r--r--platform/android/src/geojson/geometry.cpp47
-rw-r--r--platform/android/src/geojson/geometry.hpp8
-rw-r--r--platform/android/src/geojson/geometry_collection.cpp63
-rw-r--r--platform/android/src/geojson/geometry_collection.hpp28
-rw-r--r--platform/android/src/geojson/line_string.cpp13
-rw-r--r--platform/android/src/geojson/line_string.hpp10
-rw-r--r--platform/android/src/geojson/multi_line_string.cpp11
-rw-r--r--platform/android/src/geojson/multi_line_string.hpp9
-rw-r--r--platform/android/src/geojson/multi_point.cpp10
-rw-r--r--platform/android/src/geojson/multi_point.hpp10
-rw-r--r--platform/android/src/geojson/multi_polygon.cpp23
-rw-r--r--platform/android/src/geojson/multi_polygon.hpp9
-rw-r--r--platform/android/src/geojson/point.cpp5
-rw-r--r--platform/android/src/geojson/point.hpp9
-rw-r--r--platform/android/src/geojson/polygon.cpp10
-rw-r--r--platform/android/src/geojson/polygon.hpp8
-rw-r--r--platform/android/src/geojson/util.hpp38
-rw-r--r--platform/android/src/java/util.cpp2
-rw-r--r--platform/android/src/java/util.hpp15
-rwxr-xr-xplatform/android/src/jni.cpp2
23 files changed, 320 insertions, 198 deletions
diff --git a/platform/android/config.cmake b/platform/android/config.cmake
index 2694068dac..80d0810564 100644
--- a/platform/android/config.cmake
+++ b/platform/android/config.cmake
@@ -229,6 +229,8 @@ add_library(mbgl-android STATIC
platform/android/src/geojson/feature_collection.hpp
platform/android/src/geojson/geometry.cpp
platform/android/src/geojson/geometry.hpp
+ platform/android/src/geojson/geometry_collection.cpp
+ platform/android/src/geojson/geometry_collection.hpp
platform/android/src/geojson/line_string.cpp
platform/android/src/geojson/line_string.hpp
platform/android/src/geojson/multi_line_string.cpp
diff --git a/platform/android/src/geojson/conversion/feature.hpp b/platform/android/src/geojson/conversion/feature.hpp
index 86aa5fc03c..8fc62a2789 100644
--- a/platform/android/src/geojson/conversion/feature.hpp
+++ b/platform/android/src/geojson/conversion/feature.hpp
@@ -182,7 +182,7 @@ struct Converter<jni::Object<android::geojson::Feature>, mbgl::Feature> {
auto properties = jni::Object<gson::JsonObject>(*convert<jni::jobject*>(env, value.properties));
// Convert geometry
- auto geometry = jni::Object<android::geojson::Geometry>(*convert<jni::jobject*>(env, value.geometry));
+ auto geometry = *convert<jni::Object<android::geojson::Geometry>>(env, value.geometry);
// Create feature
auto feature = android::geojson::Feature::fromGeometry(env, geometry, properties, jid);
diff --git a/platform/android/src/geojson/conversion/geometry.hpp b/platform/android/src/geojson/conversion/geometry.hpp
index 48b9089692..242a68df02 100644
--- a/platform/android/src/geojson/conversion/geometry.hpp
+++ b/platform/android/src/geojson/conversion/geometry.hpp
@@ -1,192 +1,24 @@
#pragma once
-#include "../../conversion/constant.hpp"
-#include "../../conversion/collection.hpp"
-
#include <mapbox/geometry.hpp>
+#include "../geometry.hpp"
#include <jni/jni.hpp>
-#include "../../jni/local_object.hpp"
namespace mbgl {
namespace android {
namespace conversion {
/**
- * Turn mapbox::geometry type into Java GeoJson Geometries
- */
-template <typename T>
-class GeometryEvaluator {
-public:
-
- jni::JNIEnv& env;
-
- /**
- * static Point fromLngLat(double longitude,double latitude)
- */
- jni::jobject* operator()(const mapbox::geometry::point<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Point")).release();
- static jni::jmethodID* fromLngLat = &jni::GetStaticMethodID(env, *javaClass, "fromLngLat", "(DD)Lcom/mapbox/geojson/Point;");
-
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLat, geometry.x, geometry.y));
- }
-
- /**
- * static LineString fromLngLats(double [][])
- */
- jni::jobject* operator()(const mapbox::geometry::line_string<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/LineString")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "([[D)Lcom/mapbox/geojson/LineString;");
-
- // Create
- jni::LocalObject<jni::jarray<jni::jobject>> lngLatsArray =
- jni::NewLocalObject(env, toLngLatArray(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, lngLatsArray.get()));
- }
-
- /**
- * static MultiPoint fromLngLats(double [][])
- */
- jni::jobject* operator()(const mapbox::geometry::multi_point<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/MultiPoint")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "([[D)Lcom/mapbox/geojson/MultiPoint;");
-
- // Create
- jni::LocalObject<jni::jarray<jni::jobject>> lngLatsArray =
- jni::NewLocalObject(env, toLngLatArray(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, lngLatsArray.get()));
- }
-
- /**
- * static Polygon fromLngLats(double [][][])
- */
- jni::jobject* operator()(const mapbox::geometry::polygon<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Polygon")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "([[[D)Lcom/mapbox/geojson/Polygon;");
-
- // Create
- jni::LocalObject<jni::jarray<jni::jobject>> shape =
- jni::NewLocalObject(env, shapeToLngLatArray<>(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, shape.get()));
- }
-
- /**
- * static MultiLineString fromLngLats(double [][][])
- */
- jni::jobject* operator()(const mapbox::geometry::multi_line_string<T> &geometry) const {
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/MultiLineString")).release();
- static jni::jmethodID* fromLngLats = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "([[[D)Lcom/mapbox/geojson/MultiLineString;");
-
- // Create
- jni::LocalObject<jni::jarray<jni::jobject>> shape =
- jni::NewLocalObject(env,shapeToLngLatArray<>(env, geometry));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromLngLats, shape.get()));
- }
-
- /**
- * MultiPolygon (double[][][][]) -> [[[D + Object array == [[[[D
- */
- jni::jobject* operator()(const mapbox::geometry::multi_polygon<T> &geometry) const {
-
- static jni::jclass* arrayClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[[[D")).release();
- jni::LocalObject<jni::jarray<jni::jobject>> jarray =
- jni::NewLocalObject(env, &jni::NewObjectArray(env, geometry.size(), *arrayClass));
-
- for(size_t i = 0; i < geometry.size(); i = i + 1) {
- jni::LocalObject<jni::jarray<jni::jobject>> shape =
- jni::NewLocalObject(env, shapeToLngLatArray<>(env, geometry.at(i)));
- jni::SetObjectArrayElement(env, *jarray, i, shape.get());
- }
-
- // Create the MultiPolygon
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/MultiPolygon")).release();
- static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromLngLats", "([[[[D)Lcom/mapbox/geojson/MultiPolygon;");
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromGeometries, jarray.get()));
- }
-
- /**
- * GeometryCollection
- */
- jni::jobject* operator()(const mapbox::geometry::geometry_collection<T> &collection) const {
- static jni::jclass* geometryClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/Geometry")).release();
- jni::LocalObject<jni::jarray<jni::jobject>> jarray = jni::NewLocalObject(env, &jni::NewObjectArray(env, collection.size(), *geometryClass));
-
- for(size_t i = 0; i < collection.size(); i = i + 1) {
- auto& geometry = collection.at(i);
- jni::LocalObject<jni::jobject> converted = jni::NewLocalObject(env, mapbox::geometry::geometry<T>::visit(geometry, *this));
- jni::SetObjectArrayElement(env, *jarray, i, converted.get());
- }
-
- // Turn into array list and create the GeometryCollection
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/geojson/GeometryCollection")).release();
- static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromGeometries", "(Ljava/util/List;)Lcom/mapbox/geojson/GeometryCollection;");
-
- jni::LocalObject<jni::jobject> list = jni::NewLocalObject(env, toArrayList<>(env, *jarray));
- return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromGeometries, list.get()));
- }
-
-private:
-
- /**
- * x, y -> jarray<jdouble> ([x,y])
- *
- */
- static jni::jarray<jni::jdouble> *toLngLatArray(JNIEnv &env, double x, double y) {
- jni::jarray<jni::jdouble> &jarray = jni::NewArray<jni::jdouble>(env, 2);
- jni::jdouble array[] = {x, y};
- jni::SetArrayRegion(env, jarray, 0, 2, array);
- return &jarray;
- }
-
- /**
- * vector<point<T>> -> jarray<jobject> -> [D + Object array == [[D (double[][])
- */
- static jni::jarray<jni::jobject>* toLngLatArray(JNIEnv &env,
- std::vector<mapbox::geometry::point<T>> points) {
-
- static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[D")).release();
- jni::jarray<jni::jobject >& jarray = jni::NewObjectArray(env, points.size(), *javaClass);
-
- for(size_t i = 0; i < points.size(); i = i + 1) {
- mapbox::geometry::point<T> point = points.at(i);
- jni::jarray<jni::jdouble> *lngLatArray = toLngLatArray(env, point.x, point.y);
- jni::SetObjectArrayElement(env, jarray, i, lngLatArray);
- }
-
- return &jarray;
- }
-
- /**
- * polygon<T>
- * multi_line_string<T> -> jarray<jobject> -> [[D + Object array == [[[D (double[][][])
- */
- template <class SHAPE>
- static jni::jarray<jni::jobject>* shapeToLngLatArray(JNIEnv &env, SHAPE value) {
- static jni::jclass *javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[[D")).release();
- jni::jarray<jni::jobject> &jarray = jni::NewObjectArray(env, value.size(), *javaClass);
-
- for (size_t i = 0; i < value.size(); i = i + 1) {
- jni::LocalObject<jni::jarray<jni::jobject>> lngLatsArray =
- jni::NewLocalObject(env, toLngLatArray(env, value.at(i)));
- jni::SetObjectArrayElement(env, jarray, i, lngLatsArray.get());
- }
-
- return &jarray;
- }
-};
-
-/**
- * mapbox::geometry::geometry<T> -> Java GeoJson Geometry<>
+ * mapbox::geometry::geometry<T> -> Java GeoJson Geometry
*/
template <class T>
-struct Converter<jni::jobject*, mapbox::geometry::geometry<T>> {
- Result<jni::jobject*> operator()(jni::JNIEnv& env, const mapbox::geometry::geometry<T>& value) const {
- GeometryEvaluator<double> evaluator { env } ;
- jni::jobject* converted = mapbox::geometry::geometry<double>::visit(value, evaluator);
- return {converted};
+struct Converter<jni::Object<android::geojson::Geometry>, mapbox::geometry::geometry<T>> {
+ Result<jni::Object<android::geojson::Geometry>> operator()(jni::JNIEnv& env, const mapbox::geometry::geometry<T>& value) const {
+ return { android::geojson::Geometry::New(env, value) };
}
};
-}
-}
-}
+} // conversion
+} // android
+} // mbgl
diff --git a/platform/android/src/geojson/geometry.cpp b/platform/android/src/geojson/geometry.cpp
index ca19d8fb03..5635b5a0f5 100644
--- a/platform/android/src/geojson/geometry.cpp
+++ b/platform/android/src/geojson/geometry.cpp
@@ -6,6 +6,7 @@
#include "multi_line_string.hpp"
#include "polygon.hpp"
#include "multi_polygon.hpp"
+#include "geometry_collection.hpp"
#include <string>
@@ -13,7 +14,49 @@ namespace mbgl {
namespace android {
namespace geojson {
-mapbox::geojson::geometry Geometry::convert(jni::JNIEnv &env, jni::Object<Geometry> jGeometry) {
+/**
+ * Turn mapbox::geometry type into Java GeoJson Geometries
+ */
+class GeometryEvaluator {
+public:
+
+ jni::JNIEnv& env;
+
+ jni::Object<Geometry> operator()(const mbgl::Point<double> &geometry) const {
+ return jni::Cast(env, Point::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::LineString<double> &geometry) const {
+ return jni::Cast(env, LineString::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::MultiLineString<double> &geometry) const {
+ return jni::Cast(env, MultiLineString::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::MultiPoint<double> &geometry) const {
+ return jni::Cast(env, MultiPoint::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::Polygon<double> &geometry) const {
+ return jni::Cast(env, Polygon::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mbgl::MultiPolygon<double> &geometry) const {
+ return jni::Cast(env, MultiPolygon::New(env, geometry), Geometry::javaClass);
+ }
+
+ jni::Object<Geometry> operator()(const mapbox::geometry::geometry_collection<double> &geometry) const {
+ return jni::Cast(env, GeometryCollection::New(env, geometry), Geometry::javaClass);
+ }
+};
+
+jni::Object<Geometry> Geometry::New(jni::JNIEnv& env, mbgl::Geometry<double> geometry) {
+ GeometryEvaluator evaluator { env } ;
+ return mbgl::Geometry<double>::visit(geometry, evaluator);
+}
+
+mbgl::Geometry<double> Geometry::convert(jni::JNIEnv &env, jni::Object<Geometry> jGeometry) {
auto type = Geometry::getType(env, jGeometry);
if (type == Point::Type()) {
return { Point::convert(env, jni::Object<Point>(jGeometry.Get())) };
@@ -27,6 +70,8 @@ mapbox::geojson::geometry Geometry::convert(jni::JNIEnv &env, jni::Object<Geomet
return { Polygon::convert(env, jni::Object<Polygon>(jGeometry.Get())) };
} else if (type == MultiPolygon::Type()) {
return { MultiPolygon::convert(env, jni::Object<MultiPolygon>(jGeometry.Get())) };
+ } else if (type == GeometryCollection::Type()) {
+ return { GeometryCollection::convert(env, jni::Object<GeometryCollection>(jGeometry.Get())) };
}
throw std::runtime_error(std::string {"Unsupported GeoJSON type: " } + type);
diff --git a/platform/android/src/geojson/geometry.hpp b/platform/android/src/geojson/geometry.hpp
index b7f8909f6f..a1bb886683 100644
--- a/platform/android/src/geojson/geometry.hpp
+++ b/platform/android/src/geojson/geometry.hpp
@@ -1,8 +1,10 @@
#pragma once
-#include <mbgl/util/geojson.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include "../java/util.hpp"
+
#include <jni/jni.hpp>
namespace mbgl {
@@ -13,7 +15,9 @@ class Geometry : private mbgl::util::noncopyable {
public:
static constexpr auto Name() { return "com/mapbox/geojson/Geometry"; };
- static mapbox::geojson::geometry convert(jni::JNIEnv&, jni::Object<Geometry>);
+ static jni::Object<Geometry> New(jni::JNIEnv&, mbgl::Geometry<double>);
+
+ static mbgl::Geometry<double> convert(jni::JNIEnv&, jni::Object<Geometry>);
static std::string getType(jni::JNIEnv&, jni::Object<Geometry>);
diff --git a/platform/android/src/geojson/geometry_collection.cpp b/platform/android/src/geojson/geometry_collection.cpp
new file mode 100644
index 0000000000..eb3a790404
--- /dev/null
+++ b/platform/android/src/geojson/geometry_collection.cpp
@@ -0,0 +1,63 @@
+#include "geometry_collection.hpp"
+#include "../java/util.hpp"
+
+namespace mbgl {
+namespace android {
+namespace geojson {
+
+jni::Object<GeometryCollection> GeometryCollection::New(jni::JNIEnv& env, const mapbox::geometry::geometry_collection<double>& collection) {
+ // Create an array of geometries
+ auto jarray = jni::Array<jni::Object<Geometry>>::New(env, collection.size(), Geometry::javaClass);
+
+ for (size_t i = 0; i < collection.size(); i++) {
+ auto& geometry = collection.at(i);
+ auto jGeometry = Geometry::New(env, geometry);
+ jarray.Set(env, i, jGeometry);
+ jni::DeleteLocalRef(env, jGeometry);
+ }
+
+ // Turn into array list
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+
+ // create the GeometryCollection
+ static auto method = javaClass.GetStaticMethod<jni::Object<GeometryCollection> (jni::Object<java::util::List>)>(env, "fromGeometries");
+ auto jCollection = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jCollection;
+}
+
+mapbox::geometry::geometry_collection<double> GeometryCollection::convert(jni::JNIEnv &env, jni::Object<GeometryCollection> jCollection) {
+ // Get geometries
+ static auto getGeometries = javaClass.GetMethod<jni::Object<java::util::List> ()>(env, "getGeometries");
+ auto jList = jCollection.Call(env, getGeometries);
+
+ // Turn into array
+ auto jarray = java::util::List::toArray<Geometry>(env, jList);
+ jni::DeleteLocalRef(env, jList);
+
+ // Convert each geometry
+ mapbox::geometry::geometry_collection<double> collection{};
+
+ auto size = jarray.Length(env);
+ for (jni::jsize i = 0; i < size; i++) {
+ auto element = jarray.Get(env, i);
+ collection.push_back(Geometry::convert(env, element));
+ jni::DeleteLocalRef(env, element);
+ }
+
+ jni::DeleteLocalRef(env, jarray);
+ return collection;
+}
+
+void GeometryCollection::registerNative(jni::JNIEnv &env) {
+ // Lookup the class
+ javaClass = *jni::Class<GeometryCollection>::Find(env).NewGlobalRef(env).release();
+}
+
+jni::Class<GeometryCollection> GeometryCollection::javaClass;
+
+} // namespace geojson
+} // namespace android
+} // namespace mbgl \ No newline at end of file
diff --git a/platform/android/src/geojson/geometry_collection.hpp b/platform/android/src/geojson/geometry_collection.hpp
new file mode 100644
index 0000000000..9ed9953b0d
--- /dev/null
+++ b/platform/android/src/geojson/geometry_collection.hpp
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
+
+namespace mbgl {
+namespace android {
+namespace geojson {
+
+class GeometryCollection : public Geometry {
+public:
+ static constexpr auto Name() { return "com/mapbox/geojson/GeometryCollection"; };
+
+ static constexpr auto Type() { return "GeometryCollection"; };
+
+ static jni::Object<GeometryCollection> New(jni::JNIEnv&, const mapbox::geometry::geometry_collection<double>&);
+
+ static mapbox::geometry::geometry_collection<double> convert(jni::JNIEnv&, jni::Object<GeometryCollection>);
+
+ static jni::Class<GeometryCollection> javaClass;
+
+ static void registerNative(jni::JNIEnv&);
+};
+
+} // namespace geojson
+} // namespace android
+} // namespace mbgl \ No newline at end of file
diff --git a/platform/android/src/geojson/line_string.cpp b/platform/android/src/geojson/line_string.cpp
index 8eebd53550..a5f1a468ce 100644
--- a/platform/android/src/geojson/line_string.cpp
+++ b/platform/android/src/geojson/line_string.cpp
@@ -1,11 +1,22 @@
#include "line_string.hpp"
-
#include "point.hpp"
+#include "util.hpp"
+#include "../java/util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<LineString> LineString::New(jni::JNIEnv& env, const mbgl::LineString<double>& lineString) {
+ auto jList = asPointsList(env, lineString);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<LineString>(jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jLineString = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jLineString;
+}
+
mapbox::geojson::line_string LineString::convert(jni::JNIEnv &env, jni::Object<LineString> jLineString) {
mapbox::geojson::line_string lineString;
diff --git a/platform/android/src/geojson/line_string.hpp b/platform/android/src/geojson/line_string.hpp
index 86033c2e6a..98dc414642 100644
--- a/platform/android/src/geojson/line_string.hpp
+++ b/platform/android/src/geojson/line_string.hpp
@@ -1,23 +1,27 @@
#pragma once
#include <mbgl/util/geojson.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
+#include "geometry.hpp"
#include "../java/util.hpp"
+#include <jni/jni.hpp>
+
namespace mbgl {
namespace android {
namespace geojson {
-class LineString : private mbgl::util::noncopyable {
+class LineString : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/LineString"; };
static constexpr auto Type() { return "LineString"; };
+ static jni::Object<LineString> New(jni::JNIEnv&, const mbgl::LineString<double>&);
+
static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<LineString>);
static mapbox::geojson::line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<Point>*/>);
diff --git a/platform/android/src/geojson/multi_line_string.cpp b/platform/android/src/geojson/multi_line_string.cpp
index c748d4786f..4a6ea37dd1 100644
--- a/platform/android/src/geojson/multi_line_string.cpp
+++ b/platform/android/src/geojson/multi_line_string.cpp
@@ -1,11 +1,22 @@
#include "multi_line_string.hpp"
#include "line_string.hpp"
+#include "util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<MultiLineString> MultiLineString::New(jni::JNIEnv& env, const mbgl::MultiLineString<double>& multiLineString) {
+ auto jList = asPointsListsList(env, multiLineString);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<MultiLineString> (jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jMultiLineString = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jMultiLineString;
+}
+
mapbox::geojson::multi_line_string MultiLineString::convert(jni::JNIEnv &env, jni::Object<MultiLineString> jMultiLineString) {
mapbox::geojson::multi_line_string multiLineString;
diff --git a/platform/android/src/geojson/multi_line_string.hpp b/platform/android/src/geojson/multi_line_string.hpp
index 358a6b5dda..934a0cb6b5 100644
--- a/platform/android/src/geojson/multi_line_string.hpp
+++ b/platform/android/src/geojson/multi_line_string.hpp
@@ -3,20 +3,23 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
#include "../java/util.hpp"
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace geojson {
-class MultiLineString : private mbgl::util::noncopyable {
+class MultiLineString : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/MultiLineString"; };
static constexpr auto Type() { return "MultiLineString"; };
+ static jni::Object<MultiLineString> New(jni::JNIEnv&, const mbgl::MultiLineString<double>&);
+
static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<MultiLineString>);
static mapbox::geojson::multi_line_string convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Point>>*/>);
diff --git a/platform/android/src/geojson/multi_point.cpp b/platform/android/src/geojson/multi_point.cpp
index 4f9ff596b2..6f62541209 100644
--- a/platform/android/src/geojson/multi_point.cpp
+++ b/platform/android/src/geojson/multi_point.cpp
@@ -8,6 +8,16 @@ namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<MultiPoint> MultiPoint::New(JNIEnv& env, const mbgl::MultiPoint<double>& multiPoint) {
+ auto jList = asPointsList(env, multiPoint);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<MultiPoint>(jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jMultiPoint = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jMultiPoint;
+}
+
mapbox::geojson::multi_point MultiPoint::convert(jni::JNIEnv &env, jni::Object<MultiPoint> jMultiPoint) {
mapbox::geojson::multi_point multiPoint;
diff --git a/platform/android/src/geojson/multi_point.hpp b/platform/android/src/geojson/multi_point.hpp
index e893e879af..cfe80cd34c 100644
--- a/platform/android/src/geojson/multi_point.hpp
+++ b/platform/android/src/geojson/multi_point.hpp
@@ -1,22 +1,26 @@
#pragma once
#include <mbgl/util/geojson.hpp>
+#include <mbgl/util/geometry.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
+#include "geometry.hpp"
#include "../java/util.hpp"
+#include <jni/jni.hpp>
+
namespace mbgl {
namespace android {
namespace geojson {
-class MultiPoint : private mbgl::util::noncopyable {
+class MultiPoint : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/MultiPoint"; };
static constexpr auto Type() { return "MultiPoint"; };
+ static jni::Object<MultiPoint> New(jni::JNIEnv&, const mbgl::MultiPoint<double>&);
+
static mapbox::geojson::multi_point convert(jni::JNIEnv&, jni::Object<MultiPoint>);
static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiPoint>);
diff --git a/platform/android/src/geojson/multi_polygon.cpp b/platform/android/src/geojson/multi_polygon.cpp
index aadba8c8a6..cc872d4955 100644
--- a/platform/android/src/geojson/multi_polygon.cpp
+++ b/platform/android/src/geojson/multi_polygon.cpp
@@ -1,11 +1,34 @@
#include "multi_polygon.hpp"
#include "polygon.hpp"
+#include "util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<MultiPolygon> MultiPolygon::New(JNIEnv& env, const mbgl::MultiPolygon<double>& multiPolygon) {
+ auto jarray = jni::Array<jni::Object<java::util::List>>::New(env, multiPolygon.size(), java::util::List::javaClass);
+
+ for (size_t i = 0; i < multiPolygon.size(); i++) {
+ auto& geometry = multiPolygon.at(i);
+ auto jPolygon = asPointsListsList(env, geometry);
+ jarray.Set(env, i, jPolygon);
+ jni::DeleteLocalRef(env, jPolygon);
+ }
+
+ // Turn into array list
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+
+ // create the MultiPolygon
+ static auto method = javaClass.GetStaticMethod<jni::Object<MultiPolygon> (jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jMultiPolygon = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jMultiPolygon;
+}
+
mapbox::geojson::multi_polygon MultiPolygon::convert(jni::JNIEnv &env, jni::Object<MultiPolygon> jMultiPolygon) {
mapbox::geojson::multi_polygon multiPolygon;
diff --git a/platform/android/src/geojson/multi_polygon.hpp b/platform/android/src/geojson/multi_polygon.hpp
index 6e1dfacfc8..b4657af09d 100644
--- a/platform/android/src/geojson/multi_polygon.hpp
+++ b/platform/android/src/geojson/multi_polygon.hpp
@@ -3,20 +3,23 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
#include "../java/util.hpp"
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace geojson {
-class MultiPolygon : private mbgl::util::noncopyable {
+class MultiPolygon : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/MultiPolygon"; };
static constexpr auto Type() { return "MultiPolygon"; };
+ static jni::Object<MultiPolygon> New(jni::JNIEnv&, const mbgl::MultiPolygon<double>&);
+
static mapbox::geojson::multi_polygon convert(jni::JNIEnv&, jni::Object<MultiPolygon>);
static jni::Object<java::util::List> coordinates(jni::JNIEnv&, jni::Object<MultiPolygon>);
diff --git a/platform/android/src/geojson/point.cpp b/platform/android/src/geojson/point.cpp
index e95376cd2e..aa9dc1a7f6 100644
--- a/platform/android/src/geojson/point.cpp
+++ b/platform/android/src/geojson/point.cpp
@@ -7,6 +7,11 @@ namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<Point> Point::New(jni::JNIEnv& env, const mbgl::Point<double>& point) {
+ static auto method = javaClass.GetStaticMethod<jni::Object<Point> (jni::jdouble, jni::jdouble)>(env, "fromLngLat");
+ return javaClass.Call(env, method, point.x, point.y);
+}
+
mapbox::geojson::point Point::convert(jni::JNIEnv &env, jni::Object<Point> jPoint) {
mapbox::geojson::point point;
diff --git a/platform/android/src/geojson/point.hpp b/platform/android/src/geojson/point.hpp
index c6412299bf..627bd1b649 100644
--- a/platform/android/src/geojson/point.hpp
+++ b/platform/android/src/geojson/point.hpp
@@ -3,20 +3,23 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <jni/jni.hpp>
-
#include "../java/util.hpp"
+#include "geometry.hpp"
+
+#include <jni/jni.hpp>
namespace mbgl {
namespace android {
namespace geojson {
-class Point : private mbgl::util::noncopyable {
+class Point : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/Point"; };
static constexpr auto Type() { return "Point"; };
+ static jni::Object<Point> New(jni::JNIEnv&, const mbgl::Point<double>&);
+
static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<Point>);
static mapbox::geojson::point convert(jni::JNIEnv&, jni::Object<java::util::List/*<Double>*/>);
diff --git a/platform/android/src/geojson/polygon.cpp b/platform/android/src/geojson/polygon.cpp
index 30ba996640..96058b63b3 100644
--- a/platform/android/src/geojson/polygon.cpp
+++ b/platform/android/src/geojson/polygon.cpp
@@ -8,6 +8,16 @@ namespace mbgl {
namespace android {
namespace geojson {
+jni::Object<Polygon> Polygon::New(jni::JNIEnv& env, const mbgl::Polygon<double>& polygon) {
+ auto jList = asPointsListsList(env, polygon);
+
+ static auto method = javaClass.GetStaticMethod<jni::Object<Polygon> (jni::Object<java::util::List>)>(env, "fromLngLats");
+ auto jPolygon = javaClass.Call(env, method, jList);
+
+ jni::DeleteLocalRef(env, jList);
+ return jPolygon;
+}
+
mapbox::geojson::polygon Polygon::convert(jni::JNIEnv &env, jni::Object<Polygon> jPolygon) {
mapbox::geojson::polygon polygon;
diff --git a/platform/android/src/geojson/polygon.hpp b/platform/android/src/geojson/polygon.hpp
index a8b2b93827..f3c23b4d7b 100644
--- a/platform/android/src/geojson/polygon.hpp
+++ b/platform/android/src/geojson/polygon.hpp
@@ -3,20 +3,24 @@
#include <mbgl/util/geojson.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include "geometry.hpp"
+#include "../java/util.hpp"
+
#include <jni/jni.hpp>
-#include "../java/util.hpp"
namespace mbgl {
namespace android {
namespace geojson {
-class Polygon : private mbgl::util::noncopyable {
+class Polygon : public Geometry {
public:
static constexpr auto Name() { return "com/mapbox/geojson/Polygon"; };
static constexpr auto Type() { return "Polygon"; };
+ static jni::Object<Polygon> New(jni::JNIEnv&, const mbgl::Polygon<double>&);
+
static mapbox::geojson::polygon convert(jni::JNIEnv &, jni::Object<Polygon>);
static mapbox::geojson::polygon convert(jni::JNIEnv&, jni::Object<java::util::List/*<java::util::List<Point>>*/>);
diff --git a/platform/android/src/geojson/util.hpp b/platform/android/src/geojson/util.hpp
index ece8e52433..5e6d90a953 100644
--- a/platform/android/src/geojson/util.hpp
+++ b/platform/android/src/geojson/util.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "point.hpp"
+
#include <type_traits>
namespace mbgl {
@@ -17,6 +19,42 @@ To convertExplicit(From&& src) {
return *reinterpret_cast<std::add_pointer_t<To>>(&src);
}
+/**
+ * Geometry -> List<Point>
+ */
+template <class T>
+static jni::Object<java::util::List> asPointsList(jni::JNIEnv& env, const T& pointsList) {
+ auto jarray = jni::Array<jni::Object<Point>>::New(env, pointsList.size(), Point::javaClass);
+
+ for (jni::jsize i = 0; i < pointsList.size(); i++) {
+ auto jPoint = Point::New(env, pointsList.at(i));
+ jarray.Set(env, i, jPoint);
+ jni::DeleteLocalRef(env, jPoint);
+ }
+
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+ return jList;
+}
+
+/**
+ * Geometry -> List<List<Point>>
+ */
+template <class SHAPE>
+static jni::Object<java::util::List> asPointsListsList(JNIEnv& env, SHAPE value) {
+ auto jarray = jni::Array<jni::Object<java::util::List>>::New(env, value.size(), java::util::List::javaClass);
+
+ for (size_t i = 0; i < value.size(); i = i + 1) {
+ auto pointsList = asPointsList(env, value[i]);
+ jarray.Set(env, i, pointsList);
+ jni::DeleteLocalRef(env, pointsList);
+ }
+
+ auto jList = java::util::Arrays::asList(env, jarray);
+ jni::DeleteLocalRef(env, jarray);
+ return jList;
+}
+
} // namespace geojson
} // namespace android
} // namespace mbgl
diff --git a/platform/android/src/java/util.cpp b/platform/android/src/java/util.cpp
index effd2ae0d0..89c4c77794 100644
--- a/platform/android/src/java/util.cpp
+++ b/platform/android/src/java/util.cpp
@@ -5,12 +5,14 @@ namespace android {
namespace java {
namespace util {
+jni::Class<Arrays> Arrays::javaClass;
jni::Class<List> List::javaClass;
jni::Class<Set> Set::javaClass;
jni::Class<Map> Map::javaClass;
jni::Class<Map::Entry> Map::Entry::javaClass;
void registerNative(jni::JNIEnv& env) {
+ Arrays::javaClass = *jni::Class<Arrays>::Find(env).NewGlobalRef(env).release();
List::javaClass = *jni::Class<List>::Find(env).NewGlobalRef(env).release();
Set::javaClass = *jni::Class<Set>::Find(env).NewGlobalRef(env).release();
Map::javaClass = *jni::Class<Map>::Find(env).NewGlobalRef(env).release();
diff --git a/platform/android/src/java/util.hpp b/platform/android/src/java/util.hpp
index dedb8ac348..c6b07acac5 100644
--- a/platform/android/src/java/util.hpp
+++ b/platform/android/src/java/util.hpp
@@ -24,6 +24,21 @@ public:
};
+class Arrays : private mbgl::util::noncopyable {
+public:
+
+ static constexpr auto Name() { return "java/util/Arrays"; };
+
+ template <class T>
+ static jni::Object<List> asList(jni::JNIEnv& env, jni::Array<jni::Object<T>> array) {
+ static auto asList = Arrays::javaClass.GetStaticMethod<jni::Object<List>(jni::Array<jni::Object<>>)>(env, "asList");
+ return javaClass.Call(env, asList, (jni::Array<jni::Object<>>) array);
+ }
+
+ static jni::Class<Arrays> javaClass;
+
+};
+
class Set : private mbgl::util::noncopyable {
public:
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index 68db977407..c8c20e939a 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -14,6 +14,7 @@
#include "geojson/feature.hpp"
#include "geojson/feature_collection.hpp"
#include "geojson/geometry.hpp"
+#include "geojson/geometry_collection.hpp"
#include "geojson/line_string.hpp"
#include "geojson/multi_line_string.hpp"
#include "geojson/multi_point.hpp"
@@ -116,6 +117,7 @@ void registerNatives(JavaVM *vm) {
geojson::Feature::registerNative(env);
geojson::FeatureCollection::registerNative(env);
geojson::Geometry::registerNative(env);
+ geojson::GeometryCollection::registerNative(env);
geojson::LineString::registerNative(env);
geojson::MultiLineString::registerNative(env);
geojson::MultiPoint::registerNative(env);