Version:0.9 StartHTML:0000000105 EndHTML:0000098735 StartFragment:0000000141 EndFragment:0000098699
unit GoogleDirForm_mX5_64_2_OSM_21_Generic;
interface
{uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Edit, FMX.Controls.Presentation;       }
  //Purpose: get coordinates of two points and route directions - TAddressGeoCodeOSM5
type
  TDirections = {class(}TForm;
  var
    LblFrom: TLabel;
    lbllong: TLabel;
    EdtLong: TEdit;
    LblLat: TLabel;
    EdtLat: TEdit;
    BtnGoGoogle: TButton;
    LblLocation, lbltitle: TLabel;
    LblTo: TLabel;
    LblLong2: TLabel;
    EdtLong2: TEdit;
    LblLat2: TLabel;
    EdtLat2: TEdit;
    LblLocation2: TLabel;
    EdtGoogleLink: TEdit;
    CBxGoNow: TCheckBox;
    LBlCrowFlies, Coords: TLabel;
    fromlat, fromlong, tolat, tolong: string;
    procedure TDirectionsEdtFromChange(Sender: TObject);
    procedure TDirectionsEdtToChange(Sender: TObject);
    procedure TDirectionsBtnGoGoogleClick(Sender: TObject);
    procedure TDirectionsFormCreate(Sender: TObject);
  //private
    { Private declarations }
    Procedure TDirectionsEditChangeData(AEdtLong,AEdtLat:TEdit;ALabel:TLabel);
  //public
    { Public declarations }
  //end;
var
  Directions: TDirections;
implementation
//{$R *.fmx}

//uses IsNavUtils;
//https://sourceforge.net/projects/maxbox/files/Docu/SourceV5/IsNavUtils2.pas/download

{ TDirections }
procedure TDirectionsBtnGoGoogleClick(Sender: TObject);
Var
  LocFrom,LocTo:RNavigateLongLat;
  Long,Lat:Double;
begin
  LocFrom:=RNavigateLongLat.create;
  Locto:=RNavigateLongLat.create;
  Long:=RealFrmDegreeText(EdtLong.Text);
  Lat:= RealFrmDegreeText(EdtLat.Text);
  LocFrom.CreateDec(Long,Lat);
  Long:=RealFrmDegreeText(EdtLong2.Text);
  Lat:= RealFrmDegreeText(EdtLat2.Text);
  LocTo.CreateDec(Long,Lat);
  // { 0 Start 1 End 3 Center }
  EdtGoogleLink.Text:=LocFrom.GoogleLinkDirectionsTo(LocTo, 0);
  LBlCrowFlies.Caption:='Distance as Crow Flys ='+FormatFloat('0.0km',LocTo.MetresFrom(LocFrom)/1000);
  if CBxGoNow.Checked then
     LocFrom.GoGoogleDirectionsTo(LocTo, 0);
end;
procedure TDirectionsEditChangeData(AEdtLong, AEdtLat: TEdit; ALabel: TLabel);
Var
  Loc:RNavigateLongLat;
  Long,Lat:Double;
begin
  loc:= RNavigateLongLat.create;
  Long:=RealFrmDegreeText(AEdtLong.Text);
  Lat:= RealFrmDegreeText(AEdtLat.Text);
  Loc.CreateDec(Long,Lat);
  ALabel.caption:=Loc.LocatationText(3);
end;
procedure TDirectionsEdtFromChange(Sender: TObject);
begin
  TDirectionsEditChangeData(EdtLong,EdtLat,LblLocation);
end;
procedure TDirectionsEdtToChange(Sender: TObject);
begin
  TDirectionsEditChangeData(EdtLong2,EdtLat2,LblLocation2);
end;
procedure TDirectionsFormCreate(Sender: TObject);
begin
   TDirectionsEdtFromChange(nil);
   TDirectionsEdtToChange(nil);
   LBlCrowFlies.caption:='Distance as Crow Flys:';
   writeln('fmx form create..');
end;
//--------------------------------weather and geocoordinates section ----------
Const
  UrlWeatherReport25=
     'http://api.openweathermap.org/data/2.5/weather?q=%s&units=metric&APPID'+
                                      '=55013bf3d09cfb0619989a00ed5bed_____yourAPIKey';
  GEOCoordREX2 = 
              
'"lon":([\d\.-]+).*"lat":([\d\.-]+).*';  
              
 
type TTlatlong = record
       lat, long: double;
       descript: string;
     end;  
                                                                       
function TAddressGeoCodeOSM(faddress: string): tlatlong;
var url, res, display: string;
  jo: TJSONObject; urlid: TIduri; winapi: TWinApiDownload;
 begin
  urlid:= TIdURI.create('');
  url:= urlid.URLEncode('https://nominatim.openstreetmap.org/search?format=json&q='+
                                                                fAddress);
  writeln(url)
  winapi:= TWinApiDownload.create;
  winapi.useragent:= 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1'; 
  winapi
.url:= url;
  writeln('check url: '+itoa(winapi.CheckURL(url)));      
  winapi
.download1(res);
  if (res <> '') and (res <> '[]') then begin
   //windown.OnWorkStart
   StrReplace(res, '[{', '{');
   jo:= TJSONObject.create4(res);
   try
     if jo.getString('place_id') <> ' ' then               
       display
:= jo.getstring('display_name');
     result.descript:= Format('Coords: lat %2.5f  lng %2.5f %s place_id: %d',
                             [jo.getdouble('lat'),jo.getdouble('lon'),display,
                                                  jo.getint('place_id')]); 
     result
.lat:= jo.getdouble('lat'); 
     result
.long:= jo.getdouble('lon');                                     
   
except
     writeln('Geo E: '+ExceptiontoString(exceptiontype, exceptionparam));                 
   
finally                                  
     jo
.Free;    
     urlid
.free;
     winapi.free;
   end; 
  
end else showmessagebig('OSM geo location not found! ');
end;  
             
  
var  latf, lonf: Double;
   
   
function GEOCoord2PointX(apistr: string): TFloatPoint;
   begin
     setdecimalseparator('.')
     with TPerlRegex.Create do try 
       regex
:= GEOCoordREX2; 
       subject
:= apistr;
       if match then begin
         result.x:= strtofloat(groups[1])
         result.y:= strtofloat(groups[2])
       end;     
      
finally Free; 
     
end;
   end; 
   
function GetGeoWeather(const location: string;
                                  const UrlRestAPI: string): string;
  var lStrm: TStringStream;
begin
  lStrm:= TStringStream.Create('');
  try
     try
       HTTPGet(Format(UrlRestAPI,[location]),lStrm);
     except
        //if something wrong try using a backup server.
        //writeln('html back: '+GetURLAsString('http://api.openweathermap.org'));
       writeln('OWeather_Map Exception: '+Gethtm(UrlWeatherReport25))
     end;
     lStrm.Seek(0,0);
     result:= 'GEO_Weather_Report5: '+(lStrm.ReadString(lStrm.Size));
  finally
     lStrm.Free;
  end;
end;
//----------------------end weather and geocode section------------------------//
procedure loadFMXForm;
begin
Directions:= TDirections.create(self)
with directions do begin
  Left:= 0; Top:= 0 ;
  formstyle:= fsstayontop;
  Caption:= 'Form64 Googel Directions WebForm5'
  ClientHeight:= 591
  ClientWidth:= 756
  icon.loadfromresourcename(hinstance, 'XARCHIPELAGO'); //XLINUX'); //'ARCHIPELAGO');
  //FormFactor.Width:= 320
  //FormFactor.Height:= 480
  //FormFactor.Devices:= [Desktop]
  OnCreate:= @TDirectionsFormCreate;
  //DesignerMasterStyle:= 0
  Show;
  Lbltitle:= TLabel.create(directions)
  with lbltitle do begin
   parent:= directions;
    left:= 60; top:= 2;
    Width:= 200; Height:= 17
    font.style2:= fsbold2;
    font.color:= clnavy;
    caption:= 'Google Directions NavUtils5'
    font.size:= 20;
  end;
  LblFrom:= TLabel.create(directions)
  with lblfrom do begin
   parent:= directions;
    //StyledSettings:= [Family, Size, Style]
    left:= 160;
    top:= 60;
    //Scale.X:= 2.000000000000000000
    //Scale.Y:= 2.000000000000000000
    Width:= 41
    Height:= 17
    //Size.PlatformDefault:= False
    //TextSettings.FontColor:= claCrimson
    font.style2:= fsbold2;
    caption:= 'From'
    TabOrder:= 26
  end;
  lbllong:= TLabel.create(directions)
  with lbllong do begin
   parent:= directions;
    left:= 260; top:= 96
    Width:= 105; Height:= 17
    //Size.PlatformDefault:= False
    caption:= 'Source Longitude'
    TabOrder:= 17
  end ;
  EdtLong:= TEdit.create(directions)
  with edtlong do begin
   parent:= directions;
    //Touch.InteractiveGestures:= [LongTap, DoubleTap]
    TabOrder:= 9
    Text:= fromlong; //'7.44744';  //50.9473; // - lon: 6.9503 Cologne//'145  30 30'
    left:= 424; top:= 88
    Width:= 281; Height:= 30
    //Size.PlatformDefault:= False
    OnChange:= @TDirectionsEdtFromChange;
  end;
  lbllat:= TLabel.create(directions)
  with lbllat do begin
   parent:= directions;
    left:= 260; top:= 136
    Width:= 97; Height:= 17
    //PlatformDefault:= False
    caption:= 'Source Latitude'
    TabOrder:= 18
  end;
  EdtLat:= TEdit.create(directions)
  with edtlat do begin
   parent:= directions;
    //Touch.InteractiveGestures:= [LongTap, DoubleTap]
    TabOrder:= 10
    Text:= fromlat; //'46.94797'
    left:= 424; top:= 128
    Width:= 281; Height:= 30
    //PlatformDefault:= False
    OnChange:= @TDirectionsEdtFromChange;
  end;
   BtnGoGoogle:= TButton.create(directions)
   with btngogoogle do begin
    parent:= directions;
    left:= 369; top:= 392
    Width:= 140; Height:= 32
    //Size.PlatformDefault:= False
    TabOrder:= 11
    caption:= '&Go to Google..'
    OnClick:= @TDirectionsBtnGoGoogleClick;
  end;
  LblLocation:= TLabel.create(directions)
  with lbllocation do begin
   parent:= directions;
    left:= 160;  top:= 176
    Width:= 553; Height:= 17
    //.PlatformDefault:= False
    caption:= 'LblLocation'
    TabOrder:= 19
  end;
  Lblto:= TLabel.create(directions)
  with lblto do begin
   parent:= directions;
    //StyledSettings:= [Family, Size, Style]
    left:= 160
    top:= 250
    //Scale.X:= 2.000000000000000000
    //Scale.Y:= 2.000000000000000000
    Width:= 41
    Height:= 17
    //Size.PlatformDefault:= False
    //TextSettings.FontColor:= claCrimson
    font.style2:= fsbold2;
    caption:= 'To'
    TabOrder:= 25
  end;
   LblLong2:= TLabel.create(directions)
   with lbllong2 do begin
    parent:= directions;
    left:= 260; top:= 280
    Width:= 105; Height:= 17
    //Size.PlatformDefault:= False
    caption:= 'Dest Longitude'
    TabOrder:= 16
  end;
  EdtLong2:= TEdit.create(directions)
  with edtlong2 do begin
   parent:= directions;
    //Touch.InteractiveGestures:= [LongTap, DoubleTap]
    TabOrder:= 7
    Text:=  toLong; //'7.11161'; //Graz'145.69'        50.9473
    left:= 424; top:= 272
    Width:= 281;  Height:= 30
    //Size.PlatformDefault:= False
    OnChange:= @TDirectionsEdtToChange ;
  end;
  LblLat2:= TLabel.create(directions)
   with lbllat2 do begin
    parent:= directions;
    left:= 260; top:= 320
    Width:= 97; Height:= 17
    //Size.PlatformDefault:= False
    caption:= 'Dest Latitude'
    TabOrder:= 15
  end ;
  EdtLat2:= TEdit.create(directions)
  with edtlat2 do begin
   parent:= directions;
    //Touch.InteractiveGestures:= [LongTap, DoubleTap]
    TabOrder:= 8
    Text:= tolat; //'49.27092' //- lon: 15.4168  Graz'-37.55'
    left:= 424;  top:= 312
    Width:= 281; Height:= 30
    //PlatformDefault:= False
    OnChange:= @TDirectionsEdtToChange ;
  end;
  LblLocation2:= TLabel.create(directions)
  with lbllocation2 do begin
   parent:= directions;
    left:= 160;  top:= 360
    Width:= 553; Height:= 17
    //PlatformDefault:= False
    caption:= 'LblLocation'
    TabOrder:= 14
  end ;
  EdtGoogleLink:= TEdit.create(directions)
  with edtgooglelink do begin
   parent:= directions;
    //Touch.InteractiveGestures:= [LongTap, DoubleTap]
    TabOrder:= 27; left:= 20;
    top:= 448; Width:= 710
    Height:= 28
    //Size.PlatformDefault:= False
  end ;
  CBxGoNow:= TCheckBox.create(directions)
  with  CBxGoNow do begin
   parent:= directions;
    left:= 64; top:= 400
    Width:= 273; Height:= 19
    checked:= true;
    //Size.PlatformDefault:= False
    TabOrder:= 28
    caption:= 'Check To See Link In Browser'
  end;
 LBlCrowFlies:= TLabel.create(directions)
 with lblcrowflies do begin
   parent:= directions;
    left:= 96; top:= 500
    Width:= 601; Height:= 17
    //Size.PlatformDefault:= False
    caption:= 'LBlCrowFlies'
    TabOrder:= 30
  end;
 Coords:= TLabel.create(directions)
 with coords do begin
   parent:= directions;
    left:= 96; top:= 530
    Width:= 601; Height:= 17
    caption:= 'GeoCoords: '
  end;
  TDirectionsFormCreate(self);
 end;
end; 
var WebBrowser1: TWebBrowser;
procedure loadWebform;
var Form1:  TForm;
begin
 Form1:= TForm.create(self);
 with form1 do begin
  SetBounds(76,46,1200, 1100)
  Caption:= 'maXbox5 WinControlWebBrowserFeed_WeatherReport'
  Color:= clBtnFace
  Font
.Charset:= DEFAULT_CHARSET
  Font
.Color:= clWindowText
  Font
.Name:= 'MS Sans Serif'
  Font.Style:= []
  OldCreateOrder := False
  
//OnShow := @TForm1FormShow;
  PixelsPerInch:= 96
  WebBrowser1:= TWebBrowser.create(form1);
  with webbrowser1 do begin
    TWinControl(WebBrowser1).Name:= 'MyWebBrowser5';
    //TWinControl(WebBrowser1).loadfromstream('MyWebBrowser1');
    TWinControl(WebBrowser1).Parent:= form1;
    TWinControl(WebBrowser1).setbounds(20,24,962,441)
    TWinControl(WebBrowser1).color:= clblack;
    TWinControl(WebBrowser1).Align:= alClient;
    Silent:= True;
    //EmbeddedWB1.HostCSS:= FmtCSS;
    //WebBrowser1.OleObject.Document.bgColor := '#000000';
    //(WebBrowser1.Document as TWinControl).Color := clblack;
     Color:=  clblack; //'#000000';
    TabOrder:= 0
    end;
   end;
 form1.show;
end; 

var f_latlong, t_latlong: TLatlong; atext: string;
begin //@main
 
 setdebugcheck
(false);
 writ('SystemCodePage: '+itoa(SystemCodePage)); 
 writ
('lib compiler: '+libcompilerstring);
 writeln('CPUSpeed '+cpuspeed);
 //loadFMXForm();
   {
   sr:= GetGeoWeather(removespaces('Melbourne,AU'), UrlWeatherReport25);
   sr:= GetGeoWeather(removespaces('Bern, CH'), UrlWeatherReport25);
   writeln(sr)
   lonf:= GEOCoord2PointX(sr).x  
   latf:= GEOCoord2PointX(sr).y 
   PrintF('Lon: %.4f - Lat: %.4f ',[lonf, latf]) 
   coords.caption:= coords.caption+format(' Lon: %.4f - Lat: %.4f',[lonf,latf]); 
   }
   //latlong:=  TAddressGeoCodeOSM('Gereonswall 66, Cologne, Germany');
 
  writeln
(mbversion +'  '+version)
  writeln(itoa(MBVERIALL));
  
   
//From___
   f_latlong:=  TAddressGeoCodeOSM5('Cathedral, Bern, Switzerland');
   //To___ 
   t_latlong:=  TAddressGeoCodeOSM5('Ljubljana, Slovenia');
   
   fromlat
:=  flots(f_latlong.lat);
   fromlong:= flots(f_latlong.long);                     //Bern
   tolat:=    flots(t_latlong.lat);
   tolong:=   flots(t_latlong.long);                     //Jersey
 
  
// ----------------------Input From To Example-----------------------------//
  //fromlat:=  '46.9479';    fromlong:= '7.44744';                     //Bern
  //tolat:=    '49.1857';    tolong:=  '-2.1102';                      //St. Jersey
  //-------------------------------------------------------------------
   
   loadFMXForm
();
 
  
//function TAddressGeoCodeOSM5 is now internal precompiled  > V51470
  //latlong:=  TAddressGeoCodeOSM5('Hauptbahnhof, Graz, Austria');
 
  writeln
('OSM _from: '+f_latlong.descript);
  writeln('OSM _to:   '+t_latlong.descript);
  writeln('get geocoords: '+format(' lat: %.4f - lon: %.4f',[t_latlong.lat,t_latlong.long])); 
  coords
.caption:= coords.caption+format(' Dest: lat: %.4f - lon: %.4f',[t_latlong.lat,t_latlong.long]); 
  OpenWeb
('https://www.latlong.net/c/?lat='+flots(t_latlong.lat)+'&long='+flots(t_latlong.long));
  loadWebform();
  WebBrowser1.Navigate('https://wttr.in/Ljubljana');
 end.
end.
Doc:  https://maxbox4.wordpress.com/2024/03/06/geocoding-iv/
      https://medium.com/@maxkleiner1/geocoding-iv-572a602f4daa
Testunit From Cologne to Graz
         get geocoords
:  lat: 50.9473 - lon: 6.9503 Cologne
         get geocoords
:  lat: 47.0739 - lon: 15.4168  Graz
         get geocoords
:  lat: 46.9479 - lon: 7.44744 Bern
         get geocoords
:  lat: 49.27092 - lon 7.11161 St. Ingbert
         
ref
: http://www.softwareschule.ch/examples/tripadvisor.txt