Schnittstellen für den Austausch von GIS-Daten (GIS = Geographisches Informations System) werden heute meist als C/C++, BASIC- oder FORTRAN-Programme kodiert. Der Programmieraufwand für die Erstellung einer Schnittstelle ist vor allem im Bereich der GIS-Systeme gross, da neben Sachdaten auch Geometriedaten übertragen werden müssen. Dies führt dazu, dass von den GIS-Systemherstellern nur relativ wenige Schnittstellen (häufig DXF) mit begrenztem Funktionsumfang angeboten werden.
Mit der Entwicklung von ICS wurde ein anderer Weg beschritten. Bei ICS handelt es sich um ein erweiterbares Schnittstellensystem für die schnelle Entwicklung von GIS-Schnittstellen. Folgende Ideen lagen der Entwicklung von ICS zugrunde:
Jedes Schnittstellenprogramm kann in einen Input- und in einen Outputmodul zerlegt werden. Dabei liest der Inputmodul Objekte aus der Inputdatei und wandelt sie in ein neutrales internes Objektformat um. Der Outputmodul nimmt Objekte vom Inputmodul entgegen und schreibt sie in die Outputdatei. Damit wird eine Entkoppelung des Schnittstellenprogramms in zwei unabhängige, wiederverwendbare Module erreicht.
Im Kern werden die Funktionen zusammengefasst, die von allen Modulen benötigt werden (z.B. String- und Geometriefunktionen). Dadurch müssen diese Funktionen nur einmal programmiert werden.
Der Datenfluss der Objekte vom Inputmodul zum Outputmodul wird nicht durch ein fix kodiertes Programm gesteuert, sondern über die Skriptsprache iG/Script.
Nachfolgend ist die Architektur einer ICS-Schnittstelle dargestellt:
![]() | |
Der Kern und die Input- bzw. Outputmodule werden von der infoGrips GmbH entwickelt. iG/Script-Konfigurationen können auch vom Benutzer geschrieben werden. |
Der ICS-Kern enthält neben den allgemeinen Funktionen für die Behandlung von Datenstrukturen (Strings, Geometrie, Maps etc.) einen Interpreter für die Sprache iG/Script. iG/Script ist eine allgemeine Programmiersprache mit einem vordefinierten Satz von Standardfunktionen. Die Sprache enthält neben arithmetischen-, logischen- und Zuweisungsoperationen, Kontrollstrukturen wie IF und WHILE. Daneben bietet sie die Möglichkeit, den Sprachumfang durch Prozeduren zu erweitern. Als Basistypen kennt die Sprache iG/Script die Typen Integer, Real, String, Boolean und Geometrie. Strukturierte Datentypen können über den Datentyp Map und List erzeugt werden. Input- bzw. Outputmodule können, falls nötig, zusätzliche Datentypen implementieren.
Zu bestehenden Programmiersprachen ist iG/Script am ehesten mit der Programmiersprache FORTH verwandt. Mit FORTH verbindet sie, dass sie ebenfalls alle Operationen über einen Stack abwickelt und eine klammerfreie Darstellung von Ausdrücken verwendet. Der wesentliche Unterschied zwischen FORTH und iG/Script liegt darin, dass FORTH für die hardwarenahe Programmierung entwickelt wurde, iG/Script hingegen ist eine hardwareunabhängige Sprache, die sich besonderst für die Entwicklung von Schnittstellenapplikationen eignet.
iG/Script ist im iG/Script Benutzer- und Referenzhandbuch detailliert beschrieben.
Jeder ICS Konfigurationsscript besteht aus folgenden Skriptteilen:
Der .cfg Konfigurationsdatei, welche alle Konfigurationsparameter enthält und den Datenfluss der Schnittstelle regelt.
Den (optionalen) .out Dateien, welche benutzerdefinierte iG/Script Prozeduren enthalten.
Den .lib Dateien, welche nützliche Sammlungen von iG/Script Prozeduren enthalten.
Den .mod Dateien, welche Input-, Output- oder Verarbeitungsmodule implementieren.
Dem Verarbeitungsalgorithmus RUN1.
Will ein Benutzer eine ICS Konfiguration erstellen, so muss er eine .cfg Datei und allenfalls eine oder mehrere .out Datei erzeugen. Die übrigen Konfigurationsteile (d.h. .lib, .mod und .prg Dateien) werden von der infoGrips GmbH zur Verfügung gestellt, und sind vollständig in diesem Handbuch dokumentiert. Nachfolgend ist die Aufteilung einer ICS Konfiguration in ihre Skriptteile dargestellt:
Die benutzerdefinierbaren Konfigurationsteile sind in den nächsten Abschnitten beschrieben. Die Beschreibung der von der infoGrips GmbH zur Verfügung gestellten Komponenten ist in den Anhängen dieser Dokumentation enthalten.
Die .cfg Datei enthält folgende Konfigurationsteile:
Die Angabe der Lizenzinformationen.
Die Definition des Benutzerinputs.
Die Parameter für die Input-, Output- bzw. Verarbeitungsmodule.
Die Definition der Inputquellen.
Die Festlegung des Verarbeitungsablaufs.
Die Angabe der benötigten Skriptbibliotheken.
Die Angabe der benötigten Input-, Output- und Verarbeitungsmodule.
Die Angabe der verwendeten Benutzerprozeduren.
Die Angabe des Verarbeitungsalgorithmus RUN1.
Nachfolgend ist ein typisches Beispiel einer .cfg Datei dargestellt, an welchem die einzelnen Konfigurationsteile kurz vorgestellt werden:
!===============================================================! ! ! ! INTERLIS => TEXT Configuration Vers. 1.0 ! ! ! !===============================================================! !<1> |LICENSE \license\iltoolspro.lic |LICENSE \license\iltools.lic !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! user input ! !<2a> MAP USER_INPUT1 DIALOG => FILE ! FILE | STRING | ODBC MESSAGE => 'Enter .itf Input File' FILE_FILTER => itf FILE_EXISTS => TRUE OPT => input END_MAP !<2b> MAP USER_INPUT2 DIALOG => FILE ! FILE | STRING | ODBC MESSAGE => 'Enter .txt Output File' FILE_FILTER => txt FILE_EXISTS => FALSE OPT => output END_MAP !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! parameter maps for intput modules ! !<3a> MAP ILIN_PARAM INTERLIS_DEF => \models\Grunddatensatz.ili LOG_TABLE => ON TRACE => OFF STATISTICS => ON VALUE_CHECK => OFF ENUM_TO_TEXT => ON END_MAP !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! parameter maps for output modules ! !<3b> MAP TXTOUT_PARAM STATISTICS => ON END_MAP !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! input sources ! !<4> MAP INPUT_SOURCES I1 => ILIN,OPT.input END_MAP !++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! classification ! !<5> MAP INOUT I1 => IN.TOPIC,IN.TABLE I1,Fixpunkte,LFP => Fix_Punkt0 I1,Fixpunkte,LFP3 => Fix_Punkt0 I1,* => OFF END_MAP !<6> |INCL \script\util.lib !<7> |INCL \script\ilin.mod |INCL \script\txtout.mod !<8> |INCL \script\il2txt\Grunddatensatz.out !<9> |INCL \script\run1.prg
Erläuterungen zu den einzelnen Konfigurationsteilen:
Mit der |LICENSE Direktive werden die von der
Konfiguration benötigten Lizenzen angegeben. Es können mehrere
Lizenzdateien angebeben werden, wenn die Konfiguration unter
verschiedenen Lizenzen lauffähig ist (z.B. INTERLIS Tools und INTERLIS
Tools Professional). Falls diese Angaben vergessen werden, bricht die
Konfiguration zur Laufzeit mit einer Fehlermeldung ab (no
license found for ...).
Die meisten Konfigurationen verlangen vom Benutzer interaktive
Eingaben (z.B. Auswahl der Inputdatei bzw. Angabe der Outputdatei).
Mit den USER_INPUTx Maps können beliebig viele
Parameter interaktiv vom Benutzer abgefragt werden (s.a. Abschnitt 2.4.1, „Abfrage von Benutzerparametern“).
Alle Input-, Output- und Verarbeitungsmodule benötigen diverse
Parameter, z.B. die Angabe des Datenmodells für einen INTERLIS 1
Outputmodul. Die Parameter für die diversen von der Konfiguration
benötigten Module werden in den <MODUL>_PARAM
Maps definiert. Alle Parameter der einzelnen Module sind im Anhang
beschrieben. Einige Module benötigen neben der
<MODUL>_PARAM Map noch weitere Angaben (z.B.
Symbologie Maps für den DXFOUT Modul). In diesem Fall ist das
ebenfalls in der Moduldokumentation im Anhang beschrieben.
In der Map INPUT_SOURCES wird festgelegt, in
welcher Reihenfolge die Inputmodule ausgelesen werden (s.a. Abschnitt 2.4, „Der RUN1 Algorithmus“).
Die INOUT Map legt fest, wie die von den
Inputmodulen gelesenen Objekte an die Verarbeitungs- bzw. Outputmodule
weiter geleitet werden (s.a. Abschnitt 2.4, „Der RUN1 Algorithmus“).
Skriptbibliotheken werden mit der |INCL
Direktive eingebunden. Die verfügbaren Skriptbibliotheken sind im
Anhang beschrieben.
Alle benötigten Input-, Output- und Verarbeitungsmodule müssen
mit |INCL eingebunden werden. Die verfügbaren
Module sind im Anhang beschrieben.
Falls die Konfiguration benutzerdefinierte Prozeduren verwendet,
müssen diese mit |INCL eingebunden werden (s.a.
Abschnitt 2.4.6, „Benutzerprozeduren in Abbildungsvorschriften“).
Schliesslich muss mit |INCL \script\run1.prg
der Verarbeitungsalgorithmus angegeben werden, welcher den Inhalt der
.cfg Datei interpretiert. Im Moment steht der RUN1
Algorithmus zur Verfügung (s.a. Abschnitt 2.4, „Der RUN1 Algorithmus“).
Der RUN1 Algorithmus interpretiert
den Inhalt der .cfg Datei und steuert die Input-, Output- und
Verarbeitungsmodule. Der RUN1 Algorithmus ist in der Skriptdatei
\script\run1.prg implementiert. Diese Datei muss daher
am Ende jeder .cfg Datei mit |INCL eingebunden werden.
Der RUN1 Algorithmus verfügt über folgende Eigenschaften:
Kann beliebig viele Parameter vom Benutzer interaktiv abfragen.
Kann beliebig viele Inputquellen verarbeiten.
Kann beliebig viele Input-, Output- und Verarbeitungsmodule über
die INOUT Map verknüpfen.
Kann Macros aus der Map MACRO
verarbeiten.
Kann parametrisierte Benutzerprozeduren aufrufen.
Kann Triggerprozeduren aufrufen.
Die Einzelnen Eigenschaften von RUN1 werden in den folgenden Unterabschnitten näher erläutert.
Sollen in einer Konfiguration interaktiv Parameter abgefragt
werden (z.B. Input- und Outputdatei), so müssen in der .cfg Datei Maps
der Form USER_INPUTx angelegt werden, wobei
x für eine Zahl zwischen 1 .. 9 steht. Die
USER_INPUTx Maps werden vom RUN1 Algorithmus in der
Reihenfolge ihrer Nummer ausgewertet (zuerst 1, dann 2, dann 3, etc.).
Nachfolgend ist ein Beispiel für eine USER_INPUT Map
dargestellt:
MAP USER_INPUT2 DIALOG => FILE ! FILE | FILES | ZIP | STRING | ODBC MESSAGE => 'Enter .txt Output File' FILE_FILTER => txt FILE_EXISTS => FALSE OPT => output END_MAP
Das obige Beispiel fragt vom Benutzer eine Datei ab
(DIALOG => FILE), welche nicht bereits existiert
(FILE_EXISTS => FALSE) und die Endung .txt
aufweisen muss (FILE_FILTER => txt). Die einzelnen
Parameter der USER_INPUT Maps haben folgende
Bedeutung:
DIALOGFILEDer Benutzer muss eine Datei auswählen. Ob die Datei
bereits existieren muss oder nicht, wird mit dem Parameter
FILE_EXISTS (TRUE |
FALSE) festgelegt. Weiter kann mit
FILE_FILTER angegeben werden, welche
Dateieendung die Datei aufweisen muss.
FILESIm Prinzip gleich wie FILE mit dem Unterschied, dass mehrere Dateien vom Benutzer ausgewählt werden können.
ZIPErweiterung zu FILE. Es muss ein .zip Archiv
ausgewählt werden. In ZIP_FILTER kann
zusätzlich ein Filter für die aus dem Archiv zu
selektierenden Dateien angegeben werden.
DIRECTORYDer Benutzer muss ein Dateiverzeichnis auswählen.
STRINGDer Benutzer muss eine Zeichenkette (String) eingeben.
ODBCDer Benutzer muss eine bestehende ODBC Datenquelle auswählen.
PROCEDUREEs wird eine vom Benutzer unter
PROCEDURE_NAME angegebene Prozedur
aufgerufen, welche den Parameterwert abfragt. Die Prozedur
muss als Resultat einen String oder eine Liste von Strings
auf dem Stack zurück liefern.
CONSTANTDer Parameterwert ist eine Konstante. Der
Parameterwert kann in OPT_VALUE gesetzt
werden.
MESSAGEMeldung welche dem Benutzer bei der Abfrage des Parameters angezeigt werden soll. Bemerkung: Falls die Meldung Leerzeichen enthält, muss die Meldung zwischen Hochkommas gestellt werden.
OPTName unter welchem der Wert des Parameters in der OPT Map abgespeichert werden soll.
Von einer ICS Konfiguration können gleichzeitig mehrere
Inputquellen verarbeitet werden. Inputquellen lesen Objekte von einer
externen Datenquelle (z.B. INTERLIS-Datei, ODBC-Datenbank) und wandeln
diese Objekte in eine interne Struktur um (IN-Objekt). Der Benutzer muss
die von ihm benötigten Inputquellen in der Map
INPUT_SOURCES definieren.
Beispiel 1. Definition von Inputquellen
MAP INPUT_SOURCES I1 => ILIN,OPT.input D1 => DB,features END_MAP
Erläuterungen zum obigen Beispiel:
In der Map INPUT_SOURCES wurden die
Inputquellen I1 und D1
definiert.
Die Quelle I1 liest Inputobjekte aus der
vom Benutzer gewählten INTERLIS-Inputdatei
(OPT.input) welche in
ILIN_PARAM konfiguriert wurde.
Die Quelle D1 liest Datensätze aus der
Tabelle features einer relationalen Datenbank, die in
DB_PARAM konfiguriert wurde.
Es ist erlaubt beliebig viele Inputquellen (z.B. mehrere
INTERLIS-Quellen und mehrere Datenbankquellen) gleichzeitig zu
definieren. Die Inputquellen werden von RUN1 in der Reihenfolge geöffnet
und gelesen, in der sie definiert wurden (hier: zuerst
I1, dann D1).
Alle von den Inputquellen gelieferten Objekte müssen klassifiziert
werden. Die Klassifikation wird nach folgendem Schema durch Einträge in
der Map INOUT ermittelt:
Die erste Klassifikation ist der Name der gerade aktiven
Inputquelle (z.B. I1).
In den folgenden Schritten wird versucht, die Klassifikation
zu verfeinern. Dazu wird die aktuelle Klassifikation erneut durch
die Map INOUT abgebildet.
Falls die Abbildung eine Abbildungsvorschrift liefert, ist die Klassifikation abgeschlossen. Das Resultat der Klassifikation ist die Abbildungsvorschrift (z.B. COPY). Weiter mit Schritt 7.
Falls die Abbildung den Namen einer IN-Objekt Komponente
liefert (z.B. IN.TABLE) wird der Wert (z.B.
BoFlaeche) der Komponente an die aktuelle Klassifikation durch eine
Komma getrennt angehängt. Weiter mit Schritt 2.
Falls die Klassifikation in der Map INOUT
keine Abbildung hat, wird der letzte Teil der aktuellen
Klassifikation durch * ersetzt. Weiter mit Schritt 2.
Falls noch immer keine Abbildung gefunden werden konnte, ist
dies ein Fehler. Das Objekt wird in die Map
UNDEFINED_OBJECTS eingetragen. Fertig.
Falls die Abbildungsvorschrift gleich OFF
ist, wird das Objekt ignoriert (bzw. in die Map
IGNORED_OBJECTS eingetragen), sonst wird die
gefundene Abbildungsvorschrift ausgeführt.
Im folgenden Beispiel werden Objekte aus der INTERLIS Tabelle
Fixpunkte.HFP je nach Inhalt der Komponente IN.TOPIC
und IN.TABLE klassifiziert.
Erläuterungen:
Da die Daten von der Inputquelle I1 gelesen
werden, ist der Wert der ersten Klassifikation für jedes Objekt
I1 (Schritt 1).
I1 wird durch INOUT
abgebildet das Resultat ist IN.TOPIC,IN.TABLE
(Schritt 2).
Da es sich bei IN.TOPIC,IN.TABLE um
Komponenten des IN-Objekts handelt, wird der Inhalt von
IN.TOPIC,IN.TABLE durch ein Komma getrennt an die
aktuelle Klassifikation angehängt (hier:
I1,Fixpunkte,HFP)(Schritt 4).
Die aktuelle Klassifikation wird wieder durch
INOUT abgebildet (Schritt 2) und man erhält
schliesslich COPY_IN_OUT0 (Schritt 3).
COPY_IN_OUT0 ist eine Abbildungsvorschrift,
die von ICS ausgeführt wird.
Man kann das obige Beispiel auch als eine speziell kodierte IF Anweisung verstehen. Der iG/Script Code dazu lautet wie folgt:
IF VAR.SOURCE = 'I1' THEN
IF IN.TOPIC = 'Fixpunkte' THEN
IF IN.TABLE = 'HFP' THEN
COPY_IN_OUT0
END_IF
END_IF
END_IFDie in Abschnitt 2.4.3, „Die INOUT Map“ gefundenen Abbildungsvorschriften werden nach folgendem Schema ausgeführt:
Die Abbildungsvorschrift ist eine Liste von iG/Script Prozeduren und/oder Macros.
Alle Macros werden durch ihren Wert ersetzt (Macros können in der Map MACRO deklariert werden, s.a. 4.1.7).
Falls das erste Element der Liste eine iG/Script Prozedur ist, wird die Prozedur aufgerufen. Weiter mit Schritt 5.
Falls das erste Element der Liste keine iG/Script Prozedur
ist, ist dies ein Fehler (unknown procedure ...).
Fertig.
Die Prozedur wird ausgeführt und die aktuelle Abbildungsvorschrift wird um die Prozedur und ihre Argumente reduziert.
Falls die Abbildungsvorschrift nach der Reduktion leer ist, sind wir fertig.
Falls die Liste nach der Reduktion nicht leer ist, weiter mit Schritt 3.
In der Map MACRO können Sie Abbkürzungen für
häufig gebrauchte Prozeduraufrufe und/oder Argumente definieren.
Hier wurde z.B. der Macro DIN definiert. Der
Macro wird zur Laufzeit durch seinen Wert ersetzt (hier:
DISPLAY_OBJECT,IN). Der Macro DIN
kann nun in jeder Abbildungsvorschrift der INOUT Map
benutzt werden.
Der Benutzer kann ICS Konfigurationen mit eigenen iG/Script Prozeduren ergänzen. Die neuen Prozeduren sollten in einer .out Datei definiert werden. Die benutzerdefinierten Prozeduren können in jeder Abbildungsvorschrift benutzen werden. Es ist sogar möglich Prozeduren mit Parametern zu definieren. Die Programmiersprache iG/Script ist ausführlich im iG/Script Benutzer- und Referenzhandbuch beschrieben.
Benutzerprozeduren müssen ihre Parameter mit den vordefinierten Prozeduren:
GET_SPARAMString Parameter.
GET_IPARAMInteger Parameter.
GET_RPARAMReal Parameter.
GET_PPARAMPunkt Parameter.
GET_LPARAMLinien Parameter.
GET_APARAMFlächen Parameter.
GET_PARAMBeliebiges ICS-Objekt.
Diese Prozeduren sind in der Skriptbibliothek
\script\util.lib definiert.
Beispiel 4. Parameterübernahme in Benutzerprozeduren
PROCEDURE Bodb_Centroid1 ! Art 'Bodenbedeckung' => OUT.TOPIC 'BoFlaeche' => OUT.TABLE IN.OBJID => OUT.OBJID IN.Geometrie => OUT.Geometrie GET_SPARAM => OUT.Art WRITE_OBJECT END_PROCEDURE
Die Prozedur Bodb_Centroid1 schreibt eine
Bodenbedeckungszentroid in die INTERLIS Transferdatei. Die Prozedur
übernimmt den Artcode (Art) des Zentroids als Parameter. Die neue
Prozedur kann wie folgt in einer Abbildungsvorschrift der
INOUT Map benutzt werden:
MAP INOUT ... I1,Bodenbedeckung,BoFlaeche => Bodb_Centroid1,befestigt.Bahn ... END_MAP
Beim Ausführen der Abbildungsvorschrift wird die Prozedur
Bodb_Centroid1 mit dem Parameter
befestig.Bahn aufgerufen und damit ein Centroid in
der INTERLIS-Tabelle BoFlaeche erzeugt.
![]() | |
Die Zahl |
Triggerprozeduren sind Prozeduren, welche in einem bestimmten Moment in der Konfiguration automatisch aufgerufen werden. Der RUN1 Algorithmus unterstützt folgende Triggerprozeduren:
PRE_TRANSFERWird einmal vor dem Öffnen aller Sourcen aufgerufen.
PRE_SOURCE_<SOURCE>Wird vor dem Öffnen der Source
<SOURCE> aufgerufen.
PRE_OPEN_<SOURCE>Wird aufgerufen bevor Objekte aus der Source
<SOURCE> ausgelesen werden. Die
<SOURCE> ist aber bereits offen (im
Gegensatz zu PRE_SOURCE_<SOURCE>).
![]() | |
In älteren Versionen der INTERLIS Tools wurde
|
![]() | |
Falls mit der in der |
PRE_INOUT_<SOURCE>Wird vor dem Durchlaufen der INOUT Map
aufgerufen. Dieser Trigger kann z.B. für die Berechnung von
virtuellen Attributen benutzt werden.
![]() | |
In älteren Versionen der INTERLIS Tools hiess dieser
Trigger |
POST_INOUT_<SOURCE>Wird nach dem Durchlaufen der INOUT Map aufgerufen.
POST_CLOSE_<SOURCE>Wird vor dem Schliessen der Source
<SOURCE> aufgerufen.
POST_SOURCE_<SOURCE>Wird nach dem Schliessen der Source
<SOURCE> aufgerufen.
POST_TRANSFERWird einmal nach dem Schliessen aller Sourcen aufgerufen.
Den gleichen Effekt wie mit Triggern kann man z.T. auch durch
Verwendung der Pseudoinputquelle NOOP erreichen.
NOOP ist eine spezielle Datenquelle die nur ein
einziges Objekt liefert. Diese Eigenschaft kann man z.B. wie folgt
nutzen:
MAP INPUT_SOURCES N1 => NOOP M1 => MSIN,OPT.input END_MAP MAP INOUT N1 => MeineInitialisierung0 M1 => ... ! etc. END_MAP
Die Inputquellen werden von ICS in der Reihenfolge geöffnet und
gelesen, in der sie definiert wurden, d.h. zuerst N1
(NOOP) und dann M1
(MSIN). Das von NOOP generierte
Objekt bewirkt, dass die Benutzerprozedur
MeineInitialisierung0 einmal aufgerufen wird (z.B.
für spezielle Initialisierungen von Benutzermaps). In diesem Fall hätte
man das Gleiche jedoch auch ohne NOOP, mit einem
PRE_SOURCE_M1 Trigger, erreichen können.
![]() | |
Wir empfehlen die Verwendung von |