Die hier beschriebene Programmierschnittstelle ermöglicht die
vereinfachte Programmierung einer Verbindung zwischen Bausteinen des
MOBILE-Kernsystem einerseits und dem Geographischen Informationssystem
ArcView andererseits. Vorausgesetzt wird die Kenntnis des allgemeinen
Leitfadens zur Programmierung eines Bausteins für die ObjectBase,
er findet sich unter[Müg97].
Desweiteren wird die Kenntnis der Programmiersprache Java sowie der
ArcView-eigenen Programmiersprache Avenue vorausgesetzt. Zur Programmierung in
Avenue siehe Abschnitt Eigenschaften der Programmiersprache Avenue, S.69
sowie[ESR94c] und[ESR95b]. Zur Programmierung in Java siehe[Sun98].
Ein Beispiel für die Umsetzung dieses Leitfadens befindet sich im
nächsten Abschnitt, Die Kopplung des SimpleEmissionModel mit ArcView
als Anwendungsbeispiel der Schnittstelle ab S. 126.
Ich empfehle zum Zweck der Programmierung die Benutzung der unter
verfügbaren Dokumentation der Java-Klassen und Avenue-Scripte, die auch
als Quelltexte vorliegen (s.[Hup98] und[Hup98a]).
Grundsätzlich ist ein Baustein mit GIS-Kopplung zunächst einmal ein
atomarer Baustein der MOBILE-ObjectBase und muß als solcher von
einer der Bausteinklassen
* Generator (Datenquelle),
* Evaluator (Auswertungsmethode),
* Simulator (Simulationsmodell) oder
* Recorder (Datensenke)
abgeleitet werden und den in oben genanntem allgemeinen Leitfaden aufgestellten
Spezifikationen entsprechen.
Für jeden Baustein mit GIS-Kopplung muß im GIS ArcView ein dazu
korrespondierendes Avenue-Script programmiert werden.
Zwischen dem MOBILE-Kernsystem und ArcView können alle
konvertierbaren MSL-Daten-Typen ausgetauscht werden. Konvertierbar in
diesem Sinne sind alle jenen MSL-Daten-Typen, für die die vier in den
Zeilen 1, 2, 5 und 6 der Tab. 4 aufgeführten Konverter implementiert sind.
Für einige, die extrizierbaren MSL-Daten-Typen, existieren zudem
die in den Zeilen 3 und 4 dieser Tabelle genannten Konverter, die die
Programmierung des Zugriffs auf die MSL-Daten-Objekte erleichtern.
Extrizieren bedeutet die nicht informationserhaltende Konvertierung
eines MSL-Daten-Objektes aus der Avenue-Repräsentation in ein
möglichst ähnliches Avenue-Objekt. Der umgekehrte Vorgang, die
Erstellung der Avenue-Repräsentation aus einem Avenue-Objekt unter
Zuhilfenahme von Standardannahmen nennt sich intrizieren (vgl.
Abschnitt Realisierung, Datenfluß, S.101).
Der Austausch von Daten geschieht zusammen mit der Ausführung des
korrespondierenden Avenue-Scripts durch einen Aufruf der Methode
Mobile.GIS.ArcView.ArcView.executeScript().
Zusammen mit dem Namen des Avenue-Scripts kann der Name des ArcView-Projekts
angegeben werden, in dem es sich befindet. Der Projektname muß die
Angabe des Pfades, in dem es sich befindet, mit enthalten. Der Standardpfad
wird über die Methode
Mobile.GIS.ArcView.Paths.getProjectPath()
zur Verfügung gestellt, zur genauen Verwendung siehe die etwa die
Datenquelle TrafficFlowAndVelocity oder die Java-Dokumentation.
Wird kein Projektname mit angegeben, so wird vorausgesetzt, daß sich das
Projekt im Standardpfad befindet und den gleichen Namen wie das Avenue-Script
trägt.
Es dürfen innerhalb eines Bausteins sowohl mehrere verschiedene
Avenue-Scripte aufgerufen werden als auch der Aufruf eines Scripts auch
mehrfach innerhalb eines Bausteines erfolgen. So wird in der
Beispiel-Datenquelle TrafficFlowAndVelocity das korrespondierende
Avenue-Script gleichen Namens innerhalb einer alle Stunden des Tages
durchlaufenden while-Schleife für jede Stunde einmal
aufgerufen.
Zu beachten ist in jedem Fall, daß ein Projekt nur einmal je
Durchführung des höchsten Experiments[20] geladen wird, deshalb müssen eventuell nötige
Initialisierungen darauf Rücksicht nehmen. Der Zustand, wie oft ein Script
während eines Experiments bereits aufgerufen wurde, darf dazu in globalen
Variablen vermerkt werden, ansonsten sollten globale Variablen möglichst
vermieden werden. Kann nicht auf sie verzichtet werden, so sollten sie nach
Beendigung des Scripts gelöscht werden, indem ihnen vor dem Ende des
Scripts der Wert NIL zugewiesen wird.
Der Avenue-Befehl av.clearGlobals darf nicht verwendet werden,
da er auch die globalen Variablen löschen würde, die zur Verwaltung
des MOBILE-Systems benutzt werden. Um Namenskonflikte mit globalen Variablen
anderer Scripte zu vermeiden, müssen die Namen aller globalen Variablen
aus dem obligatorischen Unterstrich und dem Namen des Avenue-Scripts bestehen.
Die
Klassen des Java-seitigen Teils der Programmierschnittstelle sind
* Mobile.GIS.ArcView.ArcView
* Mobile.GIS.ArcView.ParameterList
* Mobile.GIS.ArcView.Paths
Der Kürze halber werden Methoden über ihren Klassennamen, nicht aber
über den Packagenamen angegeben, soweit dies eindeutig ist.
Die Methode ArcView.executeScript() veranlaßt die
Ausführung eines Avenue-Scripts im GIS ArcView. Die dafür notwendigen
Initialisierungen ArcViews werden verborgen ausgeführt. Insbesondere
braucht ArcView nicht gestartet zu sein. Es sollte kein Projekt geöffnet
sein.
Um festzulegen, welche MSL-Daten-Objekte an das korrespondierende Avenue-Script
übermittelt werden sollen, wird neben seinem Namen und gegebenenfalls dem
Projektnamen ein Java-Objekt vom Typ ParameterList an
ArcView.executeScript() übergeben.
Die zu übergebenden MSL-Daten-Objekte[21]
werden vor dem Aufruf mittels ParameterList.add() unter Angabe ihres
Namens der Parameterliste hinzugefügt. Als Name wird am besten der
Bezeichner der Objektvariable in Java gewählt. So kann leicht Java- wie
Avenue-seitig ein in Bezug auf die MSL-Daten-Objekte gleicher Namensraum
hergestellt werden. Im Beispiel TrafficFlowAndVelocity wird das Objekt
streetLength unter dem Namen "streetLength" der
Parameterliste parameterList hinzugefügt. Im korrespondierenden
Avenue-Script kann eine ebenso bezeichnete Variable erzeugt werden, die ihren
Wert unter Angabe des Namens "streetLength" (identische,
grossschreibungssignifikante Schreibweise) aus der übermittelten
Parameterliste erhält. Die Übermittlung selbst bleibt in dieser
Sicht verborgen.
Nach der Ausführung des Avenue-Scripts gibt die Methode
executeScript()
wiederum ein Objekt vom Typ ParameterList zurück. Um auf dieses
zu verweisen, kann im allgemeinen von derselben
ParameterList-Variable, im genannten Beispiel parameterList,
Gebrauch gemacht werden. Wenn sie innerhalb einer Schleife verwendet wird, so
ist zum Beispiel durch instantiieren eines neuen
ParameterList-Objektes sicherzustellen, daß sich keine
MSL-Daten-Objekte mehr in dem von der Variable referenzierten
ParameterList-Objekt befinden, die für den vorhergehenden Aufruf bestimmt
waren oder von ihm stammen, da sie sonst erneut bzw. zusätzlich mit
übertragen würden.
Tritt während der Ausführung des korrespondierenden Avenue-Scripts
oder in der damit verbundenen Datenübertragung ein Fehler auf, so wird
dieser Fehler bereits von
ArcView.executeScript() an MobileErrorHandling
übergeben, so daß er nicht zusätzlich abgefangen zu werden
braucht.
Nach der Ausführung des Avenue-Scripts können die
zurückgegebenen MSL-Daten-Objekte vermittels parameterList.get()
entnommen werden, etwa als
streetLength = parameterList.get("streetLength")
Diese können sowohl im Baustein selbst noch verarbeitet werden oder
über OutputPorts an andere Bausteine weitergegeben werden.
Dieser
Teil der Programmierschnittstelle besteht aus den Avenue-Scripten
* MobileReadAll,
* MobileWriteAll,
* MobileError und
* MobileImportProject
sowie einer Reihe von Avenue-Scripten, deren Namen mit
* "MobileIntricate" bzw.
* "MobileExtricate"
beginnen und verwendet darüberhinaus Avenue-Datentyp Dictionary.
Weil es für Avenue kein so komfortables Dokumentationstool wie
Javadoc für Java gibt, sind die kommentierten Quelltexte unter
[Hup98] im WWW verfügbar gemacht.
Zunächst einmal soll der prinzipielle Aufbau eines Avenue-Scripts, das
diese Programmierschnittstelle verwendet, erläutert werden.
Als erstes erfolgt der Aufruf des Avenue-Scripts MobileReadAll, das im
Rahmen des Transfers der MSL-Daten-Objekte vom Mobile-Kernsystem zum GIS
ArcView der Konvertierung aus der Java-Repräsentation in die
Avenue-Repräsentation dient.
parameterList = av.Run("MobileReadAll", SELF)
Die Parameterliste ist vom Avenue-Datentyp Dictionary und kann mittels
get(aString) ein Objekt des angegebenen Namens zurückgeben,
sofern es ein Objekt dieses Namens enthält (s. "Dictionary" in
[ESR95b]) . In der folgenden Programmzeile wird das MSL-Daten-Objekt
streetName unter Angabe seines Namens, den es Java-seitig bekommen
hat, aus der Parameterliste parameterList entnommen.
streetName = parameterList.get("streetName")
streetName enthält dann die Avenue-Repräsentation des
MSL-Daten-Objektes. An dieser Stelle kann die Umwandlung der
Avenue-Repräsentation in ein Objekt mit möglichst ähnlichem
Avenue-Typ erfolgen.
Die Namenskonvention ist, dem entsprechenden Avenue-Objekt denselben Bezeichner
zuzüglich "AvD" (Avenue-Daten-Typ) zu geben. Der Name des Avenue-Scripts,
das die Umwandlung aus der Avenue-Repräsentation in ein Avenue-Objekt
vornimmt, setzt sich aus "MobileExtricate" und dem Typ des
MSL-Daten-Objekts zusammen, in diesem Beispiel also
streetNameAvD =
av.Run("MobileExtricateText",streetName)
Es gibt jedoch nicht für alle konvertierbaren MSL-Daten-Objekte ein noch
sinnvoll ähnliches Avenue-Objekt und daher auch kein
"MobileExtricate...".
Eine Liste der extrizierbaren MSL-Daten-Typen ist dem Abschnitt Umwandlung
von MSL-Daten-Objekten in Avenue-Objekte (S. 116) zu entnehmen.
Ist die Umwandlung der übergebenen MSL-Datenobjekte abgeschlossen, so
folgt als nächstes die Berechnung der Rückgabeparameter. Hierzu steht
prinzipiell die gesamte Funktionalität des GIS ArcView bzw. der
Programmiersprache Avenue zur Verfügung.
Da in den Bausteinen keine Benutzerinteraktion stattfinden soll, sind die
korrespondierenden Avenue-Scripte so zu programmieren, daß sie nicht auf
Eingriffe der BenutzerIn angewiesen sind. Auch Fehlermeldungen sollen nicht
direkt in ArcView auf dem Bildschirm erscheinen, sondern mittels des
Avenue-Scripts MobileError an das MOBILE-Kernsystem übertragen
werden. Diese werden dann Java-seitig an Mobile.Errorhandling
weitergeleitet.
Werden Daten oder weitere Avenue-Scripte für die Ausführung des
korrespondierenden Avenue-Scripts benötigt, die sich nicht im selben
ArcView-Projekt befinden, so ist das ArcView-Projekt zunächst zu
importieren. Dazu muß das Avenue-Script MobileImportProject
verwendet werden. Projekte werden auf diese Art nicht mehrfach importiert, da
es eine Liste bereits importierter Projekte fortschreibt. Es ist zu beachten,
daß deshalb möglicherweise nicht mehr alle Daten in dem Zustand
sind, der beim Start des Experiments vorlag. Soll dies sichergestellt werden,
so ist mit einer Kopie zu arbeiten.
Wenn alle erforderlichen Aktionen in Avenue ausgeführt sind, so
müssen gegebenenfalls zurückzugebende Werte in die
Avenue-Repräsentation überführt werden. Dies kann für
einige Typen von Avenue-Objekten durch MobileIntricate erzielt werden.
Welche Typen intrizierbar sind kann dem Abschnitt Umwandlung von
MSL-Daten-Objekten in Avenue-Objekte (S. 116f) entnommen werden. Die
Liste der intrizierbaren Avenue-Typen ist im wesentlichen das Pendant zu der
Liste der extrizierbaren Avenue-Typen. Da es in Avenue keine 3D-Punkte gibt,
gibt es auch keine
MobileIntricatePoint3D.
Sollen konvertierbare MSL-Daten-Objekte zum MOBILE-Kernsystem
zurückgegeben werden, die nicht intrizierbar sind, so muß die im
Abschnitt Repräsentation der MSL-Datentypen in Avenue
(S. 112f) beschriebene Struktur der Avenue-Repräsentation direkt
aufgebaut werden.
Für den nicht intrizierbaren MSL-Daten-Typen Length ist dies wie folgt
durchzuführen:
' streetLengthAvD ist ein Avenue-Objekt vom Typ Number
' streetLength soll die Avenue-Repräsentation eines
' MSL-Length-Objekts werden.
' Die Maßeinheit m steht für Meter
streetLength = {"Length", streetLengthAvD, "m"}
Vor dem Transfer der Rückgabeparameter müssen die
Avenue-Repräsentationen der MSL-Daten-Objekte der
Rückgabeparameterliste hinzugefügt werden, die in Avenue ein Objekt
vom Typ Dictionary ist.
Dieses Dictionary muß zunächst instantiiert werden. Der
Konstruktor Dictionary.make() verlangt die Angabe der maximal in das
Dictionary einzusetzenden Elemente, in diesem Fall eines:
returnParameterList = Dictionary.Make(1)
Anschließend muß jeder Rückgabeparameter unter Angabe seines
Namens in die Rückgabeparameterliste eingesetzt werden. Auch hier gilt
die Namenskonvention, daß der Name, unter dem ein MSL-Daten-Objekt in die
Rückgabeparameterliste eingefügt wird, der gleiche sein soll, wie der
Objekt-Bezeichner in Avenue und der Bezeichner des Java-Objekts, das der Liste
Java-seitig entnommen wird.
returnParameterList.add("streetLength ",
streetLength)
Zum Schluß des korrespondierenden Avenue-Scripts wird das Avenue-Script
MobileWriteAll aufgerufen. Es dient dem Transfer der
Rückgabeparameter vom GIS ArcView zum MOBILE-Kernsystem.
av.Run("MobileWriteAll", returnParameterList)
Die Rückgabeparameter können, wie oben bereits erwähnt,
Java-seitig wieder aus der Liste entnommen werden.
[20] Das höchste Experiment ist dasjenige
Experiment, das während des aktuellen Experimentlaufs nicht Teil eines
anderen Experiments ist.
[21] genaugenommen ihre
Java-Repräsentationen, also die von Mobile.MSL.MSLData
abgeleiteten Klassen instantiierten Java-Objekte