ingo@3661: \section{Geodatenimport} ingo@3661: aheinecke@5007: Der Geodaten Importer ist ein in der Programmiersprache Python aheinecke@5007: geschriebenes Kommandozeilen Werkzeug zum Import von Shapefiles in aheinecke@5007: eine Datenbank. tom@6750: Zum Lesen der Shapefiles und zum Schreiben der Geodaten tom@6750: in die Datenbank wird die GDAL-Bibliothek verwendet. aheinecke@5007: Um Daten in eine Oracle Datenbank zu importieren ist es nötig, dass tom@6750: GDAL und GDAL-Python-Bindings mit Oracle-Unterstützung installiert aheinecke@5007: sind. Bei der Verwendung von PostgreSQL entfällt dieser Schritt. aheinecke@5007: Weitere Details hierzu befinden sich im ingo@3661: Kapitel \ref{Systemanforderungen} und \ref{Installationsanleitung}. tom@6750: Für die Transformation der Daten verwendet GDAL wiederum die PROJ4-Bibliothek. tom@6749: Die Daten werden vor dem Schreiben in die Datenbank alle tom@6750: in die Gauß-Krüger-Projektion Zone 3 (EPSG-Code 31467) transformiert. tom@6749: Ist für die zu importierenden Daten keine Projektion ersichtlich tom@6750: (fehlende \textit{*.prj}-Datei), so findet keine Transformation statt. tom@6750: Dies führt nur zu Problemen mit dem Fachdienst FLYS, falls die Daten nicht tom@6750: bereits in der genannten Projektion vorlagen. ingo@3661: ingo@3676: Der Importer kann mit einem Shellscript von der Kommandozeile gestartet werden ingo@3661: (siehe Kapitel \ref{Starten des Geodaten Importers}). Nach dem Start wird anhand der ingo@3661: Konfiguration festgestellt, welche Klassen von Shapefiles aus dem Dateisystem ingo@3676: importiert werden sollen. Für jede Klasse gibt es einen speziellen ingo@3680: Parser, der die speziellen Attribute eines Shapefiles liest und in die entsprechende ingo@3680: Relation der Datenbank schreibt. Die Parser sind speziell auf das aheinecke@5007: Dateisystem der BfG ausgerichtet. So wird beispielsweise erwartet, dass die Shapefiles der ingo@3661: Gewässerachse im Ordner $Geodaesie/Flussachse+km$ liegen. Weitere Informationen zu tom@6750: den einzelnen Parsern sind Kapitel \ref{Beschreibung der Parser} zu tom@6750: entnehmen. Der Erfolg oder Misserfolg eines Shape-Imports wird tom@6750: im Logfile vermerkt. Folgende Einträge können dem Logfile ingo@3661: entnommen werden: ingo@3661: tom@6750: \textbf{INFO: Inserted \# features} tom@6750: \\Gibt die Anzahl der erfolgreich importierten Features an. ingo@3661: tom@6750: \textbf{INFO: Failed to create \# features} tom@6750: \\Gibt die Anzahl der Features an, die nicht importiert werden konnten. ingo@3661: tom@6750: \textbf{INFO: Found 3 unsupported features of type: '...'} ingo@3661: \\Gibt die Anzahl der Features an, die aufgrund ihres Datentyps nicht importiert aheinecke@5007: werden konnten. Wenn etwa Punkte erwartet wurden aber sich im Shapefile tom@6750: Polygone befanden. aheinecke@5007: tom@6750: \textbf{INFO: Did not import values from fields: '...' ...} tom@6750: \\Der Importer schreibt neben der geographischen Information weitere tom@6750: Attribut-Daten in die Datenbank. tom@6750: Attribut-Spalten die nicht importiert wurden (z.B. auf Grund tom@6750: von Tippfehlern oder unterschiedlicher Schreibweise), tom@6750: werden wie angegeben im Logfile aufgeführt. ingo@3661: ingo@3680: \textbf{ERROR: No source SRS given! No transformation possible!} ingo@3680: \\Das Shapefile enthält keine Information, in welcher Projektion die Geometrien ingo@3680: vorliegen. Es findet keine Transformation in die Zielprojektion statt. Bitte tom@6750: beachten Sie, dass FLYS diese Geometrien später ggf.\ nicht korrekt darstellen ingo@3680: kann. ingo@3680: ingo@3661: \textbf{ERROR: Unable to insert feature: DETAIL} tom@6750: \\Beim Lesen eines Features ist ein Fehler aufgetreten. tom@6750: Das Feature konnte nicht in die Datenbank geschrieben werden. ingo@3661: ingo@3661: \textbf{ERROR: Exception while committing transaction} ingo@3661: \\Beim Abschluss des Schreib-Vorgangs in die Datenbank ist ein unerwarteter tom@6750: Fehler aufgetreten. Die Features des Shapes sind nicht importiert worden. ingo@3661: ingo@3671: \textbf{ERROR 1: ORA-01017: invalid username/password; logon denied} ingo@3671: \\Es konnte keine Verbindung zur Oracle Datenbank hergestellt werden. Prüfen Sie ingo@3671: die Verbindungseinstellungen. ingo@3671: tom@6750: Weitere Fehler, die von der Oracle-Datenbank kommen, können ebenfalls im tom@6750: Logfile angezeigt werden. tom@6750: ingo@3661: Damit die Geodaten eines Shapes später eindeutig in der Datenbank identifiziert ingo@3661: werden können, wird für jede Geometrie der Pfad des Shapes im Dateisystem in ingo@3661: einer Spalte der Datenbank gespeichert. Anwendungen, die auf der Datenbank ingo@3661: aufbauen, können die Geodaten eines Shapefiles später anhand dieses Merkmals ingo@3661: gruppieren und anzeigen. ingo@3661: ingo@3661: ingo@3661: \subsection{Beschreibung der Parser} ingo@3661: \label{Beschreibung der Parser} ingo@3661: ingo@3661: Wie im letzten Kapitel beschrieben, sind die Parser speziell an das Dateisystem tom@6751: der BfG angepasst. Im Folgenden werden zu jedem Parser folgende Informationen ingo@3661: angegeben: ingo@3661: ingo@3661: \textbf{Pfad} tom@6751: \\Der Pfad, in dem die Shapefiles im Dateisystem abgelegt sein müssen (ausgehend tom@6751: vom Gewässer Verzeichnis). ingo@3661: ingo@3661: \textbf{Geometrie} ingo@3661: \\Der Geometrie Typ, der für diese Klasse von Shapefiles erwartet wird. ingo@3661: ingo@3661: \textbf{Attribute} ingo@3661: \\Eine Liste der Attribute, die vom Parser aus dem Shape gelesen werden. tom@6801: In Klammern als alternativ bezeichnete Attribut-Namen werden in tom@6801: das gleiche Datenbankfeld geschrieben, wie das vorgenannte Feld. tom@6801: Die alternativen Namen werden vom Importer zusätzlich unterstützt, tom@6801: um Dateien aus dem heterogenen Bestand der BfG unverändert tom@6801: importieren zu können. ingo@3661: tom@6751: Zudem werden Datenbank-Attribute beschrieben, die nicht direkt aus tom@6751: Attribut-Spalten des Shapefiles gelesen werden. ingo@3661: ingo@3661: \subsubsection{Achsen} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Geodaesie/Flussachse+km \\ tom@6751: Geometrie & LINESTRING, MULTILINESTRING \\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Das Attribut 'name' wird auf den Namen des Shapefiles gesetzt. tom@6751: Zusätzlich wird das Attribut 'kind\_id' gesetzt, welches tom@6751: für die aktuelle Achse (\textit{achse.shp}) 1 ist und für sonstige Achsen (weitere Linien-Shapes) 2. ingo@3661: tom@6751: \subsubsection{Hydr. Grenzen} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} tom@6751: Pfad & Hydrologie/Hydr.Grenzen \\ tom@6751: Geometrie & LINESTRING, MULTILINESTRING, POLYGON, MULTIPOLYGON \\ tom@6751: Attribute & SECTIE, STROVOER \\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Das Attribut 'name' wird auf den Namen des Shapefiles gesetzt. tom@6751: Das Attribut 'kind' wird 1 gesetzt für Daten aus dem tom@6751: Unterverzeichnis \textit{Linien/BfG}, tom@6751: 2 für Daten aus \textit{Linien/Land}, tom@6751: 3 für Daten aus \textit{Sonstige} tom@6751: und für alle übrigen 0. tom@6751: Ausgenommen sind Dateien, in deren Namen 'Talaue' tom@6751: (Groß-Klein-Schreibung irrelevant) vorkommt. tom@6751: tom@6751: Linien und Polygone werden in der Datenbank in unterschiedlichen tom@6751: Tabellen gespeichert. tom@6751: ingo@3661: \subsubsection{Bauwerke} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Geodaesie/Bauwerke \\ ingo@3661: Geometrie & LINESTRING \\ tom@6751: Attribute & Name (alternativ: KWNAAM), tom@6751: km (alternativ: station, wsv-km), tom@6751: z (alternativ: Höhe, Hoehe, m+NHN)\\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Das Attribut 'name' wird auf den Namen des Shapefiles gesetzt. tom@6751: Das Attribut 'kind\_id' ist 0 für Sonstige, tom@6751: 1 für Brücken, 2 für Wehre, 3 für Pegel. tom@6751: Es wird aus dem Dateinamen hergeleitet tom@6751: (\textit{bruecken.shp, wehre.shp, pegel.shp}, teilweise auch alternative Schreibweisen unterstützt) tom@6751: oder je Feature gesetzt, wenn in einer Attributspalte tom@6751: die Werte 'bruecke' und 'wehr' (teilweise auch alternative Schreibweisen unterstützt) vorkommen. tom@6751: Ausgenommen sind Dateien, in deren Namen 'Buhnen' tom@6751: (Groß-Klein-Schreibung irrelevant) vorkommt. ingo@3661: ingo@3661: \subsubsection{Querprofilspuren} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Geodaesie/Querprofile \\ ingo@3661: Geometrie & LINESTRING \\ tom@6751: Attribute & KILOMETER (alternativ: KM, STATION), ELEVATION \\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Das Attribut 'kind\_id' wird 1 gesetzt für die Datei \textit{qps.shp} (aktuelle Querprofilspuren) tom@6751: und 0 für alle weiteren. ingo@3661: ingo@3661: \subsubsection{Festpunkte} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Geodaesie/Festpunkte \\ ingo@3661: Geometrie & POINT \\ tom@6751: Attribute & KM (alternativ: ELBE\_KM), X, Y, HPGP (alternativ: ART) \\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Das Attribut 'name' wird auf den Namen des Shapefiles gesetzt. tom@6751: tom@6751: \subsubsection{Hochwassermarken} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} tom@6751: Pfad & Hydrologie/HW-Marken/hw-marken.shp \\ tom@6751: Geometrie & POINT \\ tom@6751: Attribute & Ort (alternativ: Pegel), tom@6751: km (alternativ: station, wsv-km, FlussKm), tom@6751: z (alternativ: z mit anschließender Zahl, m+NHN)\\ tom@6800: \end{tabular*} tom@6751: tom@6751: Groß-Klein-Schreibung im Dateinamen ist irrelevant. tom@6751: Für das Attribut 'year' im Dateinamen nach einer Jahreszahl tom@6751: nach folgendem Muster gesucht: \textit{\_YYYY\_} oder \textit{-YYYY-}. Gelingt dies nicht, erscheint im Logfile die Warnung tom@6751: 'Could not extract year from filename: ...'. ingo@3661: ingo@3661: \subsubsection{Talaue} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Hydrologie/Hydr.Grenzen \\ ingo@3661: Geometrie & POLYGON, MULTIPOLYGON \\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Es werden nur Dateien betrachtet, in deren Namen das Wort 'Talaue' tom@6751: (Groß-Klein-Schreibung irrelevant) vorkommt. tom@6751: Das Attribut 'name' wird auf den Namen des Shapefiles gesetzt. tom@6751: Das Attribut 'kind\_id' wird 1 gesetzt für die Datei \textit{talaue.shp} (aktuelle Talaue) tom@6751: und 0 für alle weiteren. ingo@3661: ingo@3661: \subsubsection{Hochwasserschutzanlagen} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Hydrologie/HW-Schutzanlagen \\ tom@6751: Geometrie & LINESTRING, MULTILINESTRING, POINT \\ tom@6751: Attribute & Name, Art, Quelle, Anmerkung, Stand, Verband, tom@6751: km (alternativ: Deich\_km), Bereich, tom@6751: Hoehe, Hoehe\_soll, WSP\_Bfg100, Bundesland tom@6751: (Teilweise auch alternative Schreibweisen unterstützt)\\ tom@6800: \end{tabular*} ingo@3661: tom@6751: Das Attribut 'name' wird auf den Namen des Shapefiles gesetzt, tom@6751: wenn kein Attribut 'Name' im Shapefile vorhanden ist. tom@6751: Das Feld 'kind\_id' wird per Default auf 2 (für Damm) gesetzt. tom@6751: Wird ein Attribut 'ART' im Shapefile gefunden, tom@6751: so wird 'kind\_id' entsprechend dieses Feldes gesetzt tom@6751: (1 für die Werte 'Durchlass', 'Rohr1', 'Rohr 1', 'Rohr 2', tom@6751: 2 für die Werte 'Damm', 'Deich', 'Hochufer', 'Hauptdeich', 'Sommerdeich', tom@6751: 3 für den Wert 'Graben'). tom@6751: Es wird versucht das Bundesland aus dem Dateinamen zu ermitteln, tom@6751: wenn das Shapefile kein Attribut 'Bundesland' enthält. tom@6751: tom@6751: Linien und Punkte werden in der Datenbank in unterschiedlichen tom@6751: Tabellen gespeichert. tom@6751: tom@6751: \subsubsection{Buhnen} tom@6751: ingo@3661: ingo@3661: \subsubsection{Kilometrierung} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Geodaesie/Flussachse+km \\ ingo@3661: Geometrie & POINT \\ ingo@3661: Attribute & name, km, KM \\ tom@6800: \end{tabular*} ingo@3661: ingo@3661: ingo@3661: \subsubsection{Überschwemmungsfläche} tom@6800: \hspace{5mm} tom@6800: \begin{tabular*}{155mm}[t]{l@{\extracolsep\fill}p{125mm}} ingo@3661: Pfad & Hydrologie/UeSG/Berechnung \\ ingo@3661: Geometrie & POLYGON, MULTIPOLYGON \\ ingo@3661: Attribut & name, diff, count, area, perimeter \\ tom@6800: \end{tabular*} ingo@3661: tom@6751: \subsubsection{Digitale Gelände-Modelle} tom@6751: % Zeitpunkt mit 'Jahr_von' angeben. tom@6751: ingo@3661: \subsection{Konfiguration} ingo@3661: \label{Konfiguration} ingo@3681: Der Geodaten Importer kann über die Datei \textit{contrib/run\_geo.sh} ingo@3661: konfiguriert werden. Öffnen Sie die Datei mit einem Texteditor Ihrer Wahl. ingo@3661: In den Zeilen 4-9 werden Optionen definiert, die zwangsläufig angepasst ingo@3661: werden müssen: ingo@3661: ingo@3661: \textbf{RIVER\_PATH} ingo@3661: \\Der Pfad zum Gewässer im Dateisystem. ingo@3661: aheinecke@4971: \textbf{RIVER\_NAME} aheinecke@4971: \\Der Datenbank Name des zu importierenden Gewässers. Wird dieser Parameter aheinecke@4971: nicht übergeben werden die Ordnernamen im mit dem Parameter RIVER\_PATH aheinecke@4971: angegebenen Verzeichnis als Flussnamen interpretiert und es wird versucht aheinecke@4971: diese zu Importieren. ingo@3661: ingo@3661: \textbf{HOST} ingo@3661: \\Der Host der Datenbank. ingo@3661: ingo@3661: \textbf{USER} ingo@3661: \\Der Nutzer, der zum Verbinden zur Datenbank verwendet wird. ingo@3661: ingo@3661: \textbf{PASS} ingo@3661: \\Das Passwort für USER zum Verbinden zur Datenbank. ingo@3661: ingo@3661: In den Zeilen 12-23 werden weitere Optionen definiert, die bei Bedarf angepasst ingo@3661: werden können. Falls nicht anders angegeben, können die Optionen mit den Werten ingo@3661: `0` und `1` belegt werden. ingo@3661: ingo@3661: \textbf{VERBOSE} ingo@3661: \\Dieser Wert gibt die Granularität der Log-Ausgaben während des ingo@3661: Imports an. Je höher der Wert, desto mehr Informationen werden ingo@3661: in das Logfile geschrieben. Aktuell sind die Werte `0`, `1` und ingo@3661: `2` definiert. Wird der Wert `0` gesetzt, werden nur Fehler und ingo@3661: Warnungen in das Logfile geschrieben. Bei `1` werden neben ingo@3661: Fehlern und Warnungen auch Infos in das Logfile geschrieben. Bei ingo@3661: `2` werden sämtliche Ausgaben des Programms geschrieben. Dieser ingo@3661: Modus ist hauptsächlich für die Entwicklung gedacht. ingo@3661: aheinecke@4871: \textbf{OGR\_CONNECTION} aheinecke@4871: \\Hiermit kann direkt ein beliebiger Verbindungs string angegegeben aheinecke@4871: werden, welcher die host, user und passwort werde überschreibt. aheinecke@4871: Dieser Option wird direkt an die OGR Bibliothek weitergegeben und ermöglicht aheinecke@4871: verbesserte Tests und Entwicklung mit verschiedenen Daten Backends. aheinecke@4871: ingo@3661: \textbf{SKIP\_AXIS} ingo@3661: \\Bei gesetztem Wert `1` werden keine Flussachsen importiert. ingo@3661: ingo@3661: \textbf{SKIP\_KMS} ingo@3661: \\Bei gesetztem Wert `1` werden keine Kilometrierungen importiert. ingo@3661: ingo@3661: \textbf{SKIP\_CROSSSECTIONS} ingo@3661: \\Bei gesetztem Wert `1` werden keine Querprofilespuren importiert. ingo@3661: ingo@3661: \textbf{SKIP\_FIXPOINTS} ingo@3661: \\Bei gesetztem Wert `1` werden keine Festpunkte importiert. ingo@3661: ingo@3661: \textbf{SKIP\_BUILDINGS} ingo@3661: \\Bei gesetztem Wert `1` werden keine Bauwerke importiert. ingo@3661: ingo@3661: \textbf{SKIP\_FLOODPLAINS} ingo@3661: \\Bei gesetztem Wert `1` werden keine Talauen importiert. ingo@3661: ingo@3661: \textbf{SKIP\_HYDR\_BOUNDARIES} ingo@3661: \\Bei gesetztem Wert `1` werden keine hydrologischen Grenzen importiert. ingo@3661: aheinecke@4880: \textbf{SKIP\_HWS\_LINES} aheinecke@4880: \\Bei gesetztem Wert `1` werden kein Hochwasserschutz Liniendaten importiert. aheinecke@4880: aheinecke@4880: \textbf{SKIP\_HWS\_POINTS} aheinecke@4880: \\Bei gesetztem Wert `1` werden kein Hochwasserschutz Punktdaten importiert. ingo@3661: ingo@3661: \textbf{SKIP\_CATCHMENTS} ingo@3676: \\Bei gesetztem Wert `1` werden keine Einzugsgebiete importiert. ingo@3661: ingo@3661: \textbf{SKIP\_UESG} ingo@3661: \\Bei gesetztem Wert `1` werden keine Überschwemmungsflächen importiert. ingo@3661: aheinecke@4971: \textbf{SKIP\_DGM} aheinecke@4971: \\Bei gesetztem Wert `1` werden keine Informationen über Digitale Geländemodelle importiert. aheinecke@4971: aheinecke@5353: \textbf{SKIP\_JETTIES} aheinecke@5353: \\Bei gesetztem Wert `1` werden keine Informationen über Buhnen importiert. ingo@3661: aheinecke@5545: \textbf{SKIP\_FLOODMARKS} aheinecke@5545: \\Bei gesetztem Wert `1` werden keine Informationen über HW-Marken importiert. aheinecke@5545: ingo@3661: \subsection{Starten des Geodaten Importers} ingo@3661: \label{Starten des Geodaten Importers} ingo@3661: Der Geodaten Importer wird mittels eines Shellskripts von einer Konsole ingo@3676: gestartet. Dazu führen Sie folgenden Befehl aus:\\ ingo@3661: ingo@3661: \begin{lstlisting} ingo@3676: sh contrib/run_geo.sh > geo-import.log ingo@3661: \end{lstlisting} ingo@3676: ingo@3661: Der Importer wird nun gestartet. Sämtliche Log-Ausgaben werden in die Datei ingo@3676: $geo-import.log$ geschrieben. ingo@3676: ingo@3676: \textbf{Hinweis} ingo@3676: \\Bitte beachten Sie, dass der Geodaten Importer aufgrund der eingesetzten ingo@3676: Technologien derzeit nicht in der Lage ist, lesend auf die Oracle Datenbank ingo@3676: zuzugreifen. Entsprechend kann beim Import nicht festgestellt werden, ob sich ingo@3676: Shapefiles bereits in der Datenbank befinden, oder nicht. Ein erneuter Import ingo@3676: Vorgang der Geodaten würde also dazu führen, dass Geometrien doppelt in der ingo@3676: Datenbank abgelegt werden. ingo@3676: