source: trunk/info/info/alkisn/alkisexport.php @ 431

Revision 431, 13.2 KB checked in by frank.jaeger, 18 months ago (diff)

kleine Fehlerkorrekturen an der Auskunft

Line 
1<?php
2/*      alkisexport.php
3
4        ALKIS-Auskunft
5        Author: Frank JÀger, Kommunales Rechenzentrum Minden-Ravensberg/Lippe (Lemgo)
6       
7        CSV-Export von ALKIS-Daten zu einem Flurstueck, Grundbuch, EigentÃŒmer oder Straße.
8        Es wird eine GML-ID ÃŒbergeben.
9        Es wird ein gespeicherter View verwendet, der nach der gml_id gefiltert wird.
10        Der View verkettet Flurstueck - Buchungsstelle - Grundbuch - EigentÃŒmer
11        Die Lagebezeichnung des FlurstÃŒcks wird in ein Feld komprimiert.
12        Parameter Beispiele:
13                ?gkz=mandant&tabtyp=flurstueck/grundbuch/buchung/person/strasse&gmlid=DE...  Standard
14                ?gkz=270&tabtyp=gemarkung&gemarkung=2662         Sonderfall ganze Gemarkung
15                ?gkz=270&gemarkung=2662
16                ?gkz=mandant&tabtyp=strasse&haus=m&gmlid=DE...   Filter &haus=m/o = mit oder ohne Hausnummer
17                ?gkz=mandant&tabtyp=strasse&haus=o               bei Strasse auch ohne gmlid zulÀssig - nicht verwenden wenn aus NBA unscharf geladen
18                ?gkz240,tabtyp=flstliste&gmlliste=DE...,DE....
19        Beispiele fÃŒr Fehler:
20                ?gkz=270&tabtyp=gemarkung&gmlid=2662
21                ?gkz=270&tabtyp=flurstueck&gemarkung=2662
22                ?gkz=270&tabtyp=flurstueck
23                ?gkz=270&gmlid=2662
24
25        Version:
26        --------
27        2016-02-23      Version fÃŒr norGIS-ALKIS-Import
28        ....
29        2018-05-03 Aufruf aus neuem GrundstÃŒcksnachweis: tabtyp='buchung', angepasster View "exp_csv" notwendig
30        2018-10-16 Neuer Aufruf-Typ aus der rÀumlichen Selektion, &tabtyp=flstliste&prefix=DENW15&gmlliste=AL...,AL....
31        2020-12-16 Input-Validation und Strict Comparisation (===), BerechtigungsprÃŒfung vorÃŒbergehend deaktiviert
32        2021-12-01 Client-Encoding
33        2022-07-05 PHP 8.1: Connection verwenden bei "pg_prepare" und "pg_execute", keine NULL-Werte in String-Functions verwenden
34
35        ToDo:.
36        - In den gespeicherten Views "exp_csv" und "exp_csv_str" den Fall Kataster-Amts-Mix berÃŒcksichtigen.
37        - Abruf FlurstÃŒck sollte auch mit "fskennz" (ggg-ff-zzz/nn) statt "gml-id" möglich sein
38        - In Dateiname den Straßennamen statt der gmlid verwenden? (Umlaute?)
39        - in alkislage.php fÃŒr den Typ "ohne Haunummer" den Export mit strasse und haus=o verlinken
40*/
41
42function lage_zum_fs($gmlid) {
43        // Zu einem FlurstÃŒck die Lagebezeichnungen (mit Hausnummer) so aufbereiten,
44        // dass ggf. mehrere Lagebezeichnungen in eine Zelle der Tabelle passen.
45        // FS >westAuf> Lage >> Katalog
46        global $con;
47        $sql ="SELECT DISTINCT s.bezeichnung, l.hausnummer "
48        ."FROM ax_flurstueck f JOIN ax_lagebezeichnungmithausnummer l ON l.gml_id=ANY(f.weistauf) "
49        ."JOIN ax_lagebezeichnungkatalogeintrag s ON l.kreis=s.kreis AND l.gemeinde=s.gemeinde AND l.lage=s.lage "
50        ."WHERE f.gml_id= $1 AND f.endet IS NULL AND l.endet IS NULL AND s.endet IS NULL ORDER BY s.bezeichnung, l.hausnummer;";
51
52        $v=array($gmlid);
53        $res=pg_prepare($con, "", $sql);
54        $res=pg_execute($con, "", $v);
55        if (!$res) {return "** Fehler bei Lagebezeichnung **";}
56        $j=0;
57        $lagehsnr="";
58        $salt="";
59        while($row = pg_fetch_assoc($res)) {
60                if ($j > 0) {$lagehsnr.=", ";}
61                $sneu=$row["bezeichnung"];
62                if ($sneu === $salt) { // gleiche Str.
63                        $lagehsnr.=$row["hausnummer"]; // HsNr dran hÀngen
64                } else { // Name UND HsNr dran hÀngen
65                        $lagehsnr.=$sneu." ".$row["hausnummer"];
66                }
67                $salt=$sneu; // Name f. nÀchste Runde
68                $j++;
69        }
70        pg_free_result($res);
71        return($lagehsnr);
72}
73
74// START
75$tabtyp='';  $haus=''; // Var. init.
76$cntget = extract($_GET); // Parameter in Variable umwandeln
77
78// strikte Validierung aller Parameter
79if (isset($gmlid)) {
80        if ( !preg_match('#^[0-9A-Za-z]{16}$#', $gmlid)) {die("Eingabefehler gmlid");}
81} else {
82        $gmlid="";
83}
84
85// FS-Limit? x (16+1) =
86if (isset($gmlliste)) {
87        if (!preg_match("#^[0-9A-Za-z,]{16,2000}$#", $gmlliste)) {
88                die("Eingabefehler gmlliste");
89        }
90}
91
92if (isset($gkz)) {
93        if (!preg_match('#^[0-9]{3}$#', $gkz)) {die("Eingabefehler gkz");}
94} else {
95        die("Fehlender Parameter");
96}
97if (isset($gemarkung)) {
98        if (!preg_match('#^[0-9]{4}$#', $gemarkung)) {die("Eingabefehler gemarkung");}
99} else {
100        $gemarkung='';
101}
102if (!preg_match('#^[m|o]{0,1}$#', $haus)) {die("Eingabefehler haus");}
103if (!preg_match('#^[a-z]{0,10}$#', $tabtyp)) {die("Eingabefehler tabtyp");}
104
105include "alkis_conf_location.php";
106include "alkisfkt.php";
107
108if ($tabtyp === '') { // Parameter (-kombinationen) prÃŒfen
109        if ($gemarkung != '') { // Dieser Parameters bestimmt auch eindeutig den $tabtyp
110                $tabtyp = 'gemarkung';
111        } else {  // Bei "gmlid" MUSS man zwingend die Tabelle dazu nennen
112                $err="\nFehler: Art des Suchfilters nicht angeben.";
113                exit ($err);
114        }
115} elseif ($tabtyp === 'gemarkung') {
116        if ($gemarkung === '') {
117                $err="\nFehler: Gemarkungsnummer nicht angeben.";
118                exit ($err);
119        }
120}
121
122if ($gmlid != '') { // Angabe von gmlid ist der Normalfall, das passt fÃŒr fast jeden tabtyp
123        if ($tabtyp === 'strasse' and $haus != '') { // den Zusatzfilter m/o im Dateinamen dokumentieren
124                if ($haus === 'm') {
125                        $filename='alkis_'.$tabtyp.'_'.$gmlid.'_mit_hsnr.csv';
126                } else {  // = o
127                        $filename='alkis_'.$tabtyp.'_'.$gmlid.'_ohne_hsnr.csv.csv';
128                }
129        } else {
130                $filename='alkis_'.$tabtyp.'_'.$gmlid.'.csv';
131        }
132} else { // Oh Oh! Keine gmlid! - Alternativen?
133        if ($gemarkung != '') { // Sonderfall 1 - Gemarkungsnummer statt gmlid als Filter
134                if ($tabtyp != 'gemarkung') {
135                        $err = "Fehler: Falsche Kombination Parameter tabtyp='".$tabtyp."' mit Wert fuer Gemarkungsnummer.";
136                        echo "\n".$err; exit ($err);
137                }
138                $filename='alkis_'.$tabtyp.'_'.$gemarkung.'.csv';
139
140/*      // $gmlid zu strasse ist noch notwendig solange kein Filter auf "Gemeinde" verwendet wird.
141        } elseif ($haus === 'm' or $haus === 'o') { // Sonderfall 2 - alle mit/ohne Hausnummer, nur ÃŒber View "exp_csv_str" möglich
142                if ($tabtyp != 'strasse') {
143                        $err="\nFehler: Falsche Kombination Parameter tabtyp='".$tabtyp."' mit Wert fuer Haus.";
144                        exit ($err);
145                }
146                if ($haus === 'm') { // den Zusatzfilter m/o im Dateinamen dokumentieren
147                        $filename='alkis_'.$tabtyp.'_mit_hsnr.csv';
148                } else {
149                        $filename='alkis_'.$tabtyp.'_ohne_hsnr.csv';
150                }
151*/
152        } elseif ($gmlliste != '') { // Sonderfall 3 - FlurstÃŒcke aus rÀumlicher Selection
153                if ($tabtyp != 'flstliste') {
154                        $err = "Fehler: Falsche Kombination Parameter tabtyp='".$tabtyp."' mit Liste der GML-ID.";
155                        echo "\n".$err; exit ($err);
156                }
157                if (!isset($prefix) or !preg_match("#^[A-Z0-9,]{6}$#", $prefix)) {
158                        die("Eingabefehler prefix");
159                }
160                $filename='alkis_gebiet.csv'; // RÀumliche Selection
161
162        } else {
163                $err="\nFehler: Kein passender Wert fuer die Suche angegeben.";
164                exit ($err);
165        }
166}
167
168// DOWNLOAD der CSV-Datei vorbereiten (statt HTML-Ausgabe)
169header('Content-type: application/octet-stream');
170header('Content-Disposition: attachment; filename="'.$filename.'"');
171
172// CSV-Ausgabe: Kopfzeile mit Feldnamen
173echo "FS-Kennzeichen;GmkgNr;Gemarkung;Flur;Flurstueck;Flaeche;Adressen;GB-BezNr;GB-Bezirk;GB-Blatt;BVNR;Anteil_am_FS;Buchungsart;Namensnummer;AnteilDerPerson;RechtsGemeinschaft;Person;GebDatum;Anschrift;Anteil(berechnet)";
174
175// Datenbank-Verbindung
176$con = pg_connect($dbconn." options='--application_name=ALKIS-Auskunft_alkisexport.php'");
177if (!$con) {
178        $err= "Fehler beim Verbinden der DB";
179        echo "\n".$err; exit($err);
180}
181//pg_set_client_encoding($con, 'LATIN1'); // FÃŒr Excel kein UTF8
182pg_set_client_encoding($con, 'WIN1252'); // Auch Buchstaben z.B. mit "CARON", wie ş Ŝ š Š
183
184//$viewname="exp_csv"; // Standard-View, in der DB gespeichert
185$v=array($gmlid); // Standard-Filter-Feld
186
187// Der Parameter "Tabellentyp" bestimmt den Namen des Filter-Feldes aus dem View "exp_csv".
188switch ($tabtyp) { // zulaessige Werte fuer &tabtyp=
189
190        case 'flurstueck': // ax_flurstueck.gml_id
191                $sql="SELECT * FROM exp_csv WHERE fsgml = $1 ";
192                break;
193
194        case 'grundbuch': // ax_buchungsblatt.gml_id
195                $sql="SELECT * FROM exp_csv WHERE gbgml = $1 ";
196                break;
197
198        case 'buchung': // ax_buchungsstelle.gml_id (bei "Recht an" die herrschende Buchung)
199                $sql="SELECT * FROM exp_csv WHERE gsgml = $1 "; // 2022-11-02: gsgml im View eingefÃŒgt
200                break;
201
202        case 'person': // ax_person.gml_id
203                $sql="SELECT * FROM exp_csv WHERE psgml = $1 ";
204                break;
205
206        case 'strasse': // ax_lagebezeichnungkatalogeintrag.gml_id = Straße-GML-ID
207                // alternativer View mit "_str", ist in der Datenbank gespeichert
208                $sql="SELECT * FROM exp_csv_str WHERE stgml = $1 ";
209                break;
210
211        case 'gemarkung': // SONDERfall als Parameter wird "Gemarkungsnummer" und nicht "gml_id" geliefert
212                $sql="SELECT * FROM exp_csv WHERE gemarkungsnummer = $1 ";
213                $v=array($gemarkung);
214                break;
215
216        case 'flstliste':
217        // GML-ID aufgeteilt: 6 Byte konstant, 10 Byte variabel in Liste
218                $sql="SELECT * FROM exp_csv WHERE substring(fsgml from 1 for 6) = $1 "
219                        ." AND substring(fsgml from 7 for 10) IN ('".str_replace(",", "','", $gmlliste)."')";
220                $v=array($prefix);
221                break;
222
223        default:
224                $err="\nFalscher Parameter '".$tabtyp."'";
225                exit($err);
226                break;
227}
228
229if ($haus === 'm' or $haus === 'o') { // nur FS mit/ohne verschl. Lagebez.
230//      if ($gmlid === '') { // m/o-Filter als einziger Filter
231//              $sql="SELECT * FROM ".$viewname." WHERE fall='".$haus."' "; // Ersetzen
232//              $v=array(); // kein Filter-Feld
233//              // ToDo: Filter auf Gemeinde notwendig, wenn nicht auf strasse gefiltert wird.
234//              // - Sonst Ausgabe von Rand-FlurstÃŒcken (bei geometrischer Filterung des NBA-Verfahrens)
235//              // - Sonst ggf. Ausgabe Kreisgebiet
236//      } else { // als zusÀtzlicher Filter AND
237
238                $sql.=" AND fall='".$haus."' "; // m/o-Filter AnhÀngen
239
240//      }
241}
242
243$res=pg_prepare($con, "", $sql);
244$res=pg_execute($con, "", $v);
245if (!$res) {
246        $err="\nFehler bei Datenbankabfrage";
247        exit($err);
248}
249$i=1; // Kopfzeile zÀhlt mit
250$fsalt='';
251
252// Datenfelder auslesen
253while($row = pg_fetch_assoc($res)) {
254        $i++; // Zeile der Tabelle
255        $rechnen=true; // Formel in letzte Spalte?
256
257        // Flurstueck
258        $fsgml=$row["fsgml"];
259        $fs_kennz=$row["fs_kennz"]; // Rechts Trim "_" ?
260        $gmkgnr=$row["gemarkungsnummer"];
261        $gemkname=$row["gemarkung"];
262        $flurnummer=$row["flurnummer"];
263        $flstnummer=$row["zaehler"];
264        $nenner=$row["nenner"];
265        // Bruchnummer kann in Excel als Datum interpretiert werden. In '' setzen.
266        if ($nenner > 0) {$flstnummer="'".$flstnummer."/".$nenner."'";} // BruchNr
267        $fs_flae=$row["fs_flae"]; // amtliche Fl. aus DB-Feld
268
269        // Grundbuch (Blatt)
270        $gb_bezirk=$row["gb_bezirk"]; // Nummer des Bezirks
271    $gb_beznam=$row["beznam"];    // Name des Bezirks
272        $gb_blatt=$row["gb_blatt"];
273
274        // Buchungsstelle (Grundstueck)
275        $bu_lfd=$row["bu_lfd"]; // BVNR
276        $bu_ant=$row["bu_ant"]; // '=zaehler/nenner' oder NULL
277        $bu_key=$row["buchungsart"]; // SchlÃŒssel
278        $bu_art=$row["bu_art"]; // entschlÃŒsselt (Umlaute in ANSI!)
279        if($bu_ant == '') { // Keine Bruch-Zahl
280                $bu_ant = '1'; // "voller Anteil" (Faktor 1)
281        } else {
282                $bu_ant=str_replace(".", ",", $bu_ant); // Dezimalkomma statt -punkt.           
283        }
284
285        // Namensnummer
286        $nam_lfd="'".kurz_namnr($row["nam_lfd"])."'"; // In Hochkomma, wird sonst wie Datum dargestellt.
287        $nam_ant=$row["nam_ant"];
288        $nam_adr=$row["nam_adr"]; // Art der Rechtsgemeischaft (SchlÃŒssel)
289
290        if ($nam_adr == '') {     // keine Rechtsgemeinschaft
291                $rechtsg='';
292                if ($nam_ant == '') { // und kein Bruch-Anteil
293                        $nam_ant=1; // dann ganzer Anteil
294                }
295        } else {
296                $rechnen=false; // bei Rechtsgemeinschaft die Anteile manuell interpretieren
297                if ($nam_adr == 9999) { // sonstiges
298                        $rechtsg=$row["nam_bes"]; // Beschrieb der Rechtsgemeinschaft
299                } else {
300                //      $rechtsg=rechtsgemeinschaft($nam_adr); // EntschlÃŒsseln
301                        $rechtsg=$row["nam_adrv"]; // Art der Rechtsgemeischaft (Value zum Key)
302                }
303        }
304
305        // Person
306        $vnam=$row["vorname"];
307        $nana=$row["nachnameoderfirma"];
308        $namteil=$row["namensbestandteil"];
309        //$name=anrede($row["anrede"]); 
310        $name=$row["anrv"]; // Anrede (Value zum Key)
311        if ($name != "") {$name.=" ";} // Trenner
312        if ($namteil != "") {$name.=$namteil." ";} // von und zu
313        $name.=$nana;
314        if ($vnam != "") {$name.=", ".$vnam;} // Vorname nach hinten
315        $gebdat=$row["geburtsdatum"];
316        // Koennte man im View in deutsches Format umwandeln: "to_char(cast(geburtsdatum AS date),'DD.MM.YYYY') AS geburtsdatum"
317
318        // Adresse der Person (Eigentuemer)
319        // Im View ist per subquery geregelt, dass nur die "juengste" Adresse verwendet wird.
320        $ort=$row["ort"];
321        if ($ort == "") {
322                $adresse="";
323        } else {
324                $adresse=$row["strasse"]." ".$row["hausnummer"].", ".$row["plz"]." ".$ort;
325                $land=$row["land"]; // nur andere Laender anzeigen
326                if (($land != "DEUTSCHLAND") and ($land != "")) {
327                        $adresse.=" (".$land.")";
328                }
329        }
330
331        // Adressen (Lage) zum FS
332        if($fsgml != $fsalt) { // nur bei geÀndertem Kennz.
333                $lage=lage_zum_fs($fsgml); // die Lage neu ermitteln
334                $fsalt=$fsgml;
335        }
336
337        // Den Ausgabe-Satz montieren aus FlurstÃŒcks-, Grundbuch- und Namens-Teil
338        //      A             B           C             D               E               F            G
339        $fsteil=$fs_kennz.";".$gmkgnr.";".$gemkname.";".$flurnummer.";".$flstnummer.";".$fs_flae.";".$lage.";";
340        //      H              I              J             K           L           M
341        $gbteil=$gb_bezirk.";".$gb_beznam.";".$gb_blatt.";".$bu_lfd.";".$bu_ant.";".$bu_art.";";
342        //       N            O            P            Q         R           S
343        $namteil=$nam_lfd.";".$nam_ant.";".$rechtsg.";".$name.";".$gebdat.";".$adresse;
344
345        // Anteile "GB am FS" und "Pers am GB" verrechnen
346        if ($rechnen) { // beide Anteile verwertbar
347                $formelteil=";=L".$i."*O".$i; // Spalte T
348        } else {
349                $formelteil=';';
350        }
351
352        // Ausgabe in die CSV-Datei -> Download -> Tabellenkalkulation
353        echo "\n".$fsteil.$gbteil.$namteil.$formelteil;
354}
355pg_free_result($res);
356if ($i === 1) { // nur Kopf
357        if ($gmlid == '') {
358                $err="\nKein Treffer";
359        } else {
360                $err="\nKein Treffer fuer gml_id='".$gmlid."'";
361        }
362        exit ($err);
363}
364pg_close($con);
365exit(0);
366?>
Note: See TracBrowser for help on using the repository browser.