Calculate distance between two points by latitude and longitude

Asked

Viewed 8,954 times

11

I need to calculate the distance in kilometer(Km) between two points through their latitude and longitude. I have not found an effective way to do.

The latitudes and longitudes I have are formatted as follows:

lat: -29.6518875

long: -51.1716005

I found ways to calculate them when they are in degrees, but nothing when they are in this format.

  • http://www.tdevrocks.com.br/2014/09/26/quick-post-likesaber-distance-entre-dois-pontos-no-mapmap/ see if this helps you.

  • I’ll test it, thank you.

  • 1

    @R.Gasparin just mark the solution as accepted, need not and should not touch the title.

2 answers

8


Try this code with me it worked:

function sgn(a: real): real;
begin
  if a < 0 then sgn := -1 else sgn := 1;
end;

function atan2(y, x: real): real;
begin
  if x > 0  then atan2 := arctan(y/x)
  else if x < 0  then atan2 := arctan(y/x) + pi
  else atan2 := pi/2 * sgn(y);
end;

procedure TForm1.Button2Click(Sender: TObject);
var Long1, Lat1, Long2, Lat2, Val1, Val2, Long, Lat: Double;
begin
  Lat1 := 41.500605;
  Long1 := -7.731313;
  Lat2 := 37.186851;
  Long2 := -8.742056;

  Lat1 := Lat1 * pi / 180.0;
  Long1 := Long1 * pi / 180.0;
  Lat2 := Lat2 * pi / 180.0;
  Long2 := Long2 * pi / 180.0;

  Lat := Lat2 - Lat1;
  Long := Long2 - Long1;

  Val1 := 6371.0;
  Val2 := sin(Lat / 2) * sin(Lat / 2) + cos(Lat1) * cos(Lat2) * sin(Long / 2) * sin(Long / 2);
  Val2 := 2 * ATan2(sqrt(Val2), sqrt(1 - Val2));

  Memo1.Lines.Add(FloatToStr(Val1 * Val2) + ' KM');
end;

Any question or doubt ask, more information on the formula can consult Great-Circle Distance.

  • 1

    I can’t understand these variables and where these numbers came from, it’s confusing.

  • These are the equations needed to arrive at the solution, I do not know how to explain better than that.

  • I can try to assign new variables more explicit, and try to explain the whole process better.. came to test?

  • I leave here this Link, which is where I guided myself: www.tdevrocks.com.br/2014/09/26/Quick-post-como-saber-a-distancia-entre-dois-pontos-no-mapa/

  • I don’t understand where these names come from, so it’s confusing. What does W1 mean for example.

  • I have not tested yet, I would like to understand better these issues that I have mentioned so that I can implement in my application.

  • I tried to improve the code when I could from a glance

  • Now you are better to understand, tested and works. Thank you!

  • If you no longer have any questions or questions and if your question has been answered, you should then assign your feedback to my answer and close the question.

  • 2

    I believe the solution is the formula "harvesine": https://en.wikipedia.org/wiki/Great-circle_distance

  • Are you sure the distance has been calculated correctly?

  • @Ricardodarochavitor has more than one way to calculate geodesics, the "right" depends on many factors. If you want more precision than Haversine, you need to use Vincenty, for example. If you want more precision, you need to apply the most suitable algorithm to the right region, and that varies a lot. Today we use WGS84 for almost everything, but it’s not every region that gets so good.

Show 7 more comments

1

Follow the full code based on the contribution of colleague Tmc, ready to test

In a blank form:

copy the code below and press Ctrl+V (Paste)

object Edit1: TEdit
  Touch.InteractiveGestures = [LongTap, DoubleTap]
  TabOrder = 0
  KeyboardType = NumberPad
  Text = '41.500605'
  Position.X = 56.0
  Position.Y = 56.0
  TextPrompt = 'Latitude1'
end
object Edit2: TEdit
  Touch.InteractiveGestures = [LongTap, DoubleTap]
  TabOrder = 1
  KeyboardType = NumberPad
  Text = '-7,731313'
  Position.X = 56.0
  Position.Y = 80.0
  TextPrompt = 'Longitude1'
end
object Edit3: TEdit
  Touch.InteractiveGestures = [LongTap, DoubleTap]
  TabOrder = 2
  KeyboardType = NumberPad
  Text = '37,186851'
  Position.X = 56.0
  Position.Y = 128.0
  TextPrompt = 'Latitude2'
end
object Edit4: TEdit
  Touch.InteractiveGestures = [LongTap, DoubleTap]
  TabOrder = 3
  KeyboardType = NumberPad
  Text = '-8,742056'
  Position.X = 56.0
  Position.Y = 152.0
  TextPrompt = 'Longitude2'
end
object Button1: TButton
  Position.X = 56.0
  Position.Y = 184.0
  TabOrder = 4
  Text = 'Distancia'
  OnClick = Button1Click
end
object Label1: TLabel
  Position.X = 56.0
  Position.Y = 40.0
  Text = 'Coordenada A'
end
object Label2: TLabel
  Position.X = 56.0
  Position.Y = 112.0
  Text = 'Coordenada B'
end
object Label3: TLabel
  Position.X = 56.0
  Position.Y = 216.0
end

Paste the following code below implementation, then press Shift+Ctrl+C to create the signatures

  function CalcDistanciaCoord(Lat1,Lng1,Lat2,Lng2:Double):Double;//Retorna distancia em Km
    const
           r:Double = 6371.0;//Raio da terra
    var
           Val, Lng, Lat: Double;
           piLat1,piLng1,piLat2,piLng2:Double;

    function sgn(a: real): real;
    begin
    //if a < 0 then sgn := -1 else sgn := 1;
        result := a/abs(a)
    end;

    function atan2(y, x: real): real;
    begin
      if x > 0  then atan2 := arctan(y/x)
      else if x < 0  then atan2 := arctan(y/x) + pi
          else atan2 := pi/2 * sgn(y);
    end;

begin
  piLat1 := Lat1 * pi / 180.0;
  piLng1 := Lng1 * pi / 180.0;
  piLat2 := Lat2 * pi / 180.0;
  piLng2 := Lng2 * pi / 180.0;

  Lat := Lat2 - Lat1;
  Lng := Lng2 - Lng1;

  Val := sin(Lat / 2) * sin(Lat / 2) + cos(Lat1) * cos(Lat2) * sin(Lng / 2) * sin(Lng / 2);
  Val := 2 * ATan2(sqrt(Val), sqrt(1 - Val));

  Result:= r * Val;
end;

procedure TForm1.Button1Click(Sender: TObject);
var d,La1,Lo1,La2,Lo2:Double;
    begin
    La1 := StrToFloat(Edit1.text);
    Lo1 := StrToFloat(Edit2.text);
    La2 := StrToFloat(Edit3.text);
    Lo2 := StrToFloat(Edit4.text);
    d:=CalcDistanciaCoord(La1,Lo1,La2,Lo2);
    label3.text:=formatfloat('#0.000000 Km',d);
    //label1.caption:=formatfloat('#0.000000 Km",d);//VCL
    end;
  • From what I checked in google MAPS the calculation is wrong. Someone can check?

  • It will not match with google (of course it is to approximate), because Haversine is a very "rounded" approach. If you want more precision, you need to use other formulas and strategies. And in order to calculate real distance, you need to use the terrain map, which is a little outside the question, I think. Two pairs of coordinates can have different distances if both are in a desert or each on the side of a mountain.

  • But the difference is too big... 10424.16... against 562Km, so there’s some error in the equations, you can check?

  • 1

    You need to take the original formula (Haversine) and compare it. There you find where you went wrong. It could be some silly parameter wrong.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.