Polygon area calculation using Latitude and Longitude - c#

I am using a solution I've found in this post:
Polygon area calculation using Latitude and Longitude generated from Cartesian space and a world file
There is something wrong because the values I am getting are not real. For example we know a football field should have around 5,300.00 square meters, right? but the calculation is giving 5,759,154.21.
This is the code:
private static double CalculatePolygonArea(IList<Position> coordinates)
{
double area = 0;
if (coordinates.Count > 2)
{
for (var i = 0; i < coordinates.Count - 1; i++)
{
Position p1 = coordinates[i];
Position p2 = coordinates[i + 1];
area += (ConvertToRadian(p2.Longitude) - ConvertToRadian(p1.Longitude)) * (2 + Math.Sin(ConvertToRadian(p1.Latitude)) + Math.Sin(ConvertToRadian(p2.Latitude)));
}
area = area * 6378137 * 6378137 / 2;
}
return Math.Abs(area);
}
private static double ConvertToRadian(double input)
{
return input * Math.PI / 180;
}
What can be wrong here? Any help?

The area calculation you are using is just plain wrong.... :-/
I use the SphericalUtil.ComputeSignedArea method from Google's Android Maps Utils.
Note: Google's Java code for that is under Apache License Version 2.0, and I converted it to C#.
Looking up that football field up in one of my apps, I get: 4,461, not quite the actual 5,531 but not bad for using Google Map photos...
Here is just the ComputeSignedArea:
public static class SphericalUtil
{
const double EARTH_RADIUS = 6371009;
static double ToRadians(double input)
{
return input / 180.0 * Math.PI;
}
public static double ComputeSignedArea(IList<LatLng> path)
{
return ComputeSignedArea(path, EARTH_RADIUS);
}
static double ComputeSignedArea(IList<LatLng> path, double radius)
{
int size = path.Count;
if (size < 3) { return 0; }
double total = 0;
var prev = path[size - 1];
double prevTanLat = Math.Tan((Math.PI / 2 - ToRadians(prev.Latitude)) / 2);
double prevLng = ToRadians(prev.Longitude);
foreach (var point in path)
{
double tanLat = Math.Tan((Math.PI / 2 - ToRadians(point.Latitude)) / 2);
double lng = ToRadians(point.Longitude);
total += PolarTriangleArea(tanLat, lng, prevTanLat, prevLng);
prevTanLat = tanLat;
prevLng = lng;
}
return total * (radius * radius);
}
static double PolarTriangleArea(double tan1, double lng1, double tan2, double lng2)
{
double deltaLng = lng1 - lng2;
double t = tan1 * tan2;
return 2 * Math.Atan2(t * Math.Sin(deltaLng), 1 + t * Math.Cos(deltaLng));
}
}

Related

How to get all points between two geo coordinates

I have two geo positions lets say A and B and distance between both of them say D.
So I know A, B, and D.
Now I want to get all the points (l,m,n,o... etc.) in a distance of 3 meters each.
Note:
If I draw a straight line between A and B then all the required points should lie on that straight line.
What I have done so far:
I have searched a lot and come across this website but there is an example which is in javascript and when I converted this code into c# then I do not get exact points.
Please help me! Thank you!
For those who believe this question as a duplicate for like this then I want to clarify that I do not need to calculate distance. In my question distance is already known.
Finally, I came across the following Code:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
namespace Calc
{
public static class Program
{
private static readonly long RADIUS_OF_EARTH = 6371000; // radius of earth in m
public static void Main(string[] args)
{
// point interval in meters
int interval =2;
// direction of line in degrees
//start point
double lat1 = 28.6514975008004;
double lng1 = 77.2216437757015;
// end point
double lat2 = 28.6514763167883;
double lng2 = 77.2221480309963;
MockLocation start = new MockLocation(lat1, lng1);
MockLocation end = new MockLocation(lat2, lng2);
double azimuth = calculateBearing(start, end);
Console.WriteLine(azimuth);
List<MockLocation> coords = getLocations(interval, azimuth, start, end);
foreach (MockLocation mockLocation in coords)
{
Console.WriteLine(mockLocation.lat + ", " + mockLocation.lng);
}
Console.ReadLine();
}
/**
* returns every coordinate pair in between two coordinate pairs given the desired interval
* #param interval
* #param azimuth
* #param start
* #param end
* #return
*/
private static List<MockLocation> getLocations(int interval, double azimuth, MockLocation start, MockLocation end)
{
Console.WriteLine("getLocations: " +
"\ninterval: " + interval +
"\n azimuth: " + azimuth +
"\n start: " + start.toString());
double d = getPathLength(start, end);
int dist = (int)d / interval;
int coveredDist = interval;
List<MockLocation> coords = new List<MockLocation>();
MockLocation mock = new MockLocation(start.lat, start.lng);
coords.Add(mock);
for (int distance = 0; distance < dist; distance += interval)
{
MockLocation coord = getDestinationLatLng(start.lat, start.lng, azimuth, coveredDist);
coveredDist += interval;
coords.Add(coord);
}
coords.Add(new MockLocation(end.lat, end.lng));
return coords;
}
public static double ToRadians(this double val)
{
return (Math.PI / 180) * val;
}
/**
* calculates the distance between two lat, long coordinate pairs
* #param start
* #param end
* #return
*/
private static double getPathLength(MockLocation start, MockLocation end)
{
double lat1Rads = ToRadians(start.lat);
double lat2Rads = ToRadians(end.lat);
double deltaLat = ToRadians(end.lat - start.lat);
double deltaLng = ToRadians(end.lng - start.lng);
double a = Math.Sin(deltaLat / 2) * Math.Sin(deltaLat / 2) + Math.Cos(lat1Rads) * Math.Cos(lat2Rads) * Math.Sin(deltaLng / 2) * Math.Sin(deltaLng / 2);
double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
double d = RADIUS_OF_EARTH * c;
return d;
}
/**
* returns the lat an long of destination point given the start lat, long, aziuth, and distance
* #param lat
* #param lng
* #param azimuth
* #param distance
* #return
*/
private static MockLocation getDestinationLatLng(double lat, double lng, double azimuth, double distance)
{
double radiusKm = RADIUS_OF_EARTH / 1000; //Radius of the Earth in km
double brng = ToRadians(azimuth); //Bearing is degrees converted to radians.
double d = distance / 1000; //Distance m converted to km
double lat1 = ToRadians(lat); //Current dd lat point converted to radians
double lon1 = ToRadians(lng); //Current dd long point converted to radians
double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(d / radiusKm) + Math.Cos(lat1) * Math.Sin(d / radiusKm) * Math.Cos(brng));
double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(d / radiusKm) * Math.Cos(lat1), Math.Cos(d / radiusKm) - Math.Sin(lat1) * Math.Sin(lat2));
//convert back to degrees
lat2 = ToDegrees(lat2);
lon2 = ToDegrees(lon2);
return new MockLocation(lat2, lon2);
}
/**
* calculates the azimuth in degrees from start point to end point");
double startLat = ToRadians(start.lat);
* #param start
* #param end
* #return
*/
private static double calculateBearing(MockLocation start, MockLocation end)
{
double startLat = ToRadians(start.lat);
double startLong = ToRadians(start.lng);
double endLat = ToRadians(end.lat);
double endLong = ToRadians(end.lng);
double dLong = endLong - startLong;
double dPhi = Math.Log(Math.Tan((endLat / 2.0) + (Math.PI / 4.0)) / Math.Tan((startLat / 2.0) + (Math.PI / 4.0)));
if (Math.Abs(dLong) > Math.PI)
{
if (dLong > 0.0)
{
dLong = -(2.0 * Math.PI - dLong);
}
else
{
dLong = (2.0 * Math.PI + dLong);
}
}
double bearing = (ToDegrees(Math.Atan2(dLong, dPhi)) + 360.0) % 360.0;
return bearing;
}
public static double ToDegrees(double radians)
{
double degrees = (180 / Math.PI) * radians;
return (degrees);
}
public class MockLocation
{
public double lat;
public double lng;
public MockLocation(double lat, double lng)
{
this.lat = lat;
this.lng = lng;
}
public string toString()
{
return (lat + "," + lng).ToString();
}
}
}
}
I hope this will help other learners.

Maximum clockwise angles from 3 nearest points

Help me, because I'm rly tired of this...
I need to count angles between current point and the closest 3 points (look at an image below) - I need to sort the angles in descending order (to get the point with the largest angle - if it doesn't fit expectations, I have to get another one).
I tried to do something, but it doesn't work...
private static Vertex[] SortByAngle(IEnumerable<Vertex> vs, Vertex current, Vertex previous)
{
if (current.CompareTo(previous) == 0)
{
previous.X = previous.X - 1.0; // this is a trick to handle the first point
}
var vertices = new Dictionary<Vertex, double>();
foreach (var v in vs)
{
double priorAngle = Angle(previous, current);
double nextAngle = Angle(current, v);
double angleInBetween = 180.0 - (priorAngle + nextAngle);
vertices.Add((Vertex) v.Clone(), angleInBetween);
}
// here the angles are incorrect, because I want to sort them in desc order, but it's a real mess when I do OrderByDescending - something is wrong with my code:S
vertices = vertices.OrderBy(v => v.Value).ToDictionary(k => k.Key, v => v.Value);
return vertices.Select(v => new Vertex(v.Key.X, v.Key.Y)).ToArray();
}
private static double Angle(Vertex v1, Vertex v2, double offsetInDegrees = 0.0)
{
return (RadianToDegree(Math.Atan2(-v2.Y + v1.Y, -v2.X + v1.X)) + offsetInDegrees);
}
public static double RadianToDegree(double radian)
{
var degree = radian * (180.0 / Math.PI);
if (degree < 0)
degree = 360 + degree;
return degree;
}
vs is my set of 3 nearest points
current and previous are obvious:)
i didn't tested it, but i restyled a little, avoiding dictionaries. I think your mistake is in: double angleInBetween = 180.0 - (priorAngle + nextAngle); should be: double angleInBetween = (180.0 - priorAngle) + nextAngle;
public struct Vertex
{
public double X { get; set; }
public double Y { get; set; }
}
private static double CalcDistance(Vertex v1, Vertex v2)
{
double dX = (v2.X - v1.X);
double dY = (v2.Y - v1.Y);
return Math.Sqrt((dX * dX) + (dY * dY));
}
private static Vertex[] SortByAngle(IEnumerable<Vertex> vs, Vertex current, Vertex previous)
{
var verticesOnDistance = from vertex in vs
where !vertex.Equals(current)
let distance = CalcDistance(current, vertex)
orderby distance
select vertex;
double priorAngle = Angle(previous, current);
var verticeAngles = from vertex in verticesOnDistance.Take(3)
let nextAngle = Angle(current, vertex)
let angleInBetween = (180.0 - priorAngle) + nextAngle
orderby angleInBetween descending
select vertex;
return verticeAngles.ToArray();
}
private static double Angle(Vertex v1, Vertex v2, double offsetInDegrees = 0.0)
{
return (RadianToDegree(Math.Atan2(-v2.Y + v1.Y, -v2.X + v1.X)) + offsetInDegrees);
}
public static double RadianToDegree(double radian)
{
var degree = radian * (180.0 / Math.PI);
if (degree < 0)
degree = 360 + degree;
return degree;
}
I'm running a little out of time here. I'll be on later... I'm not sure this is correct, but maybe shine another light on it...
Good luck

Trying to get data from class into main program

I am new to C# so I apologise if the format of my code is wrong. Currently I am trying to work out how to return a value from a class that calculates the distance for my data.
Here is what I have so far, when I ask or two points however the only thing that comest out is DistanceGenerator.Coursework I can't see what I am doing wrong, any help?
namespace DistanceGenerator
{
class Program
{
static void Main(string[] args)
{
//Displays data in correct Format
List<float> inputList = new List<float>();
TextReader tr = new StreamReader("c:/users/tom/documents/visual studio 2010/Projects/DistanceCalculator3/DistanceCalculator3/TextFile1.txt");
String input = Convert.ToString(tr.ReadToEnd());
String[] items = input.Split(',');
Console.WriteLine("Point Latitude Longtitude Elevation");
for (int i = 0; i < items.Length; i++)
{
if (i % 3 == 0)
{
Console.Write((i / 3) + "\t\t");
}
Console.Write(items[i]);
Console.Write("\t\t");
if (((i - 2) % 3) == 0)
{
Console.WriteLine();
}
}
Console.WriteLine();
Console.WriteLine();
// Ask for two inputs from the user which is then converted into 6 floats and transfered in class Coordinates
bool exit = false;
do
{
Console.WriteLine("Please enter the two points that you wish to know the distance between:");
string point = Console.ReadLine();
string[] pointInput = point.Split(' ');
int pointNumber = Convert.ToInt16(pointInput[0]);
int pointNumber2 = Convert.ToInt16(pointInput[1]);
double latitude = (Convert.ToDouble(items[pointNumber * 3]));
double longtitude = (Convert.ToDouble(items[(pointNumber * 3) + 1]));
double elevation = (Convert.ToDouble(items[(pointNumber * 3) + 2]));
double latitude2 = (Convert.ToDouble(items[pointNumber2 * 3]));
double longtitude2 = (Convert.ToDouble(items[(pointNumber2 * 3) + 1]));
double elevation2 = (Convert.ToDouble(items[(pointNumber2 * 3) + 2]));
//Calculate the distance between two points
Distance curDistance = new Distance(latitude, longtitude, elevation, latitude2, longtitude2, elevation2);
Console.WriteLine(curDistance);
Console.WriteLine("If you wish to calculate another distance type 1 and return, if you wish to end the program, type -1.");
string reset;
do
{
reset = Console.ReadLine().Trim();
}
while (reset != "1" && reset != "-1");
if (reset == "-1") exit = true;
}
while (!exit);
}
}
}
//and here is the class
namespace DistanceGenerator
{
class Distance
{
private double latitude;
private double longtitude;
private double elevation;
private double latitude2;
private double longtitude2;
private double elevation2;
public Distance(double latitude, double longtitude, double elevation, double latitude2, double longtitude2, double elevation2)
{
// TODO: Complete member initialization
this.latitude = latitude;
this.longtitude = longtitude;
this.elevation = elevation;
this.latitude2 = latitude2;
this.longtitude2 = longtitude2;
this.elevation2 = elevation2;
}
private double curDistance()
{
const double PIx = 3.141592653589793;
const double RADIO = 6371;
double dlat = ((latitude2) * (PIx / 180)) - ((latitude) * (PIx / 180));
double dlon = ((longtitude2) * (PIx / 180)) - ((longtitude) * (PIx / 180));
double a = (Math.Sin(dlat / 2) * Math.Sin(dlat / 2)) + Math.Cos((latitude) * (PIx / 180)) * Math.Cos((latitude2) * (PIx / 180)) * (Math.Sin(dlon / 2) * Math.Sin(dlon / 2));
double angle = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
double ultimateDistance = (angle * RADIO);
return ultimateDistance;
}
}
}
curDistance in your Main method is an instance of the Distance class.
The curDistnace method on the Distnace class, is private, making it unusable outside of the class - you can make it public:
public double curDistance()
You don't want to output the class, but the value of the calculation. For that you need to invoke the method curDistance on the Distance instance (which, you have confusingly also named curDistance):
Console.WriteLine(curDistance.curDistance());

C# equivalent of computeArea of Google Maps API

Google Maps Api has a google.maps.geometry.spherical.computeArea method.
How can I write its equivalent in C#? (What will be the formula)
I have a set of lat long values for which I need to calculate area (in meters) of the enclosed polygon.
Sample code is highly appreciated.
Sorry for adding an answer to an old question, but if someone else is looking for a quickly answer:
private const double EARTH_RADIUS = 6378137;
public class LatLng
{
public double latitude { get; private set; }
public double longitude { get; private set; }
public LatLng(double latitude, double longitude)
{
this.latitude = latitude;
this.longitude = longitude;
}
}
public static double computeArea(List<LatLng> path)
{
return Math.Abs(computeSignedArea(path));
}
private static double computeSignedArea(List<LatLng> path, double radius = EARTH_RADIUS)
{
int size = path.Count;
if (size < 3) { return 0; }
double total = 0;
LatLng prev = path[size - 1];
double prevTanLat = Math.Tan((Math.PI / 2 - toRadians(prev.latitude)) / 2);
double prevLng = toRadians(prev.longitude);
// For each edge, accumulate the signed area of the triangle formed by the North Pole
// and that edge ("polar triangle").
foreach (LatLng point in path)
{
double tanLat = Math.Tan((Math.PI / 2 - toRadians(point.latitude)) / 2);
double lng = toRadians(point.longitude);
total += polarTriangleArea(tanLat, lng, prevTanLat, prevLng);
prevTanLat = tanLat;
prevLng = lng;
}
return total * (radius * radius);
}
private static double polarTriangleArea(double tan1, double lng1, double tan2, double lng2)
{
double deltaLng = lng1 - lng2;
double t = tan1 * tan2;
return 2 * Math.Atan2(t * Math.Sin(deltaLng), 1 + t * Math.Cos(deltaLng));
}
private static double toRadians(double input)
{
return input * Math.PI / 180;
}
Reference https://github.com/googlemaps
What have you tried yourself?
There are some very similar questions with detailed answers, so it's best to refer to them:
Polygon area calculation using Latitude and Longitude generated from Cartesian space and a world file
Calculating area enclosed by arbitrary polygon on Earth's surface
You can get the formula from Wikipedia.

Adding distance to a GPS coordinate

I'm trying to generate some points at random distances away from a fixed point using GPS.
How can I add distance in meters to a GPS coordinate?
I've looked at UTM to GPS conversion but is there a simpler method to achieve this?
I'm working on Android platform just in case.
Cheers,
fgs
P0(lat0,lon0) : initial position (unit : degrees)
dx,dy : random offsets from your initial position in meters
You can use an approximation to compute the position of the randomized position:
lat = lat0 + (180/pi)*(dy/6378137)
lon = lon0 + (180/pi)*(dx/6378137)/cos(lat0)
This is quite precise as long as the random distance offset is below 10-100 km
Edit: of course in Java Math.cos() expects radians so do use Math.cos(Math.PI/180.0*lat0) if lat0 is in degrees as assumed above.
To take a square I'm using this:
private double[] getBoundingBox(final double pLatitude, final double pLongitude, final int pDistanceInMeters) {
final double[] boundingBox = new double[4];
final double latRadian = Math.toRadians(pLatitude);
final double degLatKm = 110.574235;
final double degLongKm = 110.572833 * Math.cos(latRadian);
final double deltaLat = pDistanceInMeters / 1000.0 / degLatKm;
final double deltaLong = pDistanceInMeters / 1000.0 / degLongKm;
final double minLat = pLatitude - deltaLat;
final double minLong = pLongitude - deltaLong;
final double maxLat = pLatitude + deltaLat;
final double maxLong = pLongitude + deltaLong;
boundingBox[0] = minLat;
boundingBox[1] = minLong;
boundingBox[2] = maxLat;
boundingBox[3] = maxLong;
return boundingBox;
}
This returns an array with 4 coordinates, with them you can make a square with your original point in center.
A detailed outline is given at http://www.movable-type.co.uk/scripts/latlong.html.
If you, somewhere, need to interconvert longitude/latitude to UTM coordinates (the ones used in GPS) you may want to have a look at http://www.uwgb.edu/dutchs/UsefulData/UTMFormulas.htm
If you want to go east or north or west or south you can use this:
#SuppressLint("DefaultLocale")
public static double go_mock_loc(double xx_lat,double xx_long,double xx_dinstance,String Direction)
{
// double xx_lat= 45.815005;
// double xx_long= 15.978501;
// int xx_dinstance=500;
int equator_circumference=6371000;
int polar_circumference=6356800;
double m_per_deg_long = 360 / polar_circumference;
double rad_lat=(xx_lat* (Math.PI) / 180);
double m_per_deg_lat = 360 / ( Math.cos(rad_lat) * equator_circumference);
double deg_diff_long = xx_dinstance * m_per_deg_long;
double deg_diff_lat = xx_dinstance * m_per_deg_lat;
double xx_north_lat = xx_lat + deg_diff_long;
//double xx_north_long= xx_long;
double xx_south_lat = xx_lat - deg_diff_long;
//double xx_south_long= xx_long;
//double xx_east_lat = xx_lat;
double xx_east_long= xx_long + deg_diff_lat;
//double xx_west_lat = xx_lat;
double xx_west_long= xx_long - deg_diff_lat;
if (Direction.toUpperCase().contains("NORTH")) {
return xx_north_lat;
} else if (Direction.toUpperCase().contains("SOUTH"))
{
return xx_south_lat;
} else if (Direction.toUpperCase().contains("EAST"))
{
return xx_east_long;
} else if (Direction.toUpperCase().contains("WEST"))
{
return xx_west_long;
}
else
return 0;
}
I found that solution of #Bogdan Khrystov is very well.
So here is C# version of his solution.
public enum GeoDirection
{
NORTH = 1, SOUTH = 2, EAST = 3, WEST = 4
}
public static Tuple<double, double> AddDistanceInMeters(double latitude, double longitude, int distanceInMeters, GeoDirection direction)
{
var equatorCircumference = 6371000;
var polarCircumference = 6356800;
var mPerDegLong = 360 / (double)polarCircumference;
var radLat = latitude * Math.PI / 180;
var mPerDegLat = 360 / (Math.Cos(radLat) * equatorCircumference);
var degDiffLong = distanceInMeters * mPerDegLong;
var degDiffLat = distanceInMeters * mPerDegLat;
var xxNorthLat = latitude + degDiffLong;
var xxSouthLat = latitude - degDiffLong;
var xxEastLong = longitude + degDiffLat;
var xxWestLong = longitude - degDiffLat;
switch (direction)
{
case GeoDirection.NORTH:
return new Tuple<double, double>(xxNorthLat, longitude);
case GeoDirection.SOUTH:
return new Tuple<double, double>(xxSouthLat, longitude);
case GeoDirection.EAST:
return new Tuple<double, double>(latitude, xxEastLong);
case GeoDirection.WEST:
return new Tuple<double, double>(latitude, xxWestLong);
default:
return null;
}
}
rewrite #Ersin Gülbahar answer in Kotlin:
object LocationUtil {
enum class Direction {
NORTH, SOUTH, EAST, WEST
}
fun addDistanceInMeters(
latitude: Double,
longitude: Double,
distanceInMeters: Int,
direction: Direction
): Pair<Double, Double> {
val equatorCircumference = 6371000
val polarCircumference = 6356800
val mPerDegLong = (360 / polarCircumference.toDouble())
val radLat = latitude * Math.PI / 180
val mPerDegLat = 360 / (Math.cos(radLat) * equatorCircumference)
val degDiffLong = distanceInMeters * mPerDegLong
val degDiffLat = distanceInMeters * mPerDegLat
val xxNorthLat = latitude + degDiffLong
val xxSouthLat = latitude - degDiffLong
val xxEastLong = longitude + degDiffLat
val xxWestLong = longitude - degDiffLat
return when (direction) {
Direction.NORTH -> Pair(xxNorthLat, longitude)
Direction.SOUTH -> Pair(xxSouthLat, longitude)
Direction.EAST -> Pair(latitude, xxEastLong)
Direction.WEST -> Pair(latitude, xxWestLong)
}
}
}
This code splits the line between two coordinates in n segments. Replace the delta calculation by your fixed distance
#Override
public void split(Coordinates p1, Coordinates p2, int segments) {
double φ1 = Math.toRadians(p1.getLat());
double λ1 = Math.toRadians(p1.getLon());
double φ2 = Math.toRadians(p2.getLat());
double λ2 = Math.toRadians(p2.getLon());
double xDelta = (φ2 - φ1) / segments;
double yDelta = (λ2 - λ1) / segments;
for (int i = 0; i < segments; i++){
double x = φ1 + i * xDelta;
double y = λ1 + i * yDelta;
double xc = Math.toDegrees(x);
double yc = Math.toDegrees(y);
System.out.println(xc+","+yc);
}
}
Combining answers from #Ersin Gülbahar and #Stéphane above, I came up with this solution in Flutter/Dart:
import 'dart:math' as math;
enum Direction { north, south, east, west }
double moveCoordinate(
double latitude, double longitude, double distanceToMoveInMeters, Direction directionToMove) {
const earthEquatorRadius = 6378137;
final latitudeOffset = (180 / math.pi) * (distanceToMoveInMeters / earthEquatorRadius);
final longitudeOffset = (180 / math.pi) *
(distanceToMoveInMeters / earthEquatorRadius) /
math.cos(math.pi / 180 * latitude);
switch (directionToMove) {
case Direction.north:
return latitude + latitudeOffset;
case Direction.south:
return latitude - latitudeOffset;
case Direction.east:
return longitude + longitudeOffset;
case Direction.west:
return longitude - longitudeOffset;
}
return 0;
}
This works, tested. The code is C# but you can easily change it to another language
private PointLatLng NewPositionBasedOnDistanceAngle(PointLatLng org, double distance, double bearing)
{
double rad = bearing * Math.PI / 180; //to radians
double lat1 = org.Lat * Math.PI / 180; //to radians
double lng1 = org.Lng * Math.PI / 180; //to radians
double lat = Math.Asin(Math.Sin(lat1) * Math.Cos(distance / 6378137) + Math.Cos(lat1) * Math.Sin(distance / 6378137) * Math.Cos(rad));
double lng = lng1 + Math.Atan2(Math.Sin(rad) * Math.Sin(distance / 6378137) * Math.Cos(lat1), Math.Cos(distance / 6378137) - Math.Sin(lat1) * Math.Sin(lat));
return new PointLatLng(lat * 180 / Math.PI, lng * 180 / Math.PI); // to degrees
}

Categories

Resources