Google Earth ferngesteuert, Teil II

Google Earth in Ihrer eigenen Anwendung – angezeigt in einem ganz normalen Formular, das Sie nach Belieben mit Steuerelementen bestücken können, um durch die Gegend zu schwirren, Orte zu suchen, Details anzuzeigen oder gar Grafiken oder Texte unterzubringen Ja, das geht. Wir zeigen, wie es funktioniert und was Sie beim Einsatz des benötigten ActiveX-Steuerelements beachten müssen.

Vor einiger Zeit haben wir gezeigt, wie Sie Google Earth aus Access heraus automatisieren. Mithilfe der COM-Schnittstelle lassen sich Orte anfliegen, Daten auslesen, Ortsmarken setzen und vieles mehr. Auch mit den neueren Versionen der Software funktioniert diese Lösung nach wie vor. Die damals geäußerte Mutmaßung, Google werde im Laufe der Zeit das Objektmodell erweitern, hat sich aber leider nicht bestätigt. Stattdessen gibt es seit einigen Monaten ein Browser-Plugin von Google Earth, das Sie als ActiveX-Steuerelement in Access-Formulare einbinden und fernsteuern können.

Die Beispieldatenbank zum Beitrag Google Earth ferngesteuert (Shortlink 457) öffnet Google Earth im Webbrowser und steuert es über die Automationsschnittstelle fern. Eine solche Lösung lässt sich vielseitig einsetzen, um etwa Orte zu Kundendaten anzuzeigen. Das große Handicap der Lösung besteht jedoch darin, dass die zwei separaten Anwendungen – Access und Google Earth – viel Platz benötigen und ein sinnvolles Arbeiten somit eigentlich nur mit zwei Monitoren möglich ist.

Im Frühsommer erschien die erste Beta des Google Earth-Plugins V 4.3 – die Versionsnummer lehnt sich jeweils an die Version der Standalone-Anwendung an. Dabei handelt es sich um ein Steuerelement, das für den Einsatz in Webseiten gedacht ist und ähnlich arbeitet, wie die Satellitenansicht von Google-Maps. Während jene aber ein statisches 2D-Erscheinungsbild liefert, lässt sich die 3D-Weltkugel oder -karte im Plugin über Maus und Tastatur in gleicher Weise bewegen wie in der Google Earth-Anwendung.

Installation

Gerät man auf eine Webseite wie [1], die das Plugin eingebaut hat, so ist zunächst nichts Weltbewegendes zu sehen. Stattdessen fordert eine Grafik mit hinterlegtem Link dazu auf, das Plugin herunterzuladen. Tatsächlich ist dies die einzige Möglichkeit, das Plugin zu installieren; eine direkte Download-URL gibt es nicht.

Der Grund hierfür ist, dass Google eine kleine Setup.exe zwischenschaltet, die erst überprüft, ob sich eine Version des Plugins bereits auf dem System befindet und ob es sich um eine möglicherweise veraltete Version handelt. Nur diese Setup.exe kennt den Ort des aktuellen Pakets im Web, das dann im Folgenden automatisch heruntergeladen und installiert wird.

Nach einem Refresh der Webseite zeigt sich Google Earth im Plugin-Fenster. Im Internet-Explorer erscheint zuvor wahrscheinlich in der Meldungsleiste die Nachfrage, ob man das ActiveX-Steuerelement zulassen will. Diese Nachfrage führt auch schon zur Erkenntnis, dass es sich bei dem Plugin nur um ein ActiveX-Steuerelement handeln kann und nicht etwa um ein JavaScript-Gebäude wie bei Google-Maps.

Technik

Das ActiveX-Steuerelement selbst übernimmt nur einen kleinen Teil der Arbeit. Im Hintergrund werkelt eine vollständige Installation von Google Earth (geplugin.exe), die aber gegenüber der Standalone-Anwendung modifiziert ist. Das ActiveX-Control fungiert lediglich als Host für die eigentliche Anwendung.

Diese Arbeitsteilung ist nötig, damit das Plugin unabhängig von Browser und Plattform eingesetzt werden kann. So kommt etwa im Firefox ein anderes Plugin zum Einsatz, welches auf QWidgets statt ActiveX basiert. Auch dieses verwendet jedoch die gleiche Google Earth-Engine im Hintergrund.

Die Aufgabe des Plugins besteht also darin, die Interaktion zum Benutzer und zur Webseite (JavaScript) sicherzustellen sowie die 3D-Daten der Engine per DirectX zu rendern. Damit es per Scriptsprache steuerbar ist, muss es wohl eine Schnittstelle enthalten, die Anweisungen an die Google Earth-Engine weiterleitet. Für ein ActiveX-Control ist das die eingebaute Typbibliothek, welche sich in die Verweise eines VBA-Projekts einbinden lassen können sollte.

Wo aber befindet sich das ActiveX-Steuerelement Beim Stöbern durch die Verzeichnisse der Plugin-Installation – standardmäßig C:\Programme\Google\Google Earth Plugin – findet man einen Zweig IE, der die Datei plugin_ax.dll enthält. Und die ist das gesuchte ActiveX-Steuerelement.

Plugin im Access-Formular

Was als ActiveX-Control in Webseiten funktioniert, das sollte man auch in Access-Formularen im Entwurf über das Menü Einfügen | ActiveX-Steuerelement… verwenden können. Die Frage ist nur, wie das Steuerelement wohl heißt. Den Ausdruck Google… sucht man in der Liste der Steuerelemente vergeblich – das Control nennt sich etwas kryptisch GEPluginCoClass Object.

Das Einfügen ins Formular erfolgt problemlos. Das Steuerelement zeigt sich im Entwurf als weiße Fläche mit dem Schriftzug ATL 8.0, was lediglich den Schluss zulässt, dass es wahrscheinlich mit Visual Studio C++ 2005 entwickelt wurde.

Wer das Formular nun öffnet, wird zunächst enttäuscht. Das Steuerelement zeigt lediglich eine schwarze Fläche ohne Erdkugel. So einfach scheint es Google uns offenbar nicht machen zu wollen. Tatsächlich benötigt das Control erst Initialisierungscode, bevor es das tut, was wir von ihm erwarten.

Da die Schnittstelle des Controls in keiner Weise dokumentiert ist, da es schließlich für die Verwendung in Webseiten vorgesehen ist, die es über von Google eingeklinkte komplizierte JavaScripts steuert, hat das Ausklamüsern eines funktionierenden Initialisierungscodes speziell für die neue, Anfang April erschienene Version 5 etwas Kopfzerbrechen bereitet – dazu später mehr.

Lizenzfragen

An dieser Stelle muss darauf hingewiesen werden, dass der Einsatz des Controls unter Access nicht ganz im Sinne von Google ist. Es gibt eine Webseite [2], die Terms of Service, mit ausführlichen Informationen darüber, unter welchen Umständen Google Earth verwendet werden kann und darf.

Das dort angesprochene Google Earth API [3] besteht aus einem umfangreichen Satz von JavaScripts, die nach Angabe eines Keys von den Google-Servern nachgeladen werden und damit in eigene Webseiten integriert werden können.

Diesen Key bekommt man aber nur nach Registrierung des APIs bei Google, wenn auch kostenlos. Ein Key ist dabei immer einer bestimmten Domain oder einem Unterverzeichnis derselben zugeordnet. Über diese Kombination kann Google dann Nutzungsstatistiken erheben, und das ist wohl der Gegenwert, den Google für die freie Verwendung des Systems erwarten.

Nun braucht man unter Access aber kein JavaScript zur Steuerung des Plugins und damit entfällt auch die sonst notwendige Angabe eines Keys. Die Daten, welche die Google Earth-Engine von den Servern zieht, können damit nicht mehr dem Nutzer zugeordnet werden. Schlimmstenfalls ist die IP des Rechners bekannt.

Auch wenn für diese Situation keine klaren Handlungsanweisungen in den Terms of Service zu finden sind, kann man davon ausgehen, dass eine kommerzielle Nutzung ausgeschlossen ist. Google bietet jedoch eine Enterprise-Lizenz für Google Earth an, die gegebenenfalls zu erwerben wäre. Wie viel das kostet, ist offenbar Verhandlungssache, denn konkrete Preisangaben sucht man vergeblich.

Es ist also grundsätzlich wichtig, sich die Lizenzbestimmungen genauer anzusehen und selbst zu entscheiden, wie und unter welchen Umständen man das Plugin einsetzen möchte und darf.

Objektmodell

Wenn ein ActiveX-Steuerelement in ein Formular oder einen Bericht eingebaut wird, dann setzt Access bekanntlich automatisch einen Verweis auf die zuständige Objektbibliothek. Für das Google Earth-Steuerelement lautet der Name der Bibliothek GEPlugin. Öffnen Sie einfach den VBA-Objektkatalog (F2 im VBA-Editor) und wählen Sie diesen Eintrag aus dem linken oberen Kombinationsfeld aus.

War die KML-Bibliothek (Earthlib 1.0) für Google Earth so, wie sie im erwähnten Beitrag vorgestellt wurde, noch recht überschaubar, wird man hier von der Fülle der Schnittstellen und Methoden der GEPlugin-Library geradezu erschlagen.

Die Funktionalität erstreckt sich über Dutzende Klassen mit zahllosen Methoden und Eigenschaften. Das ist einerseits erfreulich, verspricht es doch ausgefeilte Steuerungsmöglichkeiten des Plugins, andererseits verwirrend, weil es keinerlei Dokumentation für das Objektmodell gibt.

Das jedoch ist auch nicht ganz richtig, wie sich herausstellte. Das Objektmodell ist eng an das des JavaScript-APIs gekoppelt, welches Sie sich unter [3] zu Gemüte führen können. Sowohl die Klassenbezeichnungen als auch die Methodennamen sind weitgehend identisch mit jenen im API.

Ihr besonderes Augenmerk sollte lediglich solchen Methodennamen gelten, die einen abschließenden Unterstrich aufweisen. Hier handelt es sich ausnahmslos um Funktionen, die spezifisch für das ActiveX-Plugin und nicht dokumentiert sind.

Das komplette Objektmodell von Google Earth zu erläutern, würde diesen Beitrag sprengen. Dazu brauchte man gut und gerne ein ganzes Buch. Daher der Verweis auf die API-Dokumentation [3] und auch auf die KML-Referenz [4], die im Gegensatz zum API genauer erklärt, wie die einzelnen Objekte einzusetzen und zu kombinieren sind.

Wer im Aufbau von KML-Dateien bewandert ist, einem Google Earth-spezifischen XML-Schema, der wird das Objektmodell schneller verstehen. Die in der Beispieldatenbank GoogleEarther5.mdb enthaltenen Routinen sollten darüber hinaus hinreichend Ausgangsmaterial für die weitere Programmierung und Erforschung des Steuerelements enthalten.

Plugin vs. Google Earth-Automatisierung

Eingangs wurde bereits der größte Vorzug genannt: Man braucht mit dem Plugin nicht mehr zwei Anwendungen, die sich den Monitor teilen oder gar Umschalten notwendig machen, sondern hat nur noch ein Access-Formular vor sich. Das enthaltene GE-Steuerelement lässt sich, je nach Anforderungen, auch per Code auf beliebige Abmessungen bringen (Width, Height).

Was im ferngesteuerten Google Earth nur mit Verrenkungen möglich war, etwa das Setzen von Ortsmarken oder das Zeichnen von Polygonen, lässt sich nun per Objektmodell erledigen. Früher musste zu diesem Zweck erst langwierig ein XML-String zusammengesetzt werden. Nun bildet sich dessen Hierarchie in Klassen und Eigenschaften ab, die man setzen sowie ab- und aufrufen kann.

Der absolute Clou ist jedoch die Möglichkeit, auf Ereignisse des Steuerelements zu reagieren. Das ist mit der Fernsteuerlösung schlicht unmöglich. Sowohl die Erdoberfläche wie auch jedes angelegte Objekt auf ihr ruft Mausereignisse hervor, die abgefangen und behandelt werden können. Ein Klick auf eine gesetzte Ortsmarke ruft eben ein Click-Ereignis hervor, das Bewegen der Maus über die Oberfläche zeitigt MouseMove-Ereignisse und der Fortschritt des Renderns löst ein Frame-Ereignis aus.

Und schließlich lässt sich ein Screenshot des Plugins in einem Formular auch leichter bewerkstelligen als in einer Fremdanwendung.

Plugin-Demo

Die neue Anwendung GoogleEarther5.mdb orientiert sich zunächst an jener des eingangs erwähnten Beitrags. Sie finden hier ein gleichartiges Kundenformular, das die Kunden der Nordwind-Datenbank anzeigt. Statt des seinerzeit eingesetzten MSForms-Bildsteuerelements kommt nun aber das Google Earth-Steuerelement ins Spiel, das im Current-Ereignis unmittelbar zur Adresse des Kundendatensatzes navigiert.

Daneben gibt es noch ein Formular namens frmGEPlugin, das einige der möglichen Features des Steuerelements demonstrieren soll. Beim Start der Datenbank wird aber zunächst automatisch das Formular frmStart geladen. Es hat die Aufgabe zu ermitteln, ob das Plugin überhaupt schon in korrekter Version auf dem Rechner installiert ist. Sollte das der Fall sein, dann schließt es sich sang-und klanglos wieder, bevor es überhaupt sichtbar wurde.

Andernfalls meldet es, wie die notwendige Installation erfolgen kann (siehe Bild 1). Die Anwendung erwartet zwingend die neue Version 5 (April 2009), weil die Objektbibliothek nicht mehr kompatibel zur Version 4 (Mai 2008) ist. Sollten Sie bereits irgendwann Version 4 installiert haben, so ist es ratsam, diese zuerst über die Systemsteuerung zu deinstallieren, bevor die neue Version aufgespielt wird. Der Startcode im Formular ist ziemlich simpel:

frmStart.png

Bild 1: Das Startformular erscheint, falls das Plugin nicht in der entsprechenden Version installiert ist.

Dim objGE As Object
Set objGE = µ
CreateObject("GEPluginCoClass.GEPluginCoClass")

Hier wird über late binding versucht, eine Instanz des Plugins zu erhalten. Dazu bedarf es noch gar keines im Formular enthaltenen ActiveX-Steuerelements, das ohnehin zur Fehlermeldung Dieses Formular enthält kein Steuerelement beim Öffnen führen würde.

Lässt sich eine Instanz erstellen, dann ist das Plugin offensichtlich installiert. Im nächsten Schritt erfolgt jedoch noch eine Überprüfung auf die passende Version, was diese Zeilen erreichen:

strVersion = objGE.getPluginVersion
If Val(strVersion) < 5 Then...

Das Objekt GEPluginCoClass kennt eine Funktion getPluginVersion, welche die Dateiversionsnummer der plugin_ax.dll zurückgibt – aktuell etwa 5.0.11655.6079. Wichtig ist nur die erste Zahl, die die Hauptversion wiedergibt und daher einfach mit Val() ermittelt wird. Waren die Tests erfolgreich, dann öffnet der weitere Code das Formular frmGEPlugin.

Bis dieses sichtbar geladen ist, dürfte aber noch einige Zeit verstreichen, die mit einem in die Beispieldatenbank integrierten Meldungsformular überbrückt wird.

Diese Zeit benötigt das Plugin nämlich für seine Initialisierung. Machen Sie sich bewusst, dass dazu im Hintergrund ein komplettes Google Earth geladen werden muss, welches in Gestalt der geplugin.exe im Hauptverzeichnis des Plugins zu finden ist. Die Initialisierung geht zwar schneller vonstatten als bei der Standalone-Version, auf 5-10 Sekunden müssen Sie sich aber schon einrichten.

Interessant ist der Sachverhalt, dass nach Schließen des Formulars frmGEPlugin und erneutem Öffnen die Initialisierung blitzschnell abläuft. Sie müssen also nicht befürchten, dass bei jedem Öffnen des Formulars eine Wartepause einzulegen ist. Einfache Erklärung: Ein Schließen des Plugins führt noch nicht automatisch zum Beenden der Engine geplugin.exe im Hintergrund. Eine neue Instanz des Plugins kann daher schnell auf den noch bestehenden Prozess zugreifen. Das zeigt sich auch darin, dass bei erneutem Öffnen nicht etwa wieder die Erdkugel erscheint, wie in Bild 2, sondern der zuletzt im Plugin angezeigte Ort.

frmDemo1.png

Bild 2: Demoformular zum Google Earth-Plugin

Das Entladen der geplugin.exe geschieht nach meinen Erfahrungen erst nach ca. 30-40 Sekunden. Einfluss hat man darauf nicht. Die geplugin.exe arbeitet also in der Art eines autonomen zeitgesteuerten Services. Das Demo-Formular (siehe Bild 2) enthält zahlreiche Steuerelemente, über die auf das Plugin eingewirkt werden kann.

Dabei enthält die Formularklasse nur relativ wenig Code. Der größte Teil ist nämlich in die Klasse clsGEPlugin ausgelagert, die einen Wrapper für das Steuerelement darstellt. Ein solches Klassenmodul ist empfehlenswert, weil die direkte Programmierung des Controls doch etwas aufwendig ist. Einmal erstellt, kann es in beliebige Anwendungen integriert werden und hält den restlichen benötigten Code in Grenzen.

In der aktuellen Ausbaustufe der Wrapper-Klasse ist nicht viel mehr als das Notwendigste implementiert. Einige umfangreichere Prozeduren verdeutlichen zusätzlich, wie über das Objektmodell in Anlehnung an das KML-Schema neue Objekte auf die Erdoberfläche gebracht werden können.

Sie können die Klasse aber für Ihre Zwecke gern aufbohren. Anregungen dazu bietet die API-Dokumentation [3] genügend. Im Folgenden sollen einige der Prozeduren der Wrapper-Klasse näher beleuchtet werden.

Wrapper clsGEPlugin

Damit eine Instanz der Klasse mit einem GEPlugin in einem Formular kommunizieren kann, besitzt es eine Objektreferenz in Form der Variablen objGE. Sie ist modulweit gültig und das entscheidende Objekt der Klasse. Sie wird über die Klasseneigenschaft GEObject gesetzt:

Property Set GEObject(obj As GEPluginCoClass)
Set objGE = obj
End Property

Nennt sich das Steuerelement im Formular etwa ctlGEPlugin und die Instanz des Wrappers objGEC, dann lautet eine Zuweisung so:

Set objGEC.GEObject = Me!ctlGEPlugin.Object

Damit ist freilich noch nichts gewonnen. Das zunächst schwarze Plugin füllt sich erst mit Leben, nachdem die Prozedur InitializeGE aufgerufen wurde. Der Trick bei der Initialisierung des Steuerelements ist das Timing, mit welchem bestimmte Methoden abgesetzt und abgefragt werden.

Die erste benötigte Methode lautet:

objGE.start_("")

Ohne diese Anweisung geschieht rein gar nichts. Ebenso obligatorisch ist die folgende Initialisierungsmethode objGE.SetMainDatabase. Sie ist in Version 5 neu und gibt einige Rätsel wegen der enthaltenen Parameter auf:

Sub setMainDatabase_(mainDatabaseURL As String, µ
    userName As String, password As String)

Hier war zunächst vermutet worden, dass Google nunmehr irgendwelche Zugangsschranken eingebaut hätte, denn egal, was für die (unbekannten) Parameter eingesetzt wurde, der Methodenaufruf löste immer einen Fehler aus.

Tatsächlich ist aber nicht der Inhalt der Parameter dafür verantwortlich, sondern der Zustand der Engine im Hintergrund. Diese nimmt die Methode offenbar erst ab einem unklaren Zustand entgegen, dafür dann jedoch erfreulicherweise mit schnöden Leerstrings als Parameter. Der Erfolg des Aufrufs wird daher in einer Zeitschleife abgefragt.

Auch dann ist das Steuerelement aber noch nicht bereit. Erst, wenn die Funktion objGE.testEarthFullyInitialized_ den Wert 0 zurückgibt, können weitere Methoden an das Steuerelement abgesetzt werden. Versucht man das schon früher, dann wird man regelmäßig mit der Fehlermeldung Die Methode … des Objekts _GePluginCoClass schlug fehl konfrontiert.

Im Anschluss setzt InitializeGE noch einige Eigenschaften des Plugins wie etwa die Sichtbarkeit:

    objGE.GetWindow.setVisibility 1

Unterbleibt dies, ist im Steuerelement nämlich ebenso nichts zu sehen. Setzen Sie später setVisibility auf 0, dann wird die Erdkugel wiederum ausgeblendet.

Es wurde erwähnt, dass das Steuerelement auch Ereignisse auslösen kann. Das geschieht jedoch nicht standardmäßig. Jedes Ereignis muss grundsätzlich erst aktiviert werden:

    objGE.getGlobe.onMousemoveEventEnabled 1

Hier wird angewiesen, dass die Erdkugel beim Überfahren mit der Maus Ereignisse ausgeben soll. Das entspricht etwa dem, was Sie auch schon von Access kennen: Ein Steuerelement erzeugt erst dann ein MouseMove-Ereignis, wenn dessen Eigenschaft OnMouseMove auf den String-Wert [Event Procedure] gesetzt wurde. Ein anderes nützliches Ereignis ist dieses:

    objGE.onFrameendEventEnabled 1

Das aktiviert die Fortschrittsereignisse beim Rendern der Erdoberfläche. Um den prozentualen Fortschritt zu erhalten, muss dazu allerdings noch eine Eigenschaft in der ausgelösten Ereignisprozedur abgefragt werden:

    Debug.Print objGE.getStreamingPercent

Übrigens zeigt sich während des gesamten Initialisierungsvorgangs optional die oben erwähnte Wartemeldung. Verantwortlich dafür ist das Formular frmMsg, welches von der Routine anfangs geöffnet wird.

Nachdem InitializeGE durchlaufen ist, sollte im Plugin-Fenster die Weltkugel erscheinen. Das Plugin ist nun bereit, um weitere Anweisungen entgegenzunehmen.

Anfliegen

Kümmern wir uns nun darum, wie man einen beliebigen Ort der Erde ansteuern kann. Die einfachste Variante besteht in der Übergabe von Breiten- und Längengrad an die Funktion GotoLoc der Wrapper-Klasse.

Welcher Ausschnitt der Erde im Plugin-Fenster zu sehen ist, das bestimmt eine Kamera, welche als KmlCameraCoClass ihre Entsprechung im Objektmodell findet. Leider kann man nicht einfach die Parameter Latitude und Longitude dieser Kamera einstellen. Genau genommen gibt es noch nicht mal eine öffentlich zugreifbare Kamera, sondern nur ein Kopieobjekt über das View-Objekt des Plugins:

    Dim objCam As KmlCameraCoClass
    Set objCam = objGE.getView.copyAsCamera(1)

Die Eigenschaften dieses Objekts können nun gesetzt werden:

    objCam.setLatitude <Breitengrad, Double>
    objCam.setLongitude <Längengrad, Double>
    objCam.setAltitude <Höhe über Erdboden, Double>

Da es sich bislang nur um ein Objekt im Speicher handelt, steuert das Setzen dieser Eigenschaften noch nicht die Plugin-Kamera selbst. Das muss man explizit veranlassen, indem die Kamerakopie dem Plugin zugewiesen wird:

    objGE.getView.setAbstractView objCam

Adressen finden

Nun werden Längen- und Breitengrad einer Adresse meist nicht bekannt sein. In der Google Earth-Standalone-Anwendung gibt es das SearchController-Objekt, über das man aus einem Adresstext die Koordinaten eines Feature-Objekts ermitteln kann – Google Earth bedient sich dabei offenbar des gleichen Servers wie Google Maps.

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar