Can Poyrazoğlu
Can Poyrazoğlu

Reputation: 34810

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?

Upvotes: 9

Views: 5496

Answers (2)

antonio
antonio

Reputation: 18262

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

Upvotes: 22

SoulBA
SoulBA

Reputation: 21

It is not possible to get a precise offset in meters from latitude and longitude. This would assume that the earth is a perfect and smooth sphere which is not true.

If you want to reduce your error you should adjust the amount of kilometers per degree according to your latitude. The answer you linked has an estimate of 111km per degree but this varies according to your latitude(specially in the longitude direction). See the table:

Lat    1°Lat≃       1°Lon≃
0°   110.574 km   111.320 km
15°  110.649 km   107.550 km
30°  110.852 km   96.486 km
45°  111.132 km   78.847 km
60°  111.412 km   55.800 km
75°  111.618 km   28.902 km
90°  111.694 km   0.000 km

Ref: wikipedia :P

I hope this helps!

Upvotes: 2

Related Questions