namespace Nominatim;
require_once(CONST_BasePath.'/lib/SpecialSearchOperator.php');
+require_once(CONST_BasePath.'/lib/SearchContext.php');
/**
* Description of a single interpretation of a search query.
private $sHouseNumber = '';
/// Postcode for the object.
private $sPostcode = '';
- /// Geographic search area.
- private $oNearPoint = false;
+ /// Global search constraints.
+ private $oContext;
// Temporary values used while creating the search description.
- /// Index of phrase currently processed
+ /// Index of phrase currently processed.
private $iNamePhrase = -1;
+ public function __construct($oContext)
+ {
+ $this->oContext = $oContext;
+ }
+
public function getRank()
{
return $this->iSearchRank;
return $this->sPostcode;
}
- public function setNear(&$oNearPoint)
- {
- $this->oNearPoint = $oNearPoint;
- }
-
public function setPoiSearch($iOperator, $sClass, $sType)
{
$this->iOperator = $iOperator;
public function isCountrySearch()
{
return $this->sCountryCode && sizeof($this->aName) == 0
- && !$this->iOperator && !$this->oNearPoint;
- }
-
- public function isNearSearch()
- {
- return (bool) $this->oNearPoint;
+ && !$this->iOperator && !$this->oContext->hasNearPoint();
}
public function isPoiSearch()
/////////// Query functions
- public function queryCountry(&$oDB, $sViewboxSQL)
+ public function queryCountry(&$oDB)
{
$sSQL = 'SELECT place_id FROM placex ';
$sSQL .= "WHERE country_code='".$this->sCountryCode."'";
$sSQL .= ' AND rank_search = 4';
- if ($sViewboxSQL) {
- $sSQL .= " AND ST_Intersects($sViewboxSQL, geometry)";
+ if ($this->oContext->bViewboxBounded) {
+ $sSQL .= ' AND ST_Intersects('.$this->oContext->sqlViewboxSmall.', geometry)';
}
$sSQL .= " ORDER BY st_area(geometry) DESC LIMIT 1";
return chksql($oDB->getCol($sSQL));
}
- public function queryNearbyPoi(&$oDB, $sCountryList, $sViewboxSQL, $sViewboxCentreSQL, $sExcludeSQL, $iLimit)
+ public function queryNearbyPoi(&$oDB, $sCountryList, $iLimit)
{
if (!$this->sClass) {
return array();
if ($sCountryList) {
$sSQL .= ' JOIN placex USING (place_id)';
}
- if ($this->oNearPoint) {
- $sSQL .= ' WHERE '.$this->oNearPoint->withinSQL('ct.centroid');
- } else {
- $sSQL .= " WHERE ST_Contains($sViewboxSQL, ct.centroid)";
+ if ($this->oContext->hasNearPoint()) {
+ $sSQL .= ' WHERE '.$this->oContext->withinSQL('ct.centroid');
+ } else if ($this->oContext->bViewboxBounded) {
+ $sSQL .= ' WHERE ST_Contains('.$this->oContext->sqlViewboxSmall.', ct.centroid)';
}
if ($sCountryList) {
$sSQL .= " AND country_code in ($sCountryList)";
}
- if ($sExcludeSQL) {
- $sSQL .= ' AND place_id not in ('.$sExcludeSQL.')';
- }
- if ($sViewboxCentreSQL) {
- $sSQL .= " ORDER BY ST_Distance($sViewboxCentreSQL, ct.centroid) ASC";
- } elseif ($this->oNearPoint) {
- $sSQL .= ' ORDER BY '.$this->oNearPoint->distanceSQL('ct.centroid').' ASC';
+ $sSQL .= $this->oContext->excludeSQL(' AND place_id');
+ if ($this->oContext->sqlViewboxCentre) {
+ $sSQL .= ' ORDER BY ST_Distance(';
+ $sSQL .= $this->oContext->sqlViewboxCentre.', ct.centroid) ASC';
+ } elseif ($this->oContext->hasNearPoint()) {
+ $sSQL .= ' ORDER BY '.$this->oContext->distanceSQL('ct.centroid').' ASC';
}
$sSQL .= " limit $iLimit";
if (CONST_Debug) var_dump($sSQL);
return chksql($oDB->getCol($sSQL));
}
- if ($this->oNearPoint) {
+ if ($this->oContext->hasNearPoint()) {
$sSQL = 'SELECT place_id FROM placex WHERE ';
$sSQL .= 'class=\''.$this->sClass."' and type='".$this->sType."'";
- $sSQL .= ' AND '.$this->oNearPoint->withinSQL('geometry');
+ $sSQL .= ' AND '.$this->oContext->withinSQL('geometry');
$sSQL .= ' AND linked_place_id is null';
if ($sCountryList) {
$sSQL .= " AND country_code in ($sCountryList)";
}
- $sSQL .= ' ORDER BY '.$this->oNearPoint->distanceSQL('centroid')." ASC";
+ $sSQL .= ' ORDER BY '.$this->oContext->distanceSQL('centroid')." ASC";
$sSQL .= " LIMIT $iLimit";
if (CONST_Debug) var_dump($sSQL);
return chksql($oDB->getCol($sSQL));
if ($sCountryTerm) {
$sSQL .= ' AND '.$sCountryTerm;
}
+ $sSQL .= $this->oContext->excludeSQL(' AND p.place_id');
$sSQL .= " LIMIT $iLimit";
if (CONST_Debug) var_dump($sSQL);
return chksql($oDB->getCol($sSQL));
}
- public function queryNamedPlace(&$oDB, $aWordFrequencyScores, $sCountryList, $iMinAddressRank, $iMaxAddressRank, $sExcludeSQL, $sViewboxSmall, $sViewboxLarge, $iLimit)
+ public function queryNamedPlace(&$oDB, $aWordFrequencyScores, $sCountryList, $iMinAddressRank, $iMaxAddressRank, $iLimit)
{
$aTerms = array();
$aOrder = array();
}
}
- if ($this->oNearPoint) {
- $aTerms[] = $this->oNearPoint->withinSQL('centroid');
- $aOrder[] = $this->oNearPoint->distanceSQL('centroid');
+ if ($this->oContext->hasNearPoint()) {
+ $aTerms[] = $this->oContext->withinSQL('centroid');
+ $aOrder[] = $this->oContext->distanceSQL('centroid');
} elseif ($this->sPostcode) {
if (!sizeof($this->aAddress)) {
$aTerms[] = "EXISTS(SELECT place_id FROM location_postcode p WHERE p.postcode = '".$this->sPostcode."' AND ST_DWithin(search_name.centroid, p.geometry, 0.1))";
}
}
+ $sExcludeSQL = $this->oContext->excludeSQL('place_id');
if ($sExcludeSQL) {
- $aTerms[] = 'place_id not in ('.$sExcludeSQL.')';
+ $aTerms[] = $sExcludeSQL;
}
- if ($sViewboxSmall) {
- $aTerms[] = 'centroid && '.$sViewboxSmall;
+ if ($this->oContext->bViewboxBounded) {
+ $aTerms[] = 'centroid && '.$this->oContext->sqlViewboxSmall;
}
- if ($this->oNearPoint) {
- $aOrder[] = $this->oNearPoint->distanceSQL('centroid');
+ if ($this->oContext->hasNearPoint()) {
+ $aOrder[] = $this->oContext->distanceSQL('centroid');
}
if ($this->sHouseNumber) {
} else {
$sImportanceSQL = '(CASE WHEN importance = 0 OR importance IS NULL THEN 0.75-(search_rank::float/40) ELSE importance END)';
}
- if ($sViewboxSmall) {
- $sImportanceSQL .= " * CASE WHEN ST_Contains($sViewboxSmall, centroid) THEN 1 ELSE 0.5 END";
- }
- if ($sViewboxLarge) {
- $sImportanceSQL .= " * CASE WHEN ST_Contains($sViewboxLarge, centroid) THEN 1 ELSE 0.5 END";
- }
+ $sImportanceSQL .= $this->oContext->viewboxImportanceSQL('centroid');
$aOrder[] = "$sImportanceSQL DESC";
if (sizeof($this->aFullNameAddress)) {
}
- public function queryHouseNumber(&$oDB, $aRoadPlaceIDs, $sExcludeSQL, $iLimit)
+ public function queryHouseNumber(&$oDB, $aRoadPlaceIDs, $iLimit)
{
$sPlaceIDs = join(',', $aRoadPlaceIDs);
$sSQL = 'SELECT place_id FROM placex ';
$sSQL .= 'WHERE parent_place_id in ('.$sPlaceIDs.')';
$sSQL .= " AND transliteration(housenumber) ~* E'".$sHouseNumberRegex."'";
- if ($sExcludeSQL) {
- $sSQL .= ' AND place_id not in ('.$sExcludeSQL.')';
- }
+ $sSQL .= $this->oContext->excludeSQL(' AND place_id');
$sSQL .= " LIMIT $iLimit";
if (CONST_Debug) var_dump($sSQL);
$sSQL .= " or interpolationtype='all') and ";
$sSQL .= $iHousenumber.">=startnumber and ";
$sSQL .= $iHousenumber."<=endnumber";
-
- if ($sExcludeSQL) {
- $sSQL .= ' AND place_id not in ('.$sExcludeSQL.')';
- }
+ $sSQL .= $this->oContext->excludeSQL(' AND place_id');
$sSQL .= " limit $iLimit";
if (CONST_Debug) var_dump($sSQL);
$sSQL = 'SELECT place_id FROM location_property_aux';
$sSQL .= ' WHERE parent_place_id in ('.$sPlaceIDs.')';
$sSQL .= " AND housenumber = '".$this->sHouseNumber."'";
- if ($sExcludeSQL) {
- $sSQL .= " AND place_id not in ($sExcludeSQL)";
- }
+ $sSQL .= $this->oContext->excludeSQL(' AND place_id');
$sSQL .= " limit $iLimit";
if (CONST_Debug) var_dump($sSQL);
$sSQL .= " or interpolationtype='all') and ";
$sSQL .= $iHousenumber.">=startnumber and ";
$sSQL .= $iHousenumber."<=endnumber";
-
- if ($sExcludeSQL) {
- $sSQL .= ' AND place_id not in ('.$sExcludeSQL.')';
- }
+ $sSQL .= $this->oContext->excludeSQL(' AND place_id');
$sSQL .= " limit $iLimit";
if (CONST_Debug) var_dump($sSQL);
}
- public function queryPoiByOperator(&$oDB, $aParentIDs, $sExcludeSQL, $iLimit)
+ public function queryPoiByOperator(&$oDB, $aParentIDs, $iLimit)
{
$sPlaceIDs = join(',', $aParentIDs);
$aClassPlaceIDs = array();
$sSQL .= " AND class='".$this->sClass."' ";
$sSQL .= " AND type='".$this->sType."'";
$sSQL .= " AND linked_place_id is null";
+ $sSQL .= $this->oContext->excludeSQL(' AND place_id');
$sSQL .= " ORDER BY rank_search ASC ";
$sSQL .= " LIMIT $iLimit";
$fRange = 0.05;
$sOrderBySQL = '';
- if ($this->oNearPoint) {
- $sOrderBySQL = $this->oNearPoint->distanceSQL('l.centroid');
+ if ($this->oContext->hasNearPoint()) {
+ $sOrderBySQL = $this->oContext->distanceSQL('l.centroid');
} elseif ($sPlaceIDs) {
$sOrderBySQL = "ST_Distance(l.centroid, f.geometry)";
} elseif ($sPlaceGeom) {
$sSQL .= " WHERE ST_Contains('$sPlaceGeom', l.centroid)";
}
- if ($sExcludeSQL) {
- $sSQL .= ' AND l.place_id not in ('.$sExcludeSQL.')';
- }
+ $sSQL .= $this->oContext->excludeSQL(' AND l.place_id');
$sSQL .= 'limit 300) i ';
if ($sOrderBySQL) {
$sSQL .= 'order by order_term asc';
$aClassPlaceIDs = array_merge($aClassPlaceIDs, chksql($oDB->getCol($sSQL)));
} else {
- if ($this->oNearPoint) {
- $fRange = $this->oNearPoint->radius();
+ if ($this->oContext->hasNearPoint()) {
+ $fRange = $this->oContext->nearRadius();
}
$sOrderBySQL = '';
- if ($this->oNearPoint) {
- $sOrderBySQL = $this->oNearPoint->distanceSQL('l.geometry');
+ if ($this->oContext->hasNearPoint()) {
+ $sOrderBySQL = $this->oContext->distanceSQL('l.geometry');
} else {
$sOrderBySQL = "ST_Distance(l.geometry, f.geometry)";
}
$sSQL .= " AND ST_DWithin(l.geometry, f.centroid, $fRange)";
$sSQL .= " AND l.class='".$this->sClass."'";
$sSQL .= " AND l.type='".$this->sType."'";
- if ($sExcludeSQL) {
- $sSQL .= " AND l.place_id not in (".$sExcludeSQL.")";
- }
+ $sSQL .= $this->oContext->excludeSQL(' AND l.place_id');
if ($sOrderBySQL) {
$sSQL .= "ORDER BY orderterm ASC";
}
echo "<td>".$this->sPostcode."</td>";
echo "<td>".$this->sHouseNumber."</td>";
- if ($this->oNearPoint) {
- echo "<td>".$this->oNearPoint->lat()."</td>";
- echo "<td>".$this->oNearPoint->lon()."</td>";
- echo "<td>".$this->oNearPoint->radius()."</td>";
- } else {
- echo "<td></td><td></td><td></td>";
- }
-
echo "</tr>";
}
}