diff options
Diffstat (limited to 'platform/android/src/geometry/conversion/geometry.hpp')
-rw-r--r-- | platform/android/src/geometry/conversion/geometry.hpp | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/platform/android/src/geometry/conversion/geometry.hpp b/platform/android/src/geometry/conversion/geometry.hpp new file mode 100644 index 0000000000..385ba9034e --- /dev/null +++ b/platform/android/src/geometry/conversion/geometry.hpp @@ -0,0 +1,184 @@ +#pragma once + +#include "../../conversion/constant.hpp" +#include "../../conversion/collection.hpp" + +#include <mapbox/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; + + /** + * Point (double[]) + */ + jni::jobject* operator()(const mapbox::geometry::point<T> &geometry) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/Point")).release(); + static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([D)Lcom/mapbox/services/commons/geojson/Point;"); + + //Create Point + jni::LocalObject<jni::jarray<jni::jdouble>> position = jni::NewLocalObject(env, toGeoJsonPosition(env, geometry.x, geometry.y)); + return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, position.get())); + } + + /** + * LineString (double[][]) + */ + jni::jobject* operator()(const mapbox::geometry::line_string<T> &geometry) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/LineString")).release(); + static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[D)Lcom/mapbox/services/commons/geojson/LineString;"); + + //Create + jni::LocalObject<jni::jarray<jni::jobject>> coordinates = jni::NewLocalObject(env, toGeoJsonCoordinates(env, geometry)); + return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, coordinates.get())); + } + + /** + * MultiPoint (double[][]) + */ + jni::jobject* operator()(const mapbox::geometry::multi_point<T> &geometry) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/MultiPoint")).release(); + static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[D)Lcom/mapbox/services/commons/geojson/MultiPoint;"); + + //Create + jni::LocalObject<jni::jarray<jni::jobject>> coordinates = jni::NewLocalObject(env, toGeoJsonCoordinates(env, geometry)); + return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, coordinates.get())); + } + + /** + * Polygon (double[][][]) + */ + jni::jobject* operator()(const mapbox::geometry::polygon<T> &geometry) const { + static jni::jclass* javaClass = jni::NewGlobalRef(env, &jni::FindClass(env, "com/mapbox/services/commons/geojson/Polygon")).release(); + static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[[D)Lcom/mapbox/services/commons/geojson/Polygon;"); + + //Create + jni::LocalObject<jni::jarray<jni::jobject>> shape = jni::NewLocalObject(env, toShape<>(env, geometry)); + return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, shape.get())); + } + + /** + * MultiLineString (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/services/commons/geojson/MultiLineString")).release(); + static jni::jmethodID* fromCoordinates = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[[D)Lcom/mapbox/services/commons/geojson/MultiLineString;"); + + //Create + jni::LocalObject<jni::jarray<jni::jobject>> shape = jni::NewLocalObject(env, toShape<>(env, geometry)); + return reinterpret_cast<jni::jobject*>(jni::CallStaticMethod<jni::jobject*>(env, *javaClass, *fromCoordinates, shape.get())); + } + + /** + * MultiPolygon (double[][][][]) -> [[[D + Object array == [[[[D + */ + jni::jobject* operator()(const mapbox::geometry::multi_polygon<T> &geometry) const { + static jni::jclass* listClass = jni::NewGlobalRef(env, &jni::FindClass(env, "[[[D")).release(); + jni::LocalObject<jni::jarray<jni::jobject>> jarray = jni::NewLocalObject(env, &jni::NewObjectArray(env, geometry.size(), *listClass)); + + for(size_t i = 0; i < geometry.size(); i = i + 1) { + jni::LocalObject<jni::jarray<jni::jobject>> shape = jni::NewLocalObject(env, toShape<>(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/services/commons/geojson/MultiPolygon")).release(); + static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromCoordinates", "([[[[D)Lcom/mapbox/services/commons/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/services/commons/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/services/commons/geojson/GeometryCollection")).release(); + static jni::jmethodID* fromGeometries = &jni::GetStaticMethodID(env, *javaClass, "fromGeometries", "(Ljava/util/List;)Lcom/mapbox/services/commons/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>* toGeoJsonPosition(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> (double[][]) -> [D + Object array == [[D + */ + static jni::jarray<jni::jobject>* toGeoJsonCoordinates(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::LocalObject<jni::jarray<jni::jdouble>> position = jni::NewLocalObject(env, toGeoJsonPosition(env, point.x, point.y)); + jni::SetObjectArrayElement(env, jarray, i, position.get()); + } + + return &jarray; + } + + /** + * polygon<T> + * multi_line_string<T> + * -> jarray<jobject> (double[][][]) -> [[D + Object array == [[[D + */ + template <class SHAPE> + static jni::jarray<jni::jobject>* toShape(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>> coordinates = jni::NewLocalObject(env, toGeoJsonCoordinates(env, value.at(i))); + jni::SetObjectArrayElement(env, jarray, i, coordinates.get()); + } + + return &jarray; + } +}; + +/** + * 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}; + } +}; + + +} +} +} |