-- =================================================================================== -- ALKIS-PostGIS Mapbender-Navigation und Buchauskunft für NorGIS-ALKIS-Importer -- =================================================================================== -- Aufgabe: Views bereit stellen für den CSV-Export in der ALKIS-Buch-Auskunft. -- Ausführung in: Step "postcreate.d" des ALKIS-Importers. Hier also nur Definitionen machen, keine Daten bearbeiten. --Stand -- 2016-02-23 -- 2016-11-24 Index auf ax.person.nachnameoderfirma für WMS Flurstuecke_kommunal -- 2016-12-01 exp_csv: Fehlerkorrektur bei Entschlüsselung der Buchungsart -- Optimierte Version (ohne Doppelverbindung) -- 2017-02-23 Spalte "fall" aus View "flst_an_strasse" im View "exp_csv_str" ausgeben. -- Darauf basiert ein neuer Filter im Programm "alkisexport.php". -- Sortierung FS-Kennz. repariert in Views "exp_csv" und "exp_csv_str" -- 2017-10-10 Berechtigungen rausgenommen in getrennte Datei -- 2017-12-06 Umbenennung von "x_classic2norgis.sql" nach "views_exp_csv.sql" -- 2017-12-20 Beseitigung des Fehlers: Mehrere Adressen zur Person fuehren zu mehrfachen Zeilen (Wiederholung Flurstück und Flaeche ..) -- Es wird je Persoon nur noch die "letzte" Adresse verwendet (subquery). -- Der View "exp_csv_str" ist jetzt direkt als 4fach-UNION (2x2) codiert statt mit eingebettetem gespeicherten 2fach-Union. -- Hauptvorteil: Keine undurchsichtigen Abhängigkeiten. Ist auch etwas schneller. -- 2017-12-20 Suche (Sortierung) 'letzte Adresse' nach "beginnt" statt nach "gml_id" -- 2018-05-02 Aufruf aus Grundstücksnahweis: tabtyp='buchung' $filter="gsgml" -- ToDo: -- - Überdenken: Ist die UNION-Abfrage mit "Recht an" notwendig und sinnvoll? -- -- Wenn ja, bei welchen Filtern? -- Ein Erbbaurecht wird geliefert (1x "an") aber Untererbbaurecht nicht mehr (2x Recht "an") -- I n d i c e s -- ============================ -- Der WMS "Flurstuecke Kommunal" (aus View "st_flurst[gkz][e|r]") wird langsam, wenn er in einer kreisweiten Datenbank ausgeführt wird. -- Das Filter-Feld benötigt einen Index: DROP INDEX if exists ax_person_nname; CREATE INDEX ax_person_nname ON ax_person USING btree (nachnameoderfirma COLLATE pg_catalog."default"); -- V i e w s -- ============================ -- Generelle Export-Struktur "Flurstück - Buchung - Grundbuch - Person" -- -------------------------------------------------------------------- -- Wird benötigt im Auskunft-Modul "alkisexport.php": -- Je nach aufrufendem Modul wird der Filter (WHERE) an anderer Stelle gesetzt (gml_id von FS, GB oder Pers.) -- Für Filter nach "Straße" siehe die nachfolgende Sonderversion "exp_csv_str". -- Problem / Konflikt: -- Es kann nur eine lineare Struktur aus Spalten und Zeilen exportiert werden. -- Wenn nicht nur die Daten des Ausgangs-Objektes exportiert werden, sondern auch verbundene Tabellen in -- einer 1:N-Struktur, dann verdoppeln sich Zeileninhalte und es werden redundante Daten erzeugt. -- Diese Redundanzen müssen vom dem Programm gefiltert werden, das die Daten über eine Schnittstelle einliest. -- Anwendungs-Beispiel: Abrechnung von Anliegerbeiträgen. DROP VIEW IF EXISTS exp_csv; CREATE OR REPLACE VIEW exp_csv AS SELECT -- Fall: einfache Buchung (ohne "Recht an") -- F l u r s t ü c k f.gml_id AS fsgml, -- möglicher Filter Flurstücks-GML-ID f.flurstueckskennzeichen AS fs_kennz, f.gemarkungsnummer, -- Teile des FS-Kennz. noch mal einzeln f.flurnummer, f.zaehler, f.nenner, f.amtlicheflaeche AS fs_flae, g.bezeichnung AS gemarkung, -- G r u n d b u c h gb.gml_id AS gbgml, -- möglicher Filter Grundbuch-GML-ID gb.bezirk AS gb_bezirk, gb.buchungsblattnummermitbuchstabenerweiterung AS gb_blatt, z.bezeichnung AS beznam, -- GB-Bezirks-Name -- B u c h u n g s s t e l l e (Grundstück) s.gml_id AS gsgml, -- möglicher Filter Grundstück-GML-ID s.laufendenummer AS bu_lfd, -- BVNR '=' || s.zaehler || '/' || s.nenner AS bu_ant, -- als Excel-Formel (nur bei Wohnungsgrundbuch JOIN über 'Recht an') s.buchungsart, -- verschlüsselt wb.v AS bu_art, -- Buchungsart entschlüsselt -- N a m e n s N u m m e r (Normalfall mit Person) nn.laufendenummernachdin1421 AS nam_lfd, '=' || nn.zaehler|| '/' || nn.nenner AS nam_ant, -- als Excel-Formel -- R e c h t s g e m e i n s c h a f t (Sonderfall von Namensnummer, ohne Person, ohne Nummer) rg.artderrechtsgemeinschaft AS nam_adr, rg.v AS nam_adrv, -- Art der Rechtsgem. - Value zum Key rg.beschriebderrechtsgemeinschaft AS nam_bes, -- P e r s o n p.gml_id AS psgml, -- möglicher Filter Personen-GML-ID p.anrede, -- Anrede key wp.v AS anrv, -- Anrede Value zum Key p.vorname, p.namensbestandteil, p.nachnameoderfirma, -- Familienname p.geburtsdatum, -- A d r e s s e der Person a.postleitzahlpostzustellung AS plz, a.ort_post AS ort, -- Anschreifenzeile 1: PLZ+Ort a.strasse, a.hausnummer, -- Anschriftenzeile 2: Straße+HsNr a.bestimmungsland AS land FROM ax_flurstueck f -- Flurstück JOIN ax_gemarkung g -- entschlüsseln ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer JOIN ax_buchungsstelle s -- FS >istGebucht> Buchungstelle ON f.istgebucht = s.gml_id JOIN ax_buchungsblatt gb -- Buchung >istBestandteilVon> Grundbuchblatt ON gb.gml_id = s.istbestandteilvon JOIN ax_buchungsblattbezirk z ON gb.land=z.land AND gb.bezirk=z.bezirk JOIN ax_namensnummer nn -- Blatt benennt> Person ON p.gml_id = nn.benennt LEFT JOIN ax_anschrift a -- nur die "letzte" Anschrift zur Person verwenden ON a.gml_id = (SELECT gml_id FROM ax_anschrift an WHERE an.gml_id = ANY(p.hat) AND an.endet IS NULL ORDER BY an.beginnt DESC LIMIT 1) -- E n t s c h l ü s s e l n: LEFT JOIN alkis_wertearten wp -- Entschlüsseln "Person - Anrede" ON cast(p.anrede AS character varying) = wp.k AND wp.element = 'ax_person' AND wp.bezeichnung = 'anrede' LEFT JOIN alkis_wertearten wb -- Entschlüsseln "Buchungsart" ON cast(s.buchungsart AS character varying) = wb.k -- buchungsart = integer / .k = char 4stellig AND wb.element = 'ax_buchungsstelle' AND wb.bezeichnung = 'buchungsart' -- 2mal "LEFT JOIN" verdoppelt die Zeile in der Ausgabe. Darum als Subquery in Spalten packen: -- Noch mal "GB -> NamNum", aber dieses Mal für "Rechtsgemeinschaft". -- Kommt max. 1 mal je GB vor und hat keine Relation auf Person. LEFT JOIN ( SELECT gr.gml_id, r.artderrechtsgemeinschaft, r.beschriebderrechtsgemeinschaft, wr.v FROM ax_namensnummer r JOIN ax_buchungsblatt gr ON r.istbestandteilvon = gr.gml_id -- Blatt istGebucht> Buchungstelle istBestandteilVon> Grundbuchblatt ON gb.gml_id = s.istbestandteilvon JOIN ax_buchungsblattbezirk z ON gb.land=z.land AND gb.bezirk=z.bezirk JOIN ax_namensnummer nn -- Blatt benennt> Person ON p.gml_id = nn.benennt LEFT JOIN ax_anschrift a -- nur die "letzte" Anschrift zur Person verwenden ON a.gml_id = (SELECT gml_id FROM ax_anschrift an WHERE an.gml_id = ANY(p.hat) AND an.endet IS NULL ORDER BY an.beginnt DESC LIMIT 1) -- E n t s c h l ü s s e l n: LEFT JOIN alkis_wertearten wp -- Entschlüsseln "Person - Anrede" ON cast(p.anrede AS character varying)=wp.k AND wp.element='ax_person' AND wp.bezeichnung='anrede' LEFT JOIN alkis_wertearten wb -- Entschlüsseln "Buchungsart" ON cast(s.buchungsart AS character varying) = wb.k AND wb.element = 'ax_buchungsstelle' AND wb.bezeichnung = 'buchungsart' LEFT JOIN ( SELECT gr.gml_id, r.artderrechtsgemeinschaft, r.beschriebderrechtsgemeinschaft, wr.v FROM ax_namensnummer r JOIN ax_buchungsblatt gr ON r.istbestandteilvon = gr.gml_id -- Blatt weistAuf> ax_lagebezeichnungMIThausnummer ax_lagebezeichnungkatalogeintrag JOIN ax_lagebezeichnungmithausnummer lm -- Lage MIT ON lm.gml_id = ANY (f.weistauf) JOIN ax_lagebezeichnungkatalogeintrag sm ON lm.land=sm.land AND lm.regierungsbezirk=sm.regierungsbezirk AND lm.kreis=sm.kreis AND lm.gemeinde=sm.gemeinde AND lm.lage=sm.lage JOIN ax_gemarkung g -- entschlüsseln ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer JOIN ax_buchungsstelle s -- FS >istGebucht> Buchungstelle ON f.istgebucht = s.gml_id JOIN ax_buchungsblatt gb -- Buchung >istBestandteilVon> Grundbuchblatt ON gb.gml_id = s.istbestandteilvon JOIN ax_buchungsblattbezirk z ON gb.land=z.land AND gb.bezirk=z.bezirk JOIN ax_namensnummer nn -- Blatt benennt> Person ON p.gml_id = nn.benennt LEFT JOIN ax_anschrift a -- nur die "letzte" Anschrift zur Person verwenden ON a.gml_id = (SELECT gml_id FROM ax_anschrift an WHERE an.gml_id = ANY(p.hat) AND an.endet IS NULL ORDER BY an.beginnt DESC LIMIT 1) -- E n t s c h l ü s s e l n: LEFT JOIN alkis_wertearten wp -- Entschlüsseln "Person - Anrede" ON cast(p.anrede AS character varying) = wp.k AND wp.element = 'ax_person' AND wp.bezeichnung = 'anrede' LEFT JOIN alkis_wertearten wb -- Entschlüsseln "Buchungsart" ON cast(s.buchungsart AS character varying) = wb.k -- buchungsart = integer / .k = char 4stellig AND wb.element = 'ax_buchungsstelle' AND wb.bezeichnung = 'buchungsart' -- 2mal "LEFT JOIN" verdoppelt die Zeile in der Ausgabe. Darum als Subquery in Spalten packen: -- Noch mal "GB -> NamNum", aber dieses Mal für "Rechtsgemeinschaft". -- Kommt max. 1 mal je GB vor und hat keine Relation auf Person. LEFT JOIN ( SELECT gr.gml_id, r.artderrechtsgemeinschaft, r.beschriebderrechtsgemeinschaft, wr.v FROM ax_namensnummer r JOIN ax_buchungsblatt gr ON r.istbestandteilvon = gr.gml_id -- Blatt weistAuf> ax_lagebezeichnungMIThausnummer ax_lagebezeichnungkatalogeintrag JOIN ax_lagebezeichnungmithausnummer lm -- Lage MIT ON lm.gml_id = ANY (f.weistauf) JOIN ax_lagebezeichnungkatalogeintrag sm ON lm.land=sm.land AND lm.regierungsbezirk=sm.regierungsbezirk AND lm.kreis=sm.kreis AND lm.gemeinde=sm.gemeinde AND lm.lage=sm.lage JOIN ax_gemarkung g -- entschlüsseln ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer -- FS >istGebucht> Buchungstelle istBestandteilVon> Grundbuchblatt ON gb.gml_id = s.istbestandteilvon JOIN ax_buchungsblattbezirk z ON gb.land=z.land AND gb.bezirk=z.bezirk JOIN ax_namensnummer nn -- Blatt benennt> Person ON p.gml_id = nn.benennt LEFT JOIN ax_anschrift a -- nur die "letzte" Anschrift zur Person verwenden ON a.gml_id = (SELECT gml_id FROM ax_anschrift an WHERE an.gml_id = ANY(p.hat) AND an.endet IS NULL ORDER BY an.beginnt DESC LIMIT 1) -- E n t s c h l ü s s e l n: LEFT JOIN alkis_wertearten wp -- Entschlüsseln "Person - Anrede" ON cast(p.anrede AS character varying)=wp.k AND wp.element='ax_person' AND wp.bezeichnung='anrede' LEFT JOIN alkis_wertearten wb -- Entschlüsseln "Buchungsart" ON cast(s.buchungsart AS character varying) = wb.k AND wb.element = 'ax_buchungsstelle' AND wb.bezeichnung = 'buchungsart' LEFT JOIN ( SELECT gr.gml_id, r.artderrechtsgemeinschaft, r.beschriebderrechtsgemeinschaft, wr.v FROM ax_namensnummer r JOIN ax_buchungsblatt gr ON r.istbestandteilvon = gr.gml_id -- Blatt zeigtAuf> ax_lagebezeichnungOHNEhausnummer ax_lagebezeichnungkatalogeintrag JOIN ax_lagebezeichnungohnehausnummer lo -- Lage OHNE ON lo.gml_id = ANY (f.zeigtauf) JOIN ax_lagebezeichnungkatalogeintrag so -- Straße OHNE ON lo.land=so.land AND lo.regierungsbezirk=so.regierungsbezirk AND lo.kreis=so.kreis AND lo.gemeinde=so.gemeinde AND lo.lage=so.lage JOIN ax_gemarkung g -- entschlüsseln ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer JOIN ax_buchungsstelle s -- FS >istGebucht> Buchungstelle ON f.istgebucht = s.gml_id JOIN ax_buchungsblatt gb -- Buchung >istBestandteilVon> Grundbuchblatt ON gb.gml_id = s.istbestandteilvon JOIN ax_buchungsblattbezirk z ON gb.land=z.land AND gb.bezirk=z.bezirk JOIN ax_namensnummer nn -- Blatt benennt> Person ON p.gml_id = nn.benennt LEFT JOIN ax_anschrift a -- nur die "letzte" Anschrift zur Person verwenden ON a.gml_id = (SELECT gml_id FROM ax_anschrift an WHERE an.gml_id = ANY(p.hat) AND an.endet IS NULL ORDER BY an.beginnt DESC LIMIT 1) -- E n t s c h l ü s s e l n: LEFT JOIN alkis_wertearten wp -- Entschlüsseln "Person - Anrede" ON cast(p.anrede AS character varying) = wp.k AND wp.element = 'ax_person' AND wp.bezeichnung = 'anrede' LEFT JOIN alkis_wertearten wb -- Entschlüsseln "Buchungsart" ON cast(s.buchungsart AS character varying) = wb.k -- buchungsart = integer / .k = char 4stellig AND wb.element = 'ax_buchungsstelle' AND wb.bezeichnung = 'buchungsart' -- 2mal "LEFT JOIN" verdoppelt die Zeile in der Ausgabe. Darum als Subquery in Spalten packen: -- Noch mal "GB -> NamNum", aber dieses Mal für "Rechtsgemeinschaft". -- Kommt max. 1 mal je GB vor und hat keine Relation auf Person. LEFT JOIN ( SELECT gr.gml_id, r.artderrechtsgemeinschaft, r.beschriebderrechtsgemeinschaft, wr.v FROM ax_namensnummer r JOIN ax_buchungsblatt gr ON r.istbestandteilvon = gr.gml_id -- Blatt zeigtAuf> ax_lagebezeichnungOHNEhausnummer ax_lagebezeichnungkatalogeintrag JOIN ax_lagebezeichnungohnehausnummer lo -- Lage OHNE ON lo.gml_id = ANY (f.zeigtauf) JOIN ax_lagebezeichnungkatalogeintrag so -- Straße OHNE ON lo.land=so.land AND lo.regierungsbezirk=so.regierungsbezirk AND lo.kreis=so.kreis AND lo.gemeinde=so.gemeinde AND lo.lage=so.lage JOIN ax_gemarkung g -- entschlüsseln ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer -- FS >istGebucht> Buchungstelle istBestandteilVon> Grundbuchblatt ON gb.gml_id = s.istbestandteilvon JOIN ax_buchungsblattbezirk z ON gb.land=z.land AND gb.bezirk=z.bezirk JOIN ax_namensnummer nn -- Blatt benennt> Person ON p.gml_id = nn.benennt LEFT JOIN ax_anschrift a -- nur die "letzte" Anschrift zur Person verwenden ON a.gml_id = (SELECT gml_id FROM ax_anschrift an WHERE an.gml_id = ANY(p.hat) AND an.endet IS NULL ORDER BY an.beginnt DESC LIMIT 1) -- E n t s c h l ü s s e l n: LEFT JOIN alkis_wertearten wp -- Entschlüsseln "Person - Anrede" ON cast(p.anrede AS character varying)=wp.k AND wp.element='ax_person' AND wp.bezeichnung='anrede' LEFT JOIN alkis_wertearten wb -- Entschlüsseln "Buchungsart" ON cast(s.buchungsart AS character varying) = wb.k AND wb.element = 'ax_buchungsstelle' AND wb.bezeichnung = 'buchungsart' LEFT JOIN ( SELECT gr.gml_id, r.artderrechtsgemeinschaft, r.beschriebderrechtsgemeinschaft, wr.v FROM ax_namensnummer r JOIN ax_buchungsblatt gr ON r.istbestandteilvon = gr.gml_id -- Blatt