Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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) enter image description here

share|improve this question
3  
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
1  
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
1  
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
show 3 more comments

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

share|improve this answer
    
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
show 3 more comments

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...

share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.