Index: trunk/mapbender/http/nav/alkisnav.css
===================================================================
--- trunk/mapbender/http/nav/alkisnav.css	(revision 420)
+++ trunk/mapbender/http/nav/alkisnav.css	(revision 425)
@@ -5,21 +5,23 @@
 	2014-02-06 kosmetische Ãberarbeitung
 	2015-12-10 Rahmen breiter, mehr HsNr je Zeile
+	2021-12-29 Abstand vor .hn
 */
-body,p,a,.textfield,.sbutton	{font-family: Verdana, Arial, Helvetica, sans-serif;}
+body,p,a,.textfield,.sbutton {font-family: Verdana, Arial, Helvetica, sans-serif;}
 body {font-size: 11px; color: #000000; margin: 0px; border: 0px;}
 p {font-size: 10px;}
-p.hilfe 	{font-size:  9px; text-align: right; color: gray; padding-right: 3px;} /* Programmier-Hilfsfelder */
-p.start 	{font-size:  9px; color: gray; padding: 2px; margin: 2px; border: 0px;}
+p.hilfe {font-size:  9px; text-align: right; color: gray; padding-right: 3px;} /* Programmier-Hilfsfelder */
+p.start {font-size:  9px; color: gray; padding: 2px; margin: 2px; border: 0px;}
 p.nam {font-size: 10px; border: 1px solid navy; padding: 3px; margin: 0px; color: maroon;}
 p.err {font-size: 11px; color: red;} /* Fehler -> Anwender */
 p.dbg {font-size: 10px; color: gray;} /* Debug -> Entwickler */
-p.ein, p.anz, p.blt	{font-size: 9px; text-align: right;} /* Einleitung, Anzahl am Ende, BlÃ€ttern weitere ... */
-p.ein  {color: navy; font-weight: bold;}
+p.ein, p.anz, p.blt {font-size: 9px; text-align: right;} /* Einleitung, Anzahl am Ende, BlÃ€ttern weitere ... */
+p.ein {color: navy; font-weight: bold;}
 p.anz, p.blt {color: purple;}
+p.hn {color: gray; margin-left: 28px; margin-top: 8px; margin-bottom: 2px;} /* Hist.-Nachf. Ãberschr. */
 
 a {text-decoration: none;}
 a:hover, a:active {color: red;}
 a.hislnk {color: gray; font-style: italic; text-align: right; padding-left: 50px;} /* Link zur Historie */
-a.hsnro	{color: gray; font-style: italic;} /* HsNr ohne Haus */
+a.hsnro {color: gray; font-style: italic;} /* HsNr ohne Haus */
 a.blt {color: maroon; background-color: yellow;} /* Link weitere ... */
 
@@ -37,5 +39,5 @@
 div.fs {color: navy; margin-left: 28px; margin-top: 0px;} /* Flurstueck */
 div.hi {color: gray; margin-left: 28px; margin-top: 0px;} /* Historie */
-div.hn, p.hn	{color: gray; margin-left: 28px; margin-top: 0px;} /* Historie-Nachfolger */
+div.hn {color: gray; margin-left: 28px; margin-top: 0px;} /* Historie-Nachfolger */
 
 div.stu {color: maroon; font-size: 13px;} /* Strasse - Ueberschrift */
Index: trunk/mapbender/http/nav/alkisnav_fkt.php
===================================================================
--- trunk/mapbender/http/nav/alkisnav_fkt.php	(revision 420)
+++ trunk/mapbender/http/nav/alkisnav_fkt.php	(revision 425)
@@ -11,4 +11,6 @@
 	2018-11-09 Full-Schema
 	2019-02-12 Sortierung FlurstÃŒcksnummer repariert
+	2021-11-23 Neue Var. $katamtmix  (Kataster-Amt-Mix).
+	           SchlÃŒsseltabellen sind mehrfach belegt. Dadurch doppelte Treffer bei der Suche.
 */
 
@@ -316,5 +318,5 @@
 	// Zu einem Grundbuch-Blatt (identifiziert ÃŒber seine gml_id) suchen der 
 	// Buchungen (Gruppenwechsel) und FlurstÃŒcke (Links)
-	global $gemeinde, $blattgml, $epsg, $gfilter, $debug;
+	global $gemeinde, $blattgml, $epsg, $gfilter, $debug, $katamtmix;
 
 	// SQL-Bausteine
@@ -337,6 +339,7 @@
 
 	// hinten gleich
-	$sql2="JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer "
-		."WHERE s1.istbestandteilvon = $1 AND f.endet IS NULL AND s1.endet IS NULL ";
+	$sql2 ="JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer ";
+	if ($katamtmix){$sql2.="AND substr(f.gml_id, 1, 6) = substr(g.gml_id, 1, 6) ";}
+	$sql2.="WHERE s1.istbestandteilvon = $1 AND f.endet IS NULL AND s1.endet IS NULL ";
 
 	switch ($gfilter) {
Index: trunk/mapbender/http/nav/alkisnav_fls.php
===================================================================
--- trunk/mapbender/http/nav/alkisnav_fls.php	(revision 420)
+++ trunk/mapbender/http/nav/alkisnav_fls.php	(revision 425)
@@ -10,4 +10,10 @@
 	2018-11-12 Full-Schema
 	2019-02-12 Sortierung FlurstÃŒcksnummer wieder hergestellt (kaputt gegangen bei Umstellung Full-Schema)
+	2021-11-24 fÃŒhrende '0' Trimmen bei Flur, ZÃ€hler, Nenner in der Zerlegung
+	2021-12-29 Sortierung der Nachfolger eines hist. FS
+	
+ToDo:
+	Vermeiden der Tabellen "gema_shl" und "gem_shl". Das sind NorBIT/ALB-Relikte, die irgendwann entfallen werden.
+	Besser primÃ€re ax_*-Tabellen verwenden.
 */
 
@@ -129,5 +135,5 @@
 
 	if (count($arr) > 1) {
-		$zflur=h_hinten($arr[1]);
+		$zflur=ltrim(h_hinten($arr[1]), '0');
 		if (count($arr) > 2) {
 			$zfsnr=trim($arr[2]);
@@ -172,6 +178,11 @@
 	} else {
 		$zn=explode("/", $zfsnr, 2); // Bruchnummer?
-		$zzaehler=h_hinten(trim($zn[0]));
-		if (count($zn) > 1) {$znenner=h_hinten(trim($zn[1]));} else {$znenner="";}
+		$zzaehler=ltrim(h_hinten(trim($zn[0])), '0');
+		if (count($zn) > 1) {
+			$znenner=ltrim(h_hinten(trim($zn[1])), '0');
+		} else {
+			$znenner="";
+		}
+	//	if ($debug > 1) {echo "<p class='dbg'>Gemkg: '".$gemkg."' Flur: '".$zflur."' Zaehler: '".$zzaehler."' Nenner: '".$znenner."'</p>";}
 		if ( ! is_ne_zahl($zzaehler)) {
 			echo "<p class='err'>FlurstÃŒcksnummer '".$zzaehler."' ist nicht numerisch</p>";
@@ -283,6 +294,6 @@
 		echo "\n\t<a title='Nachweis' href='javascript:imFenster(\"".$auskpath.$auskprog.".php?gkz=".$gkz."&amp;gmlid=".$gml."\")'>";
 			echo "\n\t\t<img class='nwlink' src='ico/".$ico."' width='16' height='16' alt='FS' title='Nachweis'>";
-		echo "\n\t</a> ";		
-		echo "Flst. <a href='".$_SERVER['SCRIPT_NAME']."?gkz=".$gkz."&amp;gemeinde=".$gemeinde."&amp;epsg=".$epsg."&amp;fskennz=".$fs.$hisparm."'>".$fskenn."</a>";					
+		echo "\n\t</a>&nbsp;";		
+		echo "hist. Flst. <a href='".$_SERVER['SCRIPT_NAME']."?gkz=".$gkz."&amp;gemeinde=".$gemeinde."&amp;epsg=".$epsg."&amp;fskennz=".$fs.$hisparm."'>".$fskenn."</a>";					
 	echo "\n</div>";
 	return;
@@ -418,10 +429,8 @@
 		echo "\n<p class='anz'>Keine Gemarkung.</p>";
 		if ($debug > 1) {
-/*
-			// Nach Umstellung auf NorGIS-Struktur muss im Mapbender die Gemeinde 3stellig konfiguriert werden
+/*			// Nach Umstellung auf NorGIS-Struktur muss im Mapbender die Gemeinde 3stellig konfiguriert werden
 			if (strlen($gemeinde) < 3) {
 				echo "<p class='err'>URL-Parameter &gemeinde=nnn im Mapbender gazetteer_alkis.SRC muss 3stellig sein!<br>Ist aber '".$gemeinde."'.</p>";
-			}
-*/
+			} */
 			if ($debug > 2) {echo "<p class='dbg'>SQL=<br>".$sql."<br>$1 = ".$match."</p>";}
 		}
@@ -473,5 +482,5 @@
 	if ($AuchGemkZeile) { // Kopf davor ausgeben
 		if (! gg_head($zgemkg6, true)) {
-			if ($debug >= 1) {echo "\n<p class='dbg'>Gem.-Gemkg.-Kopf abgebrochen</p>";}	
+			if ($debug > 0) {echo "\n<p class='dbg'>Gem.-Gemkg.-Kopf abgebrochen</p>";}	
 			return false;
 		} 
@@ -479,4 +488,5 @@
 
 	// Body
+	// ++ ToDo: (optional) nur Fluren ausgeben, in denen auch FlurstÃŒcke enthalten sind.
 	$sql ="SELECT gemarkungsteilflur AS flur FROM ax_gemarkungsteilflur f WHERE gemarkung= $1 ORDER BY gemarkungsteilflur LIMIT $2 ;";
 	$v=array($zgemkg4, $linelimit);
@@ -621,10 +631,6 @@
 	}
 	$sql.="FROM ax_flurstueck f WHERE f.gemarkungsnummer= $1 AND f.flurnummer= $2 AND f.zaehler= $3 ";
-
 	If ($znenner != "") {
-		$suchnenn = ltrim($znenner, '0');
-		If ($suchnenn != "") {
-			$sql.="AND f.nenner='".$suchnenn."' ";
-		}
+		$sql.="AND f.nenner='".$znenner."' ";
 	}
 	$sql.="AND endet IS NULL ORDER BY cast(f.zaehler AS integer), cast(f.nenner AS integer);";
@@ -732,5 +738,6 @@
 			$nasql ="SELECT 'a' AS ftyp, gml_id, gemarkungsnummer, flurnummer, zaehler, nenner FROM ax_flurstueck ".$nawhcl
 			."UNION SELECT 'h' AS ftyp, gml_id, gemarkungsnummer, flurnummer, zaehler, nenner FROM ax_historischesflurstueck ".$nawhcl
-			."UNION SELECT 'o' AS ftyp, gml_id, gemarkungsnummer, flurnummer, zaehler, nenner FROM ax_historischesflurstueckohneraumbezug ".$nawhcl;
+			."UNION SELECT 'o' AS ftyp, gml_id, gemarkungsnummer, flurnummer, zaehler, nenner FROM ax_historischesflurstueckohneraumbezug ".$nawhcl
+			."ORDER BY gemarkungsnummer, flurnummer, zaehler, nenner";
 
 			$v=array();
@@ -773,8 +780,7 @@
 }
 
-// ===========
 // Start hier!
-// ===========
-if ($debug >= 1) {echo "\n<p class='dbg'>gemeinde='".$gemeinde."'. gfilter='".$gfilter."'</p>";}
+
+// if ($debug >= 1) {echo "\n<p class='dbg'>gemeinde='".$gemeinde."'. gfilter='".$gfilter."'</p>";}
 
 // Validation: Eingabefeld aus Formular.
@@ -800,5 +806,5 @@
 } else { // Die Formular-Eingabe interpretieren (kann auch ein Link sein)
 	$retzer=ZerlegungFsKennz($fskennz);
-	if ($debug >= 1) {echo "\n<p class='dbg'>Return Zerlegung: ".$retzer."</p>";}	
+	if ($debug > 1) {echo "\n<p class='dbg'>Return Zerlegung: ".$retzer."</p>";}	
 	switch ($retzer) { // Returnwert der Zerlegung des FS-Kennz.
 	case 0: // leere Eingabe
Index: trunk/mapbender/http/nav/alkisnav_eig.php
===================================================================
--- trunk/mapbender/http/nav/alkisnav_eig.php	(revision 420)
+++ trunk/mapbender/http/nav/alkisnav_eig.php	(revision 425)
@@ -11,4 +11,7 @@
 	2018-11-12 Full-Schema
 	2019-02-12 Sortierung FlurstÃŒcksnummer repariert
+	2021-12-01 Fehlerkorrektur "benennt". Neue Var. $katamtmix  (Kataster-Amt-Mix).
+	           SchlÃŒsseltabellen sind mehrfach belegt. Dadurch doppelte Treffer bei der Suche.
+			   Weitere Buchstaben fÃŒr Namen-Suche zugelassen.
 */
 
@@ -110,5 +113,5 @@
 function personendaten() { 
 	// Adresse und Geburtsdatum der aktuellen Person ausgeben
-	global $gkz, $gemeinde, $epsg, $name, $person, $blattgml, $auskpath; // $debug
+	global $gkz, $gemeinde, $epsg, $name, $person, $blattgml, $auskpath;
 	$sql ="SELECT p.nachnameoderfirma, p.vorname, to_char(cast(p.geburtsdatum AS date),'DD.MM.YYYY') AS geburtsdatum, p.namensbestandteil, "
 	."a.ort_post, a.postleitzahlpostzustellung AS plz, a.strasse, a.hausnummer "
@@ -162,5 +165,5 @@
 	$linelimit=150;
 	$arr = explode(",", $name);
-	$name0 = trim($arr[0]);	// Nachname
+	$name0 = trim($arr[0]);		// Nachname
 	if (count($arr) > 1) {
 		$name1=trim($arr[1]);	// Vorname
@@ -245,5 +248,5 @@
 // Alternativ wÃŒrde eine Hilfstabelle benÃ¶tigt, in der im PostProcessing 
 // das GB-zu-Gemeinde-VerhÃ€ltnis vorbereitet wird.
-	global $gkz, $gemeinde, $epsg, $name, $person, $blattgml, $debug, $bltbez, $bltblatt, $bltseite, $kennztyp, $zgbbez;
+	global $gkz, $gemeinde, $epsg, $name, $person, $blattgml, $debug, $bltbez, $bltblatt, $bltseite, $kennztyp, $zgbbez, $katamtmix;
 	$linelimit=150;
 
@@ -256,10 +259,11 @@
 	$sql ="SELECT gb.gml_id AS gml_g, gb.buchungsblattnummermitbuchstabenerweiterung as blatt, b.bezirk, b.bezeichnung AS beznam "
 	."FROM ax_namensnummer n JOIN ax_buchungsblatt gb ON n.istbestandteilvon=gb.gml_id "
-	."JOIN ax_buchungsblattbezirk b ON gb.land=b.land AND gb.bezirk=b.bezirk "
-	."WHERE n.bennennt = $1 AND n.endet IS NULL AND gb.endet IS NULL AND b.endet IS NULL;";
+	."JOIN ax_buchungsblattbezirk b ON gb.land=b.land AND gb.bezirk=b.bezirk ";
+	if ($katamtmix){$sql.="AND substr(gb.gml_id,1,6) = substr(b.gml_id,1,6) ";}
+	$sql.="WHERE n.benennt = $1 AND n.endet IS NULL AND gb.endet IS NULL AND b.endet IS NULL ";
 
 	// Parameter $gbkennz, z.B. nach Klick auf Zeile "Bezirk"
 	if ($kennztyp > 1) { // 2=Such Bezirk-Nummer, 3=Such Blatt, 4=Such Buchung BVNR
-		#if ($debug > 0) {echo "<p class='dbg'>Filter Bezirk '".$zgbbez."'<p>";}
+		#if ($debug > 1) {echo "<p class='dbg'>Filter Bezirk '".$zgbbez."'<p>";}
 		$sql.="AND b.bezirk='".$zgbbez."' ";
 		$bezirkaktuell = true;
@@ -333,5 +337,5 @@
 // Im zweiten Schritt wird gesucht nach Rechten einer Buchungstelle des durchsuchten Blattes an anderen
 // Buchungstellen.
-	global $gkz, $gemeinde, $name, $person, $blattgml, $epsg, $gfilter, $debug;
+	global $gkz, $gemeinde, $name, $person, $blattgml, $epsg, $gfilter, $debug, $katamtmix;
 	if($backlink) { // Erneuter Ansatz bei Person oder GB mÃ¶glich.
 
@@ -347,6 +351,7 @@
 		// Grundbuch-Daten ermitteln
 		$sql ="SELECT gb.gml_id AS gml_g, gb.buchungsblattnummermitbuchstabenerweiterung as blatt, b.bezirk, b.bezeichnung AS beznam "
-		."FROM ax_buchungsblatt gb JOIN ax_buchungsblattbezirk b ON gb.land=b.land AND gb.bezirk=b.bezirk "
-		."WHERE gb.gml_id= $1 AND gb.endet IS NULL and b.endet IS NULL LIMIT 1 ;";
+		."FROM ax_buchungsblatt gb JOIN ax_buchungsblattbezirk b ON gb.land=b.land AND gb.bezirk=b.bezirk ";
+		if ($katamtmix){$sql.="AND substr(gb.gml_id,1,6) = substr(b.gml_id,1,6) ";}
+		$sql.="WHERE gb.gml_id= $1 AND gb.endet IS NULL and b.endet IS NULL LIMIT 1 ;";
 		$v=array($blattgml);
 		$res=pg_prepare("", $sql);
@@ -376,5 +381,5 @@
 // weil "ungefiltert" in "2+3" zu lange Listen entstehen wÃŒrden, die durchblÃ€ttert werden mÃŒssen. 
 
-	global $gkz, $gemeinde, $epsg, $name, $person, $blattgml, $gfilter, $debug, $bltbez, $bltblatt, $bltbvnr, $bltseite, $bltrecht, $kennztyp, $zgbbez;
+	global $gkz, $gemeinde, $epsg, $name, $person, $blattgml, $gfilter, $debug, $bltbez, $bltblatt, $bltbvnr, $bltseite, $bltrecht, $kennztyp, $zgbbez, $katamtmix;
 	$linelimit=80; // als Limit "Anzahl FlurstÃŒcke" in den beiden folgenden Abfragen
 	// darf nun etwas knapper sein, weil man jetzt blÃ€ttern kann
@@ -406,6 +411,7 @@
 	$sql1.="FROM ax_namensnummer nn "
 	."JOIN ax_buchungsblatt gb ON gb.gml_id=nn.istbestandteilvon "
-	."JOIN ax_buchungsblattbezirk b ON gb.land=b.land AND gb.bezirk=b.bezirk "
-	."JOIN ax_buchungsstelle s1 ON gb.gml_id=s1.istbestandteilvon ";
+	."JOIN ax_buchungsblattbezirk b ON gb.land=b.land AND gb.bezirk=b.bezirk ";
+	if ($katamtmix){$sql.="AND substr(gb.gml_id,1,6) = substr(b.gml_id,1,6) ";}
+	$sql1.="JOIN ax_buchungsstelle s1 ON gb.gml_id=s1.istbestandteilvon ";
 
 	// Baustein A: Auswahl 1 oder 2
@@ -621,7 +627,6 @@
 }
 
-// ===========
 // Start hier!
-// ===========
+
 // Parameter:  
 // 1. name   = Suche nach Namensanfang oder -bestandteil.
@@ -633,5 +638,5 @@
 // Hier formatierte Meldung und html-Foot.
 if (isset($name) and $name != "" ) { 
-	if (!preg_match('#^[a-zA-Z0-9Ã€Ã¶ÃŒÃÃÃÃ*,. \-&/]{1,50}$#', $name)) {
+	if (!preg_match('#^[a-zA-Z0-9Ã€Ã¶ÃŒÃÃÃÃÅŸÅœÅ¡Å *,. \-&/]{1,50}$#', $name)) {
 		echo "<p class='err'>Eingabe unzul&auml;ssig!</p>";
 	//	if ($debug > 1) {echo "<p class='err'>Name='".$name."' LÃ€nge='".strlen($name)."</p>";}
Index: trunk/mapbender/http/nav/alkisnav_adr.php
===================================================================
--- trunk/mapbender/http/nav/alkisnav_adr.php	(revision 420)
+++ trunk/mapbender/http/nav/alkisnav_adr.php	(revision 425)
@@ -8,4 +8,7 @@
 	2018-02-15 Strikte Input-Validation der Parameter
 	2018-11-12 Full-Schema
+	2021-11-24 Neue Var. $katamtmix  (Kataster-Amt-Mix).
+	           SchlÃŒsseltabellen sind mehrfach belegt. Dadurch doppelte Treffer bei der Suche.
+
 ToDo:
 	-	Gruppierung (mit Zeile) der StraÃenliste nach Gemeinde
@@ -47,5 +50,4 @@
 	$gfilter = 0;
 }
-// // http://skrzmaptest01.asp.krzwan.de/mapbender/nav/alkisnav_adr.php?gkz=210&gemeinde=004&epsg=25832&str_schl=0575800401798
 if (isset($str_schl) ) {
 	if (!preg_match('#^[0-9]{4,13}$#', $str_schl)) {die("Eingabefehler Stra&zlig;enschl&uuml;ssel");}
@@ -90,9 +92,9 @@
 function suchStrName() {
 	// Strassen nach Name(-nsanfang)
-	global $street, $scalestr, $str_schl, $gkz, $gemeinde, $epsg, $gfilter, $debug, $auskpath;
+	global $street, $scalestr, $str_schl, $gkz, $gemeinde, $epsg, $gfilter, $debug, $auskpath, $katamtmix;
 	//if ($debug > 1) {echo "<p class='dbg'>function suchStrName()<p>";} // Ablauf-Verfolgung
 
 	$linelimit=120;  // -> in Conf?
-	$str_schl=""; // Loeschen vorh. Ergebnis
+	$str_schl=""; // LÃ¶schen vorh. Ergebnis
 	preg_match("/^(\D+)(\d*)(\D*)/",$street,$matches); # 4 matches name/nr/zusatz 
 	//echo "match: 1='".$matches[1]."', 2='".$matches[2]."', 3='".$matches[3]."'";
@@ -108,6 +110,7 @@
 	$sql ="SELECT g.gemeinde, g.bezeichnung AS gemname, k.gml_id, k.bezeichnung, k.schluesselgesamt, k.lage "
 	."FROM ax_lagebezeichnungkatalogeintrag k "
-	."JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde "
-	."WHERE k.bezeichnung ILIKE $1 AND k.endet IS NULL AND g.endet IS NULL ";
+	."JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde ";
+	if ($katamtmix){$sql.="AND substr(k.gml_id,1,6) = substr(g.gml_id,1,6) ";}
+	$sql.="WHERE k.bezeichnung ILIKE $1 AND k.endet IS NULL AND g.endet IS NULL ";
 
 	switch ($gfilter) {
@@ -143,5 +146,5 @@
 			$gwgem=$gemname;
 		}
-		$gkey=$row["schluesselgesamt"]; // Land-RegBez-Kreis-Gem-Strasse - fÃŒr weitere Suche
+		$gkey=$row["schluesselgesamt"]; // Land-RegBez-Kreis-Gem-StraÃe - fÃŒr weitere Suche
 		$skey=$row["lage"]; // Nur Str.-schl. daraus
 		$kgml=$row["gml_id"]; // ID von Katalog
@@ -164,6 +167,6 @@
 }
 
-function suchStrKey() { // Strassen nach num. Schluessel
-	global $street, $scalestr, $str_schl, $gkz, $gemeinde, $epsg, $gfilter, $debug, $auskpath;
+function suchStrKey() { // StraÃen nach num. SchlÃŒssel
+	global $street, $scalestr, $str_schl, $gkz, $gemeinde, $epsg, $gfilter, $debug, $auskpath, $katamtmix;
 	//if ($debug > 1) {echo "<p class='dbg'>function suchStrKey()<p>";} // Ablauf-Verfolgung
 	$linelimit=60;
@@ -174,8 +177,10 @@
 		$match=str_pad($street, 5, "0", STR_PAD_LEFT); // "Wie eine Zahl" verarbeiten 
 	}
+
 	$sql ="SELECT g.bezeichnung AS gemname, k.gml_id, k.bezeichnung, k.schluesselgesamt, k.lage "
 	."FROM ax_lagebezeichnungkatalogeintrag as k "
-	."JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde "
-	."WHERE k.lage LIKE $1 AND k.endet IS NULL AND g.endet IS NULL ";
+	."JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde ";
+	if ($katamtmix){$sql.="AND substr(k.gml_id,1,6) = substr(g.gml_id,1,6) ";}
+	$sql.="WHERE k.lage LIKE $1 AND k.endet IS NULL AND g.endet IS NULL ";
 	switch ($gfilter) {
 		case 1: // Einzelwert
@@ -217,16 +222,17 @@
 }
 
-function suchHausZurStr($showParent) { // Haeuser zu einer Strasse
-	global $str_schl, $gkz, $scalestr, $scalehs, $epsg, $gemeinde, $epsg, $gfilter, $debug, $auskpath;
+function suchHausZurStr($showParent) { // HÃ€user zu einer StraÃe
+	global $str_schl, $gkz, $scalestr, $scalehs, $epsg, $gemeinde, $epsg, $gfilter, $debug, $auskpath, $katamtmix;
 	//if ($debug > 1) {echo "<p class='dbg'>function suchHausZurStr()<p>";} // Ablauf-Verfolgung
 
 	// Head
-	// Strasse zum Strassenschluessel
+	// StraÃe zum StrassenschlÃŒssel
 	$sql ="SELECT g.bezeichnung AS gemname, k.gml_id AS kgml, k.bezeichnung, k.land, k.regierungsbezirk, k.kreis, k.gemeinde, k.lage "
 	."FROM ax_lagebezeichnungkatalogeintrag as k "
-	."JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde "
-	."WHERE k.schluesselgesamt = $1 AND k.endet IS NULL AND g.endet IS NULL LIMIT 1"; 
-
-  	$v=array($str_schl);	// Schluessel-Gesamt ..
+	."JOIN ax_gemeinde g ON k.land=g.land AND k.regierungsbezirk=g.regierungsbezirk AND k.kreis=g.kreis AND k.gemeinde=g.gemeinde ";
+	if ($katamtmix){$sql.="AND substr(k.gml_id,1,6) = substr(g.gml_id,1,6) ";}
+	$sql.="WHERE k.schluesselgesamt = $1 AND k.endet IS NULL AND g.endet IS NULL LIMIT 1"; 
+
+  	$v=array($str_schl);	// SchlÃŒssel-Gesamt ..
 	$res=pg_prepare("", $sql);
 	$res=pg_execute("", $v);
@@ -238,5 +244,5 @@
 
 	if($row = pg_fetch_array($res)) { // .. gefunden
-		$kgml=$row["kgml"]; // ID aus Katalog
+		$kgml=$row["kgml"]; 	// ID aus Katalog
 		$sname=$row["bezeichnung"];
 		$land =$row["land"];	// Einzel-Felder fÃŒr JOIN _lagebezeichnung_
@@ -247,5 +253,5 @@
 		$gemname=htmlentities($row["gemname"], ENT_QUOTES, "UTF-8");
 		if ($showParent) {
-			// EINE Koordinate zur Strasse besorgen
+			// EINE Koordinate zur StraÃe besorgen
 			// ax_Flurstueck >zeigtAuf> ax_LagebezeichnungOhneHausnummer
 			$sqlko ="SELECT ";
@@ -300,5 +306,5 @@
 
 		// Body
-		// Haeuser zum Strassenschluessel
+		// HÃ€user zum StraÃenschlÃŒssel
 		$sql="SELECT min(replace(h.hausnummer,' ','')) AS hsnr, ";
 		if($epsg == "25832") { // Transform nicht notwendig
@@ -348,5 +354,5 @@
 			$cnt++;
 			$count++;
-			if($count == 7) { // Max. Hausnummern je Zeile (Test: 3stellige HsNr mit Zusatz)
+			if($count == 7) { // Max. HausNr je Zeile (Test: 3stellige HsNr mit Zusatz)
 				echo "\n</tr>";
 				$count = 0;
@@ -363,10 +369,9 @@
 	return;
 }
-// ===========
+
 // Start hier!
-// ===========
 
 // Validation: Eingabefeld aus Formular.
-// Suchbegriff (StraÃenname) oder StraÃenschlÃŒssel.
+// Suchbegriff StraÃenname oder StraÃenschlÃŒssel.
 // Hier formatierte Meldung und html-Foot.
 if (isset($street) and $street != "" ) {
@@ -398,6 +403,5 @@
 }
 
-// Nach Durchlaufen des PHP-Scriptes die zuletzt ausgefÃŒhrte Transaktion 
-//  im Kopf des Ergebnisrahmens anzeigen.
+// Nach Durchlaufen des PHP-Scriptes die zuletzt ausgefÃŒhrte Transaktion im Kopf des Ergebnisrahmens anzeigen.
 // Dazu die im HTML-Header definierte Javascript-Function benutzen.
 // Alternativ wird auch aus dem Javascript "positionieren Karte" dieser Titel gesetzt.
Index: trunk/mapbender/http/nav/alkisnav_grd.php
===================================================================
--- trunk/mapbender/http/nav/alkisnav_grd.php	(revision 420)
+++ trunk/mapbender/http/nav/alkisnav_grd.php	(revision 425)
@@ -10,4 +10,6 @@
 	2018-11-12 Full-Schema
 	2019-02-12 Sortierung FlurstÃŒcksnummer repariert
+	2021-11-24 Neue Var. $katamtmix  (Kataster-Amt-Mix).
+	           SchlÃŒsseltabellen sind mehrfach belegt. Dadurch doppelte Treffer bei der Suche.
 */
 
@@ -107,5 +109,5 @@
 	$linelimit=40;
 
-	$sql="SELECT stelle, bezeichnung AS ag FROM ax_dienststelle "
+	$sql="SELECT DISTINCT stelle, bezeichnung AS ag FROM ax_dienststelle "
 	."WHERE stelle IN (".$liste_ag.") AND stellenart = 1000 AND endet IS NULL ORDER BY bezeichnung LIMIT $1 ;";
 	$res = pg_prepare("", $sql);
@@ -138,5 +140,5 @@
 	// Auch wenn BlÃ€tter vorhanden sind, kann es eine "Sackgasse" sein.
 	// Manchmal haben die BlÃ€tter keine FlurstÃŒcke im Filter-Bereich (Gemeinde).
-	global $debug;
+	global $debug, $katamtmix;
 	$linelimit=100; // Bezirke/AG
 
@@ -146,6 +148,7 @@
 	// Body
 	// Die Subquery stellt sicher, dass nur Bezirke aufgelistet werden, die auch BlÃ€tter enthalten
-	$sql ="SELECT g.bezirk, g.bezeichnung FROM ax_buchungsblattbezirk g JOIN ax_dienststelle a ON g.gehoertzu_stelle = a.stelle "
-	."WHERE a.stelle = $1 AND a.stellenart = 1000 AND a.endet IS NULL AND g.endet IS NULL "
+	$sql ="SELECT DISTINCT g.bezirk, g.bezeichnung FROM ax_buchungsblattbezirk g JOIN ax_dienststelle a ON g.gehoertzu_stelle = a.stelle ";
+	if ($katamtmix){$sql.="AND substr(g.gml_id,1,6) = substr(a.gml_id,1,6) ";}
+	$sql.="WHERE a.stelle = $1 AND a.stellenart = 1000 AND a.endet IS NULL AND g.endet IS NULL "
 	."AND NOT (SELECT gml_id FROM ax_buchungsblatt b WHERE b.land=g.land AND b.bezirk=g.bezirk AND b.endet IS NULL LIMIT 1) IS NULL "
 	."ORDER BY g.bezeichnung LIMIT $2 ;";
@@ -180,7 +183,9 @@
 	// Zu einem Grundbuchbezirks-SchlÃŒssel die Zeilen "AG" und "Bezirk" ausgeben
 	// Parameter = SchlÃŒssel des Bezirks
-	#global $debug;
+	global $katamtmix;
 	$sql ="SELECT a.stelle, a.bezeichnung AS ag, g.bezeichnung FROM ax_buchungsblattbezirk g "
-	."JOIN ax_dienststelle a ON g.gehoertzu_stelle = a.stelle WHERE g.bezirk= $1 AND g.endet IS NULL AND a.endet IS NULL LIMIT 1;";
+	."JOIN ax_dienststelle a ON g.gehoertzu_stelle = a.stelle ";
+	if ($katamtmix){$sql.="AND substr(g.gml_id,1,6) = substr(a.gml_id,1,6) ";}
+	$sql.="WHERE g.bezirk= $1 AND g.endet IS NULL AND a.endet IS NULL LIMIT 1;";
 	$v=array($gbbez);
 	$res=pg_prepare("", $sql);
@@ -209,10 +214,11 @@
 function SuchGBBezName() {
 	// Grundbuch-Bezirk suchen nach Name(-nsanfang)
-	global $gkz, $gemeinde, $debug, $gbkennz;
+	global $gkz, $gemeinde, $debug, $gbkennz, $katamtmix;
 	$linelimit=80;
 
-	$sql ="SELECT a.stelle, a.bezeichnung AS ag, g.bezirk, g.bezeichnung FROM ax_buchungsblattbezirk g "
-	."JOIN ax_dienststelle a ON g.gehoertzu_stelle = a.stelle "
-	."WHERE g.bezeichnung ILIKE $1 AND g.endet IS NULL AND a.endet IS NULL "
+	$sql ="SELECT DISTINCT a.stelle, a.bezeichnung AS ag, g.bezirk, g.bezeichnung FROM ax_buchungsblattbezirk g "
+	."JOIN ax_dienststelle a ON g.gehoertzu_stelle = a.stelle ";
+	if ($katamtmix){$sql.="AND substr(g.gml_id,1,6) = substr(a.gml_id,1,6) ";}
+	$sql.="WHERE g.bezeichnung ILIKE $1 AND g.endet IS NULL AND a.endet IS NULL "
 	."ORDER BY a.bezeichnung, g.bezeichnung LIMIT $2 ;"; // "AND a.stellenart=1000 " Amtsgericht
 	if ( $gbkennz == "") {
@@ -307,5 +313,4 @@
 function gml_blatt() {
 	// Kennzeichen "Bezirk + Blatt" eingegeben. Dazu die gml_id des Blattes ermitteln.
-	// 2018-10: Sonderfall Buchstabe: Auch finden wenn der nicht eingegeben wurde.
 	global $debug, $zgbbez, $zblatt, $zblattn, $zblattz;
 	$sql ="SELECT b.gml_id, b.buchungsblattnummermitbuchstabenerweiterung AS blatt FROM ax_buchungsblatt b "
@@ -380,5 +385,5 @@
 		$gef_blatt=$row["blatt"];	// gefunden ggf. mit Buchstabe (Wildcard)
 		if ($zblatt != $gef_blatt) {
-			echo "\n<p class='dbg'>Blatt mit Buchstabenerweiterung gefunden.</p>";
+		//	echo "\n<p class='dbg'>Blatt mit Buchstabenerweiterung gefunden.</p>";
 			$zblatt=$gef_blatt;
 			$zblattz=substr($zblatt, strlen($zblatt)-1, 1);
@@ -397,5 +402,5 @@
 	// Die gml_id der Buchungsstelle (BVNR, GrundstÃŒck) ist bekannt = $buchunggml
 	// Die gebuchten FlurstÃŒcke und dienende/herrschenden Buchungen werden ausgegeben.
-	global $debug, $gemeinde, $epsg, $buchunggml, $zgbbez, $zblatt, $zblattn, $zblattz, $zbvnr, $gfilter;
+	global $debug, $gemeinde, $epsg, $buchunggml, $zgbbez, $zblatt, $zblattn, $zblattz, $zbvnr, $gfilter, $katamtmix;
 	// NoLimit?
 
@@ -409,5 +414,4 @@
 			echo "<p class='err'>Kennzeichen Bezirk und Blatt nicht gesetzt</p>";
 		} // ++ suchen!
-	//	zeile_buchung($buchunggml, $zbvnr, $zgbbez."-".$zblattn.$zblattz, false, true);
 		zeile_buchung($buchunggml, $zbvnr, $zgbbez."-".$zblatt, false, true); // $zblatt wird aktualisiert, wenn Buchstabe gefunden wurde
 	}
@@ -445,4 +449,5 @@
 	// Direkte Buchungen (Flurst.)
 	$sql =$sqlanf."FROM ax_flurstueck f JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer ";
+	if ($katamtmix){$sql.="AND substr(g.gml_id,1,6) = substr(f.gml_id,1,6) ";}
 	$sql.="WHERE f.istgebucht = $1 AND f.endet IS NULL ".$sqlfilter."ORDER BY f.gemarkungsnummer, f.flurnummer, cast(f.zaehler AS integer), cast(f.nenner AS integer);";
 
@@ -482,8 +487,10 @@
 	."FROM ax_buchungsstelle sh JOIN ax_buchungsstelle sd ON sd.gml_id=ANY(sh.an) "
 	."JOIN ax_flurstueck f ON f.istgebucht=sd.gml_id "
-	."JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer "
-	."JOIN ax_buchungsblatt bd ON sd.istbestandteilvon=bd.gml_id "
-	."JOIN ax_buchungsblattbezirk gd ON bd.land=gd.land AND bd.bezirk=gd.bezirk "
-	."WHERE sh.gml_id = $1 AND sh.endet IS NULL AND sd.endet IS NULL AND f.endet IS NULL AND bd.endet IS NULL AND gd.endet IS NULL "
+	."JOIN ax_gemarkung g ON f.land=g.land AND f.gemarkungsnummer=g.gemarkungsnummer ";
+	if ($katamtmix){$sql.="AND substr(f.gml_id,1,6) = substr(g.gml_id,1,6) ";}
+	$sql.="JOIN ax_buchungsblatt bd ON sd.istbestandteilvon=bd.gml_id "
+	."JOIN ax_buchungsblattbezirk gd ON bd.land=gd.land AND bd.bezirk=gd.bezirk ";
+	if ($katamtmix){$sql.="AND substr(bd.gml_id,1,6) = substr(gd.gml_id,1,6) ";}
+	$sql.="WHERE sh.gml_id = $1 AND sh.endet IS NULL AND sd.endet IS NULL AND f.endet IS NULL AND bd.endet IS NULL AND gd.endet IS NULL "
 
 	.$sqlfilter."ORDER BY gd.bezeichnung, bd.buchungsblattnummermitbuchstabenerweiterung, cast(sd.laufendenummer AS integer), f.gemarkungsnummer, f.flurnummer, cast(f.zaehler AS integer), cast(f.nenner AS integer);";
@@ -494,7 +501,5 @@
 	if (!$res) {
 		echo "\n<p class='err'>Fehler bei Buchungsstelle (gml, Recht an).</p>";
-		if ($debug >= 3) {
-			echo "\n<p class='err'>'".$sql."'<br>\nmit $1 ='".$buchunggml."'</p>";
-		}
+		if ($debug >= 3) {echo "\n<p class='err'>'".$sql."'<br>\nmit $1 ='".$buchunggml."'</p>";}
 	}
 	$zfs2=0;
@@ -544,7 +549,5 @@
 }
 
-// ===========
 // Start hier!
-// ===========
 
 // Validation: Eingabefeld aus Formular.
