}
)));
}
+
+ 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 = '';
// 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 >= 26) {
- $oRes->iResultRank++;
- } else {
- $oRes->iResultRank += 2;
+ 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
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);
$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.
}
// 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 {
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 |