#!/bin/bash ## ------------------------------------------------- ## DB-Server - Produktion - ## Konvertierung von ALKIS NAS-Format nach PostGIS - ## NAS-Daten in einem Ordner konvertieren - ## Batch-Teil, Aufruf mit geprueften Parametern - ## ------------------------------------------------- ## ## Ordner-Struktur: ## /mandant/ ## /01/*.xml.zip ## /02/*.xml.zip ## usw. ## /temp/ ## Auf der gleichen Ebene wie die Datenordner muss ein Ordner /temp/ existieren. ## Dort werden die NAS-Daten temporaer ausgepackt. ## Relativ zum mitgegebenen Parameter ist das: '../temp/' ## Parallel laufende Konvertierungen zum gleichen Mandanten ## wuerden hier durcheinander geraten. Vermeiden! ## ## Stand: ## 2012-06-04 SQL-Skripte in deren Verzeichnis ausfuehren (Voraussetzung fuer \i Includes) ## 2014-01-31 F.J. krz: Import Eintrag erzeugen (nach Vorschlag Marvin Brandt, Unna) ## 2014-02-13 A.Emde WhereGroup: Einführung DBUSER, damit im Skript der Datenbankbenutzer angegeben werden kann ## 2014-06-18 F.J. DB-User nicht "postgres" (in $con). ## Konverter ind Nacharbeiten sonst mit unterschiedlichem User. ## Entfernen der historischen Objekte nach Konvertierung. ## 2014-09-23 F.J. krz: Zählung der Funktionen in delete, dies in import-Tabelle eintragen (Metadaten) ## 2015-03-16 F.J. krz: "-nlt CONVERT_TO_LINEAR" ersetzt "ST_CurvePolygon" näherungsweise durch "ST_Polygon" ## 2015-03-24 F.J. krz: export NAS_INDICATOR ## 2015-05-26 F.J. krz: Pfad auf Version 1.11 geändert (Parameter -append wird bei TRUNK 2.0 ignoriert) ## Dazu "-nlt CONVERT_TO_LINEAR" vorübergehend deaktiviert (erst ab 2.0 notwendig) ## gdal-Version in Import-Tabelle schreiben. Zwischenfrage vor Konvertierung. ## DB-Dump vor Aktualisierungslauf, auf Nachfrage. ## 2015-10-27 F.J. krz: Teile von "pp_laden.sql" ausgelegert nach "pp_gebiete.sql". ## Dies wird bei Parameter "pp" (mit Post-Processing) nur beim Erstladen mit ausgeführt. ## Bei Aktualisierungen müssen die Gebiete (Übersichten) nicht jedes Mal neu generiert werden. ## ToDo: ## - Unterscheidung e/a noch sinnvoll? Immer "a" = Aktualisierung = -update ? ## - PostProcessing: Aufruf Script, sonst redundant zu pflegen # Speicher-Ort dieses Scriptes legt den Pfad fuer Logging fest POSTNAS_HOME=$(dirname $0) # Konverterpfad. # TRUNK-Version 2.0.0Beta1 (selbst gebaut) # Dabei: "-nlt CONVERT_TO_LINEAR" verwenden # PATH=/opt/gdal-2.0/bin:$PATH # Stabile-Version 1.11.2 (selbst gebaut) # Dabei: "-nlt CONVERT_TO_LINEAR" NICHT verwenden PATH=/opt/gdal-1.11/bin:$PATH # Konfiguration: EPSG=25832 DBUSER=b600352 if [ $DBUSER == "" ] then echo "kein DBUSER gesetzt" else PGUSER=" -U ${DBUSER} " OGRPGUSER=" user=${DBUSER}" fi echo " ********************************************** ** K o n v e r t i e r u n g PostNAS ** ********************************************** " # Aufruf-Parameter: ORDNER=$1 DBNAME=$2 UPD=$3 PP=$4 # Parameter plausibilisieren if [ $ORDNER == "" ] then echo "Parameter 1 'Ordner' ist leer" exit 1 fi if [ $DBNAME == "" ] then echo "Parameter 2 'Datenbank' ist leer" exit 2 fi if [ $UPD == "a" ] then verarb="NBA-Aktualisierung" update=" -update " else if [ $UPD == "e" ] then verarb="Erstladen" update="" else echo "Parameter 3 'Aktualisierung' ist weder e noch a" exit 3 fi fi if [ $PP == "nopp" ] then echo "KEIN Post-Processing nach dieser Konvertierung" else if [ $PP == "pp" ] then echo "mit Post-Processing" else echo "FEHLER: Parameter 4 'Post-Proscessing' ist weder 'nopp' noch 'pp'" exit 4 fi fi # DB-Connection (User, Port, Datenbank-Name) con="${PGUSER} -p 5432 -d ${DBNAME} " # Anzeige Historie echo "vorangegangene Konvertierung:" psql $con -c "SELECT id, datum, verzeichnis, importart FROM import ORDER BY id DESC LIMIT 1;" # Anzeige Parameter echo "Datenbank: ${DBNAME}" echo "DBUSER: ${DBUSER}" #echo "PGUSER: ${PGUSER}" #echo "OGRPGUSER: ${OGRPGUSER}" echo "Ordner NAS-Daten: ${ORDNER}" echo "Verarbeitungs-Modus: ${verarb}" echo "POSTNAS_HOME: ${POSTNAS_HOME}" echo "Programm-Version: `ogr2ogr --version` " # Kontrolle der Parameter echo " Abschließende Bestaetigung:" until [ "$JEIN" = "j" -o "$JEIN" = "n" ] do echo "Mit diesen Parametern konvertieren? - j oder n" read JEIN done if test $JEIN != "j" then echo " #### Abbruch" exit 1 fi # Fehlerprotokoll: errprot=${POSTNAS_HOME}'/log/postnas_err_'$DBNAME'.prot' echo "GDAL/PostNAS Konverter-Version:" >> $errprot ogr2ogr --version >> $errprot # Sicherung der Datenbank VOR der Aktualisierung if [ $UPD == "a" ] then until [ "$DUMP" = "j" -o "$DUMP" = "n" ] do echo "Datenbank-Sicherung? - j oder n" read DUMP done if test $DUMP = "j" then echo "DB Dump wird ausgefuehrt" echo "Datenbank-Dump in /data/bkup/${DBNAME}_vor_update.sql.gz" >> $errprot pg_dump -U ${DBUSER} -o -C ${DBNAME} | gzip > /data/bkup/${DBNAME}_vor_update.sql.gz echo "DB Dump wurde ausgefuehrt" sleep 1 fi fi # Import Eintrag schreiben # Urspruenglich wurde die Tabelle "import" fuer die Trigger-Steuerung benoetigt. # Nun als Metadaten zur Datenbank-Historie nuetzlich. echo "INSERT INTO import (datum, verzeichnis, importart, gdalvers) VALUES ('"$(date '+%Y-%m-%d %H:%M:%S')"','"${ORDNER}"','"${verarb}"', '`ogr2ogr --version`');" | psql $con # Alte delete-Eintraege loeschen # Beim Eintrag in die delete-Tabelle wird ein Trigger ausgeloest. # Danach werden die Eintraege nicht mehr benoetigt. echo " Leeren der delete-Tabelle" psql $con -c 'TRUNCATE table "delete";' # Ordner abarbeiten cd ${ORDNER} rm ../temp/*.gfs echo "Dateien in " ${ORDNER} " (ls) :" ls for zipfile in *.zip ; do echo " " rm ../temp/*.xml echo "*********" #echo "* Archiv: " $zipfile unzip ${zipfile} -d ../temp # Es sollte nur ein XML-File in jedem ZIP-File stecken, aber es geht auch anders. for nasdatei in ../temp/*.xml ; do # echo "* Datei: " $nasdatei # Zwischenueberschrift im Fehlerprotokoll echo "* Datei: " $nasdatei >> $errprot # Umgebungsvariable setzen: export GML_FIELDTYPES=ALWAYS_STRINGS # PostNAS behandelt Zahlen wie Strings, PostgreSQL-Treiber macht daraus Zahlen export OGR_SETFIELD_NUMERIC_WARNING=YES # Meldung abgeschnittene Zahlen? # export OGR_SKIP=GML # NAS-Daten auch mit "falschen Header" nicht wie GML konvertieren - NEIN! # http://lists.osgeo.org/pipermail/nas/2014-December/000740.html #export CPL_DEBUG=ON # Meldung, wenn Attribute ueberschrieben werden # Headerkennungen die NAS-Daten identifizieren export NAS_INDICATOR="NAS-Operationen.xsd;NAS-Operationen_optional.xsd;AAA-Fachschema.xsd;ASDKOM-NAS-Operationen_1_1_NRW.xsd" # PostNAS Konverter-Aufruf # --config PG_USE_COPY YES # -nlt CONVERT_TO_LINEAR # ersetzt "ST_CurvePolygon" näherungsweise durch "ST_Polygon", ab Vers. 2.0 # ogr2ogr -f "PostgreSQL" -append ${update} -skipfailures -nlt CONVERT_TO_LINEAR ogr2ogr -f "PostgreSQL" -append ${update} -skipfailures \ PG:"dbname=${DBNAME} host=localhost port=5432 ${OGRPGUSER}" -a_srs EPSG:$EPSG ${nasdatei} 2>> $errprot nasresult=$? # Ergebnis in Logfile UND auf Konsole echo "* Resultat: " $nasresult " fuer " ${nasdatei} | tee -a $errprot # Farbige Anzeige des Ergebnis-Codes if [ $nasresult == 0 ] then echo -e "\e[32m${nasdatei} verarbeitet\e[0m" # grün else echo -e "\e[31m${nasdatei} fehlerhaft\e[0m" # rot fi done # Ende Zipfile done # Ende Ordner rm ../temp/*.xml echo " ** Ende Konvertierung Ordner ${ORDNER}" # Durch Einfügen in Tabelle 'delete' werden Löschungen und Aktualisierungen anderer Tabellen getriggert echo "** Die delete-Tabelle enthaelt so viele Zeilen:" psql $con -c 'SELECT COUNT(featureid) AS delete_zeilen FROM "delete";' echo "** aufgeteilt auf diese Funktionen:" psql $con -c 'SELECT context, COUNT(featureid) AS anzahl FROM "delete" GROUP BY context ORDER BY context;' # Kontext-Funktionen zählen und die Anzahl als Metadaten zum aktuellen Konvertierungslauf speichern psql $con -c " UPDATE import SET anz_delete=(SELECT count(*) FROM \"delete\" WHERE context='delete') WHERE id=(SELECT max(id) FROM import) AND verzeichnis='${ORDNER}' AND anz_delete IS NULL; UPDATE import SET anz_update=(SELECT count(*) FROM \"delete\" WHERE context='update') WHERE id=(SELECT max(id) FROM import) AND verzeichnis='${ORDNER}' AND anz_update IS NULL; UPDATE import SET anz_replace=(SELECT count(*) FROM \"delete\" WHERE context='replace') WHERE id=(SELECT max(id) FROM import) AND verzeichnis='${ORDNER}' AND anz_replace IS NULL;" # Post-Processing / Nacharbeiten if [ $PP == "nopp" ] then echo "** KEIN Post-Processing - Dies spaeter nachholen." # Dies kann sinnvoll sein, wenn mehrere kleine Aktualisierungen hintereinander auf einem grossen Bestand laufen. # Der Aufwand für das Post-Processing ist dann nur bei der LETZTEN Aktualisierung notwendig. else echo "** Post-Processing (Nacharbeiten zur Konvertierung)" echo "** - Optimierte Nutzungsarten neu Laden (Script nutzungsart_laden.sql):" (cd $POSTNAS_HOME; psql $con -f nutzungsart_laden.sql) echo "** - Straßen-Namen neu Laden (Script pp_laden.sql):" (cd $POSTNAS_HOME; psql $con -f pp_laden.sql) if [ $UPD == "e" ] then # Erstladen: Gebiete erstmalig befuellen. echo "** - Fluren, Gemarkungen, Gemeinden neu Laden (Script pp_gebiete.sql):" (cd $POSTNAS_HOME; psql $con -f pp_gebiete.sql) else # Aktualisierung: Gebiete brauchen nicht bei jeder Aktualisierung neu generiert werden. Die aendern sich kaum. echo "Die Uebersichten für Flur, Gemarkung und Gemeinde werden nicht neu generiert. Bei Bedarf das SQL-Script pp_gebiete.sql ausfuehren." fi fi echo "Das Fehler-Protokoll wurde ausgegeben in die Datei $errprot" echo " ** ENDE PostNAS 0.8-Konvertierung DB='$DBNAME' Ordner='$ORDNER' "