Datenbanklayer über CRON erzeugen
--Markus Hentschel 14:33, 28. Nov 2006 (CET)
Einige Operationen mit Daten der PostGIS-DB können ganz schön lange Laufzeiten verursachen, wenn man die Geometrie "on the fly" erzeugen lässt. Z.B. kann man alle Flurstücke in einem Layer ausgeben lassen, die eine Eintrag im ALB haben, dass sie in einem BOV liegen. Wenn man darauf ein GEOMUNION loslässt, um für jeweils ein Verfahrensgebiet auch nur ein Objekt zu erhalten, dann dauert das und man kann Kaffee trinken gehen.
Es ist aber auch möglich, das entsprechende SQL in ein Shellscript zu packen und die Abfrage z.B. einmal die Woche durchzuführen. Dann hat man eine immer aktuelle PG-Datenbanktabelle mit den bereits fertig fabrizierten Geometrien und kann auf diese mit kvwmap wie gewohnt zugreifen.
Mein Script für obiges Beispiel sieht so aus:
#!/bin/sh # cd /usr/local/pgsql/bin # # Der folgende auskommentierte Teil ist nur für den "Handbetrieb" # # Löscht die Tabelle gd_lk_bov_lauf und den Geometrie-Eintrag in geometry_columns #./psql -d kvwmapsp -U postgres -c "SELECT DropGeometryColumn('kvwmapsp','gd_lk_bov_lauf','the_geom');" #./psql -d kvwmapsp -U postgres -c "DROP TABLE gd_lk_bov_lauf;" # # Legt die Tabelle gd_lk_bov_lauf an und erzeugt den Geometrie-Eintrag in geometry_columns #./psql -d kvwmapsp -U postgres -c "CREATE TABLE gd_lk_bov_lauf #( # id varchar(100) NOT NULL, # ausfstelle varchar(100), # verfnr varchar(10), #) #WITH OIDS;" #./psql -d kvwmapsp -U postgres -c "SELECT AddGeometryColumn 'kvwmapsp','gd_lk_bov_lauf','the_geom',2398,'POLYGON',2);" #./psql -d kvwmapsp -U postgres -c "ALTER TABLE gd_lk_bov_lauf DROP CONSTRAINT enforce_geotype_the_geom; # ALTER TABLE gd_lk_bov_lauf ADD CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'POLYGON'::text OR geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL);" # # # Hier folgt der Teil für den automatischen Ablauf. Wenn die Tabelle mal händisch gelöscht und neu # angelegt wird, muss der folgende TRUNCATE-Befehl auskommentiert werden! # # Leert die Tabelle gd_lk_bov_lauf ./psql -d kvwmapsp -U postgres -c "TRUNCATE TABLE gd_lk_bov_lauf;" # # # Die Abfrage von s.verfnr garantiert, dass pro Verfahren eine Fläche (POLYGON oder MULTIPOLYGON !) erzeugt wird # s.ausfstelle LIKE 'F%': Alle Flurneuordnungsverfahren # s.verfbem != '11': Keine am Verfahrensgebiet anliegenden Flurstücke # ./psql -d kvwmapsp -U postgres -c "INSERT INTO gd_lk_bov_lauf ( SELECT max(f.objnr) AS id, a.name::varchar AS ausfstelle, s.verfnr::integer, geomunion(f.the_geom) AS the_geom FROM alb_f_verfahren s, alkobj_e_fla f, alknflst fl, alb_v_ausfuehrendestellen a WHERE s.ausfstelle LIKE 'F%' AND s.verfbem != '11' AND s.flurstkennz = fl.flurstkennz AND fl.objnr = f.objnr AND s.ausfstelle = a.ausfstelle GROUP BY a.name,s.verfnr );" # # exit 0
Problem mit GEOS bzw. GEOMUNION: Verlaufen zwei Linien von zwei zu vereinigenden Objekten nahezu parallel, versagt möglicherweise die Funktion GEOMUNION. Man erhält einen Fehler: "TopologyException: no outgoing dirEdge found - GEOS union() threw an error!". Für das Skript heißt das, dass es nur bis zum "INSERT" ausgeführt wird und dann abbricht, d.h. die Tabelle ist dann zwar da, aber leer. Weil in der ALK viele Linien ganz oder fast parallel laufen, ist die Gefahr also sehr hoch, dass das Ganze nicht funktioniert.
Diese Meldung sollte nicht mehr kommen, wenn man eine geos-Version > 3.x verwendet.
Die Lauffähigkeit des Skriptes nicht vergessen zu prüfen, in dem man es ausführbar macht und als root manuell startet.
Hat man das Skript geschrieben, speichert man es (unter SuSE) in einem der cron-Ordner ab, z.B. /etc/cron.weekly/ und macht das Skript für root ausführbar. In der Datei /etc/crontabs (wieder nur für SuSE) kann man noch einstellen, wann das Skript starten soll. Und dann harrt man der Dinge, die da kommen...