X-Git-Url: https://git.openstreetmap.org./nominatim.git/blobdiff_plain/11153633ffdf9631d411bd6ea1999cd90a5bd98b..52265a33ba2fa4e6f862688909f43fab1c13817d:/lib/Geocode.php diff --git a/lib/Geocode.php b/lib/Geocode.php index cc846f54..7f00de6e 100644 --- a/lib/Geocode.php +++ b/lib/Geocode.php @@ -518,7 +518,7 @@ foreach($this->aRoutePoints as $aPoint) { if (!$bFirst) $sViewboxCentreSQL .= ","; - $sViewboxCentreSQL .= $aPoint[1].' '.$aPoint[0]; + $sViewboxCentreSQL .= $aPoint[0].' '.$aPoint[1]; $bFirst = false; } $sViewboxCentreSQL .= ")'::geometry,4326)"; @@ -542,35 +542,9 @@ } // Do we have anything that looks like a lat/lon pair? - if (preg_match('/\\b([NS])[ ]+([0-9]+[0-9.]*)[ ]+([0-9.]+)?[, ]+([EW])[ ]+([0-9]+)[ ]+([0-9]+[0-9.]*)?\\b/', $sQuery, $aData)) - { - $fQueryLat = ($aData[1]=='N'?1:-1) * ($aData[2] + $aData[3]/60); - $fQueryLon = ($aData[4]=='E'?1:-1) * ($aData[5] + $aData[6]/60); - if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1) - { - $this->setNearPoint(array($fQueryLat, $fQueryLon)); - $sQuery = trim(str_replace($aData[0], ' ', $sQuery)); - } - } - elseif (preg_match('/\\b([0-9]+)[ ]+([0-9]+[0-9.]*)?[ ]+([NS])[, ]+([0-9]+)[ ]+([0-9]+[0-9.]*)?[ ]+([EW])\\b/', $sQuery, $aData)) - { - $fQueryLat = ($aData[3]=='N'?1:-1) * ($aData[1] + $aData[2]/60); - $fQueryLon = ($aData[6]=='E'?1:-1) * ($aData[4] + $aData[5]/60); - if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1) - { - $this->setNearPoint(array($fQueryLat, $fQueryLon)); - $sQuery = trim(str_replace($aData[0], ' ', $sQuery)); - } - } - elseif (preg_match('/(\\[|^|\\b)(-?[0-9]+[0-9]*\\.[0-9]+)[, ]+(-?[0-9]+[0-9]*\\.[0-9]+)(\\]|$|\\b)/', $sQuery, $aData)) - { - $fQueryLat = $aData[2]; - $fQueryLon = $aData[3]; - if ($fQueryLat <= 90.1 && $fQueryLat >= -90.1 && $fQueryLon <= 180.1 && $fQueryLon >= -180.1) - { - $this->setNearPoint(array($fQueryLat, $fQueryLon)); - $sQuery = trim(str_replace($aData[0], ' ', $sQuery)); - } + if ( $aLooksLike = looksLikeLatLonPair($sQuery) ){ + $this->setNearPoint(array($aLooksLike['lat'], $aLooksLike['lon'])); + $sQuery = $aLooksLike['query']; } $aSearchResults = array(); @@ -733,7 +707,7 @@ { if (substr($aData[1],-2,1) != ' ') { - $aData[0] = substr($aData[0],0,strlen($aData[1]-1)).' '.substr($aData[0],strlen($aData[1]-1)); + $aData[0] = substr($aData[0],0,strlen($aData[1])-1).' '.substr($aData[0],strlen($aData[1])-1); $aData[1] = substr($aData[1],0,-1).' '.substr($aData[1],-1,1); } $aGBPostcodeLocation = gbPostcodeCalculate($aData[0], $aData[1], $aData[2], $this->oDB); @@ -958,7 +932,7 @@ { 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; @@ -967,8 +941,11 @@ $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']) @@ -985,6 +962,7 @@ 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; } } @@ -992,7 +970,8 @@ 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']; @@ -1177,10 +1156,16 @@ { $sSQL = "select place_id from placex where calculated_country_code='".$aSearch['sCountryCode']."' and rank_search = 4"; if ($sCountryCodesSQL) $sSQL .= " and calculated_country_code in ($sCountryCodesSQL)"; + if ($bBoundingBoxSearch) + $sSQL .= " and st_overlaps($this->sViewboxSmallSQL, geometry)"; $sSQL .= " order by st_area(geometry) desc limit 1"; if (CONST_Debug) var_dump($sSQL); $aPlaceIDs = $this->oDB->getCol($sSQL); } + else + { + $aPlaceIDs = array(); + } } else { @@ -1258,7 +1243,21 @@ } } if ($aSearch['sCountryCode']) $aTerms[] = "country_code = '".pg_escape_string($aSearch['sCountryCode'])."'"; - if ($aSearch['sHouseNumber']) $aTerms[] = "address_rank between 16 and 27"; + if ($aSearch['sHouseNumber']) + { + $aTerms[] = "address_rank between 16 and 27"; + } + else + { + if ($this->iMinAddressRank > 0) + { + $aTerms[] = "address_rank >= ".$this->iMinAddressRank; + } + if ($this->iMaxAddressRank < 30) + { + $aTerms[] = "address_rank <= ".$this->iMaxAddressRank; + } + } if ($aSearch['fLon'] && $aSearch['fLat']) { $aTerms[] = "ST_DWithin(centroid, ST_SetSRID(ST_Point(".$aSearch['fLon'].",".$aSearch['fLat']."),4326), ".$aSearch['fRadius'].")"; @@ -1339,8 +1338,8 @@ $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).")"; @@ -1463,7 +1462,7 @@ } 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)); @@ -1485,7 +1484,7 @@ } 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)); @@ -1566,7 +1565,7 @@ } $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]); @@ -1727,7 +1726,11 @@ $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