5 require_once(CONST_BasePath.'/lib/lib.php');
9 * Collection of 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 /// Search radius around a given Near reference point.
19 private $fNearRadius = false;
20 /// True if search must be restricted to viewbox only.
21 public $bViewboxBounded = false;
23 /// Reference point for search (as SQL).
25 /// Viewbox selected for search (as SQL).
26 public $sqlViewboxSmall = '';
27 /// Viewbox with a larger buffer around (as SQL).
28 public $sqlViewboxLarge = '';
29 /// Reference along a route (as SQL).
30 public $sqlViewboxCentre = '';
31 /// List of countries to restrict search to (as SQL).
32 public $sqlCountryList = '';
33 /// List of place IDs to exclude (as SQL).
34 private $sqlExcludeList = '';
37 public function hasNearPoint()
39 return $this->fNearRadius !== false;
42 public function nearRadius()
44 return $this->fNearRadius;
47 public function setNearPoint($fLat, $fLon, $fRadius = 0.1)
49 $this->fNearRadius = $fRadius;
50 $this->sqlNear = 'ST_SetSRID(ST_Point('.$fLon.','.$fLat.'),4326)';
53 public function isBoundedSearch()
55 return $this->hasNearPoint() || ($this->sqlViewboxSmall && $this->bViewboxBounded);
58 public function setViewboxFromBox(&$aViewBox, $bBounded)
60 $this->bViewboxBounded = $bBounded;
61 $this->sqlViewboxCentre = '';
63 $this->sqlViewboxSmall = sprintf(
64 'ST_SetSRID(ST_MakeBox2D(ST_Point(%F,%F),ST_Point(%F,%F)),4326)',
71 $fHeight = $aViewBox[0] - $aViewBox[2];
72 $fWidth = $aViewBox[1] - $aViewBox[3];
74 $this->sqlViewboxLarge = sprintf(
75 'ST_SetSRID(ST_MakeBox2D(ST_Point(%F,%F),ST_Point(%F,%F)),4326)',
76 max($aViewBox[0], $aViewBox[2]) + $fHeight,
77 max($aViewBox[1], $aViewBox[3]) + $fWidth,
78 min($aViewBox[0], $aViewBox[2]) - $fHeight,
79 min($aViewBox[1], $aViewBox[3]) - $fWidth
83 public function setViewboxFromRoute(&$oDB, $aRoutePoints, $fRouteWidth, $bBounded)
85 $this->bViewboxBounded = $bBounded;
86 $this->sqlViewboxCentre = "ST_SetSRID('LINESTRING(";
88 foreach ($aRoutePoints as $aPoint) {
89 $fPoint = (float)$aPoint;
90 $this->sqlViewboxCentre .= $sSep.$fPoint;
91 $sSep = ($sSep == ' ') ? ',' : ' ';
93 $this->sqlViewboxCentre .= ")'::geometry,4326)";
95 $sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/69).')';
96 $sGeom = chksql($oDB->getOne("select ".$sSQL), "Could not get small viewbox");
97 $this->sqlViewboxSmall = "'".$sGeom."'::geometry";
99 $sSQL = 'ST_BUFFER('.$this->sqlViewboxCentre.','.($fRouteWidth/30).')';
100 $sGeom = chksql($oDB->getOne("select ".$sSQL), "Could not get large viewbox");
101 $this->sqlViewboxLarge = "'".$sGeom."'::geometry";
104 public function setExcludeList($aExcluded)
106 $this->sqlExcludeList = ' not in ('.join(',', $aExcluded).')';
109 public function setCountryList($aCountries)
111 $this->sqlCountryList = '('.join(',', array_map('addQuotes', $aCountries)).')';
115 * Extract a coordinate point from a query string.
117 * @param string $sQuery Query to scan.
119 * @return The remaining query string.
121 public function setNearPointFromQuery($sQuery)
123 $aResult = parseLatLon($sQuery);
125 if ($aResult !== false
126 && $aResult[1] <= 90.1
127 && $aResult[1] >= -90.1
128 && $aResult[2] <= 180.1
129 && $aResult[2] >= -180.1
131 $this->setNearPoint($aResult[1], $aResult[2]);
132 $sQuery = trim(str_replace($aResult[0], ' ', $sQuery));
138 public function distanceSQL($sObj)
140 return 'ST_Distance('.$this->sqlNear.", $sObj)";
143 public function withinSQL($sObj)
145 return sprintf('ST_DWithin(%s, %s, %F)', $sObj, $this->sqlNear, $this->fNearRadius);
148 public function viewboxImportanceSQL($sObj)
152 if ($this->sqlViewboxSmall) {
153 $sSQL = " * CASE WHEN ST_Contains($this->sqlViewboxSmall, $sObj) THEN 1 ELSE 0.5 END";
155 if ($this->sqlViewboxLarge) {
156 $sSQL = " * CASE WHEN ST_Contains($this->sqlViewboxLarge, $sObj) THEN 1 ELSE 0.5 END";
162 public function excludeSQL($sVariable)
164 if ($this->sqlExcludeList) {
165 return $sVariable.$this->sqlExcludeList;