Pop Erweiterung Adressen nun mit Straßenschlüssel

* Bugfix filtern und sortieren auf Adressenbasis funktioniert nun
This commit is contained in:
Daniel Spitzer
2026-03-01 20:06:25 +01:00
parent 7e12c6ff1d
commit 6312f6657b
2 changed files with 162 additions and 26 deletions

View File

@@ -56,6 +56,7 @@ class PopController extends mfBaseController
"city" => $pop->city,
"street" => $pop->street,
"number" => $pop->number,
"address" => trim($pop->street . ' ' . $pop->number . ', ' . $pop->zip . ' ' . $pop->city, ', '),
"state" => $pop->state,
"folder_link" => $pop->folder_link,
"doku_date" => $pop->doku_date,
@@ -1411,6 +1412,8 @@ class PopController extends mfBaseController
case "getSplicePlanForElement":
return $this->getSplicePlanForElementAction();
break;
case "searchAddress":
return $this->searchAddressApi();
default:
$return = false;
}
@@ -1965,4 +1968,97 @@ class PopController extends mfBaseController
'connections' => $result
]));
}
private function searchAddressApi()
{
$q = trim($this->request->q);
if (strlen($q) < 2) {
$this->returnJson(["results" => []]);
}
$db = FronkDB::singleton(ADDRESSDB_DBHOST, ADDRESSDB_DBUSER, ADDRESSDB_DBPASS, ADDRESSDB_DBNAME);
// split input into parts, any order allowed: "graz alte 5" or "Alte Poststraße 5, 8010 Graz"
$parts = preg_split('/[\s,]+/', $q, -1, PREG_SPLIT_NO_EMPTY);
// categorize: 4-digit = PLZ, short number = hausnummer, text = street or city
$text_parts = [];
$hausnummer = null;
$plz = null;
foreach ($parts as $part) {
if (preg_match('/^\d{4}$/', $part)) {
$plz = $part;
} elseif ($hausnummer === null && preg_match('/^\d+[a-zA-Z]?$/', $part)) {
$hausnummer = $part;
} else {
$text_parts[] = $part;
}
}
// Pre-query Gemeinde (tiny table, instant) to resolve text→gemeinde_id
$gemeinde_ids_per_part = [];
foreach ($text_parts as $tp) {
$escaped = $db->escape($tp);
$gres = $db->query("SELECT id FROM Gemeinde WHERE name LIKE '%$escaped%'");
$ids = [];
if ($gres && $db->num_rows($gres)) {
while ($grow = $db->fetch_object($gres)) {
$ids[] = (int)$grow->id;
}
}
$gemeinde_ids_per_part[$tp] = $ids;
}
// Build conditions: text parts match Strasse.name OR pre-resolved gemeinde_id (uses index)
$conditions = [];
foreach ($text_parts as $tp) {
$escaped = $db->escape($tp);
if (!empty($gemeinde_ids_per_part[$tp])) {
$ids_str = implode(',', $gemeinde_ids_per_part[$tp]);
$conditions[] = "(Strasse.name LIKE '%$escaped%' OR Strasse.gemeinde_id IN ($ids_str))";
} else {
$conditions[] = "Strasse.name LIKE '%$escaped%'";
}
}
if ($hausnummer !== null) {
$hn = $db->escape($hausnummer);
$conditions[] = "Hausnummer.hausnummer LIKE '$hn%'";
}
if ($plz !== null) {
$pz = $db->escape($plz);
$conditions[] = "Plz.plzstring LIKE '$pz%'";
}
$where = count($conditions) ? implode(' AND ', $conditions) : '1=0';
$sql = "SELECT Strasse.name as strasse, Hausnummer.hausnummer, Plz.plz, Gemeinde.name as gemeinde
FROM Strasse
STRAIGHT_JOIN Hausnummer ON (Hausnummer.strasse_id = Strasse.id)
LEFT JOIN Plz ON (Plz.id = Hausnummer.plz_id)
LEFT JOIN Gemeinde ON (Gemeinde.id = Strasse.gemeinde_id)
WHERE $where
GROUP BY Strasse.name, Hausnummer.hausnummer, Plz.plz, Gemeinde.name
ORDER BY Strasse.name, Hausnummer.hausnummer + 0, Plz.plz
LIMIT 25";
$results = [];
$res = $db->query($sql);
if ($db->num_rows($res)) {
while ($row = $db->fetch_object($res)) {
$text = $row->strasse;
if ($row->hausnummer) $text .= ' ' . $row->hausnummer;
if ($row->plz || $row->gemeinde) $text .= ', ' . trim($row->plz . ' ' . $row->gemeinde);
$results[] = [
"id" => $text,
"text" => $text,
"street" => $row->strasse,
"number" => $row->hausnummer,
"zip" => $row->plz,
"city" => $row->gemeinde,
];
}
}
$this->returnJson(["results" => $results]);
}
}