]> git.openstreetmap.org Git - nominatim.git/blobdiff - lib/Geocode.php
Merge remote-tracking branch 'upstream/master'
[nominatim.git] / lib / Geocode.php
index 016fc101215618274effd14b89ea400411ab70ff..5451c3820dee27bafbccba637151aa8e8598689d 100644 (file)
                                $sCountryCodesSQL = join(',', array_map('addQuotes', $this->aCountryCodes));
                        }
 
-                       // Hack to make it handle "new york, ny" (and variants) correctly
-                       //$sQuery = str_ireplace(array('New York, ny','new york, new york', 'New York ny','new york new york'), 'new york city, ny', $this->sQuery);
                        $sQuery = $this->sQuery;
 
                        // Conflicts between US state abreviations and various words for 'the' in different languages
                        }
 
                        // View Box SQL
-                       $sViewboxCentreSQL;
+                       $sViewboxCentreSQL = false;
                        $bBoundingBoxSearch = false;
                        if ($this->aViewBox)
                        {
                                                                                                if ($aSearch['sHouseNumber'] === '')
                                                                                                {
                                                                                                        $aSearch['sHouseNumber'] = $sToken;
+                                                                                                       // sanity check: if the housenumber is not mainly made
+                                                                                                       // up of numbers, add a penalty
+                                                                                                       if (preg_match_all("/[^0-9]/", $sToken, $aMatches) > 2) $aSearch['iSearchRank']++;
                                                                                                        if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
                                                                                                        /*
                                                                                                        // Fall back to not searching for this item (better than nothing)
                                                                                {
                                                                                        if (isset($aSearchTerm['word_id']) && $aSearchTerm['word_id'])
                                                                                        {
-                                                                                               if ((!$bStructuredPhrases || $iPhrase > 0) && sizeof($aCurrentSearch['aName']) && strlen($sToken) >= 4)
+                                                                                               if ((!$bStructuredPhrases || $iPhrase > 0) && sizeof($aCurrentSearch['aName']) && strpos($sToken, ' ') === false)
                                                                                                {
                                                                                                        $aSearch = $aCurrentSearch;
                                                                                                        $aSearch['iSearchRank'] += 1;
                                                                                                                $aSearch['aAddress'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
                                                                                                                if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
                                                                                                        }
-                                                                                                       elseif (isset($aValidTokens[' '.$sToken])) // revert to the token version?
+                                                                                                       elseif (isset($aValidTokens[' '.$sToken]) && strlen($sToken) >= 4) // revert to the token version?
                                                                                                        {
+                                                                                                               $aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                                                                                               $aSearch['iSearchRank'] += 1;
+                                                                                                               if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
                                                                                                                foreach($aValidTokens[' '.$sToken] as $aSearchTermToken)
                                                                                                                {
                                                                                                                        if (empty($aSearchTermToken['country_code'])
                                                                                                        else
                                                                                                        {
                                                                                                                $aSearch['aAddressNonSearch'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
+                                                                                                               if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
                                                                                                                if ($aSearch['iSearchRank'] < $this->iMaxRank) $aNewWordsetSearches[] = $aSearch;
                                                                                                        }
                                                                                                }
                                                                                                if (!sizeof($aCurrentSearch['aName']) || $aCurrentSearch['iNamePhrase'] == $iPhrase)
                                                                                                {
                                                                                                        $aSearch = $aCurrentSearch;
-                                                                                                       $aSearch['iSearchRank'] += 2;
+                                                                                                       $aSearch['iSearchRank'] += 1;
+                                                                                                       if (!sizeof($aCurrentSearch['aName'])) $aSearch['iSearchRank'] += 1;
                                                                                                        if (preg_match('#^[0-9]+$#', $sToken)) $aSearch['iSearchRank'] += 2;
                                                                                                        if ($aWordFrequencyScores[$aSearchTerm['word_id']] < CONST_Max_Word_Frequency)
                                                                                                                $aSearch['aName'][$aSearchTerm['word_id']] = $aSearchTerm['word_id'];
                                                                        if (CONST_Debug) var_dump($sSQL);
                                                                        $aPlaceIDs = $this->oDB->getCol($sSQL);
                                                                }
+                                                               else
+                                                               {
+                                                                       $aPlaceIDs = array();
+                                                               }
                                                        }
                                                        else
                                                        {
                                                                        // If excluded place IDs are given, it is fair to assume that
                                                                        // there have been results in the small box, so no further
                                                                        // expansion in that case.
-                                                                       if (!sizeof($aPlaceIDs) && !sizeof($this->aExcludePlaceIDs))
+                                                                       // Also don't expand if bounded results were requested.
+                                                                       if (!sizeof($aPlaceIDs) && !sizeof($this->aExcludePlaceIDs) && !$this->bBoundedSearch)
                                                                        {
                                                                                $sSQL = "select place_id from place_classtype_".$aSearch['sClass']."_".$aSearch['sType']." ct";
                                                                                if ($sCountryCodesSQL) $sSQL .= " join placex using (place_id)";
                                                                $sPlaceIDs = join(',',$aPlaceIDs);
 
                                                                // Now they are indexed look for a house attached to a street we found
-                                                               $sHouseNumberRegex = '\\\\m'.str_replace(' ','[-,/ ]',$aSearch['sHouseNumber']).'\\\\M';
-                                                               $sSQL = "select place_id from placex where parent_place_id in (".$sPlaceIDs.") and housenumber ~* E'".$sHouseNumberRegex."'";
+                                                               $sHouseNumberRegex = '\\\\m'.$aSearch['sHouseNumber'].'\\\\M';
+                                                               $sSQL = "select place_id from placex where parent_place_id in (".$sPlaceIDs.") and transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
                                                                if (sizeof($this->aExcludePlaceIDs))
                                                                {
                                                                        $sSQL .= " and place_id not in (".join(',',$this->aExcludePlaceIDs).")";
                                                                                        }
                                                                                        if ($sCountryCodesSQL) $sSQL .= " and lp.calculated_country_code in ($sCountryCodesSQL)";
                                                                                        if ($sOrderBySQL) $sSQL .= "order by ".$sOrderBySQL." asc";
-                                                                                       if ($iOffset) $sSQL .= " offset $iOffset";
+                                                                                       if ($this->iOffset) $sSQL .= " offset $this->iOffset";
                                                                                        $sSQL .= " limit $this->iLimit";
                                                                                        if (CONST_Debug) var_dump($sSQL);
                                                                                        $aClassPlaceIDs = array_merge($aClassPlaceIDs, $this->oDB->getCol($sSQL));
                                                                                        }
                                                                                        if ($sCountryCodesSQL) $sSQL .= " and l.calculated_country_code in ($sCountryCodesSQL)";
                                                                                        if ($sOrderBy) $sSQL .= "order by ".$OrderBysSQL." asc";
-                                                                                       if ($iOffset) $sSQL .= " offset $iOffset";
+                                                                                       if ($this->iOffset) $sSQL .= " offset $this->iOffset";
                                                                                        $sSQL .= " limit $this->iLimit";
                                                                                        if (CONST_Debug) var_dump($sSQL);
                                                                                        $aClassPlaceIDs = array_merge($aClassPlaceIDs, $this->oDB->getCol($sSQL));
                        }
 
                        $aClassType = getClassTypesWithImportance();
-                       $aRecheckWords = preg_split('/\b/u',$sQuery);
+                       $aRecheckWords = preg_split('/\b[\s,\\-]*/u',$sQuery);
                        foreach($aRecheckWords as $i => $sWord)
                        {
                                if (!$sWord) unset($aRecheckWords[$i]);
                                $sAddress = $aResult['langaddress'];
                                foreach($aRecheckWords as $i => $sWord)
                                {
-                                       if (stripos($sAddress, $sWord)!==false) $iCountWords++;
+                                       if (stripos($sAddress, $sWord)!==false)
+                                       {
+                                               $iCountWords++;
+                                               if (preg_match("/(^|,)\s*$sWord\s*(,|$)/", $sAddress)) $iCountWords += 0.1;
+                                       }
                                }
 
                                $aResult['importance'] = $aResult['importance'] + ($iCountWords*0.1); // 0.1 is a completely arbitrary number but something in the range 0.1 to 0.5 would seem right
 
        } // end class
 
-
-/*
-               if (isset($_GET['route']) && $_GET['route'] && isset($_GET['routewidth']) && $_GET['routewidth'])
-               {
-                       $aPoints = explode(',',$_GET['route']);
-                       if (sizeof($aPoints) % 2 != 0)
-                       {
-                               userError("Uneven number of points");
-                               exit;
-                       }
-                       $sViewboxCentreSQL = "ST_SetSRID('LINESTRING(";
-                       $fPrevCoord = false;
-               }
-*/