# Nearest point on a line ( Spherical / Mercator projection )

I have a line (Ax,Ay - Bx,By) over a mercator projection (google maps) and a random point (Cx,Cy) nearest to that line, i would to know the closest point (transparent blue on the image) over that line to point (blue in the image)

EDIT: to clarify that this is in a Mercator projection (spherical projection) • this post has very useful solution that may interest you stackoverflow.com/questions/3120357/get-closest-point-to-a-line – vinayan Dec 28 '12 at 14:38
• That light blue doesn't look like the closest, the closest should create a 90 degrees angle when connected to the dark blue, is that what you mean ? – Glenn Plas Dec 28 '12 at 15:29
• I made the pic by hand so yeah, it's posible – Colas Dec 28 '12 at 16:03
• @vinayan The post you reference solves a different problem of finding the nearest point to a line, whereas what is needed here appears to want the nearest point to a line segment. – whuber Dec 28 '12 at 16:10
• The segment should be around 20-100 meters long , the point from centimeters to 30 meters as much from the segment – Colas Dec 28 '12 at 16:56

## 2 Answers

check out this link , it made me use the following function to calculate distances to line segments.

In PHP:

``````function point_to_line_segment_distance(\$startX,\$startY, \$endX,\$endY, \$pointX,\$pointY) {

// list(\$distanceSegment, \$x, \$y) = point_to_line_segment_distance(\$startX,\$startY, \$endX,\$endY, \$pointX,\$pointY);

// Adapted from Philip Nicoletti's function, found here: http://www.codeguru.com/forum/printthread.php?t=194400

\$r_numerator = (\$pointX - \$startX) * (\$endX - \$startX) + (\$pointY - \$startY) * (\$endY - \$startY);
\$r_denominator = (\$endX - \$startX) * (\$endX - \$startX) + (\$endY - \$startY) * (\$endY - \$startY);
\$r = \$r_numerator / \$r_denominator;

\$px = \$startX + \$r * (\$endX - \$startX);
\$py = \$startY + \$r * (\$endY - \$startY);

\$s = ((\$startY-\$pointY) * (\$endX - \$startX) - (\$startX - \$pointX) * (\$endY - \$startY) ) / \$r_denominator;

\$distanceLine = abs(\$s) * sqrt(\$r_denominator);

\$closest_point_on_segment_X = \$px;
\$closest_point_on_segment_Y = \$py;

if ( (\$r >= 0) && (\$r <= 1) ) {
\$distanceSegment = \$distanceLine;
}
else {
\$dist1 = (\$pointX - \$startX) * (\$pointX - \$startX) + (\$pointY - \$startY) * (\$pointY - \$startY);
\$dist2 = (\$pointX - \$endX) * (\$pointX - \$endX) + (\$pointY - \$endY) * (\$pointY - \$endY);
if (\$dist1 < \$dist2) {
\$closest_point_on_segment_X = \$startX;
\$closest_point_on_segment_Y = \$startY;
\$distanceSegment = sqrt(\$dist1);
}
else {
\$closest_point_on_segment_X = \$endX;
\$closest_point_on_segment_Y = \$endY;
\$distanceSegment = sqrt(\$dist2);
}
}

return array(\$distanceSegment, \$closest_point_on_segment_X, \$closest_point_on_segment_Y);
}
``````

You can then use projection functions to calculate distances, I'm using the above formula to calculate the time at that point given a average speed and it works really well.

If you want a good PHP library to calculate distances between coordinates in PHP, check out GeoCalc class

• Hey Glenn Plas, your class seem to have a little offset to the left or right,i made a screenshot on Google earth you will see that offset, the pic:link, the code i used `point_to_line_segment_distance(41.421649, 2.600410, 41.413851, 2.594356, 41.415710, 2.600638))` – Colas Dec 28 '12 at 16:44
• It's not my class, just found it after searching a lot ;-) But I use 8 digits precision in my problems, you seem to use 6. That could be the reason, I never noticed any offset here. Thanks for pointing it out, I will doublecheck this soon as I need to know. – Glenn Plas Dec 28 '12 at 16:55
• Maybe you are rihgt, i can't obtain more decilmas on gEarth, btw in my last pic the segment was 1000 meters long, the offset was ~110meters – Colas Dec 28 '12 at 17:06
• That's about the scale I use it on, no more than that. I use it to see at what time a bus (public transport) passes a stop the closest. I am going to doublecheck it though and put it in a map to 'see' if it projects well on a sphere. – Glenn Plas Dec 28 '12 at 17:18
• Oh... I thought that function was made for spherical projections, so now i understand the offset – Colas Dec 28 '12 at 17:26

you can use computeDistanceBetween() function from google map api.

``````distance = google.maps.geometry.spherical.computeDistanceBetween(firstCoord, secondCoord);
``````

The distance between two points is the length of the shortest path between them. This shortest path is called a geodesic. On a sphere all geodesics are segments of a great circle. To compute this distance, call computeDistanceBetween(), passing it two LatLng objects.

You may instead use computeLength() to calculate the length of a given path if you have several locations

i hope it helps you...

• first I need to know the point (light blue) to compute the distance between – Colas Dec 28 '12 at 16:12
• My solution below does that, the point on the segment is unknown. I actually have a rather similar problem/solution as mentioned. You can safely use these on small scale's. – Glenn Plas Dec 28 '12 at 16:23