diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java index d9ffe48b305..0007a9f4a9f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java @@ -6,6 +6,7 @@ import com.mapbox.mapboxsdk.constants.GeoConstants; import com.mapbox.mapboxsdk.constants.MathConstants; +import com.mapbox.mapboxsdk.utils.MathUtils; import java.io.Serializable; @@ -118,6 +119,17 @@ public double getAltitude() { return altitude; } + /** + * Return a new LatLng object with a wrapped Longitude. This allows original data object + * to remain unchanged. + * @return New LatLng object with wrapped Longitude + */ + public LatLng wrap(){ + LatLng wrappedVersion = new LatLng(this); + wrappedVersion.setLongitude(MathUtils.wrap(wrappedVersion.getLongitude(), GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE)); + return wrappedVersion; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java index ff1b56422bc..1803462b463 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java @@ -24,4 +24,23 @@ public static float clamp(float value, float min, float max) { return Math.max(min, Math.min(max, value)); } + /** + * Constrains n to the given range (including min, excluding max) via modular arithmetic. + * + * Same formula as used in Core GL (math.hpp) + * std::fmod((std::fmod((value - min), d) + d), d) + min; + * + * @param value Value to wrap + * @param min Minimum value + * @param max Maximum value + * @return Wrapped value + */ + public static double wrap(double value, double min, double max) { + double delta = max - min; + + double firstMod = (value - min) % delta; + double secondMod = (firstMod + delta) % delta; + + return secondMod + min; + } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java index 0221b448b87..984e559298d 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/geometry/LatLngTest.java @@ -2,19 +2,17 @@ import android.location.Location; import android.os.Parcel; - import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.utils.MockParcel; - import org.junit.Test; - import java.util.Objects; - +import dalvik.annotation.TestTargetClass; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -202,4 +200,11 @@ public void testDescribeContents() { assertEquals("contents should be 0", 0, latLng.describeContents(), DELTA); } + @Test + public void testWrapped() { + LatLng latLng = new LatLng(45.0, -185.0); + LatLng wrapped = latLng.wrap(); + assertTrue(!latLng.equals(wrapped)); + assertTrue(wrapped.getLongitude() == 175.0); + } } diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp index 4b75f324f37..237fbb99da5 100755 --- a/platform/android/src/jni.cpp +++ b/platform/android/src/jni.cpp @@ -1176,7 +1176,7 @@ jni::jobject* nativeLatLngForPixel(JNIEnv *env, jni::jobject* obj, jlong nativeM jfloat x = jni::GetField(*env, pixel, *pointFXId); jfloat y = jni::GetField(*env, pixel, *pointFYId); - mbgl::LatLng latLng = nativeMapView->getMap().latLngForPixel(mbgl::ScreenCoordinate(x, y)).wrapped(); + mbgl::LatLng latLng = nativeMapView->getMap().latLngForPixel(mbgl::ScreenCoordinate(x, y)); return &jni::NewObject(*env, *latLngClass, *latLngConstructorId, latLng.latitude, latLng.longitude); }