5 require_once(CONST_BasePath.'/lib/lib.php');
9 * Collects search constraints that are independent of the
10 * actual interpretation of the search query.
12 * The search context is shared between all SearchDescriptions. This
13 * object mainly serves as context provider for the database queries.
14 * Therefore most data is directly cached as SQL statements.
18 private $fNearRadius = false;
19 public $bViewboxBounded = false;
22 public $sqlViewboxSmall = '';
23 public $sqlViewboxLarge = '';
24 public $sqlViewboxCentre = '';
25 public $sqlCountryList = '';
26 private $sqlExcludeList = '';
28 public function hasNearPoint()
30 return $this->fNearRadius !== false;
33 public function nearRadius()
35 return $this->fNearRadius;
38 public function setNearPoint($fLat, $fLon, $fRadius = 0.1)
40 $this->fNearRadius = $fRadius;
41 $this->sqlNear = 'ST_SetSRID(ST_Point('.$fLon.','.$fLat.'),4326)';
44 public function isBoundedSearch()
46 return $this->hasNearPoint() || ($this->sqlViewboxSmall && $this->bViewboxBounded);
50 public function setViewboxFromBox(&$aViewBox, $bBounded)
52 $this->bViewboxBounded = $bBounded;
53 $this->sqlViewboxCentre = '';
55 $this->sqlViewboxSmall = sprintf(
56 'ST_SetSRID(ST_MakeBox2D(ST_Point(%F,%F),ST_Point(%F,%F)),4326)',
63 $fHeight = $aViewBox[0] - $aViewBox[2];
64 $fWidth = $aViewBox[1] - $aViewBox[3];
66 $this->sqlViewboxLarge = sprintf(
67 'ST_SetSRID(ST_MakeBox2D(ST_Point(%F,%F),ST_Point(%F,%F)),4326)',
68 max($aViewBox[0], $aViewBox[2]) + $fHeight,
69 max($aViewBox[1], $aViewBox[3]) + $fWidth,
70 min($aViewBox[0], $aViewBox[2]) - $fHeight,
71 min($aViewBox[1], $aViewBox[3]) - $fWidth
75 public function setViewboxFromRoute(&$oDB, $aRoutePoints, $fRouteWidth, $bBounded)
77 $this->bViewboxBounded = $bBounded;
78 $this->sqlViewboxCentre = "ST_SetSRID('LINESTRING(";
80 foreach ($aRoutePoints as $aPoint) {
81 $fPoint = (float)$aPoint;
82 $this->sqlViewboxCentre .= $sSep.$fPoint;
83 $sSep = ($sSep == ' ') ? ',' : ' ';
85 $this->sqlViewboxCentre .= ")'::geometry,4326)";
87 $sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/69).')';
88 $sGeom = chksql($oDB->getOne("select ".$sSQL), "Could not get small viewbox");
89 $this->sqlViewboxSmall = "'".$sGeom."'::geometry";
91 $sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/30).')';
92 $sGeom = chksql($oDB->getOne("select ".$sSQL), "Could not get large viewbox");
93 $this->sqlViewboxLarge = "'".$sGeom."'::geometry";
96 public function setExcludeList($aExcluded)
98 $this->sqlExcludeList = ' not in ('.join(',', $aExcluded).')';
101 public function setCountryList($aCountries)
103 $this->sqlCountryList = '('.join(',', array_map('addQuotes', $aCountries)).')';
107 * Extract a coordinate point from a query string.
109 * @param string $sQuery Query to scan.
111 * @return The remaining query string.
113 public function setNearPointFromQuery($sQuery)
115 $aResult = parseLatLon($sQuery);
117 if ($aResult !== false
118 && $aResult[1] <= 90.1
119 && $aResult[1] >= -90.1
120 && $aResult[2] <= 180.1
121 && $aResult[2] >= -180.1
123 $this->setNearPoint($aResult[1], $aResult[2]);
124 $sQuery = trim(str_replace($aResult[0], ' ', $sQuery));
130 public function distanceSQL($sObj)
132 return 'ST_Distance('.$this->sqlNear.", $sObj)";
135 public function withinSQL($sObj)
137 return sprintf('ST_DWithin(%s, %s, %F)', $sObj, $this->sqlNear, $this->fNearRadius);
140 public function viewboxImportanceSQL($sObj)
144 if ($this->sqlViewboxSmall) {
145 $sSQL = " * CASE WHEN ST_Contains($this->sqlViewboxSmall, $sObj) THEN 1 ELSE 0.5 END";
147 if ($this->sqlViewboxLarge) {
148 $sSQL = " * CASE WHEN ST_Contains($this->sqlViewboxLarge, $sObj) THEN 1 ELSE 0.5 END";
154 public function excludeSQL($sVariable)
156 if ($this->sqlExcludeList) {
157 return $sVariable.$this->sqlExcludeList;