Finding a Lat/Lon based on direction and distance from a given point

Hello group.  I have the following function that "should" return a MapCoordinate (latitude and longitude) based on input from a MapCoordinate origin and give distance and azimuth.
It seems the longitude values I'm getting are correct, but the latitude values are not.
Anyone have a clue on what's wrong... or have a better way?

Kind Regards,
Bryan

{code}
Type
  MapCoordinate = Record
  Latitude, Longitude : Double;
end;

{code}

{code}
function LocationFromMapPoint(inMapCoordinate : MapCoordinate; direction, distance : Double): MapCoordinate;
var
  arcdistance, arcazimuth, arclat, r1, r2, tlat, tlong, azimuthlat, azimuthlong: double;
  s1, s2: String;
begin
  arcdistance := ((distance / 60) * pi / 180);
  arcazimuth := (direction * pi / 180);
  arclat := (inMapCoordinate.Latitude * pi / 180);
  r1 := sin(arclat) * cos(arcdistance);
  r2 := cos(arclat) * sin(arcdistance) * cos(arcazimuth);
  tlat := arcsin(r1 + r2);
  azimuthlat := tlat;
  tlong := arctan(sin(arcdistance) *
    sin(arcazimuth) / (cos(arclat) * cos(arcdistance) -
    sin(arclat) * sin(arcdistance) * cos(arcazimuth)));
  azimuthlong := inMapCoordinate.Longitude + ((tlong / pi * 180));
  Result.Latitude := azimuthlat;
  Result.Longitude := azimuthlong;
end;

{code}
0
Bryan
7/6/2014 4:17:34 PM
embarcadero.algorithms 211 articles. 0 followers. Follow

7 Replies
602 Views

Similar Articles

[PageSpeed] 42

Bryan Ray wrote:

> Hello group.  I have the following function that "should" return a MapCoordinate (latitude and longitude) based on input from a MapCoordinate origin and give distance and azimuth.
> It seems the longitude values I'm getting are correct, but the latitude values are not.
> Anyone have a clue on what's wrong... or have a better way?
> 
> Kind Regards,
> Bryan
> 
> {code}
> Type
>   MapCoordinate = Record
>   Latitude, Longitude : Double;
> end;
> 
> {code}
> 
> {code}
> function LocationFromMapPoint(inMapCoordinate : MapCoordinate; direction, distance : Double): MapCoordinate;
> var
>   arcdistance, arcazimuth, arclat, r1, r2, tlat, tlong, azimuthlat, azimuthlong: double;
>   s1, s2: String;
> begin
>   arcdistance := ((distance / 60) * pi / 180);
>   arcazimuth := (direction * pi / 180);
>   arclat := (inMapCoordinate.Latitude * pi / 180);
>   r1 := sin(arclat) * cos(arcdistance);
>   r2 := cos(arclat) * sin(arcdistance) * cos(arcazimuth);
>   tlat := arcsin(r1 + r2);
>   azimuthlat := tlat;                   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
>   tlong := arctan(sin(arcdistance) *
>     sin(arcazimuth) / (cos(arclat) * cos(arcdistance) -
>     sin(arclat) * sin(arcdistance) * cos(arcazimuth)));
>   azimuthlong := inMapCoordinate.Longitude + ((tlong / pi * 180));
>   Result.Latitude := azimuthlat;
>   Result.Longitude := azimuthlong;
> end;
> 
> {code}

You haven't added the aimuthlat value I marked to the InMapCoordinate.Latitude.

-- 
Tredmill
0
John
7/6/2014 5:12:43 PM
> {quote:title=John Treder wrote:}{quote}
> Bryan Ray wrote:
> 
> > Hello group.  I have the following function that "should" return a MapCoordinate (latitude and longitude) based on input from a MapCoordinate origin and give distance and azimuth.
> > It seems the longitude values I'm getting are correct, but the latitude values are not.
> > Anyone have a clue on what's wrong... or have a better way?
> > 
> > Kind Regards,
> > Bryan
> > 
> > {code}
> > Type
> >   MapCoordinate = Record
> >   Latitude, Longitude : Double;
> > end;
> > 
> > {code}
> > 
> > {code}
> > function LocationFromMapPoint(inMapCoordinate : MapCoordinate; direction, distance : Double): MapCoordinate;
> > var
> >   arcdistance, arcazimuth, arclat, r1, r2, tlat, tlong, azimuthlat, azimuthlong: double;
> >   s1, s2: String;
> > begin
> >   arcdistance := ((distance / 60) * pi / 180);
> >   arcazimuth := (direction * pi / 180);
> >   arclat := (inMapCoordinate.Latitude * pi / 180);
> >   r1 := sin(arclat) * cos(arcdistance);
> >   r2 := cos(arclat) * sin(arcdistance) * cos(arcazimuth);
> >   tlat := arcsin(r1 + r2);
> >   azimuthlat := tlat;                   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> >   tlong := arctan(sin(arcdistance) *
> >     sin(arcazimuth) / (cos(arclat) * cos(arcdistance) -
> >     sin(arclat) * sin(arcdistance) * cos(arcazimuth)));
> >   azimuthlong := inMapCoordinate.Longitude + ((tlong / pi * 180));
> >   Result.Latitude := azimuthlat;
> >   Result.Longitude := azimuthlong;
> > end;
> > 
> > {code}
> 
> You haven't added the aimuthlat value I marked to the InMapCoordinate.Latitude.
> 
> -- 
> Tredmill

Hello Tredmill,
I have added azimuthlat := InCoordinates.Latitude + azimuthlat; 
where you indicated, but I still do not get correct values.
For example if I input the following:
InLat = 30
InLon = 100
Distance = 120
Direction = 180
I would expect the resulting Lat value to be < 30, but it is 30.48869

Regards,
Bryan
0
Bryan
7/6/2014 7:27:40 PM
Bryan Ray wrote:

> > {quote:title=John Treder wrote:}{quote}
> > Bryan Ray wrote:
> > 
> > > Hello group.  I have the following function that "should" return a MapCoordinate (latitude and longitude) based on input from a MapCoordinate origin and give distance and azimuth.
> > > It seems the longitude values I'm getting are correct, but the latitude values are not.
> > > Anyone have a clue on what's wrong... or have a better way?
> > > 
> > > Kind Regards,
> > > Bryan
> > > 
> > > {code}
> > > Type
> > >   MapCoordinate = Record
> > >   Latitude, Longitude : Double;
> > > end;
> > > 
> > > {code}
> > > 
> > > {code}
> > > function LocationFromMapPoint(inMapCoordinate : MapCoordinate; direction, distance : Double): MapCoordinate;
> > > var
> > >   arcdistance, arcazimuth, arclat, r1, r2, tlat, tlong, azimuthlat, azimuthlong: double;
> > >   s1, s2: String;
> > > begin
> > >   arcdistance := ((distance / 60) * pi / 180);
> > >   arcazimuth := (direction * pi / 180);
> > >   arclat := (inMapCoordinate.Latitude * pi / 180);
> > >   r1 := sin(arclat) * cos(arcdistance);
> > >   r2 := cos(arclat) * sin(arcdistance) * cos(arcazimuth);
> > >   tlat := arcsin(r1 + r2);
> > >   azimuthlat := tlat;                   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> > >   tlong := arctan(sin(arcdistance) *
> > >     sin(arcazimuth) / (cos(arclat) * cos(arcdistance) -
> > >     sin(arclat) * sin(arcdistance) * cos(arcazimuth)));
> > >   azimuthlong := inMapCoordinate.Longitude + ((tlong / pi * 180));
> > >   Result.Latitude := azimuthlat;
> > >   Result.Longitude := azimuthlong;
> > > end;
> > > 
> > > {code}
> > 
> > You haven't added the aimuthlat value I marked to the InMapCoordinate.Latitude.
> > 
> > -- 
> > Tredmill
> 
> Hello Tredmill,
> I have added azimuthlat := InCoordinates.Latitude + azimuthlat; 
> where you indicated, but I still do not get correct values.
> For example if I input the following:
> InLat = 30
> InLon = 100
> Distance = 120
> Direction = 180
> I would expect the resulting Lat value to be < 30, but it is 30.48869
> 
> Regards,
> Bryan

You wrote the code originally and understand it completely, right? :-)
What I was suggesting without trying to complete your code for you was that you need to combine azimuthlat and InCoordinate.Latitude in a similar way that you combined azimuthlong and ImMapCoordinate.Longitude.
I don't have any of your code except what you posted here.  If the parallel between latitude and longitude is exact. you would write
{code}
  azimuthlat := inMapCoordinate.Latitude + (tlat / pi * 180);
{code}
I should also note that you're using plane trigonometry for a spherical problem, so if  Distance is large, there will be errors.

BTW, your code would be a lot easier to read if you defined a constant like R2D = pi * 180; instead of doing all the typing.
Also, the Math unit has lots of stuff that you may find helpful.
-- 
don't Tred on me
0
John
7/7/2014 3:45:19 AM
> {quote:title=John Treder wrote:}{quote}
> Bryan Ray wrote:
> 
> > > {quote:title=John Treder wrote:}{quote}
> > > Bryan Ray wrote:
> > > 
> > > > Hello group.  I have the following function that "should" return a MapCoordinate (latitude and longitude) based on input from a MapCoordinate origin and give distance and azimuth.
> > > > It seems the longitude values I'm getting are correct, but the latitude values are not.
> > > > Anyone have a clue on what's wrong... or have a better way?
> > > > 
> > > > Kind Regards,
> > > > Bryan
> > > > 
> > > > {code}
> > > > Type
> > > >   MapCoordinate = Record
> > > >   Latitude, Longitude : Double;
> > > > end;
> > > > 
> > > > {code}
> > > > 
> > > > {code}
> > > > function LocationFromMapPoint(inMapCoordinate : MapCoordinate; direction, distance : Double): MapCoordinate;
> > > > var
> > > >   arcdistance, arcazimuth, arclat, r1, r2, tlat, tlong, azimuthlat, azimuthlong: double;
> > > >   s1, s2: String;
> > > > begin
> > > >   arcdistance := ((distance / 60) * pi / 180);
> > > >   arcazimuth := (direction * pi / 180);
> > > >   arclat := (inMapCoordinate.Latitude * pi / 180);
> > > >   r1 := sin(arclat) * cos(arcdistance);
> > > >   r2 := cos(arclat) * sin(arcdistance) * cos(arcazimuth);
> > > >   tlat := arcsin(r1 + r2);
> > > >   azimuthlat := tlat;                   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
> > > >   tlong := arctan(sin(arcdistance) *
> > > >     sin(arcazimuth) / (cos(arclat) * cos(arcdistance) -
> > > >     sin(arclat) * sin(arcdistance) * cos(arcazimuth)));
> > > >   azimuthlong := inMapCoordinate.Longitude + ((tlong / pi * 180));
> > > >   Result.Latitude := azimuthlat;
> > > >   Result.Longitude := azimuthlong;
> > > > end;
> > > > 
> > > > {code}
> > > 
> > > You haven't added the aimuthlat value I marked to the InMapCoordinate.Latitude.
> > > 
> > > -- 
> > > Tredmill
> > 
> > Hello Tredmill,
> > I have added azimuthlat := InCoordinates.Latitude + azimuthlat; 
> > where you indicated, but I still do not get correct values.
> > For example if I input the following:
> > InLat = 30
> > InLon = 100
> > Distance = 120
> > Direction = 180
> > I would expect the resulting Lat value to be < 30, but it is 30.48869
> > 
> > Regards,
> > Bryan
> 
> You wrote the code originally and understand it completely, right? :-)
> What I was suggesting without trying to complete your code for you was that you need to combine azimuthlat and InCoordinate.Latitude in a similar way that you combined azimuthlong and ImMapCoordinate.Longitude.
> I don't have any of your code except what you posted here.  If the parallel between latitude and longitude is exact. you would write
> {code}
>   azimuthlat := inMapCoordinate.Latitude + (tlat / pi * 180);
> {code}
> I should also note that you're using plane trigonometry for a spherical problem, so if  Distance is large, there will be errors.
> 
> BTW, your code would be a lot easier to read if you defined a constant like R2D = pi * 180; instead of doing all the typing.
> Also, the Math unit has lots of stuff that you may find helpful.
> -- 
> don't Tred on me

Hello John,
This was not my original code, I found it on the internet, but obviously it didn't work.  I've found this website and created my own.  
http://www.movable-type.co.uk/scripts/latlong.html
It appears to be working correctly now.
Thanks for the tips.
Regards,
Bryan

{code}
function DistantPoint(inCoordinates: TTMSFMXNativeMKMapLocation; Dir, Dist : Double): TTMSFMXNativeMKMapLocation;
Const
 R = 6371; //radius of earth in KM
var
 RadialDir, RadialDist, RadialLat, RadialLon : Double;
begin
  RadialDir  := DegToRad(Dir);   //Convert to Radians
  RadialDist := (Dist/R);  //Dist / Earth's Radius
  RadialLat  := DegToRad(InCoordinates.Latitude);
  RadialLon  := DegtoRad(InCoordinates.Longitude);

  Result.Latitude := ArcSin( Sin(RadialLat) * Cos(RadialDist) +
   Cos(RadialLat) *  Sin(RadialDist) * Cos(RadialDir) );


  Result.Longitude := RadialLon + ArcTan2( Sin(RadialDir) *
   Sin(RadialDist) * Cos(RadialLat) , Cos(RadialDist) - Sin(RadialLat) *
     Sin(Result.Latitude) );

  Result.Latitude := RadToDeg(Result.Latitude);
  Result.Longitude := RadToDeg(Result.Longitude);
end;

{code}
0
Bryan
7/7/2014 4:41:15 PM
Much tidier, Bryan!

-- 
John
0
John
7/7/2014 5:21:16 PM
John,

| Much tidier, Bryan!

And MUCH MORE correct!!! <g>  


-- 

   Q 

07/07/2014 10:47:20

1.19.1.372  [Q'sBrokenToolBar] [Running on TQ]
0
Quentin
7/7/2014 5:47:41 PM
Quentin Correll wrote:

> John,
> 
> >  Much tidier, Bryan!
> 
> And MUCH MORE correct!!! <g>  

That, too.  I had to delete a lot of discussion in my two reples to Bryan.  :-)

-- 
nhoJ
0
John
7/8/2014 5:00:42 AM
Reply: