X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/b3b109b86fb747439f3a66a72bcd046b6278a0b3..00a3e843e3fb4a6fc735a019cdf7a3e38558cad6:/website/search.php diff --git a/website/search.php b/website/search.php index 95d0cadd..d486ed66 100755 --- a/website/search.php +++ b/website/search.php @@ -26,6 +26,7 @@ $iLimit = $iFinalLimit + min($iFinalLimit, 10); $iMinAddressRank = 0; $iMaxAddressRank = 30; + $aAddressRankList = array(); $sAllowedTypesSQLList = false; // Format for output @@ -139,35 +140,21 @@ $sQuery = join(', ',$aPhrases); } - function structuredAddressElement(&$aStructuredQuery, &$iMinAddressRank, &$iMaxAddressRank, $aParams, $sKey, $iNewMinAddressRank, $iNewMaxAddressRank) - { - if (!isset($_GET[$sKey])) return false; - $sValue = trim($_GET[$sKey]); - if (!$sValue) return false; - $aStructuredQuery[$sKey] = $sValue; - if ($iMinAddressRank == 0 && $iMaxAddressRank == 30) - { - $iMinAddressRank = $iNewMinAddressRank; - $iMaxAddressRank = $iNewMaxAddressRank; - } - return true; - } - // Structured query? $aStructuredOptions = array( - array('amenity', 26, 30), - array('street', 26, 30), - array('city', 14, 24), - array('county', 9, 13), - array('state', 8, 8), - array('country', 4, 4), - array('postalcode', 5, 11), + array('amenity', 26, 30, false), + array('street', 26, 30, false), + array('city', 14, 24, false), + array('county', 9, 13, false), + array('state', 8, 8, false), + array('country', 4, 4, false), + array('postalcode', 5, 11, array(5, 11)), ); $aStructuredQuery = array(); $sAllowedTypesSQLList = ''; foreach($aStructuredOptions as $aStructuredOption) { - loadStructuredAddressElement($aStructuredQuery, $iMinAddressRank, $iMaxAddressRank, $_GET, $aStructuredOption[0], $aStructuredOption[1], $aStructuredOption[2]); + loadStructuredAddressElement($aStructuredQuery, $iMinAddressRank, $iMaxAddressRank, $aAddressRankList, $_GET, $aStructuredOption[0], $aStructuredOption[1], $aStructuredOption[2], $aStructuredOption[3]); } if (sizeof($aStructuredQuery) > 0) { @@ -371,7 +358,6 @@ $bStructuredPhrases = false; } - // Convert each phrase to standard form // Create a list of standard words // Get all 'sets' of words @@ -481,7 +467,6 @@ /* Calculate all searches using aValidTokens i.e. - 'Wodsworth Road, Sheffield' => Phrase Wordset @@ -545,6 +530,42 @@ if ($aSearch['iSearchRank'] < $iMaxRank) $aNewWordsetSearches[] = $aSearch; } } + elseif ($sPhraseType == 'postalcode') + { + // We need to try the case where the postal code is the primary element (i.e. no way to tell if it is (postalcode, city) OR (city, postalcode) so try both + if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id']) + { + // If we already have a name try putting the postcode first + if (sizeof($aSearch['aName'])) + { + $aNewSearch = $aSearch; + $aNewSearch['aAddress'] = array_merge($aNewSearch['aAddress'], $aNewSearch['aName']); + $aNewSearch['aName'] = array(); + $aNewSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id']; + if ($aSearch['iSearchRank'] < $iMaxRank) $aNewWordsetSearches[] = $aNewSearch; + } + + if (sizeof($aSearch['aName'])) + { + if ((!$bStructuredPhrases || $iPhrase > 0) && $sPhraseType != 'country' && (!isset($aValidTokens[$sToken]) || strlen($sToken) < 4 || strpos($sToken, ' ') !== false)) + { + $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id']; + } + else + { + $aCurrentSearch['aFullNameAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id']; + $aSearch['iSearchRank'] += 1000; // skip; + } + } + else + { + $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id']; + //$aSearch['iNamePhrase'] = $iPhrase; + } + if ($aSearch['iSearchRank'] < $iMaxRank) $aNewWordsetSearches[] = $aSearch; + } + + } elseif (($sPhraseType == '' || $sPhraseType == 'street') && $aSearchTerm['class'] == 'place' && $aSearchTerm['type'] == 'house') { if ($aSearch['sHouseNumber'] === '') @@ -712,6 +733,7 @@ //if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens); } + } else { @@ -935,7 +957,9 @@ if ($sViewboxLargeSQL) $sImportanceSQL .= " * case when ST_Contains($sViewboxLargeSQL, centroid) THEN 1 ELSE 0.5 END"; $aOrder[] = "$sImportanceSQL DESC"; if (sizeof($aSearch['aFullNameAddress'])) + { $aOrder[] = '(select count(*) from (select unnest(ARRAY['.join($aSearch['aFullNameAddress'],",").']) INTERSECT select unnest(nameaddress_vector))s) DESC'; + } if (sizeof($aTerms)) { @@ -1154,6 +1178,22 @@ if ($iQueryLoop > 20) break; } + if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs) && ($iMinAddressRank != 0 || $iMaxAddressRank != 30)) + { + // Need to verify passes rank limits before dropping out of the loop (yuk!) + $sSQL = "select place_id from placex where place_id in (".join(',',$aResultPlaceIDs).") "; + $sSQL .= "and (placex.rank_address between $iMinAddressRank and $iMaxAddressRank "; + if (14 >= $iMinAddressRank && 14 <= $iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'"; + if ($aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$aAddressRankList).")"; + $sSQL .= ") UNION select place_id from location_property_tiger where place_id in (".join(',',$aResultPlaceIDs).") "; + $sSQL .= "and (30 between $iMinAddressRank and $iMaxAddressRank "; + if ($aAddressRankList) $sSQL .= " OR 30 in (".join(',',$aAddressRankList).")"; + $sSQL .= ")"; + if (CONST_Debug) var_dump($sSQL); + $aResultPlaceIDs = $oDB->getCol($sSQL); + } + + //exit; if (isset($aResultPlaceIDs) && sizeof($aResultPlaceIDs)) break; if ($iGroupLoop > 4) break; @@ -1188,6 +1228,7 @@ $sSQL .= "from placex where place_id in ($sPlaceIDs) "; $sSQL .= "and (placex.rank_address between $iMinAddressRank and $iMaxAddressRank "; if (14 >= $iMinAddressRank && 14 <= $iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'"; + if ($aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$aAddressRankList).")"; $sSQL .= ") "; if ($sAllowedTypesSQLList) $sSQL .= "and placex.class in $sAllowedTypesSQLList "; $sSQL .= "and linked_place_id is null "; @@ -1270,6 +1311,7 @@ $sSQL .= "from placex where place_id in ($sPlaceIDs) "; $sSQL .= "and (placex.rank_address between $iMinAddressRank and $iMaxAddressRank "; if (14 >= $iMinAddressRank && 14 <= $iMaxAddressRank) $sSQL .= " OR (extratags->'place') = 'city'"; + if ($aAddressRankList) $sSQL .= " OR placex.rank_address in (".join(',',$aAddressRankList).")"; $sSQL .= ") "; $sSQL .= "group by osm_type,osm_id,class,type,admin_level,rank_search,rank_address,calculated_country_code,importance"; if (!$bDeDupe) $sSQL .= ",place_id";