source: trunk/mapbender/http/nav/alkisnav_adr.php @ 376

Revision 376, 14.4 KB checked in by frank.jaeger, 7 years ago (diff)

Verbesserungen an der ALKIS-Buchauskunft (Geschwindigkeit, Fehlerkorrekturen, Mandantenfähigkeit) und an der Mapbender2-Navigation.

RevLine 
[66]1<?php
[376]2/*      Navigation mit ALKIS-Daten im Mapbender 2.7 - Teil Adressen-Suche
3        Diese Version des Programms verwendet die Datenbank-Struktur aus dem norGIS-ALKIS-Importer.
[330]4
[376]5Version vom
6        2016-02-11 Version fÃŒr norGIS-ALKIS-Import aus Version Classic abgeleitet.
7        2016-03-02 $gemeinde auf feste LÀnge korrigieren
8        2016-11-28 Gemeinsam genutzte Datenbanken ermöglichen
9
[140]10        ToDo:
[306]11        -       Gruppierung (mit Zeile) der Straßenliste nach Gemeinde
[140]12        -       Eingabe aus "Balken" von Buchauskunft "Lage" zulassen: Numerisch: Gem-Str-Haus-lfd
[306]13                -- lfd (NebengebÀude) als Untergliederung der geklickten Haus-Nr anzeigen
[140]14                Analog zur Zerlegung des FS-Kennz in _fls
[197]15        -       Mouse-Over in Straßenliste soll Position zeigen.
16                Dazu in der DB eine Tabelle mit Koordinate zum StraßenschlÃŒssel aufbauen.
[85]17*/
[356]18
19// Variable Initialisieren
20$str_schl="";
21$skey="";
22
[276]23$cntget = extract($_GET);
[376]24$gemeinde=str_pad($gemeinde, 3, "0", STR_PAD_LEFT); // temporÀr
[187]25include("../../conf/alkisnav_conf.php");
[306]26include("alkisnav_fkt.php"); // Funktionen
[376]27$con = pg_connect ($dbconn) or die ("Fehler bei der Verbindung zur Datenbank ".$dbpre.$dbgkz);
[356]28
[278]29echo <<<END
[376]30<!doctype html>
31<html lang="de">
[187]32<head>
33        <meta http-equiv="cache-control" content="no-cache">
34        <meta http-equiv="pragma" content="no-cache">
35        <meta http-equiv="expires" content="0">
[376]36        <meta charset="utf-8">
[187]37        <title>ALKIS-Suche Adressen</title>
38        <link rel="stylesheet" type="text/css" href="alkisnav.css">
[278]39        <script type='text/javascript'>
40                function transtitle (trans) { // Titel der letzten Transaktion anzeigen
41                        document.getElementById('transaktiontitle').innerHTML = trans;
42                }
[306]43                function imFenster(dieURL) {
44                        var link = encodeURI(dieURL);
45                        window.open(link,'','left=10,top=10,width=620,height=800,resizable=yes,menubar=no,toolbar=no,location=no,status=no,scrollbars=yes');
46                }
[278]47        </script>
[187]48</head>
[66]49<body>
[280]50<a href='javascript:history.back()'>
[356]51        <img src="ico/zurueck.png" width="16" height="16" alt="&lt;&lt;" title="zur&uuml;ck">
52</a>&nbsp;
53<span title='zuletzt ausgef&uuml;hrte Aktion'>
54        <dfn class='title' id='transaktiontitle'></dfn>
55</span>
[66]56
[278]57END;
58
[376]59function suchStrName() {
60        // Strassen nach Name(-nsanfang)
[306]61        global $street, $scalestr, $str_schl, $gkz, $gemeinde, $epsg, $gfilter, $debug, $auskpath;
[376]62        //if ($debug > 1) {echo "<p class='dbg'>function suchStrName()<p>";} // Ablauf-Verfolgung
63
64        $linelimit=120;  // -> in Conf?
65        $str_schl=""; // Loeschen vorh. Ergebnis
66        preg_match("/^(\D+)(\d*)(\D*)/",$street,$matches); # 4 matches name/nr/zusatz
67        //echo "match: 1='".$matches[1]."', 2='".$matches[2]."', 3='".$matches[3]."'";
[187]68        $matches[1] = preg_replace("/strasse/i","str", $matches[1]);
[66]69        $matches[1] = preg_replace("/str\./i","str", $matches[1]);
[376]70
[187]71        if(preg_match("/\*/",$matches[1])){
72                $match=trim(preg_replace("/\*/i","%", strtoupper($matches[1])));
73        } else {
74                $match=trim($matches[1])."%";
[66]75        }
[376]76
[334]77        $sql ="SELECT g.gemeinde, g.bezeichnung AS gemname, k.gml_id, k.bezeichnung, k.schluesselgesamt, k.lage
78        FROM ax_lagebezeichnungkatalogeintrag k
79        JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde
80        WHERE k.bezeichnung ILIKE $1 AND k.endet IS NULL AND g.endet IS NULL ";
[376]81
[85]82        switch ($gfilter) {
83                case 1: // Einzelwert
[330]84                        $sql.="AND k.gemeinde='".$gemeinde."' ";
[85]85                        break;
86                case 2: // Liste
[330]87                        $sql.="AND k.gemeinde in (".str_replace(",", "','", $gemeinde).") ";
[85]88                        break;
89                default: // kein Filter
90                        break;
[66]91        }
[306]92        $sql.="ORDER BY g.bezeichnung, k.bezeichnung, k.lage LIMIT $2 ;";
[68]93        $v=array($match,$linelimit);
94        $res=pg_prepare("", $sql);
95        $res=pg_execute("", $v);
[330]96
97        if (!$res) {
98                echo "\n<p class='err'>Fehler bei Name</p>";
99                if ($debug > 2) {echo "<p class='dbg'>SQL = '".$sql."'<p>";}
100                return;
101        }
102
[187]103        $cnt = 0;
[306]104        $gwgem="";
[66]105        while($row = pg_fetch_array($res)) {
[306]106                $gemname=$row["gemname"];
107                $gemnr=$row["gemeinde"] ;
108                if ($gwgem != $gemname) {
109                        if ($gfilter != 1) {
110                                zeile_gemeinde($gemnr, $gemname, false); // ToDo: aber ohne Link oder Link verarbeiten können
111                        }
112                        $gwgem=$gemname;
113                }
114                $gkey=$row["schluesselgesamt"]; // Land-RegBez-Kreis-Gem-Strasse - fÃŒr weitere Suche
115                $skey=$row["lage"]; // Nur Str.-schl. daraus
116                $kgml=$row["gml_id"]; // ID von Katalog
[376]117                $sname=htmlentities($row["bezeichnung"], ENT_QUOTES, "UTF-8");
118                zeile_strasse ($gkey, $skey, $sname, $kgml, $gemname);
[187]119                $cnt++;
120        }
[356]121
[66]122        if($cnt == 0) {
[376]123                echo "\n<p class='anz'>Keine Stra&szlig;e</p>";
124                //if ($debug > 2) {echo "<p class='err'>SQL = '".$sql."'<br>$1 = '".$match."'<p>";}
[66]125        } elseif($cnt == 1) { // Eindeutig
[68]126                $str_schl=$gkey; // dann gleich weiter
[66]127        } elseif($cnt >= $linelimit) {
[376]128                echo "\n<p class='anz'>".$cnt." Stra&szlig;en ... und weitere</p>";                     
[278]129        } elseif ($cnt > 1) {
130                echo "\n<p class='anz'>".$cnt." Stra&szlig;en</p>";     
131        }
[187]132        return;
133}
[66]134
[306]135function suchStrKey() { // Strassen nach num. Schluessel
136        global $street, $scalestr, $str_schl, $gkz, $gemeinde, $epsg, $gfilter, $debug, $auskpath;
[376]137        //if ($debug > 1) {echo "<p class='dbg'>function suchStrKey()<p>";} // Ablauf-Verfolgung
[306]138        $linelimit=60;
[187]139        if(preg_match("/\*/",$street)) {
[68]140                $match=trim(preg_replace("/\*/i","%",$street));
[306]141                // fuehrende Nullen eingeben oder fuehrende Wildcard
[187]142        } else {
143                $match=str_pad($street, 5, "0", STR_PAD_LEFT); // "Wie eine Zahl" verarbeiten
[68]144        }
[334]145        $sql ="SELECT g.bezeichnung AS gemname, k.gml_id, k.bezeichnung, k.schluesselgesamt, k.lage
146        FROM ax_lagebezeichnungkatalogeintrag as k
147        JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde
148        WHERE k.lage LIKE $1 AND k.endet IS NULL AND g.endet IS NULL ";
[85]149        switch ($gfilter) {
150                case 1: // Einzelwert
[330]151                        $sql.="AND k.gemeinde='".$gemeinde."' ";
[85]152                        break;
153                case 2: // Liste
[330]154                        $sql.="AND k.gemeinde in ('".str_replace(",", "','", $gemeinde)."') ";
[85]155                        break;
[68]156        }
[187]157        $sql.="ORDER BY k.lage, k.bezeichnung LIMIT $2 ;";
[330]158
[68]159        $v=array($match,$linelimit);
160        $res=pg_prepare("", $sql);
161        $res=pg_execute("", $v);
[330]162        if (!$res) {
163                echo "\n<p class='err'>Fehler bei Schl&uuml;ssel</p>";
164                return;
165        }
[187]166        $cnt = 0;
[68]167        while($row = pg_fetch_array($res)) {
168                $sname=htmlentities($row["bezeichnung"], ENT_QUOTES, "UTF-8");         
169                $gkey=$row["schluesselgesamt"];
170                $gemname=htmlentities($row["gemname"], ENT_QUOTES, "UTF-8");
171                $skey=$row["lage"];
[306]172                $kgml=$row["gml_id"]; // ID von Katalog
[376]173                zeile_strasse ($gkey, $skey, $sname, $kgml, $gemname);
[187]174                $cnt++;
175        }
[68]176        if($cnt == 0) {
[278]177                echo "\n<p class='anz'>Keine Stra&szlig;e mit Schl&uuml;ssel ".$match."</p>";
[68]178        } elseif($cnt == 1) { // Eindeutig
179                $str_schl=$gkey; // dann gleich weiter
[278]180        } elseif ($cnt >= $linelimit) {
181                echo "\n<p>".$cnt." Stra&szlig;en ... und weitere</p>";                 
182        } elseif ($cnt > 1) {
183                echo "\n<p class='anz'>".$cnt." Stra&szlig;en</p>";     
[68]184        }       
[187]185        return;
[68]186}
187
[306]188function suchHausZurStr($showParent) { // Haeuser zu einer Strasse
[309]189        global $str_schl, $gkz, $scalestr, $scalehs, $epsg, $gemeinde, $epsg, $gfilter, $debug, $auskpath;
[376]190        //if ($debug > 1) {echo "<p class='dbg'>function suchHausZurStr()<p>";} // Ablauf-Verfolgung
[306]191
192        // Head
[66]193        // Strasse zum Strassenschluessel
[334]194        $sql ="SELECT g.bezeichnung AS gemname, k.gml_id AS kgml, k.bezeichnung, k.land, k.regierungsbezirk, k.kreis, k.gemeinde, k.lage
195        FROM ax_lagebezeichnungkatalogeintrag as k
196        JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde
197        WHERE k.schluesselgesamt = $1 AND k.endet IS NULL AND g.endet IS NULL LIMIT 1";
[330]198
[306]199        $v=array($str_schl);    // Schluessel-Gesamt ..
[66]200        $res=pg_prepare("", $sql);
201        $res=pg_execute("", $v);
[330]202        if (!$res) {
203                echo "\n<p class='err'>Fehler bei Name zum Stra&szlig;enschl&uuml;ssel</p>";
204                if ($debug > 2) {echo "<p class='dbg'>SQL = '".$sql."'<p>";}
205                return;
206        }
207
[306]208        if($row = pg_fetch_array($res)) { // .. gefunden
[309]209                $kgml=$row["kgml"]; // ID aus Katalog
[66]210                $sname=$row["bezeichnung"];
[306]211                $land =$row["land"];    // Einzel-Felder fÃŒr JOIN _lagebezeichnung_
[66]212                $regb =$row["regierungsbezirk"];
213                $kreis=$row["kreis"];
214                $gemnd=$row["gemeinde"];
[306]215                $nr=$row["lage"];
[83]216                $gemname=htmlentities($row["gemname"], ENT_QUOTES, "UTF-8");
217                if ($showParent) {
[306]218                        // EINE Koordinate zur Strasse besorgen
[309]219                        // ax_Flurstueck >zeigtAuf> ax_LagebezeichnungOhneHausnummer
[197]220                        $sqlko ="SELECT ";
[86]221                        if($epsg == "25832") { // Transform nicht notwendig
[188]222                                $sqlko.="st_x(st_Centroid(f.wkb_geometry)) AS x, ";
223                                $sqlko.="st_y(st_Centroid(f.wkb_geometry)) AS y ";
[197]224                        } else {
[188]225                                $sqlko.="st_x(st_transform(st_Centroid(f.wkb_geometry), ".$epsg.")) AS x, ";
[197]226                                $sqlko.="st_y(st_transform(st_Centroid(f.wkb_geometry), ".$epsg.")) AS y ";
[86]227                        }
[83]228                        $sqlko.="FROM ax_lagebezeichnungohnehausnummer o ";
[339]229                        $sqlko.="JOIN ax_flurstueck f ON o.gml_id=ANY(f.zeigtauf) ";
[83]230                        $sqlko.="WHERE o.land= $1 AND o.regierungsbezirk= $2 AND o.kreis= $3 AND o.gemeinde= $4 AND o.lage= $5 ";       
[330]231                        $sqlko.="LIMIT 1;"; // die erstbeste Koordinate
[376]232
[83]233                        $v=array($land,$regb,$kreis,$gemnd,$nr);
234                        $resko=pg_prepare("", $sqlko);
235                        $resko=pg_execute("", $v);
236                        if ($resko) {
237                                $rowko=pg_fetch_array($resko);
238                                $x=$rowko["x"];
239                                $y=$rowko["y"];
240                        } else {               
241                                echo "\n<p class='err'>Fehler bei Koordinate zur Stra&szlig;e</p>";
242                        }
[309]243
[376]244                        // "function zeile_strasse()" hier nicht verwendbar. ZusÀtzlicher Map-Link mit Koordinate
[309]245                        // Icon -> Buchnachweis
[356]246                        echo "\n\t<br><a href='javascript:imFenster(\"".$auskpath."alkisstrasse.php?gkz=".$gkz."&amp;gmlid=".$kgml."\")'>";
247                                echo "\n\t\t<img class='nwlink' src='ico/Lage_mit_Haus.png' width='16' height='16' alt='STR' title='Buchauskunft zur Stra&szlig;e'>";
[309]248                        echo "\n\t</a>";
249
[83]250                        if ($x > 0) { // Koord. bekommen?
[115]251                                echo "\n\t<a title='Positionieren 1:".$scalestr."' href='javascript:"; // mit Link
[278]252                                                echo "transtitle(\"auf Stra&szlig;e positioniert\"); ";
[115]253                                                echo "parent.parent.parent.mb_repaintScale(\"mapframe1\",".$x.",".$y.",".$scalestr."); ";
254                                                echo "parent.parent.showHighlight(".$x.",".$y."); ";
[306]255                                        //      echo "document.location.href=\"".$_SERVER['SCRIPT_NAME']."?gkz=".$gkz."&amp;gemeinde=".$gemeinde."&amp;epsg=".$epsg."&amp;str_schl=".$str_schl."\"";
[278]256                                        echo "' "; // end href
[187]257                                        echo "\n\t\tonmouseover='parent.parent.showHighlight(" .$x. "," .$y. ")' ";
[83]258                                        echo "\n\t\tonmouseout='parent.parent.hideHighlight()'";
259                                echo ">\n\t\t".$sname." (".$nr.")\n\t</a>";
[197]260                        } else { // keine Koord. gefunden
[83]261                                echo $sname." (".$nr.")"; // nur Anzeige, ohne Link
262                        }
[85]263                        switch ($gfilter) {
264                                case 0: // Kein Filter
265                                        echo " in ".$gemname;
266                                        break;
267                                case 2: // Liste
268                                        echo " in ".$gemname;
269                                        break;
270                        }                       
[66]271                }
[83]272                echo "\n<hr>";
[306]273
274                // Body
[66]275                // Haeuser zum Strassenschluessel
[306]276                $sql="SELECT min(replace(h.hausnummer,' ','')) AS hsnr, ";
[86]277                if($epsg == "25832") { // Transform nicht notwendig
[306]278                        $sql.="avg (st_x(p.wkb_geometry)) AS x, ";
279                        $sql.="avg (st_y(p.wkb_geometry)) AS y ";               
[197]280                } else { 
[306]281                        $sql.="avg (st_x(st_transform(p.wkb_geometry,".$epsg."))) AS x, ";
282                        $sql.="avg (st_y(st_transform(p.wkb_geometry,".$epsg."))) AS y ";               
[86]283                }
[339]284                $sql.="FROM ap_pto p JOIN ax_lagebezeichnungmithausnummer h ON h.gml_id=ANY(p.dientzurdarstellungvon)
[334]285                WHERE p.art='HNR' AND h.land= $1 AND h.regierungsbezirk= $2 AND h.kreis= $3 AND h.gemeinde= $4 AND h.lage= $5
286                AND p.endet IS NULL AND h.endet IS NULL
287                GROUP BY lpad(split_part(hausnummer,' ',1), 4, '0'), split_part(hausnummer,' ',2)
288                ORDER BY lpad(split_part(hausnummer,' ',1), 4, '0'), split_part(hausnummer,' ',2);";
[356]289                // Problem: In der Datenbank gibt es mehrere hausnummern-Koordinaten fÃŒr verschiedene
290                // MaßstÀbe der Kartendarstellung
291                // Diese sollten nicht mehrfach gelistet werden. FÃŒr die Positionierung "irgendeine" nehmen.
[306]292                // Lösung: ÃŒber GROUP BY in SQL. Alternative Lösungen wÀren:
293                //  1. Gruppenwechsel bei Abarbeitung des Result
294                //  2. Subquery mit LIMIT 1 statt JOIN
[356]295                //  3. Koordinate aus dem Mittelpunkt der GebÀude-Geometrie verwenden statt aus dem PrÀsentationsobjekt der Hausnummer
[197]296
[83]297                $v=array($land,$regb,$kreis,$gemnd,$nr);
[68]298                $resh=pg_prepare("", $sql);
299                $resh=pg_execute("", $v);
[330]300                if (!$resh) {
301                        echo "\n<p class='err'>Fehler bei H&auml;user zum Stra&szlig;enschl&uuml;ssel</p>";
302                        if ($debug > 2) {echo "<p class='dbg'>SQL='".$sql."'<br>Array=".$v."</p>";}
303                        return;
304                }
[306]305
[187]306                $cnt=0;
307                $count=0;
308                echo "\n<table>";
[197]309                while($rowh = pg_fetch_array($resh)) { // mehrere HsNr je Zeile
[356]310                        if($count == 0) {echo "\n<tr>";}       
[197]311                        $hsnr=$rowh["hsnr"];
[187]312                        $x=$rowh["x"];
313                        $y=$rowh["y"];
[66]314                        echo "\n\t<td class='hsnr'>";
315                                echo "<a href='";
[278]316                                        echo "javascript:";
[306]317                                        echo "transtitle(\"auf Haus ".$hsnr." positioniert\"); ";
[278]318                                        echo "parent.parent.parent.mb_repaintScale(\"mapframe1\",".$x.",".$y.",".$scalehs."); ";
[115]319                                        echo "parent.parent.showHighlight(".$x.",".$y.");' ";
[187]320                                echo "onmouseover='parent.parent.showHighlight(".$x.",".$y.")' ";
[66]321                                echo "onmouseout='parent.parent.hideHighlight()";
[187]322                                echo "'>".$hsnr."</a>";
323                        echo "</td>";
324                        $cnt++;
325                        $count++;
[356]326                        if($count == 7) { // Max. Hausnummern je Zeile (Test: 3stellige HsNr mit Zusatz)
[66]327                                echo "\n</tr>";
328                                $count = 0;
[187]329                        }
330                }
[66]331                if($count > 0) {echo "\n</tr>";}
332                echo "\n</table>";
[306]333                if ($cnt > 1) {
334                        echo "\n<p class='anz'>".$cnt." Hausnummern</p>";
335                }
[66]336        } else {
[278]337                echo "\n<p class='anz'>Keine Stra&szlig;e</p>";
[187]338        }
339        return;
340}
[66]341// ===========
342// Start hier!
343// ===========
344if(isset($epsg)) {
[86]345        $epsg = str_replace("EPSG:", "" , $_REQUEST["epsg"]);   
[66]346} else {
347        $epsg=$gui_epsg; // aus Conf
348}
[376]349
350// Filter auf Zustaendigkeit z.B. ein Stadtgebiet
[85]351if ($gemeinde == "") {
352        $gfilter = 0; // ungefiltert
353} elseif(strpos($gemeinde, ",") === false) {
354        $gfilter = 1; // Einzelwert
355} else {
356        $gfilter = 2; // Liste
357}
[376]358// ax_lagebezeichnungkatalogeintrag.gemeinde: z.B. Classic='40' / NorBit  = '040'
359// Im Mapbender mit fuehrenden Nullen eingeben: gazetteer_alkis.SRC
360// alkisnav.htm?..&gemeinde=040&..
[306]361
[376]362// +++Zerlegung Eingabe aus "Balken" von Buchauskunft "Lage": Numerisch: Gem-Str-Haus-lfd
[306]363
[376]364if ($str_schl != "") { // Wert kommt aus aus Link
[278]365        $trans="Hausnummern zur Stra&szlig;e";
[83]366        suchHausZurStr(true);
[376]367// Wert aus Eingabe in Formular
368} elseif($street != "") {
369        if (trim($street, "*,0..9, ") == "") { // Zahl, ggf. mit Wildcard
[278]370                $trans="Suche Stra&szlig;enschl&uuml;ssel \"".$street."\"";
371                suchStrKey();
[376]372        } else { // Name suchen
[356]373                $trans="Suche Stra&szlig;enname \"".$street."*\"";
[278]374                suchStrName();
[187]375        }
[356]376        if($str_schl != "") { // EINdeutiges Ergebnis
[278]377                $trans="1 Stra&szlig;e gefunden, Hausnummern";
[187]378                suchHausZurStr(false);
[83]379        }
[356]380} else {
381        $trans="keine Eingabe";
[68]382}
[356]383
384// Nach Durchlaufen des PHP-Scriptes die zuletzt ausgefÃŒhrte Transaktion
[376]385//  im Kopf des Ergebnisrahmens anzeigen.
[356]386// Dazu die im HTML-Header definierte Javascript-Function benutzen.
387// Alternativ wird auch aus dem Javascript "positionieren Karte" dieser Titel gesetzt.
[283]388echo "
389<script type='text/javascript'>
390        transtitle ('".$trans."') ;
391</script>";
[278]392
[66]393?>
[68]394
[187]395</body>
396</html>
Note: See TracBrowser for help on using the repository browser.