From 5c79baedf933e7a3d90cbad541deee294f5ed6ed Mon Sep 17 00:00:00 2001 From: Leith Bade Date: Mon, 16 Feb 2015 15:25:31 -0800 Subject: Add projection functions to Java --- android/cpp/jni.cpp | 244 ++++++++++++++++++++- .../java/com/mapbox/mapboxgl/lib/LatLngZoom.java | 82 ------- .../main/java/com/mapbox/mapboxgl/lib/MapView.java | 17 +- .../com/mapbox/mapboxgl/lib/NativeMapView.java | 41 ++++ .../mapboxgl/lib/constants/GeoConstants.java | 2 +- .../mapboxgl/lib/constants/MathConstants.java | 2 +- .../mapbox/mapboxgl/lib/geometry/BoundingBox.java | 3 +- .../mapboxgl/lib/geometry/CoordinateRegion.java | 6 +- .../mapboxgl/lib/geometry/CoordinateSpan.java | 8 +- .../mapboxgl/lib/geometry/IProjectedMeters.java | 7 + .../com/mapbox/mapboxgl/lib/geometry/LatLng.java | 49 +++-- .../mapbox/mapboxgl/lib/geometry/LatLngZoom.java | 91 ++++++++ .../mapboxgl/lib/geometry/ProjectedMeters.java | 95 ++++++++ .../java/com/mapbox/mapboxgl/app/MainActivity.java | 6 +- 14 files changed, 515 insertions(+), 138 deletions(-) delete mode 100644 android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/LatLngZoom.java create mode 100644 android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/IProjectedMeters.java create mode 100644 android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLngZoom.java create mode 100644 android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/ProjectedMeters.java (limited to 'android') diff --git a/android/cpp/jni.cpp b/android/cpp/jni.cpp index b583b83561..eca13c764f 100644 --- a/android/cpp/jni.cpp +++ b/android/cpp/jni.cpp @@ -53,6 +53,16 @@ jclass arrayListClass = nullptr; jmethodID arrayListConstructorId = nullptr; jmethodID arrayListAddId = nullptr; +jclass projectedMetersClass = nullptr; +jmethodID projectedMetersConstructorId = nullptr; +jfieldID projectedMetersNorthingId = nullptr; +jfieldID projectedMetersEastingId = nullptr; + +jclass pointFClass = nullptr; +jmethodID pointFConstructorId = nullptr; +jfieldID pointFXId = nullptr; +jfieldID pointFYId = nullptr; + bool throw_error(JNIEnv *env, const char *msg) { if (env->ThrowNew(runtimeExceptionClass, msg) < 0) { env->ExceptionDescribe(); @@ -455,13 +465,13 @@ void JNICALL nativeSetLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, j assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - double latitude = env->GetDoubleField(latLng, latLngLatitudeId); + jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } - double longitude = env->GetDoubleField(latLng, latLngLongitudeId); + jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; @@ -550,19 +560,19 @@ void JNICALL nativeSetLatLngZoom(JNIEnv *env, jobject obj, jlong nativeMapViewPt assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); - double latitude = env->GetDoubleField(latLngZoom, latLngZoomLatitudeId); + jdouble latitude = env->GetDoubleField(latLngZoom, latLngZoomLatitudeId); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } - double longitude = env->GetDoubleField(latLngZoom, latLngZoomLongitudeId); + jdouble longitude = env->GetDoubleField(latLngZoom, latLngZoomLongitudeId); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; } - double zoom = env->GetDoubleField(latLngZoom, latLngZoomZoomId); + jdouble zoom = env->GetDoubleField(latLngZoom, latLngZoomZoomId); if (env->ExceptionCheck()) { env->ExceptionDescribe(); return; @@ -576,7 +586,7 @@ jobject JNICALL nativeGetLatLngZoom(JNIEnv *env, jobject obj, jlong nativeMapVie assert(nativeMapViewPtr != 0); NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); mbgl::LatLng latLng = nativeMapView->getMap().getLatLng(); - double zoom = nativeMapView->getMap().getZoom(); + jdouble zoom = nativeMapView->getMap().getZoom(); jobject ret = env->NewObject(latLngZoomClass, latLngZoomConstructorId, latLng.longitude, latLng.latitude, zoom); if (ret == nullptr) { @@ -705,6 +715,125 @@ nativeSetReachability(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jboolean mbgl::NetworkStatus::Reachable(); } } + +jdouble JNICALL nativeGetMetersPerPixelAtLatitude(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jdouble lat, jdouble zoom) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeGetMetersPerPixelAtLatitude"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); + return nativeMapView->getMap().getMetersPerPixelAtLatitude(lat, zoom); +} + +jobject JNICALL nativeProjectedMetersForLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeProjectedMetersForLatLng"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); + + jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + mbgl::ProjectedMeters projectedMeters = nativeMapView->getMap().projectedMetersForLatLng(mbgl::LatLng(latitude, longitude)); + + jobject ret = env->NewObject(projectedMetersClass, projectedMetersConstructorId, projectedMeters.northing, projectedMeters.easting); + if (ret == nullptr) { + env->ExceptionDescribe(); + return nullptr; + } + + return ret; +} + +jobject JNICALL nativeLatLngForProjectedMeters(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject projectedMeters) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeLatLngForProjectedMeters"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); + + jdouble northing = env->GetDoubleField(projectedMeters, projectedMetersNorthingId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + jdouble easting = env->GetDoubleField(projectedMeters, projectedMetersEastingId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + mbgl::LatLng latLng = nativeMapView->getMap().latLngForProjectedMeters(mbgl::ProjectedMeters(northing, easting)); + + jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude); + if (ret == nullptr) { + env->ExceptionDescribe(); + return nullptr; + } + + return ret; +} + +jobject JNICALL nativePixelForLatLng(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject latLng) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativePixelForLatLng"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); + + jdouble latitude = env->GetDoubleField(latLng, latLngLatitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + jdouble longitude = env->GetDoubleField(latLng, latLngLongitudeId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + mbgl::vec2 pixel = nativeMapView->getMap().pixelForLatLng(mbgl::LatLng(latitude, longitude)); + + jobject ret = env->NewObject(pointFClass, pointFConstructorId, static_cast(pixel.x), static_cast(pixel.y)); + if (ret == nullptr) { + env->ExceptionDescribe(); + return nullptr; + } + + return ret; +} + +jobject JNICALL nativeLatLngForPixel(JNIEnv *env, jobject obj, jlong nativeMapViewPtr, jobject pixel) { + mbgl::Log::Debug(mbgl::Event::JNI, "nativeLatLngForPixel"); + assert(nativeMapViewPtr != 0); + NativeMapView *nativeMapView = reinterpret_cast(nativeMapViewPtr); + + jfloat x = env->GetDoubleField(pixel, pointFXId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + jfloat y = env->GetDoubleField(pixel, pointFYId); + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + return nullptr; + } + + mbgl::LatLng latLng = nativeMapView->getMap().latLngForPixel(mbgl::vec2(x, y)); + + jobject ret = env->NewObject(latLngClass, latLngConstructorId, latLng.latitude, latLng.longitude); + if (ret == nullptr) { + env->ExceptionDescribe(); + return nullptr; + } + + return ret; +} } extern "C" { @@ -745,7 +874,7 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } - latLngZoomClass = env->FindClass("com/mapbox/mapboxgl/lib/LatLngZoom"); + latLngZoomClass = env->FindClass("com/mapbox/mapboxgl/lib/geometry/LatLngZoom"); if (latLngZoomClass == nullptr) { env->ExceptionDescribe(); return JNI_ERR; @@ -835,9 +964,57 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } + projectedMetersClass = env->FindClass("com/mapbox/mapboxgl/lib/geometry/ProjectedMeters"); + if (projectedMetersClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + projectedMetersConstructorId = env->GetMethodID(projectedMetersClass, "", "(DD)V"); + if (projectedMetersConstructorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + projectedMetersNorthingId = env->GetFieldID(projectedMetersClass, "northing", "D"); + if (projectedMetersNorthingId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + projectedMetersEastingId = env->GetFieldID(projectedMetersClass, "easting", "D"); + if (projectedMetersEastingId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + pointFClass = env->FindClass("android/graphics/PointF"); + if (pointFClass == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + pointFConstructorId = env->GetMethodID(pointFClass, "", "(FF)V"); + if (pointFConstructorId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + pointFXId = env->GetFieldID(pointFClass, "x", "F"); + if (pointFXId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + + pointFYId = env->GetFieldID(pointFClass, "y", "F"); + if (pointFYId == nullptr) { + env->ExceptionDescribe(); + return JNI_ERR; + } + // NOTE: if you get java.lang.UnsatisfiedLinkError you likely forgot to set the size of the // array correctly (too large) - std::array methods = {{ // Can remove the extra brace in C++14 + std::array methods = {{ // Can remove the extra brace in C++14 {"nativeCreate", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)J", reinterpret_cast(&nativeCreate)}, {"nativeDestroy", "(J)V", reinterpret_cast(&nativeDestroy)}, @@ -903,9 +1080,9 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { {"nativeGetScale", "(J)D", reinterpret_cast(&nativeGetScale)}, {"nativeSetZoom", "(JDJ)V", reinterpret_cast(&nativeSetZoom)}, {"nativeGetZoom", "(J)D", reinterpret_cast(&nativeGetZoom)}, - {"nativeSetLatLngZoom", "(JLcom/mapbox/mapboxgl/lib/LatLngZoom;J)V", + {"nativeSetLatLngZoom", "(JLcom/mapbox/mapboxgl/lib/geometry/LatLngZoom;J)V", reinterpret_cast(&nativeSetLatLngZoom)}, - {"nativeGetLatLngZoom", "(J)Lcom/mapbox/mapboxgl/lib/LatLngZoom;", + {"nativeGetLatLngZoom", "(J)Lcom/mapbox/mapboxgl/lib/geometry/LatLngZoom;", reinterpret_cast(&nativeGetLatLngZoom)}, {"nativeResetZoom", "(J)V", reinterpret_cast(&nativeResetZoom)}, {"nativeStartPanning", "(J)V", reinterpret_cast(&nativeStartScaling)}, @@ -928,7 +1105,15 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { {"nativeSetDebug", "(JZ)V", reinterpret_cast(&nativeSetDebug)}, {"nativeToggleDebug", "(J)V", reinterpret_cast(&nativeToggleDebug)}, {"nativeGetDebug", "(J)Z", reinterpret_cast(&nativeGetDebug)}, - {"nativeSetReachability", "(JZ)V", reinterpret_cast(&nativeSetReachability)}}}; + {"nativeSetReachability", "(JZ)V", reinterpret_cast(&nativeSetReachability)}, + //{"nativeGetWorldBoundsMeters", "(J)V", reinterpret_cast(&nativeGetWorldBoundsMeters)}, + //{"nativeGetWorldBoundsLatLng", "(J)V", reinterpret_cast(&nativeGetWorldBoundsLatLng)}, + {"nativeGetMetersPerPixelAtLatitude", "(JDD)D", reinterpret_cast(&nativeGetMetersPerPixelAtLatitude)}, + {"nativeProjectedMetersForLatLng", "(JLcom/mapbox/mapboxgl/lib/geometry/LatLng;)Lcom/mapbox/mapboxgl/lib/geometry/ProjectedMeters;", reinterpret_cast(&nativeProjectedMetersForLatLng)}, + {"nativeLatLngForProjectedMeters", "(JLcom/mapbox/mapboxgl/lib/geometry/ProjectedMeters;)Lcom/mapbox/mapboxgl/lib/geometry/LatLng;", reinterpret_cast(&nativeLatLngForProjectedMeters)}, + {"nativePixelForLatLng", "(JLcom/mapbox/mapboxgl/lib/geometry/LatLng;)Landroid/graphics/PointF;", reinterpret_cast(&nativePixelForLatLng)}, + {"nativeLatLngForPixel", "(JLandroid/graphics/PointF;)Lcom/mapbox/mapboxgl/lib/geometry/LatLng;", reinterpret_cast(&nativeLatLngForPixel)}, + }}; if (env->RegisterNatives(nativeMapViewClass, methods.data(), methods.size()) < 0) { env->ExceptionDescribe(); @@ -976,6 +1161,31 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_ERR; } + projectedMetersClass = reinterpret_cast(env->NewGlobalRef(projectedMetersClass)); + if (projectedMetersClass == nullptr) { + env->ExceptionDescribe(); + env->DeleteGlobalRef(latLngClass); + env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(runtimeExceptionClass); + env->DeleteGlobalRef(nullPointerExceptionClass); + env->DeleteGlobalRef(arrayListClass); + return JNI_ERR; + } + + + pointFClass = reinterpret_cast(env->NewGlobalRef(pointFClass)); + if (pointFClass == nullptr) { + env->ExceptionDescribe(); + env->DeleteGlobalRef(latLngClass); + env->DeleteGlobalRef(latLngZoomClass); + env->DeleteGlobalRef(runtimeExceptionClass); + env->DeleteGlobalRef(nullPointerExceptionClass); + env->DeleteGlobalRef(arrayListClass); + env->DeleteGlobalRef(projectedMetersClass); + return JNI_ERR; + } + + char release[PROP_VALUE_MAX] = ""; __system_property_get("ro.build.version.release", release); androidRelease = std::string(release); @@ -1021,5 +1231,17 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) { arrayListClass = nullptr; arrayListConstructorId = nullptr; arrayListAddId = nullptr; + + env->DeleteGlobalRef(projectedMetersClass); + projectedMetersClass = nullptr; + projectedMetersConstructorId = nullptr; + projectedMetersNorthingId = nullptr; + projectedMetersEastingId = nullptr; + + env->DeleteGlobalRef(pointFClass); + pointFClass = nullptr; + pointFConstructorId = nullptr; + pointFXId = nullptr; + pointFYId = nullptr; } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/LatLngZoom.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/LatLngZoom.java deleted file mode 100644 index c6e80b0c13..0000000000 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/LatLngZoom.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.mapbox.mapboxgl.lib; - -import android.os.Parcel; -import android.os.Parcelable; -import com.mapbox.mapboxgl.lib.geometry.LatLng; - -public class LatLngZoom extends LatLng implements Parcelable { - - public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { - public LatLngZoom createFromParcel(Parcel in) { - return new LatLngZoom(in); - } - - public LatLngZoom[] newArray(int size) { - return new LatLngZoom[size]; - } - }; - - private double zoom; - - public LatLngZoom(double lat, double lon, double zoom) { - super(lat, lon); - this.zoom = zoom; - } - - public LatLngZoom(LatLng latLng, double zoom) { - super(latLng.getLatitude(), latLng.getLongitude()); - this.zoom = zoom; - } - - private LatLngZoom(Parcel in) { - super(in); - zoom = in.readDouble(); - } - - public double getZoom() { - return zoom; - } - - public void setZoom(double zoom) { - this.zoom = zoom; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - LatLngZoom that = (LatLngZoom) o; - - if (Double.compare(that.zoom, zoom) != 0) return false; - - return true; - } - - @Override - public int hashCode() { - int result = super.hashCode(); - long temp; - temp = Double.doubleToLongBits(zoom); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - return result; - } - - @Override - public String toString() { - return "LatLngZoom [latitude=" + super.getLatitude() + ", longitude=" + super.getLongitude() + ", altitude=" + super.getAltitude() + ", zoom=" + zoom + "]"; - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeDouble(zoom); - } - -} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/MapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/MapView.java index d157cc07f8..b9545dc33e 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/MapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/MapView.java @@ -30,6 +30,7 @@ import android.widget.ZoomButtonsController; import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector; import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector; import com.mapbox.mapboxgl.lib.geometry.LatLng; +import com.mapbox.mapboxgl.lib.geometry.LatLngZoom; import org.apache.commons.validator.routines.UrlValidator; @@ -135,7 +136,6 @@ public class MapView extends SurfaceView { // Check if we are in Eclipse UI editor if (isInEditMode()) { - // TODO editor does not load properly because we don't implement this return; } @@ -386,7 +386,7 @@ public class MapView extends SurfaceView { public void removeAllClasses(long transitionDuration) { mNativeMapView.setDefaultTransitionDuration(transitionDuration); - ArrayList classes = new ArrayList(0); + ArrayList classes = new ArrayList<>(0); setClasses(classes); } @@ -436,7 +436,7 @@ public class MapView extends SurfaceView { outState.putBoolean(STATE_DEBUG_ACTIVE, isDebugActive()); outState.putString(STATE_STYLE_URL, mStyleUrl); outState.putString(STATE_ACCESS_TOKEN, getAccessToken()); - outState.putStringArrayList(STATE_CLASSES, new ArrayList(getClasses())); + outState.putStringArrayList(STATE_CLASSES, new ArrayList<>(getClasses())); outState.putLong(STATE_DEFAULT_TRANSITION_DURATION, mNativeMapView.getDefaultTransitionDuration()); } @@ -531,8 +531,6 @@ public class MapView extends SurfaceView { } } - // TODO examine how GLSurvaceView hadles attach/detach from window - // Called when view is no longer connected @Override protected void onDetachedFromWindow() { @@ -560,10 +558,6 @@ public class MapView extends SurfaceView { // Draw events // - // TODO: onDraw for UI editor mockup? - // By default it just shows a gray screen with "MapView" - // Not too important but perhaps we could put a static demo map image there - // // Input events // @@ -782,7 +776,7 @@ public class MapView extends SurfaceView { return false; } - // TODO complex decision between roate or scale or both (see Google + // TODO complex decision between rotate or scale or both (see Google // Maps app) // Cancel any animation @@ -1011,7 +1005,6 @@ public class MapView extends SurfaceView { // Called for trackball events, all motions are relative in device specific // units - // TODO: test trackball click and long click @Override public boolean onTrackballEvent(MotionEvent event) { // Choose the action @@ -1105,8 +1098,6 @@ public class MapView extends SurfaceView { @Override @TargetApi(12) public boolean onGenericMotionEvent(MotionEvent event) { // Mouse events - // TODO: SOURCE_TOUCH_NAVIGATION? - // TODO: source device resolution? //if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) { // Choose the action diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/NativeMapView.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/NativeMapView.java index c1c5dcf10a..3059c0bfa4 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/NativeMapView.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/NativeMapView.java @@ -1,8 +1,11 @@ package com.mapbox.mapboxgl.lib; +import android.graphics.PointF; import android.view.Surface; import com.mapbox.mapboxgl.lib.geometry.LatLng; +import com.mapbox.mapboxgl.lib.geometry.LatLngZoom; +import com.mapbox.mapboxgl.lib.geometry.ProjectedMeters; import java.util.List; @@ -392,6 +395,30 @@ class NativeMapView { nativeSetReachability(mNativeMapViewPtr, status); } + //public void getWorldBoundsMeters(); + + //public void getWorldBoundsLatLng(); + + public double getMetersPerPixelAtLatitude(double lat, double zoom) { + return nativeGetMetersPerPixelAtLatitude(mNativeMapViewPtr, lat, zoom); + } + + public ProjectedMeters projectedMetersForLatLng(LatLng latLng) { + return nativeProjectedMetersForLatLng(mNativeMapViewPtr, latLng); + } + + public LatLng latLngForProjectedMeters(ProjectedMeters projectedMeters) { + return nativeLatLngForProjectedMeters(mNativeMapViewPtr, projectedMeters); + } + + public PointF pixelForLatLng(LatLng latLng) { + return nativePixelForLatLng(mNativeMapViewPtr, latLng); + } + + public LatLng latLngForPixel(PointF pixel) { + return nativeLatLngForPixel(mNativeMapViewPtr, pixel); + } + // // Callbacks // @@ -553,4 +580,18 @@ class NativeMapView { private native boolean nativeGetDebug(long nativeMapViewPtr); private native void nativeSetReachability(long nativeMapViewPtr, boolean status); + + //private native void nativeGetWorldBoundsMeters(long nativeMapViewPtr); + + //private native void nativeGetWorldBoundsLatLng(long nativeMapViewPtr); + + private native double nativeGetMetersPerPixelAtLatitude(long nativeMapViewPtr, double lat, double zoom); + + private native ProjectedMeters nativeProjectedMetersForLatLng(long nativeMapViewPtr, LatLng latLng); + + private native LatLng nativeLatLngForProjectedMeters(long nativeMapViewPtr, ProjectedMeters projectedMeters); + + private native PointF nativePixelForLatLng(long nativeMapViewPtr, LatLng latLng); + + private native LatLng nativeLatLngForPixel(long nativeMapViewPtr, PointF pixel); } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/GeoConstants.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/GeoConstants.java index d7f674d7b1..fff665b5a1 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/GeoConstants.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/GeoConstants.java @@ -1,6 +1,6 @@ package com.mapbox.mapboxgl.lib.constants; -public interface GeoConstants { +public class GeoConstants { // http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius public static final int RADIUS_EARTH_METERS = 6378137; public static final double MIN_LATITUDE = -85.05112878; diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/MathConstants.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/MathConstants.java index f6a692d443..cd11523605 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/MathConstants.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/constants/MathConstants.java @@ -1,6 +1,6 @@ package com.mapbox.mapboxgl.lib.constants; -public interface MathConstants { +public class MathConstants { public static final double DEG2RAD = (Math.PI / 180.0); public static final double RAD2DEG = (180.0 / Math.PI); diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/BoundingBox.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/BoundingBox.java index 3a8141e3c3..ba60701b82 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/BoundingBox.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/BoundingBox.java @@ -2,6 +2,7 @@ package com.mapbox.mapboxgl.lib.geometry; import android.os.Parcel; import android.os.Parcelable; + import java.io.Serializable; import java.util.List; @@ -10,8 +11,6 @@ import java.util.List; */ public final class BoundingBox implements Parcelable, Serializable { - static final long serialVersionUID = 2L; - private final double mLatNorth; private final double mLatSouth; private final double mLonEast; diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateRegion.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateRegion.java index 1d2409b464..b5c5f66ba8 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateRegion.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateRegion.java @@ -7,7 +7,7 @@ public class CoordinateRegion { private LatLng center; private CoordinateSpan span; - public CoordinateRegion(LatLng center, CoordinateSpan span) { + public CoordinateRegion(final LatLng center, final CoordinateSpan span) { this.center = center; this.span = span; } @@ -16,7 +16,7 @@ public class CoordinateRegion { return center; } - public void setCenter(LatLng center) { + public void setCenter(final LatLng center) { this.center = center; } @@ -24,7 +24,7 @@ public class CoordinateRegion { return span; } - public void setSpan(CoordinateSpan span) { + public void setSpan(final CoordinateSpan span) { this.span = span; } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateSpan.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateSpan.java index 4fa239f664..b79fb7c42d 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateSpan.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/CoordinateSpan.java @@ -3,12 +3,12 @@ package com.mapbox.mapboxgl.lib.geometry; /** * Implementation of iOS MKCoordinateSpan */ -public final class CoordinateSpan { +public class CoordinateSpan { private double latitudeSpan; private double longitudeSpan; - public CoordinateSpan(double latitudeSpan, double longitudeSpan) { + public CoordinateSpan(final double latitudeSpan, final double longitudeSpan) { this.latitudeSpan = latitudeSpan; this.longitudeSpan = longitudeSpan; } @@ -17,7 +17,7 @@ public final class CoordinateSpan { return latitudeSpan; } - public void setLatitudeSpan(double latitudeSpan) { + public void setLatitudeSpan(final double latitudeSpan) { this.latitudeSpan = latitudeSpan; } @@ -25,7 +25,7 @@ public final class CoordinateSpan { return longitudeSpan; } - public void setLongitudeSpan(double longitudeSpan) { + public void setLongitudeSpan(final double longitudeSpan) { this.longitudeSpan = longitudeSpan; } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/IProjectedMeters.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/IProjectedMeters.java new file mode 100644 index 0000000000..398f368b3f --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/IProjectedMeters.java @@ -0,0 +1,7 @@ +package com.mapbox.mapboxgl.lib.geometry; + +public interface IProjectedMeters { + double getNorthing(); + + double getEasting(); +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLng.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLng.java index eddd99a940..de97b57515 100644 --- a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLng.java +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLng.java @@ -3,11 +3,13 @@ package com.mapbox.mapboxgl.lib.geometry; import android.location.Location; import android.os.Parcel; import android.os.Parcelable; + import com.mapbox.mapboxgl.lib.constants.GeoConstants; import com.mapbox.mapboxgl.lib.constants.MathConstants; + import java.io.Serializable; -public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, Serializable { +public class LatLng implements ILatLng, Parcelable, Serializable { public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public LatLng createFromParcel(Parcel in) { @@ -26,7 +28,7 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, /** * Construct a new latitude, longitude point given float arguments * @param latitude Latitude in degrees - * @param longitude Longitude in degress + * @param longitude Longitude in degrees */ public LatLng(double latitude, double longitude) { this.latitude = latitude; @@ -39,7 +41,7 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, * @param longitude Longitude in degress * @param altitude Altitude in meters */ - public LatLng(final double latitude, final double longitude, final double altitude) { + public LatLng(double latitude, double longitude, double altitude) { this.latitude = latitude; this.longitude = longitude; this.altitude = altitude; @@ -49,7 +51,7 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, * Transform a Location into a LatLng point * @param location Android Location */ - public LatLng(final Location location) { + public LatLng(Location location) { this(location.getLatitude(), location.getLongitude(), location.getAltitude()); } @@ -57,15 +59,15 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, * Clone an existing latitude longitude point * @param aLatLng LatLng */ - public LatLng(final LatLng aLatLng) { + public LatLng(LatLng aLatLng) { this.latitude = aLatLng.latitude; this.longitude = aLatLng.longitude; this.altitude = aLatLng.altitude; } protected LatLng(Parcel in) { - longitude = in.readDouble(); latitude = in.readDouble(); + longitude = in.readDouble(); altitude = in.readDouble(); } @@ -86,14 +88,25 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, @Override public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } LatLng latLng = (LatLng) o; - if (Double.compare(latLng.altitude, altitude) != 0) return false; - if (Double.compare(latLng.latitude, latitude) != 0) return false; - if (Double.compare(latLng.longitude, longitude) != 0) return false; + if (Double.compare(latLng.altitude, altitude) != 0) { + return false; + } + + if (Double.compare(latLng.latitude, latitude) != 0) { + return false; + } + if (Double.compare(latLng.longitude, longitude) != 0) { + return false; + } return true; } @@ -123,8 +136,8 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, @Override public void writeToParcel(Parcel out, int flags) { - out.writeDouble(longitude); out.writeDouble(latitude); + out.writeDouble(longitude); out.writeDouble(altitude); } @@ -133,12 +146,12 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, * @param other Other LatLng to compare to * @return distance in meters */ - public double distanceTo(final LatLng other) { + public double distanceTo(LatLng other) { - final double a1 = DEG2RAD * this.latitude; - final double a2 = DEG2RAD * this.longitude; - final double b1 = DEG2RAD * other.getLatitude(); - final double b2 = DEG2RAD * other.getLongitude(); + final double a1 = MathConstants.DEG2RAD * this.latitude; + final double a2 = MathConstants.DEG2RAD * this.longitude; + final double b1 = MathConstants.DEG2RAD * other.getLatitude(); + final double b2 = MathConstants.DEG2RAD * other.getLongitude(); final double cosa1 = Math.cos(a1); final double cosb1 = Math.cos(b1); @@ -148,6 +161,6 @@ public class LatLng implements ILatLng, GeoConstants, MathConstants, Parcelable, final double t3 = Math.sin(a1) * Math.sin(b1); final double tt = Math.acos(t1 + t2 + t3); - return RADIUS_EARTH_METERS * tt; + return GeoConstants.RADIUS_EARTH_METERS * tt; } } diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLngZoom.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLngZoom.java new file mode 100644 index 0000000000..bd8a214e2b --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/LatLngZoom.java @@ -0,0 +1,91 @@ +package com.mapbox.mapboxgl.lib.geometry; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.io.Serializable; + +public class LatLngZoom extends LatLng implements Parcelable, Serializable { + + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + public LatLngZoom createFromParcel(Parcel in) { + return new LatLngZoom(in); + } + + public LatLngZoom[] newArray(int size) { + return new LatLngZoom[size]; + } + }; + + private double zoom; + + public LatLngZoom(double latitude, double longitude, double zoom) { + super(latitude, longitude); + this.zoom = zoom; + } + + public LatLngZoom(LatLng latLng, double zoom) { + super(latLng.getLatitude(), latLng.getLongitude()); + this.zoom = zoom; + } + + private LatLngZoom(Parcel in) { + super(in); + zoom = in.readDouble(); + } + + public double getZoom() { + return zoom; + } + + public void setZoom(double zoom) { + this.zoom = zoom; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + + LatLngZoom that = (LatLngZoom) o; + + if (Double.compare(that.zoom, zoom) != 0) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + long temp; + temp = Double.doubleToLongBits(zoom); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public String toString() { + return "LatLngZoom [latitude=" + super.getLatitude() + ", longitude=" + super.getLongitude() + ", altitude=" + super.getAltitude() + ", zoom=" + zoom + "]"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeDouble(zoom); + } + +} diff --git a/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/ProjectedMeters.java b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/ProjectedMeters.java new file mode 100644 index 0000000000..9bab088d12 --- /dev/null +++ b/android/java/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxgl/lib/geometry/ProjectedMeters.java @@ -0,0 +1,95 @@ +package com.mapbox.mapboxgl.lib.geometry; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.io.Serializable; + +public class ProjectedMeters implements IProjectedMeters, Parcelable, Serializable { + + public static final Creator CREATOR = new Creator() { + public ProjectedMeters createFromParcel(Parcel in) { + return new ProjectedMeters(in); + } + + public ProjectedMeters[] newArray(int size) { + return new ProjectedMeters[size]; + } + }; + + private double northing; + private double easting; + + public ProjectedMeters(double northing, double easting) { + this.northing = northing; + this.easting = easting; + } + + public ProjectedMeters(ProjectedMeters aProjectedMeters) { + this.northing = aProjectedMeters.northing; + this.easting = aProjectedMeters.easting; + } + + protected ProjectedMeters(Parcel in) { + northing = in.readDouble(); + easting = in.readDouble(); + } + + @Override + public double getNorthing() { + return northing; + } + + @Override + public double getEasting() { + return easting; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + ProjectedMeters projectedMeters = (ProjectedMeters) o; + + if (Double.compare(projectedMeters.easting, easting) != 0) { + return false; + } + if (Double.compare(projectedMeters.northing, northing) != 0) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result; + long temp; + temp = Double.doubleToLongBits(easting); + result = (int) (temp ^ (temp >>> 32)); + temp = Double.doubleToLongBits(northing); + result = 31 * result + (int) (temp ^ (temp >>> 32)); + return result; + } + + @Override + public String toString() { + return "ProjectedMeters [northing=" + northing + ", easting=" + easting + "]"; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeDouble(northing); + out.writeDouble(easting); + } +} diff --git a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/app/MainActivity.java b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/app/MainActivity.java index 831dd99ae2..bb8a6bacc6 100644 --- a/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/app/MainActivity.java +++ b/android/java/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxgl/app/MainActivity.java @@ -15,7 +15,7 @@ import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; -import com.mapbox.mapboxgl.lib.LatLngZoom; +import com.mapbox.mapboxgl.lib.geometry.LatLngZoom; import com.mapbox.mapboxgl.lib.MapView; import com.mapzen.android.lost.LocationClient; import com.mapzen.android.lost.LocationListener; @@ -283,7 +283,7 @@ public class MainActivity extends ActionBarActivity { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - ArrayList classes = new ArrayList(1); + ArrayList classes = new ArrayList<>(1); switch(position) { // Day @@ -315,7 +315,7 @@ public class MainActivity extends ActionBarActivity { @Override public void onItemSelected(AdapterView parent, View view, int position, long id) { - ArrayList classes = new ArrayList(2); + ArrayList classes = new ArrayList<>(2); switch(position) { // Labels + Contours -- cgit v1.2.1