Index: trunk/import/pp_praesentation_sichten.sql
===================================================================
--- trunk/import/pp_praesentation_sichten.sql	(revision 293)
+++ trunk/import/pp_praesentation_sichten.sql	(revision 293)
@@ -0,0 +1,240 @@
+
+-- ALKIS PostNAS 0.7
+
+-- Post Processing (pp_) Teil 3: PrÃ€sentationsobjekte ergÃ€nzen / reparieren
+
+-- Dies Script "pp_praesentation_sichten.sql" dient der Vorbereitung der Reparatur, 
+-- die mit dem Script "pp_praesentation_action.sql" durchgefÃŒhrt wird.
+
+-- Dies Script muss beim Anlegen der Datenbank verarbeitet werden und wenn sich die Sichten verÃ€ndert haben. 
+-- Das Action-Script muss im Rahmen des Post-Processing nach jeder Konvertierung laufen.
+
+-- Stand 
+--  2013-10-16  F.J. krz: StraÃennamen fehlen in den PrÃ€sentationsobjekten, Tabelle "ap_pto"
+
+
+-- ========================================
+-- StraÃen-Namen und StraÃen-Klassifikation
+-- ========================================
+
+-- Bei den NAS-Daten, die vom Land Niedersachsen an die Kommunen abgegeben werden,
+-- tritt in zunehmenden Umfang folgendes Problem auf (Stand Oktober 2013):
+
+-- Die Namen und Klassifikationen der StraÃen fehlen in der Tabelle "ap_pto".
+-- Somit fehlt das Label fÃŒr die Darstellung des StraÃennamens in der Karte.
+-- Position und Drehwinkel sind dort aber noch vorhanden.
+
+-- Der Name, der in anderen Tabellen vorhanden ist, muss nach "ap_pto" kopiert werden,
+-- damit die WMS-Kartendarstellung wieder komplett ist.
+
+-- Tabelle: ap_pto
+-- Spalten:
+--  art:                         'strasse', 'BezKlassifizierungStrasse'
+--  schriftinhalt:               leer
+--  signaturnummer:              ??
+--  drehwinkel und wkb_geometry: gefÃŒllt
+
+-- Hintergrund:
+-- Der StraÃenname ist nach der Migration der ALKIS-Daten aus ALB und ALK zunÃ€chst redundant gespeichert worden.
+-- Er befindet sich "im Original" in "ax_lagebezeichnungkatalogeintrag.bezeichnung".
+-- FÃŒr die Darstellung im Kartenbild ist der gleiche Name oder eine Variante davon (AbkÃŒrzung, getrennt-Schreibung) 
+-- auch in jedem PrÃ€sentationsobjekt noch einmal abgelegt.
+-- Diese Redundanz fÃŒhrt bei einer Ãnderung des Namens zu einem erhÃ¶hten Aufwand.
+-- Ziel ist es daher, die identischen Kopien des Namens-Textes in "ap_pto" nicht mehr zu fÃŒhren.
+-- Dort ist nur noch dann ein Eintrag zu finden, wenn Text (oder Signaturnummer?) nicht identisch sind.
+
+-- Signaturnummern werden auch nur noch dann erfasst, wenn mehrere Werte mÃ¶glich sind.
+
+-- In Niedersachsen wurde oder wird das LÃ¶schen der identischen Texte in ap_pto mÃ¶glicherweise als Nachmigration gezielt
+-- durchgefÃŒhrt. Die Mehrzahl der Texte ist bereits gelÃ¶scht!
+-- In NRW tritt dies erst seit dem letzten Update der EQK (ibR, Stand Oktober 2013) zunÃ€chst bei den FÃ€llen auf,
+-- die seit dem Update fortgefÃŒhrt wurden. Eine groÃflÃ€chige gezielte Entfernung wurde nicht bemerkt. 
+
+
+-- Es soll versucht werden, dies Label durch die Zuordnung der Schrift-Position 
+-- in einem FlurstÃŒck und ÃŒber dessen Lagebezeichnung zu rekonstruieren.
+
+-- "Label"   >liegt in>   "FlurstÃŒck"    >hat Lagebezeichnung>   "StraÃenname"
+--           (geometrische                 (Beziehung)
+--           Verschniedung)
+
+
+-- Simulation der Fehlersituation in einem TEST-Bestand
+-- ----------------------------------------------------
+
+-- VORSICHT! - Nur in einer Test-Kopie ausfÃŒhren. LÃ¶scht Daten!
+
+  -- UPDATE ap_pto SET schriftinhalt = NULL  WHERE art = 'Strasse';
+  -- UPDATE ap_pto SET schriftinhalt = NULL  WHERE art = 'BezKlassifizierungStrasse';
+
+
+-- Anzeige der leeren SÃ€tze
+-- ---------------------------------------
+
+-- Diese Views ermitteln, ob der Fall im vorliegenden Datenbestand vorkommt.
+-- Dies ist in zunehmend in Niedersachsen der Fall.
+
+-- In NRW-Daten wurden weniger FÃ€lle gefunden.
+
+-- Dann ist jeweils auch die Signaturnummer leer. 
+-- Daher sollte "signaturnummer" nicht als Filter bei der "Reparatur" verwendet werden.
+
+
+-- DROP VIEW pp_praes_strassen_name_leer;
+CREATE OR REPLACE VIEW pp_praes_strassen_name_leer
+AS
+	SELECT gml_id, schriftinhalt, signaturnummer, art, drehwinkel
+	  FROM ap_pto
+	 WHERE schriftinhalt IS NULL
+	   AND art = 'Strasse'
+	-- AND (signaturnummer = '4107' OR signaturnummer = '8113') -- char
+;
+COMMENT ON VIEW pp_praes_strassen_name_leer 
+  IS 'Es fehlt der Name der StraÃe in der PrÃ€sentationstabelle ap_pto.';
+
+
+--DROP VIEW pp_praes_strassen_klass_leer;
+CREATE OR REPLACE VIEW pp_praes_strassen_klass_leer
+AS
+	SELECT gml_id, schriftinhalt, signaturnummer, art, drehwinkel
+	  FROM ap_pto
+	 WHERE schriftinhalt IS NULL  -- oder '' ?
+	   AND art = 'BezKlassifizierungStrasse'
+	-- AND (signaturnummer = '4080' OR signaturnummer = '4140' OR signaturnummer = '8115')
+;
+COMMENT ON VIEW pp_praes_strassen_klass_leer 
+  IS 'Es fehlt die Klassifikation der StraÃe in der PrÃ€sentationstabelle ap_pto.';
+
+
+-- Diese Views sollen zeigen, welche Namen in ap_pto.schriftinhalt eingesetzt werden,
+-- wenn die nachfolgenden update-Befehle ausgefÃŒhrt werden.
+
+-- Dies dient wÃ€hrend der Entwicklung zu manuellen Vorab-Kontrolle.
+-- Wenn hier keine Zeilen ausgegeben werden, kann die AusfÃŒhrung dieses Scriptes im Workflow ausgeschaltet werden.
+-- Dann sind (Bundesland-spezifisch) die Namen bereits gefÃŒllt und brauchen nicht 
+-- auf diese Weise rekonstruiert werden.
+
+-- An einem Referenzbestand (amtliche Karte?) kann/sollte kontrolliert werden, 
+--  ob die richtigen Namen zugeordnet werden.
+
+
+--DROP VIEW  pp_praes_strassen_name_update_vorschau;
+CREATE OR REPLACE VIEW pp_praes_strassen_name_update_vorschau
+AS
+  SELECT f.gemarkungsnummer || '-' || f.flurnummer || '-' || f.zaehler || '/' ||
+         coalesce(cast(f.nenner as character varying), '') AS fskennz, -- FlurstÃŒckskennzeichen zur Eingabe in Navigation
+         f.gml_id AS gml_fs,  -- ID des FlurstÃŒcks zum Nachsehen in der Auskunft (PHP/HTML)
+      -- p.gml_id AS gml_pto,
+         k.bezeichnung,                          -- der Name aus dem Katalog, der nach ap_pto kopiert wird
+         st_asewkt(p.wkb_geometry) AS label_geom -- Lesbare Koordinaten: Wo liegt der Label?
+  FROM   ax_lagebezeichnungkatalogeintrag  k     -- Katalog enthÃ€lt den StraÃennamen
+    JOIN ax_lagebezeichnungohnehausnummer  l     -- Diese Eintrag ist dem FlurstÃŒck als Lage o. HsNr. zugeordnet
+      ON ( k.land=l.land
+     AND k.regierungsbezirk=l.regierungsbezirk 
+     AND k.kreis=l.kreis
+     AND k.gemeinde=l.gemeinde
+     AND k.lage=l.lage )
+    JOIN alkis_beziehungen b ON l.gml_id = b.beziehung_zu 
+    JOIN ax_flurstueck     f ON f.gml_id = b.beziehung_von                -- FlurstÃŒck ..
+    JOIN ap_pto            p ON ST_Within(p.wkb_geometry, f.wkb_geometry) -- in dessen FlÃ€che die Label-Position liegt
+   WHERE p."art" = 'Strasse'  -- Filter
+     AND p.schriftinhalt      IS NULL       -- Text fehlt in ap_pto
+     AND NOT (p.wkb_geometry  IS NULL)      -- hat aber eine Position in ap_pto
+     AND b.beziehungsart = 'zeigtAuf'       -- Relation FlurstÃŒck - Lage o.HsNr
+  -- AND k.bezeichnung = 'Unter der Treff'  -- kleiner Test in Mustermonzel Testdaten
+   ORDER BY f.gemarkungsnummer, f.flurnummer, f.zaehler, f.nenner;
+
+COMMENT ON VIEW pp_praes_strassen_name_update_vorschau 
+  IS 'PrÃ€sentationsobjekt zu StraÃen. Vorschau zum Update des Namens der in ap_pto.';
+
+
+-- Werden hier zu einem PTO mÃ¶glicherweise mal mehrere Werte geliefert?
+-- In diesen Problem-FÃ€llen liefert die Subquery im Update (ohne Limit 1) mehrere Zeilen fÃŒr ein Feld.
+
+--DROP VIEW pp_praes_strassen_name_mehrfach;
+CREATE OR REPLACE VIEW pp_praes_strassen_name_mehrfach
+AS
+	SELECT p.gml_id, p.advstandardmodell,
+	   st_asewkt(p.wkb_geometry) AS label_geom,  -- Wo liegt der Label?
+       (SELECT f.gemarkungsnummer || '-' || f.flurnummer || '-' || f.zaehler || '/' ||
+        coalesce(cast(f.nenner as character varying), '') AS fskennz -- FlurstÃŒckskennzeichen zur Eingabe in Navigation
+		FROM ax_flurstueck f
+		WHERE ST_Within(p.wkb_geometry, f.wkb_geometry)
+	   ) AS flurstueck
+	FROM       ap_pto  p
+	 WHERE     p.art = 'Strasse'  
+	   AND     p.schriftinhalt IS NULL
+	   AND NOT p.wkb_geometry  IS NULL
+	   AND (SELECT count(k.bezeichnung) AS anzahl_label  -- die Subquery aus dem Update
+		   FROM ax_lagebezeichnungkatalogeintrag  k
+		   JOIN ax_lagebezeichnungohnehausnummer  l
+				ON k.land=l.land AND k.regierungsbezirk=l.regierungsbezirk AND k.kreis=l.kreis
+				   AND k.gemeinde=l.gemeinde AND k.lage=l.lage
+		   JOIN alkis_beziehungen b ON l.gml_id = b.beziehung_zu
+		   JOIN ax_flurstueck f ON f.gml_id = b.beziehung_von
+		  WHERE b.beziehungsart = 'zeigtAuf'
+			AND ST_Within(p.wkb_geometry, f.wkb_geometry)
+		  ) > 1
+	ORDER BY p.gml_id, p.advstandardmodell;
+
+COMMENT ON VIEW pp_praes_strassen_name_mehrfach 
+  IS 'PrÃ€sentationsobjekt zu StraÃen. Zu einem PTO werden ÃŒber das FlurstÃŒck mehrere Texte gefunden.';
+
+
+-- Work-Arround, bis die eindeutige Zuordnung von "ap_pto" zu "lagebezeichnung*" geklÃ€rt ist.  
+
+-- Wie "pp_praes_strassen_name_mehrfach" aber nur eine Liste der gml_id liefern um
+-- diese beim Update (vorlÃ€ufig) auszuschlieÃen.
+
+--DROP VIEW pp_praes_strassen_name_ausnahmen;
+CREATE OR REPLACE VIEW pp_praes_strassen_name_ausnahmen
+AS
+	SELECT p.gml_id
+	FROM   ap_pto  p
+	 WHERE p.art = 'Strasse'  
+	   AND p.schriftinhalt IS NULL
+	   AND NOT p.wkb_geometry  IS NULL
+	   AND (SELECT count(k.bezeichnung) AS anzahl_label  -- die Subquery aus dem Update
+		   FROM ax_lagebezeichnungkatalogeintrag  k
+		   JOIN ax_lagebezeichnungohnehausnummer  l
+				ON k.land=l.land AND k.regierungsbezirk=l.regierungsbezirk AND k.kreis=l.kreis
+				   AND k.gemeinde=l.gemeinde AND k.lage=l.lage
+		   JOIN alkis_beziehungen b ON l.gml_id = b.beziehung_zu
+		   JOIN ax_flurstueck f ON f.gml_id = b.beziehung_von
+		  WHERE b.beziehungsart = 'zeigtAuf'
+			AND ST_Within(p.wkb_geometry, f.wkb_geometry)
+		  ) > 1;
+
+COMMENT ON VIEW pp_praes_strassen_name_ausnahmen 
+  IS 'PrÃ€sentationsobjekt zu StraÃen. Zu einem PTO werden ÃŒber das FlurstÃŒck mehrere Texte gefunden. Liefert Liste der gml_is, die beim Update ausgenommen werden mÃŒssen.';
+
+
+--DROP VIEW pp_praes_strassen_klass_update_vorschau;
+CREATE OR REPLACE VIEW pp_praes_strassen_klass_update_vorschau
+AS
+  SELECT p.gml_id, -- ID des FlurstÃŒcks zum Nachsehen in der Auskunft (PHP/HTML)
+         f.gemarkungsnummer || '-' || f.flurnummer || '-' || f.zaehler || '/' ||
+         coalesce(cast(f.nenner as character varying), '') AS fskennz, -- FlurstÃŒckskennzeichen zur Eingabe in Navigation
+         k.bezeichnung,                          -- der Name aus dem Katalog, der nach ap_pto kopiert wird
+         st_asewkt(p.wkb_geometry) AS label_geom -- Lesbare Koordinaten: Wo liegt der Label?
+  FROM   ax_lagebezeichnungkatalogeintrag  k     -- Katalog enthÃ€lt den StraÃennamen
+    JOIN ax_lagebezeichnungohnehausnummer  l     -- Diese Eintrag ist dem FlurstÃŒck als Lage o. HsNr. zugeordnet
+     ON (k.land=l.land
+     AND k.regierungsbezirk=l.regierungsbezirk 
+     AND k.kreis=l.kreis
+     AND k.gemeinde=l.gemeinde
+     AND k.lage=l.lage)
+    JOIN alkis_beziehungen b ON l.gml_id = b.beziehung_zu 
+    JOIN ax_flurstueck     f ON f.gml_id = b.beziehung_von                -- FlurstÃŒck ..
+    JOIN ap_pto            p ON ST_Within(p.wkb_geometry, f.wkb_geometry) -- in dessen FlÃ€che die Label-Position liegt
+   WHERE p."art" = 'BezKlassifizierungStrasse'  -- Filter
+     AND p.schriftinhalt      IS NULL    -- Text fehlt in ap_pto
+     AND NOT (p.wkb_geometry  IS NULL)   -- hat aber eine Position in ap_pto
+     AND b.beziehungsart = 'zeigtAuf'    -- Relation FlurstÃŒck - Lage o.HsNr
+   ORDER BY f.flurnummer, f.zaehler, f.nenner;
+
+COMMENT ON VIEW pp_praes_strassen_klass_update_vorschau 
+  IS 'PrÃ€sentationsobjekt zu StraÃen. Vorschau zum Update der Klassifikation der in ap_pto.';
+
+
+-- ENDE --
Index: trunk/import/pp_praesentation_action.sql
===================================================================
--- trunk/import/pp_praesentation_action.sql	(revision 293)
+++ trunk/import/pp_praesentation_action.sql	(revision 293)
@@ -0,0 +1,115 @@
+
+-- ALKIS PostNAS 0.7
+
+-- Post Processing (pp_) Teil 3: PrÃ€sentationsobjekte ergÃ€nzen / reparieren
+
+-- Dies Script "pp_praesentation_action.sql" dient der Reparatur von fehlenden PrÃ€sentationsobjekten.
+-- Voraussetzung ist, dass vorher das Script "pp_praesentation_sichten.sql" verarbeitet wurde.
+
+-- Dies Script muss im Rahmen des Post-Processing nach jeder Konvertierung laufen.
+-- Das Sichten-Sript muss nur beim Anlegen der Datenbank einmalig verarbeitet werden 
+
+-- Stand 
+--  2013-10-16  F.J. krz: StraÃennamen fehlen in den PrÃ€sentationsobjekten, Tabelle "ap_pto"
+
+-- ========================================
+-- StraÃen-Namen und StraÃen-Klassifikation
+-- ========================================
+
+--
+-- Weitere Kommantare und ErlÃ€uterungen siehe in "pp_praesentation_sichten.sql".
+--
+
+-- Reparatur Sonderfall
+-- ====================
+
+  -- Gibt es FÃ€lle, wo der Label in einem benachbarten FS liegt?
+  -- Hat er dann einen Zuordnungspfeil?
+  -- Dann mÃŒssten diese SonderfÃ€lle zuerst gefÃŒllt werden.
+
+
+
+-- Reparatur Normalfall
+-- ====================
+
+   -- Label   >liegt in>   FlurstÃŒck     >zeigtAuf>       Lage o.H.   -->   Katalog
+   --        (Geometrisch)            (Alkis_Beziehung)             (JOIN)
+
+-- N a m e n
+UPDATE ap_pto  p          -- PrÃ€sentationsobjekte PunktfÃ¶rmig
+   SET schriftinhalt =    -- Hier fehlt der Label
+   -- Subquery "Gib mir den StraÃennamen":
+   -- Diese Subquery darf nur eine einzige Zeile liefern damit der Inhalt in eine Spalte passt.
+    (SELECT k.bezeichnung                        -- StraÃenname ...
+       FROM ax_lagebezeichnungkatalogeintrag  k  --   .. aus Katalog
+       JOIN ax_lagebezeichnungohnehausnummer  l  -- wobei dieser Katalogeintrag
+            ON     k.land=l.land
+               AND k.regierungsbezirk=l.regierungsbezirk 
+               AND k.kreis=l.kreis
+               AND k.gemeinde=l.gemeinde
+               AND k.lage=l.lage 
+       JOIN alkis_beziehungen  b  ON l.gml_id = b.beziehung_zu  -- in Beziehung steht
+       JOIN ax_flurstueck      f  ON f.gml_id = b.beziehung_von -- zu dem FlurstÃŒck
+      WHERE b.beziehungsart = 'zeigtAuf'
+        AND ST_Within(p.wkb_geometry, f.wkb_geometry) -- in dessen FlÃ€che der Label liegt
+    --LIMIT 1  -- siehe unten !
+    )
+ WHERE     p.art = 'Strasse'  -- Filter
+   AND     p.schriftinhalt IS NULL
+   AND NOT p.wkb_geometry  IS NULL
+   -- Die ap_pto zunÃ€chst auslassen, zu dessen FlurstÃŒcken es mehrere Lagebezeichnungen gibt.
+   AND p.gml_id NOT IN (SELECT * FROM pp_praes_strassen_name_ausnahmen); -- siehe unten !
+
+
+-- "LIMIT 1" wozu?
+
+-- Es wird mÃ¶glicherweise mal mehr als 1 Wert je Subquery geliefert.
+-- Dann ist dies SQL nicht ausfÃŒhrbar und bricht ab.
+
+-- In den Testdaten "Mustermonzel" sind Name und Klassifikation nicht unterscheidbar weil
+-- die Klassifikation nicht als art='BezKlassifizierungStrasse' sondern auch als art='strasse'
+-- eingetragen ist. Dann werden 2 Zeilen geliefert, die AusfÃŒhrung bricht ab.
+
+-- In aktuellen Daten ist diese Ursache ausgeschaltet.
+-- Es gibt trotzdem SonderfÃ€lle, bei dem mehrere Werte geliefert werden.
+-- Wenn das ÃŒber die Verschneidung gefundene FlurstÃŒcke mehrer "Lagebezeichnung ohne Hausnummer" hat,
+-- dann kann zur Zeit nicht jedes dieser Label der passenden Position aus ap_pto zugewiesen weden.
+-- Die obige LÃ¶sung funktioniert nur bei 1:1-Konstallationen.
+
+-- Welcher Label gehÃ¶rt dann zu welcher Position?
+-- Es gibt keine Verbindung (alkis_beziehung) zwischen "ap_pto" und "lagebezeichnung*".
+
+-- Die LÃ¶sung ÃŒber "LIMIT 1" macht die Query ausfÃŒhrbar, fÃŒhrt aber dazu, dass nur einer der 
+-- mehrfachen Label an allen Positionen angezeigt wird, was falsch ist.
+
+-- Die alternative LÃ¶sung ÃŒber 
+--    "p.gml_id NOT IN (SELECT * FROM pp_praes_strassen_name_ausnahmen)"
+-- lÃ€sst die Label dagegen zunÃ€chst leer.
+-- Diese FÃ€lle bleiben dann durch obigen Views weiterhin erkennbar. 
+
+
+-- K l a s s i f i k a t i o n e n
+-- (analog zu strassen)
+UPDATE ap_pto  p          -- PrÃ€sentationsobjekte PunktfÃ¶rmig
+   SET schriftinhalt =    -- Hier fehlt der Label
+   -- Subquery "Gib mir die StraÃen-Klassifikation":
+   -- Diese Subquery darf nur eine einzige Zeile liefern damit der Inhalt in eine Spalte passt.
+    (SELECT k.bezeichnung                        -- StraÃenname ...
+       FROM ax_lagebezeichnungkatalogeintrag  k  --   .. aus Katalog
+       JOIN ax_lagebezeichnungohnehausnummer  l  -- wobei dieser Katalogeintrag
+            ON     k.land=l.land
+               AND k.regierungsbezirk=l.regierungsbezirk 
+               AND k.kreis=l.kreis
+               AND k.gemeinde=l.gemeinde
+               AND k.lage=l.lage 
+       JOIN alkis_beziehungen  b  ON l.gml_id = b.beziehung_zu  -- in Beziehung steht
+       JOIN ax_flurstueck      f  ON f.gml_id = b.beziehung_von -- zu dem FlurstÃŒck
+      WHERE b.beziehungsart = 'zeigtAuf'
+        AND ST_Within(p.wkb_geometry, f.wkb_geometry) -- in dessen FlÃ€che der Label liegt
+    -- LIMIT 1
+    )
+ WHERE     p.art = 'BezKlassifizierungStrasse' -- Filter
+   AND     p.schriftinhalt IS NULL
+   AND NOT p.wkb_geometry  IS NULL;
+
+-- ENDE --
