![]() |
Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 4)
Anhang 35424
Use Google Maps API inside your Delphi application. Free, easy to use and much more powerful than a component. Der Kern besteht aus einer Delphi-To-JavaScript-Bridge, mit deren Hilfe Delphi-Programme über das COM-Interface des Internet Explorers auf JavaScript-Objekte und -Funktionen zugreifen können. Die Kommunikation ist dabei bidirektional: Das bedeutet, daß Objekt- und anonyme Methoden aus JavaScript heraus aufgerufen werden können - zum Beispiel als Callback-Funktion, Event-Handler oder "injizierter" Code. In diesem Framework wurde mit Hilfe dieser Delphi-To-JavaScript-Bridge das komplette Google Maps API abgebildet. Damit ist es möglich, alle Funktionen und Objekte dieses API's anzusprechen, ohne eine einzige Zeile JavaScript schreiben zu müssen. Nun gibt es schon eine Reihe von Lösungsvorschlägen und Komponenten für Delphi, die das Google Maps API kapseln (ohne Anspruch auf Vollständigkeit):
Weshalb dann noch dieses Framework? Ganz klar zwei Gründe:
Mit diesem Framework können JavaScript-Beispiele ohne Probleme nach Delphi umgesetzt werden - mit den Vorteilen einer Code-Vervollständigung und komfortablen Debugging-Möglichkeiten. Ein kleines Beispiel:
Code:
[...]
<script type="text/javascript"> function CreateMap() { var Options = {zoom: 13, center: new google.maps.LatLng(47.651743,-122.349243), mapTypeId: google.maps.MapTypeId.SATELLITE}; new google.maps.Map(document.getElementById("div_map"),Options); }; </script> </head> <body onload="CreateMap()"> [...]
Delphi-Quellcode:
In der aktuellen Version 2.0 besteht das Framework aus rund 30000 Quelltextzeilen, 10000 Zeilen Dokumentation im XML-Format und rund 10000 Zeilen in reichlich 80 Demos.
procedure TForm1.FormShow(Sender: TObject);
begin if Script=nil then with TScript.Create(WebBrowser1) do LoadAPIAsync(InitMap); end; procedure TForm1.InitMap(Sender: TObject); var Options: TMapOptions; begin with TScript(Sender) do begin Options:=TMapOptions.Create; with Options do begin Zoom:=13; Center:=New(Google.Maps.LatLng(47.651743,-122.349243)); MapTypeID:=Google.Maps.MapTypeID.Satellite; end; New(Google.Maps.Map(Options)); end; end; Systemvoraussetzungen
Das Framework wurde bisher mit folgenden Delphi-Versionen getestet:
Bekannte Probleme In Zusammenhang mit dem Internet Explorer 6 (sollte eigentlich keiner mehr benutzen):
Installation, Migration bestehender Projekte Da es sich um ein Framework handelt, muß nichts in der IDE installiert werden - es müssen lediglich die Pfade zur gmConfig.inc sowie den Verzeichnissen API und JScript eingetragen werden (global oder in den Projekt-Optionen). Die Umstellung von bestehenden Projekten unter Verwendung der Versionen 1.x auf die Version 2.0 sollte sich in der Regel auf die Anpassung der Unit-Namen beschränken. Um eine bessere Übereinstimmung zur Google Maps API-Dokumentation zu erzielen, wurden einige Units umbenannt. Auf die Einführung eines Namespace wurde mit Rücksicht auf ältere Delphi-Versionen (noch) verzichtet. Es wird empfohlen, die Initialisierung der Karte in eine separaten Methode auszulagern, um den Refresh-Mechanismus (Taste F5) des Frameworks nutzen zu können. Lizenz (Möglichst) kurz und schmerzlos: Ich mag keine seitenlangen Texte, die meist nur verunsichern (siehe aktuelle Problematik mit einer speziellen Datenbank) und die sowieso kaum jemand liest. Noch weniger mag ich Quelltexte, die am Anfang einen Hinweis enthalten, der länger ist als der eigentliche Code. Auch bin ich aus dem Alter heraus, in dem ich nach jeweils drei Zeilen mein Copyright hinterlassen muß, als hätte ich die genialste Erfindung aller Zeiten gemacht und müßte wie ein Hund mein Revier markieren. Wer das nötig hat, soll das machen - ich jedenfalls nicht. Deshalb nur folgende Regeln:
Erweiterungen
Viel Spaß! :thumb: (1) Wer für die Starter Editionen (XE bzw. XE2) keine TWebBrowser-Komponente besitzt, kann diese ![]() (2) siehe ![]() (3) Spenden über ![]() |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 2)
Beispiel 1
Erstellung einer einfachen Karte
Delphi-Quellcode:
Anhang 32930
procedure TForm1.FormShow(Sender: TObject);
var Options: TMapOptions; begin WebBrowser1.Navigate('about:blank'); with TScript.Create(WebBrowser1) do //Skript-Objekt erstellen begin LoadBrowserFromSource(WebBrowser1, //leere Seite: HTMLPage(true, //- MIT Google Maps API false, //- OHNE GPS-Sensor 'div_map'), //- MIT Div-Container für die Karte true); //warten, bis die Seite komplett geladen wurde Options:=TMapOptions.Create; //Options-Objekt anlegen with Options do begin Zoom:=13; //Zoom Center:=Google.Maps.LatLng(-25.3455315,131.0333570); //Kartenzentrum MapTypeID:=Google.Maps.MapTypeId.SATELLITE; //Kartentyp end; Google.Maps.Map(Document.GetElementById('div_map'),Options); //Karten-Objekt anlegen end; end; Anmerkung: Für den Screenshot wurde manuell auf den Kartentyp "Gelände" umgeschaltet. Compilierte Demo: |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 2)
Beipiel 2
Deaktivierung aller Steuerelemente und jeder Interaktion. Damit wird quasi eine statische Karte erzeugt.
Delphi-Quellcode:
Anhang 32932
procedure TForm1.FormShow(Sender: TObject);
var Options: TMapOptions; begin WebBrowser1.Navigate('about:blank'); with TScript.Create(WebBrowser1) do //Skript-Objekt erstellen begin LoadBrowserFromSource(WebBrowser1, //leere Seite: HTMLPage(true, //- MIT Google Maps API false, //- OHNE GPS-Sensor 'div_map'), //- MIT Div-Container für die Karte true); //warten, bis die Seite komplett geladen wurde Options:=TMapOptions.Create; //Options-Objekt anlegen with Options do begin Center:=Google.Maps.LatLng(-33,151); //Kartenzentrum DisableDefaultUI:=true; //alle Kontrollelemente ausschalten DisableDoubleClickZoom:=true; //kein Zoom per Doppelklick Draggable:=false; //Karte nicht verschiebbar KeyboardShortcuts:=false; //keine Tastenkürzel MapTypeID:=Google.Maps.MapTypeId.Roadmap; //Kartentyp ScrollWheel:=false; //kein Zoom über Mausrad Zoom:=4; //Zoom end; Google.Maps.Map(Document.GetElementById('div_map'),Options); //Karten-Objekt anlegen end; end; Compilierte Demo: |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 2)
Beispiel 3
Ein- und Ausschalten der Steuerelemente.
Delphi-Quellcode:
Anhang 32934
procedure TForm1.FormShow(Sender: TObject);
var Options: TMapOptions; begin WebBrowser1.Navigate('about:blank'); Script:=TScript.Create(WebBrowser1); //Skript-Objekt erstellen with Script do begin LoadBrowserFromSource(WebBrowser1, //leere Seite: HTMLPage(true, //- MIT Google Maps API false, //- OHNE GPS-Sensor 'div_map'), //- MIT Div-Container für die Karte true); //warten, bis die Seite komplett geladen wurde Options:=TMapOptions.Create; //Options-Objekt anlegen with Options do begin Center:=Google.Maps.LatLng(-28.643387,153.612224); //Kartenzentrum MapTypeControl:=true; //Kartentyp-Kontrolle sichtbar with MapTypeControlOptions do begin Style:=Google.Maps.MapTypeControlStyle.Dropdown_Menu; //Kartentyp-Kontrolle als aufklappbares Menü Position:=Google.Maps.ControlPosition.Top_Left; //Kartentyp-Kontrolle links oben end; NavigationControl:=true; //Navigationskontrolle sichtbar with NavigationControlOptions do begin Style:=Google.Maps.NavigationControlStyle.Android; //Navigationskontrolle im Android-Design Position:=Google.Maps.ControlPosition.Bottom; //Navigationskontrolle unten in der Mitte end; ScaleControl:=true; //Maßstab sichtbar with ScaleControlOptions do Position:=Google.Maps.ControlPosition.Top_Right; //Maßstab rechts oben StreetViewControl:=true; //StreetView-Kontrolle sichtbar MapTypeID:=Google.Maps.MapTypeId.Roadmap; //Kartentyp Straße Zoom:=12; //Zoom end; Google.Maps.Map(Document.GetElementById('div_map'),Options); //Karten-Objekt anlegen end; end; Compilierte Demo: |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 2)
Beispiel 4
Verwendung der Karten-Events
Delphi-Quellcode:
Anhang 32936
procedure TForm1.FormShow(Sender: TObject);
begin //... with Map do begin OnBoundsChanged:=MapBoundsChanged; OnCenterChanged:=MapCenterChanged; OnClick:=MapClick; OnDblClick:=MapDblClick; OnDrag:=MapDrag; OnDragEnd:=MapDragEnd; OnDragStart:=MapDragStart; OnIdle:=MapIdle; OnMapTypeIDChanged:=MapMapTypeIDChanged; OnMouseMove:=MapMouseMove; OnMouseOut:=MapMouseOut; OnMouseOver:=MapMouseOver; OnProjectionChanged:=MapProjectionChanged; OnResize:=MapResize; OnRightClick:=MapRightClick; OnTilesLoaded:=MapTilesLoaded; OnZoomChanged:=MapZoomChanged; end; end; end; Compilierte Demo: |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 1)
Die Demos 1 bis 4 im Quelltext (ohne exe). Sie wurden sowohl mit Delphi 5, Delphi 2005 PE, Delphi 2010 als auch mit Delphi XE getestet.
Achtung: Zur Compilierung sind die Units in den Unterverzeichnissen API und JScript notwendig, die bei mir separat angefordert werden können! Neue Version der Wrapper-Objekte: Jetzt ist nicht mehr TWebBrowser zur Darstellung der Karten notwendig - es wird auch ![]() Das ist vor allem bei Delphi-Versionen hilfreich, die standardmäßig keine installierte TWebBrowser-Komponente in der Palette haben - das hatte ich gestern voller Entsetzen beim Test mit Delphi 2005 PE feststellen müssen. :shock: |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 4)
Beipiel 5
Verwendung der asynchronen Funktionen des Google Maps API's mittels Callback-Funktionen, Verwendung des Geocoders und des Elevation-Service Die Arbeitsweise des Google Maps API's wurde in Version 3 konsequent asynchron gestaltet. Es fängt damit an, dass sogar das komplette API asynchron geladen werden kann:
Code:
Nachdem alle Module von den Google-Servern geladen wurden, ruft das API die angegebene (JavaScript-)Callback-Funktion auf.
http://maps.google.com/maps/api/js?sensor=true_or_false&callback=FunctionXYZ
Die ganze Umsetzung - angefangen bei der Bereitstellung der JavaScript-Funktion bis hin zum Aufruf der gewünschten Delphi-Methode - wird vom Framework übernommen. Dem eigentlichen Delphi-Quelltext sieht man die Komplexität dieses Vorganges gar nicht mehr an:
Delphi-Quellcode:
Wie wäre es aber in dem Fall, wenn die Koordinaten des Zielgebietes unbekannt sind? Wie in den vorangegangenen Beispielen gezeigt wurde, werden diese aber zur Erstellung der Karte benötigt.
procedure TForm1.FormShow(Sender: TObject);
begin WebBrowser1.Navigate('about:blank'); Script:=TScript.Create(WebBrowser1); //Skript-Objekt erstellen with Script do begin LoadBrowserFromSource(WebBrowser1, //leere Seite: HTMLPage(false, //- OHNE Google Maps API false, //- OHNE GPS-Sensor 'div_map'), //- MIT Div-Container für die Karte true); //warten, bis die leere komplett geladen wurde LoadAPIAsync(false,OnAPILoaded); //Google Maps-API asynchron laden; Parameter: kein Sensor, Callback-Methode end; end; procedure TForm1.OnAPILoaded; begin //z.B. Karte erstellen end; Für diese Aufgabe steht der Geocoder zur Verfügung. Auch dieser ist ein JavaScript-Objekt, das erstellt und mit der Anfrage "gefüttert" werden muß. Nachdem dieses Geocoder-Objekt beim Google-Server nachgefragt hat, wird wiederum eine Callback-Funktion aufgerufen:
Delphi-Quellcode:
Praktisch wäre es jetzt noch, auch die Höhe des gewünschten Punktes auf der Landkarte zu ermitteln. Dafür ist der Elevation-Service der richtige Ansprechpartner. Genau wie der Geocoder besteht er aus einem JavaScript-Objekt, das die Anfrage an Google weiterleitet und nach dem Empfang die Antwort an eine entsprechende Callback-Funktion übergibt. In Delphi sieht das so aus:
procedure TForm1.OnAPILoaded;
var GeocoderRequest: TGeocoderRequest; begin with Script do begin GeocoderRequest:=TGeocoderRequest.Create; //GeocoderRequest-Objekt anlegen GeocoderRequest.Address:='Mount Kilimanjaro'; //zu kodierende Adresse Google.Maps.Geocoder.Geocode(GeocoderRequest,GeocoderCallback); //Geocoder-Objekt erstellen und Kodierung vom Server anfordern end; end; procedure TForm1.GeocoderCallback(Sender: TObject; Results: TGeocoderResults; Status: String); var LatLng: TLatLng; //... begin with Script do begin if Status=Google.Maps.GeocoderStatus.Ok then //Kodierungsanfrage wurde ordnungsgemäß bearbeitet begin LatLng:=Results[0].Geometry.Location; //erste Adresse aus der Kodierungsanfrage //Karte neu anlegen bzw. neu zentrieren... end else ShowMessage(Status); end;
Delphi-Quellcode:
In der Demo wird mit Hilfe der ermittelten Daten ein anklickbarer Marker erstellt.
procedure TForm1.GeocoderCallback(Sender: TObject; Results: TGeocoderResults; Status: String);
var //... ElevationRequest: TLocationElevationRequest; begin with Script do begin //... ElevationRequest:=TLocationElevationRequest.Create; //ElevationRequest-Objekt anlegen ElevationRequest.Locations.Add(LatLng); //Ort für die Abfrage der Höhe if ElevationServices.Count=0 //noch kein ElevationService-Objekt vorhanden then Google.Maps.ElevationService; //-> neu anlegen ElevationServices[0].GetElevationForLocations(ElevationRequest,ElevationCallback); //... end; end; procedure TForm1.ElevationCallback(Sender: TObject; Results: TElevationResults; Status: String); begin with Script do begin if Status=Google.Maps.ElevationStatus.Ok then //irgendetwas mit den Daten machen else ShowMessage(Status); end; end; Als kleiner Zusatz wird demonstriert, wie ein Screenshot vom WebBrowser gemacht werden kann. Anhang 32955 Demo_5.zip enthält die Komponente TImage32 aus dem Paket Graphics32, Demo_5_ohne_TImage32.zip arbeitet nur mit TImage und ist deshalb auch ohne Graphics32 compilierbar. Compilierte Exe und Quelltext (ohne Exe): |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 3)
Beispiel 6
Geometrische Formen: Kreise, Rechtecke, Polygone, Polylines (auf besonderen Wunsch von DelphiFan2008) Alle diese Formen sind (JavaScript-)Objekte. Sie werden erstellt, indem ein passendes Options-Objekt angelegt, mit den entsprechende Werten initialisiert und an den Konstruktor des Geometrie-Objektes übergeben wird. Zwingend notwendig ist die Festlegung der Ausmaße: Beim Kreis wären das der Mittelpunkt und der Radius, beim Rechteck die linke untere (Süd-West) und die rechte obere Ecke (Nord-Ost) und bei den Linienobjekten die Koordinaten der einzelnen Eckpunkte. In der Regel werden diese Werte in Form von LatLng-Objekten angegeben - die einzige Ausnahme ist der Kreis: Dort wird der Radius in Metern erwartet. Optional hingegen sind zum Beispiel die Werte für Linienfarbe, -breite und -transparenz. Soll das Objekt auf einer Karte dargestellt werden, muß ihm (bzw. vor der Erstellung dem Optionsobjekt) die entsprechende Karte zugewiesen werden. Das könnte zum Beispiel so aussehen:
Delphi-Quellcode:
Soll das Objekt wieder von der Karte entfernt werden, reicht es aus, seiner Map-Eigenschaft den Wert nil zuzuweisen.
procedure TForm1.Button1Click(Sender: TObject);
var CircleOptions: TCircleOptions; begin with Script do begin CircleOptions:=TCircleOptions.Create; //Zirkeloptions-Objekt erstellen CircleOptions.Center:=Google.Maps.LatLng(10,20); //Zirkelmittelpunkt CircleOptions.Map:=Maps[0]; //Kartenobjekt zuweisen CircleOptions.Radius:=1000; //Radius in Metern CircleOptions.StrokeColor:=clRed; //Linienfarbe Google.Maps.Circle(CircleOptions); //Zirkel-Objekt erstellen end; end; Anhang 32959 Compilierte Exe und Quelltext (ohne Exe): |
AW: Google Maps über COM (Component Object Model)
Hallo,
habe nun alle Demos fehlerfrei am Laufen und habe schon in eigenen Applikationen damit herumgespielt. Finde die Umsetzung von Thom als unheimlich gelungen - den besten Ansatz den ich bisher für Delphi gefunden habe. Die Verwendbarkeit in nahezu allen Delphi Versionen ist möglich sowie die Kapselung in die Objekte ist sehr gut gelungen. Da die Library nahe an der Google Library angelehnt ist, lassen sich die Hilfen und Tutorials von Google sehr gut nutzen. Verwende die Library derzeit mit TurboDelphi2006. Bin gerade an einer Applikation, bei der ich GoogleMaps intensiv nutzen werde (Standardfunktionen sowie Marker, Polyline, Polygon, Geocoder etc.). Erfahrungsbericht folgt. Thom, weiter so ! Gruß DelphiFan2008 |
AW: Google Maps über COM (Component Object Model)
Liste der Anhänge anzeigen (Anzahl: 2)
@DelphiFan2008,
vielen Dank! Da macht die Arbeit doch gleich viel mehr Spaß! In den letzten Tagen sind noch weitere Demos entstanden und das Framework wurde weiterentwickelt. Beispiel 7 Nutzung des Routenplaners und Anzeige des berechneten Weges Anhang 33016 Compilierte Exe: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz