mirror of
https://github.com/osm-search/Nominatim.git
synced 2024-12-25 05:52:32 +03:00
do not return POIs when dropping house number in query
We've previously added searching through rank 30 in a house number search to enable searches for house number+name. This had the unintended side effect that rank 30 objects are also returned in s search that dropped the house number from the query. This is wrong because POIs cannot function as a parent to a house number. This fix drops all rank 30 objects from the results for a house number search if they do not match the requested house number.
This commit is contained in:
parent
38fbc4fcbb
commit
fe11d3cbbd
@ -55,6 +55,27 @@ class Result
|
||||
}
|
||||
)));
|
||||
}
|
||||
|
||||
public static function joinIdsByTableMinRank($aResults, $iTable, $iMinAddressRank)
|
||||
{
|
||||
return join(',', array_keys(array_filter(
|
||||
$aResults,
|
||||
function ($aValue) use ($iTable, $iMinAddressRank) {
|
||||
return $aValue->iTable == $iTable && $aValue->iAddressRank >= $iMinAddressRank;
|
||||
}
|
||||
)));
|
||||
}
|
||||
|
||||
public static function joinIdsByTableMaxRank($aResults, $iTable, $iMaxAddressRank)
|
||||
{
|
||||
return join(',', array_keys(array_filter(
|
||||
$aResults,
|
||||
function ($aValue) use ($iTable, $iMaxAddressRank) {
|
||||
return $aValue->iTable == $iTable && $aValue->iAddressRank <= $iMaxAddressRank;
|
||||
}
|
||||
)));
|
||||
}
|
||||
|
||||
public static function sqlHouseNumberTable($aResults, $iTable)
|
||||
{
|
||||
$sHousenumbers = '';
|
||||
|
@ -447,23 +447,24 @@ class SearchDescription
|
||||
|
||||
// Now search for housenumber, if housenumber provided. Can be zero.
|
||||
if (($this->sHouseNumber || $this->sHouseNumber === '0') && !empty($aResults)) {
|
||||
$aHnResults = $this->queryHouseNumber($oDB, $aResults);
|
||||
|
||||
// Downgrade the rank of the street results, they are missing
|
||||
// the housenumber.
|
||||
// the housenumber. Also drop POI places (rank 30) here, they
|
||||
// cannot be a parent place and therefore must not be shown
|
||||
// as a result for a search with a missing housenumber.
|
||||
foreach ($aResults as $oRes) {
|
||||
if ($oRes->iAddressRank < 28) {
|
||||
if ($oRes->iAddressRank >= 26) {
|
||||
$oRes->iResultRank++;
|
||||
} else {
|
||||
$oRes->iResultRank += 2;
|
||||
}
|
||||
$aHnResults[$oRes->iId] = $oRes;
|
||||
}
|
||||
}
|
||||
|
||||
$aHnResults = $this->queryHouseNumber($oDB, $aResults);
|
||||
|
||||
if (!empty($aHnResults)) {
|
||||
foreach ($aHnResults as $oRes) {
|
||||
$aResults[$oRes->iId] = $oRes;
|
||||
}
|
||||
}
|
||||
$aResults = $aHnResults;
|
||||
}
|
||||
|
||||
// finally get POIs if requested
|
||||
@ -743,16 +744,33 @@ class SearchDescription
|
||||
private function queryHouseNumber(&$oDB, $aRoadPlaceIDs)
|
||||
{
|
||||
$aResults = array();
|
||||
$sPlaceIDs = Result::joinIdsByTable($aRoadPlaceIDs, Result::TABLE_PLACEX);
|
||||
$sRoadPlaceIDs = Result::joinIdsByTableMaxRank(
|
||||
$aRoadPlaceIDs,
|
||||
Result::TABLE_PLACEX,
|
||||
27
|
||||
);
|
||||
$sPOIPlaceIDs = Result::joinIdsByTableMinRank(
|
||||
$aRoadPlaceIDs,
|
||||
Result::TABLE_PLACEX,
|
||||
30
|
||||
);
|
||||
|
||||
if (!$sPlaceIDs) {
|
||||
$aIDCondition = array();
|
||||
if ($sRoadPlaceIDs) {
|
||||
$aIDCondition[] = 'parent_place_id in ('.$sRoadPlaceIDs.')';
|
||||
}
|
||||
if ($sPOIPlaceIDs) {
|
||||
$aIDCondition[] = 'place_id in ('.$sPOIPlaceIDs.')';
|
||||
}
|
||||
|
||||
if (empty($aIDCondition)) {
|
||||
return $aResults;
|
||||
}
|
||||
|
||||
$sHouseNumberRegex = '\\\\m'.$this->sHouseNumber.'\\\\M';
|
||||
$sSQL = 'SELECT place_id FROM placex ';
|
||||
$sSQL .= 'WHERE parent_place_id in ('.$sPlaceIDs.')';
|
||||
$sSQL .= " AND housenumber ~* E'".$sHouseNumberRegex."'";
|
||||
$sSQL = 'SELECT place_id FROM placex WHERE';
|
||||
$sSQL .= " housenumber ~* E'".$sHouseNumberRegex."'";
|
||||
$sSQL .= ' AND ('.join(' OR ', $aIDCondition).')';
|
||||
$sSQL .= $this->oContext->excludeSQL(' AND place_id');
|
||||
|
||||
Debug::printSQL($sSQL);
|
||||
@ -764,11 +782,11 @@ class SearchDescription
|
||||
|
||||
$bIsIntHouseNumber= (bool) preg_match('/[0-9]+/', $this->sHouseNumber);
|
||||
$iHousenumber = intval($this->sHouseNumber);
|
||||
if ($bIsIntHouseNumber && empty($aResults)) {
|
||||
if ($bIsIntHouseNumber && $sRoadPlaceIDs && empty($aResults)) {
|
||||
// if nothing found, search in the interpolation line table
|
||||
$sSQL = 'SELECT distinct place_id FROM location_property_osmline';
|
||||
$sSQL .= ' WHERE startnumber is not NULL';
|
||||
$sSQL .= ' AND parent_place_id in ('.$sPlaceIDs.') AND (';
|
||||
$sSQL .= ' AND parent_place_id in ('.$sRoadPlaceIDs.') AND (';
|
||||
if ($iHousenumber % 2 == 0) {
|
||||
// If housenumber is even, look for housenumber in streets
|
||||
// with interpolationtype even or all.
|
||||
@ -792,9 +810,9 @@ class SearchDescription
|
||||
}
|
||||
|
||||
// If nothing found then search in Tiger data (location_property_tiger)
|
||||
if (CONST_Use_US_Tiger_Data && $bIsIntHouseNumber && empty($aResults)) {
|
||||
if (CONST_Use_US_Tiger_Data && $sRoadPlaceIDs && $bIsIntHouseNumber && empty($aResults)) {
|
||||
$sSQL = 'SELECT place_id FROM location_property_tiger';
|
||||
$sSQL .= ' WHERE parent_place_id in ('.$sPlaceIDs.') and (';
|
||||
$sSQL .= ' WHERE parent_place_id in ('.$sRoadPlaceIDs.') and (';
|
||||
if ($iHousenumber % 2 == 0) {
|
||||
$sSQL .= "interpolationtype='even'";
|
||||
} else {
|
||||
|
@ -45,3 +45,30 @@ Feature: Searching of simple objects
|
||||
Then result addresses contain
|
||||
| amenity | road |
|
||||
| Bean | The build |
|
||||
|
||||
Scenario: when missing housenumbers in search don't return a POI
|
||||
Given the places
|
||||
| osm | class | type | name |
|
||||
| N3 | amenity | restaurant | Wood Street |
|
||||
And the places
|
||||
| osm | class | type | name | housenr |
|
||||
| N20 | amenity | restaurant | Red Way | 34 |
|
||||
When importing
|
||||
And sending search query "Wood Street 45"
|
||||
Then exactly 0 results are returned
|
||||
When sending search query "Red Way 34"
|
||||
Then results contain
|
||||
| osm |
|
||||
| N20 |
|
||||
|
||||
Scenario: when the housenumber is missing the stret is still returned
|
||||
Given the grid
|
||||
| 1 | | 2 |
|
||||
Given the places
|
||||
| osm | class | type | name | geometry |
|
||||
| W1 | highway | residential | Wood Street | 1, 2 |
|
||||
When importing
|
||||
And sending search query "Wood Street"
|
||||
Then results contain
|
||||
| osm |
|
||||
| W1 |
|
||||
|
Loading…
Reference in New Issue
Block a user