# How to find a point on given line that its distance from another point is given also?

I have this input:

1. (lat1,lon1), (lat2,lon2) - Two coordinates that create the line
2. (lat0, lat0) - Point on this line
3. d - distance

I want to find a point (lat, lon), where

1. (lat, lon) is on the line (mentioned above)
2. The distance between (lat, lon) and (lat0, lon0) is d

The direction of (lat0, lon0)-to-(lat, lon) is not importent right now. [and of course, the lat/lon is given as geographic coordinates in degrees].

Can anyone knows any algorithm for that?

Many thanks!

-
At least five different approaches to this question have appeared in related threads. To select a good one, how accurately do you need to know the coordinates? How long can that line be? Where on the earth can it be situated (e.g., can it cross a pole or the +-180 meridian)? – whuber Jun 5 '12 at 19:16
Hi, thanks! I've found one thread with similar question, but there is no answer for my question. The line will be just few meters. Actually, the line is between two nodes on same way (of OSM map). And my map is of Israel. The accuracy is not so importent. – uriel Jun 6 '12 at 13:27

The input is redundant, so let's focus on the essentials:

1. You have a "base point" p0 with coordinates (x0,z0) (latitude and longitude in degrees).

2. You have a "target point" p1 with coordinates (x1,z1).

3. The distance to travel from p towards p1 is d. Let (x,z) be the coordinates of the endpoint p: we wish to compute x and z.

Because (a) d is a few meters, (b) p and p1 are not near the poles, and (c) high accuracy is not needed, we can use Euclidean calculations upon applying a moderately accurate projection. About the simplest is the cylindrical projection

``````(x,z) --> (x, z * Cos(x)) = (x, y).
``````

This reflects the shrinking of longitude (z) with varying latitude (x).

From now on we may compute with our points as if they were vectors. The solution is obtained in simple steps:

(i) The direction vector from p0 to p1 is p1 - p2 with coordinates v = (x1-x0, y1-y0).

(ii) The length of this vector, by the Pythagorean Theorem, is the square root of the sum of squares of its coordinates, Sqrt((x1-x0)^2 + (y1-y0)^2). Call this 'a'.

(iii) A parallel vector of length d is obtained by scaling the direction vector v by d/a, after expressing d in degrees. To do this, divide d by 111300 (meters per degree). Then rescale by multiplying each of x1-x0 and y1-y0 by d/a. Call this vector 'w'.

(iv) Displacing p0 by w is obtained by adding the vectors: p = p0 + w = (x,y).

(v) Unproject (x,y). This gives (x,z) = (x, y/Cos(x)).

-
That's working! Many thanks! – uriel Jun 6 '12 at 20:44

Here's a spatialite query that can get the point locations that you want: I create a linestring with your (lon1, lat1) (lon2, lat2) and the point (lon0 lat0) along the line. And I also create a (circular) buffer of size d around a point (lon, lat). I convert the buffer to a line string, and then do an intersection between that circle and the linestring. The points returned (0-2) are, I think, what you're looking for:

``````SELECT AsText(Intersection(circle_geom, line_geom))
FROM (SELECT
Boundary(Buffer(center_geom, 150)) AS circle_geom,
GeomFromText('LINESTRING(100000 500000,100400 500000,101000 500000)',2039) as line_geom
FROM (SELECT
GeomFromText('POINT(100600 500000)',2039) AS center_geom)
);

MULTIPOINT(100450 500000, 100750 500000)
``````

HTH, Micha

-
That's clever! I think it may require some modification to handle the desired input, which is (lat,lon) rather than projected coordinates. – whuber Jun 6 '12 at 20:58
Thanks for the encouragement! The OP mentioned meters, short distances, and maps of Israel where the CRS is in meters, so I went with a cartesian coordinate system. – Micha Jun 7 '12 at 21:11
Micha, would there be a similarly straightforward, simple way to execute your algorithm when the data are given in (lat,lon)--apart from doing a preliminary projection and then unprojecting the result? – whuber Jun 7 '12 at 21:16