6

I have 2 coordinates. Coordinate 1 is a 'person'. Coordinate 2 is a destination.

How do I move coordinate 1 100 meters closer to coordinate 2?

This would be used in a cron job, so only php and mysql included.

For example:

Person is at: 51.26667, 3.45417

Destination is: 51.575001, 4.83889

How would i calculate the new coordinates for Person to be 100 meters closer?

Community
  • 1
  • 1
Rene Pot
  • 24,681
  • 7
  • 68
  • 92
  • 3
    Are the coordinates in meters or is that lat/lon? If the latter, you have to do a coordinate projection into WGS84 or a simillar ellipsoid so you get coordinates in meters. Then, assuming you want to move 100 closer in a straight line (no streets or walls to consider) you can use the euclidian distance formula – Vinko Vrsalovic Jun 18 '10 at 21:55
  • those are lat,lng coordinates. Used by google maps – Rene Pot Jun 18 '10 at 21:59

3 Answers3

12

Use Haversine to calculate the difference between the two points in metres; then adjust the value of the person coordinates proportionally.

$radius = 6378100; // radius of earth in meters
$latDist = $lat - $lat2;
$lngDist = $lng - $lng2;
$latDistRad = deg2rad($latDist);
$lngDistRad = deg2rad($lngDist);
$sinLatD = sin($latDistRad);
$sinLngD = sin($lngDistRad);
$cosLat1 = cos(deg2rad($lat));
$cosLat2 = cos(deg2rad($lat2));
$a = ($sinLatD/2)*($sinLatD/2) + $cosLat1*$cosLat2*($sinLngD/2)*($sinLngD/2);
if($a<0) $a = -1*$a;
$c = 2*atan2(sqrt($a), sqrt(1-$a));
$distance = $radius*$c;

Feeding your values of:

$lat = 51.26667;        //  Just South of Aardenburg in Belgium
$lng = 3.45417;
$lat2 = 51.575001;      //  To the East of Breda in Holland
$lng2 = 4.83889;

gives a result of 102059.82251083 metres, 102.06 kilometers

The ratio to adjust by is 100 / 102059.82251083 = 0.0009798174985988102859004569070625

$newLat = $lat + (($lat2 - $lat) * $ratio);
$newLng = $lng + (($lng2 - $lng) * $ratio);

Gives a new latitude of 51.266972108109 and longitude of 3.4555267728867

Mark Baker
  • 209,507
  • 32
  • 346
  • 385
4

If you understand JavaScript, you may want to check out the moveTowards() method in the following Stack Overflow post:

This method returns the destination point when given a start point, an end point, and the distance to travel along that line. You can use point 1 as the starting point, point 2 as the end point, and a distance of 100 meters. It's written in JavaScript, but I'm sure it can be easily ported to PHP or MySQL.

You may also want to check out this other Stack Overflow post which implements a part of the above JavaScript implementation, as a user defined function for SQL Server 2008, called func_MoveTowardsPoint:

The above uses SQL Server 2008's in-built geography data type. However you can easily use two decimal data types for latitude and longitude in place of the single geography data type.

Both the SQL Server and the JavaScript examples were based on implementations from Chris Veness's article Calculate distance, bearing and more between Latitude/Longitude points.

Community
  • 1
  • 1
Daniel Vassallo
  • 337,827
  • 72
  • 505
  • 443
4

Find the angle theta between the x-axis and the vector from person to destination.

theta = Atan2(dest.y-person.y, dest.x-person.x).

Now use theta and the amount you want to advance the point to calculate the new point.

newPoint.x = advanceDistance * cos(theta) + person.x

newPoint.y = advanceDistance * sin(theta) + person.y

John Wang
  • 113
  • 6
  • The problem with this solution is that it does not consider the earth as a sphere... Degrees of latitude are parallel and are approximately 111km apart, but a degree of longitude is widest at the equator at 111km and gradually converges to zero at the poles. – Daniel Vassallo Jun 18 '10 at 22:21
  • I would still keep the answer here, because it is still relevant (to the title of the question at least)... You may simply want to put a note about this. – Daniel Vassallo Jun 18 '10 at 22:27