I'm looking for an algorithm which when given a latitude and longitude pair and a vector translation in meters in Cartesian coordinates (x,y) would give me a new coordinate. Sort of like a reverse Haversine. I could also work with a distance and a heading transformation, but this would probably be slower and not as accurate. Ideally, the algorithm should be fast as I'm working on an embedded system. Accuracy is not critical, within 10 meters would be good.
If your displacements aren't too great (less than a few kilometers) and you're not right at the poles, use the quick and dirty estimate that 111,111 meters (111.111 km) in the y direction is 1 degree (of latitude) and 111,111 * cos(latitude) meters in the x direction is 1 degree (of longitude).
As Liedman says in his answer Williams’s aviation formulas are an invaluable source, and to keep the accuracy within 10 meters for displacements up to 1 km you’ll probably need to use the more complex of these.
But if you’re willing to accept errors above 10m for points offset more than approx 200m you may use a simplified flat earth calculation. I think the errors still will be less than 50m for offsets up to 1km.
//Position, decimal degrees lat = 51.0 lon = 0.0 //Earth’s radius, sphere R=6378137 //offsets in meters dn = 100 de = 100 //Coordinate offsets in radians dLat = dn/R dLon = de/(R*Cos(Pi*lat/180)) //OffsetPosition, decimal degrees latO = lat + dLat * 180/Pi lonO = lon + dLon * 180/Pi
This should return:
latO = 51,00089832 lonO = 0,001427437
It might make sense to project the point first. You could make something like this pseudo-code:
falt_coordinate = latlon_to_utm(original_koordinate) new_flat_coordinate = flat_coordinate + (x,y) result_coordinate = utm_to_latlon(new_flat_coordinate)
where (x,y) is the desired offset.
You don't need to use utm, any flat coordinate system, that makes sense in your area will do.
What software are you working with?
I created a simple custom map on Google Maps that illustrates the estimation algorithm mentioned by the accepted answer (1/111111 == one meter). Feel free to see and play with it here: