Pobieranie odległości z Google

0

Witam.
Chciałbym pobrać do programu pisanego w Delphi dane odległości drogowej pomiędzy wybranymi w programie punktami.
Nie mam pojęcia w jaki sposób to można zrobić.
Czytam o Google Maps API, ale wciąż nie wiem jak je użyć.
Czy mógłby mi ktoś z Was podać mi prosty przykład, który mógłbym sam rozbudowywać? W jaki sposób do programu wczytać odległość np od ulicy Franciszkańskiej w Krakowie do Woronicza w Warszawie?
Pozdrawiam,
Piotr.

0
  1. lokacje masz jako adres czy współrzędne?
  2. chodzi Ci o odległość w linii prostej, sferyczną czy może po drogach?
  3. jeśli po drogach to najkrótsza, najszybsza? z uwzględnieniem przejść pieszych/rowerowych?
0

Lokalizacje jako adresy, najkrótsza odległość po drogach dla samochodu osobowego.

2

JSON https://maps.googleapis.com/maps/api/distancematrix/json?origins=polska,katowice,młyńska%204&destinations=polska,warszawa,nowogrodzka%2045&mode=driving&language=pl-PL

{
   "destination_addresses" : [ "Nowogrodzka 45, Warszawa, Polska" ],
   "origin_addresses" : [ "Młyńska 4, Katowice, Polska" ],
   "rows" : [
      {
         "elements" : [
            {
               "distance" : {
                  "text" : "291 km",
                  "value" : 291255
               },
               "duration" : {
                  "text" : "3 godz. 13 min",
                  "value" : 11569
               },
               "status" : "OK"
            }
         ]
      }
   ],
   "status" : "OK"
}

XML https://maps.googleapis.com/maps/api/distancematrix/xml?origins=polska,katowice,młyńska%204&destinations=polska,warszawa,nowogrodzka%2045&mode=driving&language=pl-PL

<DistanceMatrixResponse>
  <status>OK</status>
  <origin_address>Młyńska 4, Katowice, Polska</origin_address>
  <destination_address>Nowogrodzka 45, Warszawa, Polska</destination_address>
  <row>
    <element>
    <status>OK</status>
      <duration>
        <value>11569</value>
        <text>3 godz. 13 min</text>
      </duration>
      <distance>
        <value>291255</value>
        <text>291 km</text>
      </distance>
    </element>
  </row>
</DistanceMatrixResponse>

i naprawdę nie mam pojęcia jak SZUKAŁEŚ ale wszystko, włącznie z PRZYKŁADAMI jest tutaj https://developers.google.com/maps/documentation/distance-matrix/intro a to jest stąd https://www.google.pl/search?q=google+maps+get+distance+between+two+points+api

A i żeby Cię nie zablokowało za szybko to trzeba sobie konto założyć na googlu i potem kliknąć wielki przycisk GET A KEY i podawać ten kod przy zapytaniach

0

Dziękuję, a w jaki sposób podawać ten kod, w którym miejscu zapytania, jaka składnia?

0

wpisz sobie w google delphi get web page - adres, i jak go złożyć, masz wyżej. To co podałem jak JSON lub XML to jest to co zwraca google pod danym adresem. A jak pobrać konkretne dane z JSONa lub XMLa też znajdziesz sam - to już nie jest tajemna wiedza :p

0

Nie o to mi chodziło, pytam o KEY, w jaki sposób go podać w zapytaniu, na końcu, na początku, po jakim słowie kluczowym?

1

czyli wejście na stronę z dokumentacją i obejrzenie (bo nikt czytania nie wymaga) to za dużo dla Ciebie?
![2016-10-17 20_05_03-Developer's Guide  _  Google Maps Distance Matrix API  _  Google Developers – Op.png](//static.4programmers.net/uploads/attachment/2016-10-17 20_05_03-Developer's Guide  _  Google Maps Distance Matrix API  _  Google Developers – Op.png)

0

Przepraszam, nie czytałem całej dokumentacji, w tym czasie próbowałem bezskutecznie używać TIdHTTP.Get i zmieniłem na InternetReadFile. Liczyłem, że jeżeli ktoś wie, to być może mi powie i oszczędzi trochę czasu. Gdybyś mi nie napisał to grzebałbym w dokumentacji, ale chyba od tego forum jest aby pytać innych. Dziękuję bardzo za pomoc.
Na koniec ostatnie pytanie czy ktoś z Was wie dlaczego nieszczęsny TIdHTTP.Get zwraca mi błąd Bad Request, a przez InternetReadFile otrzymuję dane bez problemu? Wywoływany url jak w przykładowym:
https://maps.googleapis.com/maps/api/distancematrix/json?origins=polska,katowice,młyńska%204&destinations=polska,warszawa,nowogrodzka%2045&mode=driving&language=pl-PL
Pozdrawiam,
Piotr.

0
  1. forum jest od pomocy i nakierowania, od prowadzenia za rączkę jest dokumentacja
  2. jakbyś dał kod to pewnie ktoś byłby w stanie coś powiedzieć. Na chwilę obecną ja mogę tylko rzec "U mnie działa"
0

Dziękuję za pomoc, to moje pierwsza próba pobierania danych z sieci.
W poniżej przedstawionym kodzie tylko pierwsza procedura GetPage działa, dwie pozostałe powodują komunikat Bad Request. Nie są to procedury moje, lecz znalezione w sieci.

Function TForm1.Odleglosc(A1,A2:string;var odl,czs:string):boolean;
var
  s:string;
  m,n:word;
begin
  odl:='';czs:='';Odleglosc:=false;
  if (A1='')or(A2='') then Exit;
  s:='https://maps.googleapis.com/maps/api/distancematrix/json?origins=';
  s:=s+A1+'&destinations='+A2+'&mode=driving&language=pl-PL';
  s:=GetPage(s);

  // obróbka danych

end;





function TForm1.GetPage(s:string):string;
var
   hSes,hURL:HINTERNET;
   buf:array[1..1000] of Byte;
   n,dw:DWORD;
   x:string;
begin
   hSes:=InternetOpen('Download',INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
   hURL:=InternetOpenURL(hSes,PChar(s),nil, 0, 0, 0);
   InternetReadFile(hURL,@buf,1000,dw);
   InternetCloseHandle(hSes);
   InternetCloseHandle(hURL);
   x:='';
   for n:=1 to dw do x:=x+Chr(buf[n]);
   GetPage:=x;
end;



function TForm1.GetPage(s:string):string;
var
  HTTP:TIdHTTP;
begin
  HTTP:=TIdHTTP.Create;
  try
    Result:=HTTP.Get(s);
  finally
    HTTP.Free;
  end;
end;



function TForm1.GetPage(s:string):string;
var   x:TMemoryStream;
   HTTP:TIdHTTP;
begin
   HTTP:=TIdHTTP.Create;
   x:=TMemoryStream.Create();
   try
   HTTP.Get(s,x);
   x.Position:=0;
   Memo1.Lines.LoadFromStream(x);
   Result:=Memo1.Text;
   finally
   x.Free();
   end;
end;
0

Witam ponownie.
Niestety miałem reinstalację systemu, zainstalowałem Delphi 10.1 Berlin, i teraz moje procedury nie działają.
InternetReadFile zwraca mi śmieci.
Prosiłbym o jakąkolwiek działającą procedure pobierania danych przez http.
Przykłady z google nie działają:

function TForm1.GetPage(s:string):string;
var   x:TMemoryStream;
   HTTP:TIdHTTP;
begin
   HTTP:=TIdHTTP.Create;
   x:=TMemoryStream.Create();
   try
   HTTP.Get(s,x);
   x.Position:=0;
   Memo1.Lines.LoadFromStream(x);
   Result:=Memo1.Text;
   finally
   x.Free();
   end;
end;

powoduje "Socket Error # 10057
Socket is not connected."

0

podajesz prawidłowy adres?

0

Tak, jeżeli skopiuję zmienną s i uruchomię w przeglądarce jest ok.

Znalazłem jeden sposób: jeśli skompiluję na 64bit jest OK, jeśli na 32 to nie działa.

1

Z Indy:

function TForm1.GetPage(APageURL: string):string;
var
  IdHTTP: TIdHTTP;
begin
   result:= '';
   IdHTTP:= TIdHTTP.Create(Self);
   try
     IdHTTP.HandleRedirects:= True;
     result:= IdHTTP.Get(APageURL);
   finally
     IdHTTP.Free;
   end;
end;

I to musi działać jak ze strona i net online.

Na WinInet:

function TForm1.GetPage(APageURL: string):string;
var
   DownStream: TStringStream;
   hSes, hURL: HINTERNET;
   buf: array[0..1000] of WChar;
   iBytesRead: DWORD;
begin
   result:= '';
   hSes:=InternetOpen('Download', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
   hURL:=InternetOpenURL(hSes, PChar(APageURL), 0, 0, 0, 0);
   DownStream:=TStringStream.Create('', TEncoding.ASCII); //kombinuj lub TEncoding.Unicode, TEncoding.ASCII
   try
     while InternetReadFile(hURL, @buf, Length(buf), iBytesRead) and (iBytesRead > 0) do
       DownStream.WriteBuffer(buf, iBytesRead);
     result:= DownStream.DataString;
   finally
     DownStream.Free;
   end;
   InternetCloseHandle(hURL);
   InternetCloseHandle(hSes);
end;
0

Na WinInet u mnie działa, a na Indy nadal nie.
Jeszcze jedna sprawa jak wysłać email?
Żaden przykład z google nie działa, przykłady z:
Jak wysłać e-mail poprzez komponenty Indy lub FastNet
też nie działają, nie istnieje u mnie SMTP.AuthenticationType.
Mój fragment:

    Msg.From.Address := '*****@gmail.com';
    Msg.Recipients.EMailAddresses := '*****@gmail.com';
    Msg.Body.Text := tekst;
    try
      SMTP.Host := 'smtp.gmail.com';
      SMTP.Port := 587;
      TIdSSLIOHandlerSocketOpenSSL(SMTP.IOHandler).SSLOptions.Method := sslvTLSv1;
      smtp.UseTLS:=utUseExplicitTLS;
      SMTP.AuthType := satDefault;
      SMTP.Username := '*****@gmail.com';
      SMTP.Password := '*******';
      SMTP.Connect;
      SMTP.Send(Msg);
    finally
    end;
0

Jaką masz wersję Delphi i Indy (wersje Indy sprawdzisz klikając prawym na dowolnym komponencie i masz About...)?

0

Delphi XE10 Seattle
Indy 10.6.2.5298

2

Tak powinno działać:

    Msg.From.Address := '*******@gmail.com';
    Msg.Recipients.EMailAddresses := '*******@gmail.com';
    Msg.Body.Text := 'test';
    Msg.Subject:= 'temat2';
    try
      SMTP.Host := 'smtp.gmail.com';
      SMTP.Port := 465;  //tak ma być  587 to był kiedys bez ssl (teraz chyba juz nie można)
      //TIdSSLIOHandlerSocketOpenSSL(SMTP.IOHandler).SSLOptions.Method := sslvTLSv1; //zbedne wystarczy ustawic tylko IoHandler w IdSMTP i nic wiecej nie ruszac
      SMTP.UseTLS:= utUseImplicitTLS;  //tak ma być a nie utUseExplicitTLS
      SMTP.Username := '*******@gmail.com';
      SMTP.Password := '*******';
      SMTP.AuthType := satDefault;
      SMTP.Connect;
      SMTP.Send(Msg);
    except
      on e: Exception do
        ShowMessage('Błąd: ' + E.Message);
    end;

Oczywiście zakładam że masz w folderze z programem potrzebne do połączeń SSL biblioteki libeay32.dll i ssleay32.dll

Gdyby wyświetlało komunikat

...Please log in via your web browser and then try again...
zaloguj się przez przeglądarkę na skrzynkę później wejdź na adres https://www.google.com/settings/security/lesssecureapps i włącz dostęp dla mniej bezpiecznych aplikacji.

0

Dziękuję za skorygowanie moich błędów.
Już działa, nie wiem jak ustawić IOHandler więc dodałem tak:

SMTP.IOHandler :=IdSSLIOHandlerSocketOpenSSL;

Bardzo dziękuję za pomoc.
Pozdrawiam,
Piotr.

0

Jeszcze jeden problem, w temacie wiadomości polskie znaki są, ale w treści już nie.
Próbuję zmieniać CharSet, Encoding, ContentType ale bez powodzenia.
W google znalazłem taki sposób:
http://pl.comp.lang.delphi.narkive.com/q8kk37F4/polskie-litery-w-mailu-smtp-indy
Czy istnieje ustawienie polskich znaków zamiast ręcznego ich podmieniania? Dlaczego pomimo iż w temacie jest ok, treść ma inny system kodowania?
Pozdrawiam.

1

Powinno zadziałać właśnie ustawienie CharSet, Encoding, ContentType:

    Msg.From.Address := '******@gmail.com';
    Msg.Recipients.EMailAddresses:= '******@gmail.com';
    Msg.Body.DefaultEncoding:= TEncoding.UTF8;
    Msg.CharSet:= 'UTF-8';
    Msg.ContentType:= 'text/plain; charset=UTF-8';
    Msg.Body.Text:= 'Test polskich znaków ąśćółńóśźżĄŚĆŁŃÓŚŹŻ';
    Msg.Subject:= 'Test ąśćółńóśźżĄŚĆŁŃÓŚŹŻ';

A jak nie działa to treść wiadomości jest z pliku czy jak? Jeżeli tak to pokaż jak ładujesz.

0

Dziękuję kAzek, jesteś wielki.
Nie wczytywałem z pliku. Jedynie umieściłem te linie po Msg.Subject, i było tylko "text/plain" bez powtórnego charset.
Próbowałem z UTF-8,Unicode,ISO,windows-1250, zmieniałem jedno i sprawdzałem efekt, była to metoda prób i błędów, samych błędów.
Po wpisaniu Twojego kodu wszystko działa.
Bardzo dziękuję za pomoc.
Pozdrawiam,
Piotr.

1 użytkowników online, w tym zalogowanych: 0, gości: 1