Datenbanklayer über CRON erzeugen: Unterschied zwischen den Versionen

Aus kvwmap
Wechseln zu: Navigation, Suche
 
Zeile 4: Zeile 4:
  
 
Mein Script für obiges Beispiel sieht so aus:
 
Mein Script für obiges Beispiel sieht so aus:
  #!/bin/sh<br>
+
  #!/bin/sh
  cd /usr/local/pgsql/bin<br>
+
#
  ./psql -d dbname -U username -c "DROP TABLE gd_lk_bov_lauf;"<br>
+
  cd /usr/local/pgsql/bin
  ./psql -d dbname -U username -c "
+
  #
  CREATE TABLE gd_lk_bov_lauf
+
# Der folgende auskommentierte Teil ist nur für den "Handbetrieb"
  (
+
#
    id varchar(10),
+
# Löscht die Tabelle gd_lk_bov_lauf und den Geometrie-Eintrag in geometry_columns
    ausfstelle varchar(50),
+
#./psql -d kvwmapsp -U postgres -c "SELECT DropGeometryColumn('kvwmapsp','gd_lk_bov_lauf','the_geom');"
    verfnr varchar(10),
+
#./psql -d kvwmapsp -U postgres -c "DROP TABLE gd_lk_bov_lauf;"
    the_geom geometry,
+
  #
    CONSTRAINT enforce_dims_the_geom CHECK (ndims(the_geom) = 2),
+
# Legt die Tabelle gd_lk_bov_lauf an und erzeugt den Geometrie-Eintrag in geometry_columns
    CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'
+
#./psql -d kvwmapsp -U postgres -c "CREATE TABLE gd_lk_bov_lauf  
                          OR geometrytype(the_geom) = 'POLYGON' OR the_geom IS NULL),
+
#(
    CONSTRAINT enforce_srid_the_geom CHECK (srid(the_geom) = 2398)
+
id varchar(100) NOT NULL,
  );"<br>
+
ausfstelle varchar(100),
  ./psql -d dbname -U username -c "ALTER TABLE gd_lk_bov_lauf OWNER TO kvwmap;"<br>
+
verfnr varchar(10),
  ./psql -d dbname -U username -c "
+
#)
  INSERT INTO gd_lk_bov_lauf  
+
#WITH OIDS;"
  (
+
#./psql -d kvwmapsp -U postgres -c "SELECT AddGeometryColumn 'kvwmapsp','gd_lk_bov_lauf','the_geom',2398,'POLYGON',2);"
    SELECT v.verfnr AS id, v.ausfstelle, v.verfnr, geomunion(o.the_geom) AS the_geom
+
#./psql -d kvwmapsp -U postgres -c "ALTER TABLE gd_lk_bov_lauf DROP CONSTRAINT enforce_geotype_the_geom;
    FROM alb_f_verfahren v, alknflst f,alkobj_e_fla o
+
# 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);"
    WHERE v.verfbem = '10'
+
#
    AND (v.ausfstelle = 'F0024'
+
#
    OR v.ausfstelle = 'F0100'
+
# Hier folgt der Teil für den automatischen Ablauf. Wenn die Tabelle mal händisch gelöscht und neu
    OR v.ausfstelle = 'F0101'
+
# angelegt wird, muss der folgende TRUNCATE-Befehl auskommentiert werden!
    OR v.ausfstelle = 'F0103'
+
#
    )
+
# Leert die Tabelle gd_lk_bov_lauf
    AND v.flurstkennz = f.flurstkennz
+
  ./psql -d kvwmapsp -U postgres -c "TRUNCATE TABLE gd_lk_bov_lauf;"
    AND f.objnr = o.objnr
+
#
    GROUP BY v.ausfstelle, v.verfnr, o.the_geom
+
#
    ORDER BY v.ausfstelle
+
# Die Abfrage von s.verfnr garantiert, dass pro Verfahren eine Fläche (POLYGON oder MULTIPOLYGON !) erzeugt wird
    );"<br>
+
# 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
 
  exit 0
Wenn man genauer hinschaut, sieht man, dass außer dem cd-Befehl vier Befehle auftauchen, die mit "./psql -d dbname -U username -c " anfangen. Diese Befehle machen Folgendes (den "ALTER TABLE"-Befehl ignorier ich mal):
+
 
* 1. Lösche die Tabelle gd_lk_bov_lauf (also die Tabelle mit den laufenden BOVs)
+
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.
* 2. Lege die Tabelle neu an
+
* 3. Schreibe die Geometrien in die Tabelle (der eigentliche Befehl)
+
Es ist sicherlich etwas die Holzhammermethode und geht bestimmt viel besser, aber es funzt. Vielleicht fühlt sich ja jemand berufen, dieses Skript zu verbessern, nur zu.<br><br>
+
Problem bei geomunion: Verlaufen zwei Linien von zwei zu vereinigenden Objekten nahezu parallel, versagt die Funktion. 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.
+
  
 
Wenn das so ist, hilft eigentlich nur, den geomunion-Befehl rauszunehmen (oder hat jemand eine bessere Idee?). Dann bringt aber der ganze Umweg über das Skript eigentlich auch keine Punkte mehr :-)
 
Wenn das so ist, hilft eigentlich nur, den geomunion-Befehl rauszunehmen (oder hat jemand eine bessere Idee?). Dann bringt aber der ganze Umweg über das Skript eigentlich auch keine Punkte mehr :-)

Version vom 23. Juli 2007, 11:23 Uhr

--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.

Wenn das so ist, hilft eigentlich nur, den geomunion-Befehl rauszunehmen (oder hat jemand eine bessere Idee?). Dann bringt aber der ganze Umweg über das Skript eigentlich auch keine Punkte mehr :-)

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...