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

Revision 422, 13.1 KB checked in by frank.jaeger, 3 years ago (diff)

Aktualisierungen der ALKIS-Buchauskunft, neues Modul für Bauwerke, Härtung

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