Advertisement
Guest User

Geodistance Delphi Test

a guest
Aug 8th, 2015
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 3.25 KB | None | 0 0
  1. unit main;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, StdCtrls, Math;
  8.  
  9. type
  10.   TCoordNumber = Real;
  11.  
  12.   TCoords = record
  13.     coId: Cardinal;
  14.     coLon: TCoordNumber;
  15.     coLat: TCoordNumber;
  16.   end;
  17.  
  18.   TfrmMain = class(TForm)
  19.     btnGo: TButton;
  20.     btnTestDist: TButton;
  21.     procedure FormDestroy(Sender: TObject);
  22.     procedure btnTestDistClick(Sender: TObject);
  23.     procedure btnGoClick(Sender: TObject);
  24.   private
  25.     procedure InitData;
  26.   public
  27.   end;
  28.  
  29. const
  30.   CoordsQty = 2 * 1000 * 1000;
  31.  
  32. var
  33.   frmMain: TfrmMain;
  34.   GeoCoords: array of TCoords; // it will be slower if you move GeoCoords into the class
  35.  
  36. implementation
  37.  
  38. {$R *.dfm}
  39.  
  40. procedure TfrmMain.FormDestroy(Sender: TObject);
  41. begin
  42.   Finalize(GeoCoords);
  43. end;
  44.  
  45. function GetDistanceKm(lat1, lon1, lat2, lon2: TCoordNumber): Extended;
  46. var rn1, re1, rn2, re2, rd: Extended;
  47. begin
  48.   rn1 := lat1 * Pi / 180;
  49.   re1 := lon1 * Pi / 180;
  50.   rn2 := lat2 * Pi / 180;
  51.   re2 := lon2 * Pi / 180;
  52.   rd:=60*ArcCos(Sin(rn1)*Sin(rn2)+Cos(rn1)*Cos(rn2)*Cos(re2-re1));
  53.   GetDistanceKm := 1.852 * rd * 180 / Pi;
  54. end;
  55.  
  56. procedure TfrmMain.InitData;
  57. var i: Integer; s: string;
  58. begin
  59.   s := Caption;
  60.   Show;
  61.   SetLength(GeoCoords, CoordsQty);
  62.   Randomize;
  63.   for i := 0 to High(GeoCoords) do
  64.    begin
  65.     with GeoCoords[i] do
  66.      begin
  67.       coId := i + 1;
  68.       coLon := Random(360) + Random - 180;
  69.       coLat := Random(180) + Random - 90;
  70.      end;
  71.     if i and $FFFF = 0 then
  72.      begin
  73.       Caption := Caption + '|';
  74.       Application.ProcessMessages;
  75.      end;
  76.    end;
  77.   Caption := s;
  78. end;
  79.  
  80. procedure TfrmMain.btnGoClick(Sender: TObject);
  81. const RetryCount = 1000;
  82. var i, n, FoundQty: Integer;
  83.   TestLat, TestLon: TCoordNumber;
  84.   TestDist, CurrDist: Real;
  85.   StartTick, DeltaTime: DWord;
  86. begin
  87.   btnGo.Enabled := False;
  88.  
  89.   FoundQty := 0;
  90.   TestDist := 5; // 5 km
  91.   TestLat := 50.45; // y, "с.ш.",
  92.   TestLon := 30.52; // x, "в.д.",
  93.  
  94.   InitData;
  95.   StartTick := GetTickCount;
  96.  
  97.   for n := 1 to 1000 do
  98.    for i := 0 to High(GeoCoords) do
  99.     with GeoCoords[i] do
  100.      // 1 градус широты — примерно 111 км
  101.      if (abs(coLat - TestLat) * 100 < TestDist) then
  102.       // 1 градус долготы — 111.3 ... 0 км (19.8 км на параллели 80°)
  103.       if (abs(abs(coLon) - abs(TestLon)) * 10 < TestDist) then
  104.        begin
  105.         CurrDist := GetDistanceKm(TestLat, TestLon, coLat, coLon);
  106.         if CurrDist < TestDist then
  107.          Inc(FoundQty);
  108.        end;
  109.  
  110.   DeltaTime := GetTickCount - StartTick;
  111.   // у меня 1000 поисков по 2 млн. записям за 4.5 секунды
  112.   ShowMessage(IntToStr(RetryCount) + ' searches over ' + IntToStr(CoordsQty) +
  113.     ' records were performed during ' + IntToStr(DeltaTime) + ' ms. Found ' +
  114.     IntToStr(FoundQty) + ' records using distance ' + FloatToStr(TestDist) + ' km');
  115.  
  116.   btnGo.Enabled := True;
  117. end;
  118.  
  119. procedure TfrmMain.btnTestDistClick(Sender: TObject);
  120. var n1, e1, n2, e2: TCoordNumber;
  121. begin
  122.   n1 := 55.751052;
  123.   e1 := 37.623968;
  124.   n2 := 50.450000;
  125.   e2 := 30.524167;
  126.   ShowMessage('Distance is ' + FloatToStr(GetDistanceKm(n1, e1, n2, e2)) + ' km');
  127.   // Must be 755.092 km
  128. end;
  129.  
  130. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement