Перейти к содержанию
Fire Monkey от А до Я
  • 0

узнать расстояние между 2 точками


Martifan

Вопрос

Рекомендуемые сообщения

  • 0
function DistanceMeters(const Crd1,Crd2:TLocationCoord2D):Double;
begin
  try
  result := (1609.344*3958.75 *
    arccos(sin(Crd1.Latitude/57.2958) * sin(Crd1.Latitude/57.2958) +
    cos(Crd1.Latitude/57.2958) * cos(Crd2.Latitude/57.2958) * cos(Crd2.Longitude/57.2958
    - Crd1.Longitude/57.2958)));
  except
    result := 0;
  end;
end;
Ссылка на комментарий
  • 0

Если нужно решать поточнее, тогда надо представлять Землю как двухосный эллипсоид. Тогда это задача на нахождение длины дуги на поверхности эллипсоида. Решается методами вариационного исчисления. http://vasnake.blogspot.com/2006/12/blog-post_15.html

Ссылка на комментарий
  • 1
  • Модераторы

uses Math, FMX.Maps

function TMapsEngine.GetDistance(const aStart, aEnd: TMapCoordinate): Real;
const
  Radius = 6372795;
  PiDiv180 = Pi / 180;
var
  CosLatStart, SinLatStart, CosLatEnd, SinLatEnd, Delta, CosDelta, SinDelta, X, Y: Real;
begin
  try
    CosLatStart := Cos(aStart.Latitude * PiDiv180);
    CosLatEnd := Cos(aEnd.Latitude * PiDiv180);
    SinLatStart := Sin(aStart.Latitude * PiDiv180);
    SinLatEnd := Sin(aEnd.Latitude * PiDiv180);
    Delta := (aEnd.Longitude * PiDiv180) - (aStart.Longitude * PiDiv180);
    CosDelta := Cos(Delta);
    SinDelta := Sin(Delta);
    Y := Sqrt(((CosLatEnd * SinDelta) * (CosLatEnd * SinDelta)) + ((CosLatStart * SinLatEnd - SinLatStart * CosLatEnd * CosDelta)
      * (CosLatStart * SinLatEnd - SinLatStart * CosLatEnd * CosDelta)));
    X := SinLatStart * SinLatEnd + CosLatStart * CosLatEnd * CosDelta;
    Result := Round(ArcTan2(Y, X) * Radius);
  except
    Result := -1;
  end;
end;

рассчитывает отрезок по прямой, не по дороге!

Изменено пользователем ZuBy
Ссылка на комментарий
  • 0
  • Модераторы
RouteURL = 'https://maps.googleapis.com/maps/api/directions/xml?origin=%s,%s&destination=%s,%s&mode=driving&key=%s';
Str := (Format(RouteURL, [OrigLatitude, OrigLongitude, DestLatitude, DestLongitude, aGoogleDistanceKey]));

подробно

смотрим XML и разбираем

Ссылка на комментарий
  • 0

спасибо конечно но более понятном языке нету ничего?

Там же на PHP, вроде популярный язык сейчас.

Также надо учесть, что в варианте Zuby Земля представляется сферой, поэтому в вычислении расстояния погрешность будет выше.

Ссылка на комментарий
  • 0

 

спасибо конечно но более понятном языке нету ничего?

Там же на PHP, вроде популярный язык сейчас.

Также надо учесть, что в варианте Zuby Земля представляется сферой, поэтому в вычислении расстояния погрешность будет выше.

 

я разобрался и там тоже по сфера считает вот пример:

procedure calcDistance(StartLat, StartLon, EndLat, EndLon:real; var dist,bearing:real);
var D2R,R2D,a,e2:real;
    fdLambda,fdPhi,fPhimean,fTemp,fRho,fNu,fz,fAlpha,fR:real;
begin
  dist:=0;
  bearing:=0;
    if ((StartLat = 0) or (StartLon = 0) or (EndLat = 0) or (EndLon = 0)) then exit;
    if ( (abs(StartLon - EndLon) <= 0.0000014) and (abs(StartLat - EndLat) <= 0.0000008)) then exit;
    D2R := 0.01745329251994330; // Pi/180
    R2D := 57.29577951308230000; // 180/Pi
    a := 6378137.0;
    e2 := 0.00673949674233346;
    fdLambda := (StartLon - EndLon) * D2R;
    fdPhi := (StartLat - EndLat) * D2R;
    fPhimean := (StartLat + EndLat) / 2.0 * D2R;
    fTemp := 1 - e2 * Power( sin(fPhimean), 2);
    fRho := a * (1 - e2) / Power(fTemp, 1.5);
    fNu := a / sqrt(1 - e2 * sin(fPhimean) * sin(fPhimean) );
    fz := 2 * ArcSin(sqrt (
        Power(sin( fdPhi / 2.0), 2 ) + cos( EndLat * D2R )
        * cos( StartLat * D2R ) * Power(sin(fdLambda / 2.0), 2)
    ) );
    fAlpha := ArcSin(cos( EndLat * D2R ) * sin(fdLambda) / sin(fz) );
    fR := fRho * fNu / (fRho * Power(sin(fAlpha), 2) + fNu * Power(cos(fAlpha), 2));
    dist:=fz * fR;

    if (dist <= 0.999) then exit;
    Bearing := abs(fAlpha * R2D);

  if ((StartLat <= EndLat) and (StartLon > EndLon)) then
  begin
    Bearing := 360 - Bearing;
  end  else
  begin
    if ((StartLat > EndLat) and (StartLon >= EndLon)) then
    begin
        Bearing := 180 + Bearing;
    end
    else
    begin
      if ((StartLat > EndLat) and (StartLon < EndLon))  then
        begin
          Bearing := 180 - Bearing;
        end
    end;
  end;
end;
Ссылка на комментарий
  • 0

Почему Вы так решили?

Параметр e2 как раз и отвечает за отличие между полярным и экваториальным радиусами Земли.

может быть но параметр dist возвращает значение по сфера

Ссылка на комментарий
  • 0
fR := fRho * fNu / (fRho * Power(sin(fAlpha), 2) + fNu * Power(cos(fAlpha), 2));

dist:=fz * fR;

 

dist линейно зависит от fR, fR зависит от fNu и fRho, которые зависят от e2, e2 определяется разницей экваториального и полярного радиуса.

Следовательно, dist также отпределяется разницей между экваториальным и полярным радиусами. 

Почему Вы решили, что здесь также считается по сфере?

 

Изменено пользователем Alex7wrt
Ссылка на комментарий

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...