X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/5413abfb1e9f24fcd44ba22dedac7dde589d3f71..00a3e843e3fb4a6fc735a019cdf7a3e38558cad6:/website/search.php diff --git a/website/search.php b/website/search.php index 3eb50aa2..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 @@ -77,6 +78,7 @@ if (isset($aLangPrefOrder['name:de'])) $bReverseInPlan = true; if (isset($aLangPrefOrder['name:ru'])) $bReverseInPlan = true; if (isset($aLangPrefOrder['name:ja'])) $bReverseInPlan = true; + if (isset($aLangPrefOrder['name:pl'])) $bReverseInPlan = true; $sLanguagePrefArraySQL = "ARRAY[".join(',',array_map("getDBQuoted",$aLangPrefOrder))."]"; @@ -140,19 +142,19 @@ // 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) { @@ -356,7 +358,6 @@ $bStructuredPhrases = false; } - // Convert each phrase to standard form // Create a list of standard words // Get all 'sets' of words @@ -466,7 +467,6 @@ /* Calculate all searches using aValidTokens i.e. - 'Wodsworth Road, Sheffield' => Phrase Wordset @@ -530,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'] === '') @@ -697,6 +733,7 @@ //if (CONST_Debug) _debugDumpGroupedSearches($aGroupedSearches, $aValidTokens); } + } else { @@ -920,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)) { @@ -974,6 +1013,7 @@ $aPlaceIDs = $oDB->getCol($sSQL); // If not try the aux fallback table + /* if (!sizeof($aPlaceIDs)) { $sSQL = "select place_id from location_property_aux where parent_place_id in (".$sPlaceIDs.") and housenumber = '".pg_escape_string($aSearch['sHouseNumber'])."'"; @@ -985,6 +1025,7 @@ if (CONST_Debug) var_dump($sSQL); $aPlaceIDs = $oDB->getCol($sSQL); } + */ if (!sizeof($aPlaceIDs)) { @@ -1137,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; @@ -1149,6 +1206,10 @@ //var_Dump($aResultPlaceIDs);exit; // Get the details for display (is this a redundant extra step?) $sPlaceIDs = join(',',$aResultPlaceIDs); + $sImportanceSQL = ''; + if ($sViewboxSmallSQL) $sImportanceSQL .= " case when ST_Contains($sViewboxSmallSQL, ST_Collect(centroid)) THEN 1 ELSE 0.75 END * "; + if ($sViewboxLargeSQL) $sImportanceSQL .= " case when ST_Contains($sViewboxLargeSQL, ST_Collect(centroid)) THEN 1 ELSE 0.75 END * "; + $sOrderSQL = 'CASE '; foreach(array_keys($aResultPlaceIDs) as $iOrder => $iPlaceID) { @@ -1161,12 +1222,13 @@ $sSQL .= "get_name_by_language(name, ARRAY['ref']) as ref,"; $sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, "; //$sSQL .= $sOrderSQL." as porder, "; - $sSQL .= "coalesce(importance,0.75-(rank_search::float/40)) as importance, "; + $sSQL .= $sImportanceSQL."coalesce(importance,0.75-(rank_search::float/40)) as importance, "; $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(placex.place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, "; $sSQL .= "(extratags->'place') as extra_place "; $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 "; @@ -1183,13 +1245,14 @@ $sSQL .= "null as ref,"; $sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, "; //$sSQL .= $sOrderSQL." as porder, "; - $sSQL .= "-0.15 as importance, "; + $sSQL .= $sImportanceSQL."0.015 as importance, "; $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_tiger.place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, "; $sSQL .= "null as extra_place "; $sSQL .= "from location_property_tiger where place_id in ($sPlaceIDs) "; $sSQL .= "and 30 between $iMinAddressRank and $iMaxAddressRank "; $sSQL .= "group by place_id"; if (!$bDeDupe) $sSQL .= ",place_id"; + /* $sSQL .= " union "; $sSQL .= "select 'L' as osm_type,place_id as osm_id,'place' as class,'house' as type,null as admin_level,30 as rank_search,30 as rank_address,min(place_id) as place_id,'us' as country_code,"; $sSQL .= "get_address_by_language(place_id, $sLanguagePrefArraySQL) as langaddress,"; @@ -1197,7 +1260,7 @@ $sSQL .= "null as ref,"; $sSQL .= "avg(ST_X(centroid)) as lon,avg(ST_Y(centroid)) as lat, "; //$sSQL .= $sOrderSQL." as porder, "; - $sSQL .= "-0.10 as importance, "; + $sSQL .= $sImportanceSQL."0.01 as importance, "; $sSQL .= "(select max(p.importance*(p.rank_address+2)) from place_addressline s, placex p where s.place_id = min(location_property_aux.place_id) and p.place_id = s.address_place_id and s.isaddress and p.importance is not null) as addressimportance, "; $sSQL .= "null as extra_place "; $sSQL .= "from location_property_aux where place_id in ($sPlaceIDs) "; @@ -1207,6 +1270,7 @@ $sSQL .= ",get_address_by_language(place_id, $sLanguagePrefArraySQL) "; $sSQL .= "order by importance desc"; //$sSQL .= "order by rank_search,rank_address,porder asc"; + */ if (CONST_Debug) { echo "