Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Offset LatLng by some amount of meters in Android

I have a LatLng object and I want to shift it's coordinates 500 meters to the east. I couldn't find a built-in method for that. I've seen https://gis.stackexchange.com/a/2964 but my results are just too inaccurate (about 15%) to use practically. How can I make a precise shift in meters?

Note: I am NOT looking for shifting a Google Maps camera, I know how to do that.

I've tried:

static final double KILOMETERS_PER_DEGREE = 111.111;

static LatLng offsetLongitude(LatLng initialCoords, float horizontalOffsetInMeters){
    double degreeOffset = 1.0 / KILOMETERS_PER_DEGREE * horizontalOffsetInMeters / 1000.0;
    double longitudeOffset = Math.cos(initialCoords.latitude * Math.PI / 180.0) * degreeOffset;
    return new LatLng(initialCoords.latitude, initialCoords.longitude + longitudeOffset);
}

public static LatLngBounds boundsForSpanWidth(LatLng midpoint, float targetSpanWidth){
    LatLng east = offsetLongitude(midpoint, -targetSpanWidth);
    LatLng west = offsetLongitude(midpoint, targetSpanWidth);
    LatLngBounds newBounds = new LatLngBounds(west, east);
    return newBounds;
}

However, when I call it with a point (not close to poles or anything) with a target span of 5000 meters, I'm getting two points that are about 6170 meters apart. Why?

like image 676
Can Poyrazoğlu Avatar asked Apr 06 '15 19:04

Can Poyrazoğlu


1 Answers

You can use the computeOffset method from the Google Maps Android API Utility Library (https://developers.google.com/maps/documentation/android-api/utility/):

public static LatLng computeOffset(LatLng from, double distance, double heading)

Returns the LatLng resulting from moving a distance from an origin in the specified heading (expressed in degrees clockwise from north).

Parameters:

  • from - The LatLng from which to start.
  • distance - The distance to travel.
  • heading - The heading in degrees clockwise from north.

In your case (the distance parameter is measured in meters):

LatLng east = SphericalUtil.computeOffset(midpoint, 500, 90); // Shift 500 meters to the east
LatLng west = SphericalUtil.computeOffset(midpoint, 500, 270); // Shift 500 meters to the west
like image 64
antonio Avatar answered Oct 17 '22 08:10

antonio