AW: Google Maps über COM (Component Object Model)
Ich habe mal eine kurze Frage:
Wie kann ich mehrere Maps in einer Anwendung verwenden. Im Moment habe ich das so probiert:
Code:
type
TForm1 = class(TForm) ... WebBrowser1: TWebBrowser; WebBrowser2: TWebBrowser; ... private { Private-Deklarationen } public { Public-Deklarationen } MapScript1: TScript; MapScript2: TScript; procedure InitMap(Sender: TObject); end; procedure TForm1.FormShow(Sender: TObject); begin // Einmalig die Maps initialisieren if MapScript1=nil then TScript.Create(WebBrowser1).LoadAPIAsync(InitMap); if MapScript2=nil then TScript.Create(WebBrowser2).LoadAPIAsync(InitMap); end; procedure TForm1.InitMap(Sender: TObject); var MapOptions: TMapOptions; MarkerOptions: TMarkerOptions; begin with TScript(Sender) do begin MapOptions:=TMapOptions.Create; with MapOptions do begin DisableDefaultUI:=true; //alle Kontrollelemente ausschalten DisableDoubleClickZoom:=true; //kein Zoom per Doppelklick Draggable:=false; //Karte nicht verschiebbar ScrollWheel:=false; //kein Zoom über Mausrad KeyboardShortcuts:=false; //keine Tastenkürzel MapTypeID:=Google.Maps.MapTypeId.Roadmap; //Kartentyp (roadmap oder satellite) Zoom:=1; //Zoom Center:=Google.Maps.LatLng(0,0); //Kartenzentrum end; New(Google.Maps.Map(MapOptions)); // Marker Zeichnen MarkerOptions:=TMarkerOptions.Create; MarkerOptions.Map:=Google.Maps.Map(MapOptions); MarkerOptions.Position:=Google.Maps.LatLng(53,8); MarkerOptions.Title:='Letzte Position'; New(Google.Maps.Marker(MarkerOptions)); end; end; Wenn ich aber später die Parameter ändern möchte, schmiert das Programm mit einer Schutzverletzung ab:
Code:
Was mache ich falsch?
MapScript1.Maps[0].Zoom:=17;
MapScript1.Maps[0].Center:=MapScript_T1.Google.Maps.LatLng(50,10); //Kartenzentrum MapScript1.Maps[0].MapTypeID:=MapScript_T1.Google.Maps.MapTypeId.SATELLITE; |
AW: Google Maps über COM (Component Object Model)
Hallo mischo22,
Du speicherst die Script-Objekte nicht in den Variablen:
Delphi-Quellcode:
Die Lösung sollte sein:
procedure TForm1.FormShow(Sender: TObject);
begin // Einmalig die Maps initialisieren if MapScript1=nil then TScript.Create(WebBrowser1).LoadAPIAsync(InitMap); //<- Script wird erstellt, aber nicht in MapScript1 gespeichert if MapScript2=nil then TScript.Create(WebBrowser2).LoadAPIAsync(InitMap); //<- selbe Problem end;
Delphi-Quellcode:
Allerdings kannst Du Dir auch das Speichern der Script-Objekte sparen - das erfolgt schon frameworkintern:
procedure TForm1.FormShow(Sender: TObject);
begin // Einmalig die Maps initialisieren if MapScript1=nil then begin MapScript1:=TScript.Create(WebBrowser1); MapScript1.LoadAPIAsync(InitMap); end; if MapScript2=nil then begin MapScript2:=TScript.Create(WebBrowser2); MapScript2.LoadAPIAsync(InitMap); end; end;
Delphi-Quellcode:
Um später auf das Objekt zugreifen zu können, reicht
procedure TForm1.FormShow(Sender: TObject);
begin // Einmalig die Maps initialisieren if Script(WebBrowser1)=nil then with TScript.Create(WebBrowser1) do LoadAPIAsync(InitMap); if Script(WebBrowser2)=nil then with TScript.Create(WebBrowser2) do LoadAPIAsync(InitMap); end;
Delphi-Quellcode:
Wer Angst vor dem angeblich bösen "with" hat, macht es so:
with Script(WebBrowser1) do
begin Maps[0].Zoom:=17; Maps[0].Center:=New(Google.Maps.LatLng(50,10)); //<- New-Funktion verwenden Maps[0].MapTypeID:=Google.Maps.MapTypeId.SATELLITE; end;
Delphi-Quellcode:
Allerdings mußt Du bei der Erstellung von Hilfsobjekten momentan noch beachten, daß dabei ebenfalls das Script-Objekt als Parameter angegeben wird:
Script(WebBrowser1).Maps[0].Zoom:=17;
Script(WebBrowser1).Maps[0].Center:=New(Script(WebBrowser1).Google.Maps.LatLng(50,10)); //<- New-Funktion verwenden Script(WebBrowser1).Maps[0].MapTypeID:=Script(WebBrowser1).Google.Maps.MapTypeId.SATELLITE;
Delphi-Quellcode:
In der Version 3 wird es für diese Hilfsobjekte ebenfalls eine passende New-Funktion geben, so daß dann die Sache noch etwas einfacher wird:
procedure TForm1.InitMap(Sender: TObject);
var Map: TMap; MapOptions: TMapOptions; MarkerOptions: TMarkerOptions; begin with Sender as TScript do //<- hier eventuell schon einmal den harten Cast für Version 3 vermeiden (das geht nicht gut mit Interfaces) begin MapOptions:=TMapOptions.Create(Sender as TScript); //<- hier das Script-Objekt als Parameter angeben with MapOptions do begin DisableDefaultUI:=true; DisableDoubleClickZoom:=true; Draggable:=false; ScrollWheel:=false; KeyboardShortcuts:=false; MapTypeID:=Google.Maps.MapTypeId.Roadmap; Zoom:=1; Center:=New(Google.Maps.LatLng(0,0)); //<- New-Funktion verwenden end; Map:=New(Google.Maps.Map(MapOptions)); //<- Karte für den Marker merken // Marker Zeichnen MarkerOptions:=TMarkerOptions.Create(Sender as TScript); //<- hier ebenfalls das Script-Objekt angeben MarkerOptions.Map:=Map; //<- hier die Variable Map verwenden - sonst wird noch eine weitere Karte angelegt MarkerOptions.Position:=New(Google.Maps.LatLng(53,8)); //<- New-Funktion verwenden MarkerOptions.Title:='Letzte Position'; New(Google.Maps.Marker(MarkerOptions)); end; end;
Delphi-Quellcode:
with Sender as IScript do
begin MapOptions:=New(Google.Maps.MapOptions); [...] end; |
AW: Google Maps über COM (Component Object Model)
Hallo Thom,
Ich habe nun den OnShow bereich entsprechend angepasst und meine eigenen Script-Variablen entfernt. Dies sieht nun so aus:
Code:
Leider kann ich mittels der Zeilen
procedure TForm1.FormShow(Sender: TObject);
begin // Einmalig die Maps initialisieren if Script(WebBrowser_T1)=nil then with TScript.Create(WebBrowser_T1) do LoadAPIAsync(InitMap); if Script(WebBrowser_T2)=nil then with TScript.Create(WebBrowser_T2) do LoadAPIAsync(InitMap); if Script(WebBrowser_T3)=nil then with TScript.Create(WebBrowser_T3) do LoadAPIAsync(InitMap); if Script(WebBrowser_T4)=nil then with TScript.Create(WebBrowser_T4) do LoadAPIAsync(InitMap); end;
Code:
Nicht auf die Map nachträglich zugreifen. Es kommt beim Compilieren die Fehlermeldung: "Undeklarierter Bezeichner: Maps"
// Map aktualisieren
with Script(WebBrowser_T1) do begin Maps[0].Zoom:=17; ... end; |
AW: Google Maps über COM (Component Object Model)
Auf welche Funktion/Unit kommst Du, wenn Du mit Strg auf die Funktion Script klickst?
|
AW: Google Maps über COM (Component Object Model)
Ich komme auf die datei BrowserTools.pas
Code:
function Script(WebBrowser: TOleControl): IDispatch;
|
AW: Google Maps über COM (Component Object Model)
Hatte ich schon vermutet. Ändere mal bitte die Reihenfolge der Units in der uses-Anweisung: gmAPI muß nach (!) BrowserTools kommen.
|
AW: Google Maps über COM (Component Object Model)
Ok, das war schon mal der Fehler.
Perfekt ist es aber noch immer nicht. Map1 (Webbrowser_T1) scheint alle Befehle aus dem Init-Map korrekt zu verarbeiten. Bei den Maps 2-4 werden die festgelegten Center-Koordinaten nicht korrekt angewendet. Die Karten liegen nicht bei LatLng(0,0) sondern bei LatLng(-90,0). Irgend eine Idee? |
AW: Google Maps über COM (Component Object Model)
Zitat:
Lade mal bitte ein kompilierbares Projekt hoch, damit ich mir das Problem im Debugger anschauen kann. |
AW: Google Maps über COM (Component Object Model)
Habs per Mail gesendet.
|
AW: Google Maps über COM (Component Object Model)
Hallo Michael,
ist angekommen und auch schon angeschaut. Das Problem liegt bei der VCL bzw. dem TWebBrowser: Solange dieser nicht sichtbar ist, hat er eine Größe von 0x0 (oder 1x1) Pixeln. Damit liegt das Kartenzentrum (in Deinem Fall (0,0)) in der linken oberen Ecke. Mein Vorschlag wäre, nur die Karte zu laden, die am Anfang sichtbar ist und alle anderen erst dann, wenn die entsprechende Seite angeklickt wird:
Delphi-Quellcode:
Das würde auch die Startzeit des Programmes spürbar verkürzen, da jetzt nicht mehr alle Karten im OnShow-Ereignis geladen werden müssen.
procedure TForm1.PageControl1Change(Sender: TObject);
procedure InitMap(WebBrowser: TWebBrowser); begin if Script(WebBrowser)=nil then with TScript.Create(WebBrowser) do LoadAPIAsync(Self.InitMap); end; begin if PageControl1.ActivePage=TabSheet1 then InitMap(WebBrowser_T1); if PageControl1.ActivePage=TabSheet2 then InitMap(WebBrowser_T2); //bzw. Tracker2, da Du das umbenannt hattest if PageControl1.ActivePage=TabSheet3 then InitMap(WebBrowser_T3); if PageControl1.ActivePage=TabSheet4 then InitMap(WebBrowser_T4); if PageControl1.ActivePage=TabSheet5 then InitMap(WebBrowser_T5); end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:07 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz