move initial search setup to new class type

This commit is contained in:
Sarah Hoffmann
2017-10-06 00:14:48 +02:00
parent 77d4453334
commit 0067555c38
2 changed files with 107 additions and 70 deletions

View File

@@ -1023,76 +1023,59 @@ class Geocode
$aSearchResults = array(); $aSearchResults = array();
if ($sQuery || $this->aStructuredQuery) { if ($sQuery || $this->aStructuredQuery) {
// Start with a blank search // Start with a single blank search
$aSearches = array( $aSearches = array(new SearchDescription());
array(
'iSearchRank' => 0,
'iNamePhrase' => -1,
'sCountryCode' => false,
'aName' => array(),
'aAddress' => array(),
'aFullNameAddress' => array(),
'aNameNonSearch' => array(),
'aAddressNonSearch' => array(),
'sOperator' => '',
'aFeatureName' => array(),
'sClass' => '',
'sType' => '',
'sHouseNumber' => '',
'sPostcode' => '',
'oNear' => $oNearPoint
)
);
// Any 'special' terms in the search? if ($oNearPoint) {
$bSpecialTerms = false; $aSearches[0]->setNear($oNearPoint);
preg_match_all('/\\[([\\w_]*)=([\\w_]*)\\]/', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER);
foreach ($aSpecialTermsRaw as $aSpecialTerm) {
$sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
if (!$bSpecialTerms) {
$aNewSearches = array();
foreach ($aSearches as $aSearch) {
$aNewSearch = $aSearch;
$aNewSearch['sClass'] = $aSpecialTerm[1];
$aNewSearch['sType'] = $aSpecialTerm[2];
$aNewSearches[] = $aNewSearch;
}
$aSearches = $aNewSearches;
$bSpecialTerms = true;
}
} }
preg_match_all('/\\[([\\w ]*)\\]/u', $sQuery, $aSpecialTermsRaw, PREG_SET_ORDER); if ($sQuery) {
if (isset($this->aStructuredQuery['amenity']) && $this->aStructuredQuery['amenity']) { $sQuery = $aSearches[0]->extractKeyValuePairs($sQuery);
$aSpecialTermsRaw[] = array('['.$this->aStructuredQuery['amenity'].']', $this->aStructuredQuery['amenity']); }
$sSpecialTerm = '';
if ($sQuery) {
preg_match_all(
'/\\[([\\w ]*)\\]/u',
$sQuery,
$aSpecialTermsRaw,
PREG_SET_ORDER
);
foreach ($aSpecialTermsRaw as $aSpecialTerm) {
$sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery);
if (!$sSpecialTerm) {
$sSpecialTerm = $aSpecialTerm[1];
}
}
}
if (!$sSpecialTerm && $this->aStructuredQuery
&& isset($this->aStructuredQuery['amenity'])) {
$sSpecialTerm = $this->aStructuredQuery['amenity'];
unset($this->aStructuredQuery['amenity']); unset($this->aStructuredQuery['amenity']);
} }
foreach ($aSpecialTermsRaw as $aSpecialTerm) { if ($sSpecialTerm && !$aSearches[0]->hasOperator()) {
$sQuery = str_replace($aSpecialTerm[0], ' ', $sQuery); $sSpecialTerm = pg_escape_string($sSpecialTerm);
if ($bSpecialTerms) { $sToken = chksql(
continue; $this->oDB->getOne("SELECT make_standard_name('$sSpecialTerm')"),
} "Cannot decode query. Wrong encoding?"
);
$sToken = chksql($this->oDB->getOne("SELECT make_standard_name('".pg_escape_string($aSpecialTerm[1])."') AS string")); $sSQL = 'SELECT class, type FROM word ';
$sSQL = 'SELECT * ';
$sSQL .= 'FROM ( ';
$sSQL .= ' SELECT word_id, word_token, word, class, type, country_code, operator';
$sSQL .= ' FROM word ';
$sSQL .= ' WHERE word_token in (\' '.$sToken.'\')'; $sSQL .= ' WHERE word_token in (\' '.$sToken.'\')';
$sSQL .= ') AS x '; $sSQL .= ' AND class is not null AND class not in (\'place\')';
$sSQL .= ' WHERE (class is not null AND class not in (\'place\'))';
if (CONST_Debug) var_Dump($sSQL); if (CONST_Debug) var_Dump($sSQL);
$aSearchWords = chksql($this->oDB->getAll($sSQL)); $aSearchWords = chksql($this->oDB->getAll($sSQL));
$aNewSearches = array(); $aNewSearches = array();
foreach ($aSearches as $aSearch) { foreach ($aSearches as $oSearch) {
foreach ($aSearchWords as $aSearchTerm) { foreach ($aSearchWords as $aSearchTerm) {
$aNewSearch = $aSearch; $oNewSearch = clone $oSearch;
$aNewSearch['sClass'] = $aSearchTerm['class']; $oNewSearch->setPoiSearch(
$aNewSearch['sType'] = $aSearchTerm['type']; Operator::TYPE,
$aNewSearches[] = $aNewSearch; $aSearchTerm['class'],
$bSpecialTerms = true; $aSearchTerm['type'],
);
$aNewSearches[] = $oNewSearch;
} }
} }
$aSearches = $aNewSearches; $aSearches = $aNewSearches;
@@ -1212,10 +1195,10 @@ class Geocode
foreach ($aGroupedSearches as $aSearches) { foreach ($aGroupedSearches as $aSearches) {
foreach ($aSearches as $aSearch) { foreach ($aSearches as $aSearch) {
if ($aSearch['iSearchRank'] < $this->iMaxRank) { if (!isset($aReverseGroupedSearches[$aSearch->getRank()])) {
if (!isset($aReverseGroupedSearches[$aSearch['iSearchRank']])) $aReverseGroupedSearches[$aSearch['iSearchRank']] = array(); $aReverseGroupedSearches[$aSearch->getRank()] = array();
$aReverseGroupedSearches[$aSearch['iSearchRank']][] = $aSearch;
} }
$aReverseGroupedSearches[$aSearch->getRank()][] = $aSearch;
} }
} }
@@ -1226,9 +1209,9 @@ class Geocode
// Re-group the searches by their score, junk anything over 20 as just not worth trying // Re-group the searches by their score, junk anything over 20 as just not worth trying
$aGroupedSearches = array(); $aGroupedSearches = array();
foreach ($aSearches as $aSearch) { foreach ($aSearches as $aSearch) {
if ($aSearch['iSearchRank'] < $this->iMaxRank) { if ($aSearch->getRank() < $this->iMaxRank) {
if (!isset($aGroupedSearches[$aSearch['iSearchRank']])) $aGroupedSearches[$aSearch['iSearchRank']] = array(); if (!isset($aGroupedSearches[$aSearch->getRank()])) $aGroupedSearches[$aSearch->getRank()] = array();
$aGroupedSearches[$aSearch['iSearchRank']][] = $aSearch; $aGroupedSearches[$aSearch->getRank()][] = $aSearch;
} }
} }
ksort($aGroupedSearches); ksort($aGroupedSearches);

View File

@@ -8,15 +8,17 @@ namespace Nominatim;
abstract final class Operator abstract final class Operator
{ {
/// No operator selected. /// No operator selected.
const NONE = -1; const NONE = 0;
/// Search for POI of the given type.
const TYPE = 1;
/// Search for POIs near the given place. /// Search for POIs near the given place.
const NEAR = 0; const NEAR = 2;
/// Search for POIS in the given place. /// Search for POIS in the given place.
const IN = 1; const IN = 3;
/// Search for POIS named as given. /// Search for POIS named as given.
const NAME = 3; const NAME = 4;
/// Search for postcodes. /// Search for postcodes.
const POSTCODE = 4; const POSTCODE = 5;
} }
/** /**
@@ -55,4 +57,56 @@ class SearchDescription
/// Index of phrase currently processed /// Index of phrase currently processed
private $iNamePhrase = -1; private $iNamePhrase = -1;
public getRank()
{
return $this->iSearchRank;
}
/**
* Set the geographic search radius.
*/
public setNear(&$oNearPoint)
{
$this->oNearPoint = $oNearPoint;
}
public setPoiSearch($iOperator, $sClass, $sType)
{
$this->iOperator = $iOperator;
$this->sClass = $sClass;
$this->sType = $sType;
}
public hasOperator()
{
return $this->iOperator != Operator::NONE;
}
/**
* Extract special terms from the query, amend the search
* and return the shortended query.
*
* Only the first special term found will be used but all will
* be removed from the query.
*/
public extractKeyValuePairs(&$oDB, $sQuery)
{
// Search for terms of kind [<key>=<value>].
preg_match_all(
'/\\[([\\w_]*)=([\\w_]*)\\]/',
$sQuery,
$aSpecialTermsRaw,
PREG_SET_ORDER
);
foreach ($aSpecialTermsRaw as $aTerm) {
$sQuery = str_replace($aTerm[0], ' ', $sQuery);
if (!$this->hasOperator()) {
$this->setPoiSearch(Operator::TYPE, $aTerm[1], $aTerm[2]);
}
}
return $sQuery;
}
}; };