[TYPO3-mvc] Queries for a localized vendor search service
Henjo Hoeksma
me at henjohoeksma.nl
Mon Sep 19 11:06:20 CEST 2011
On 2011-09-19 08:58:13 +0000, Matthias Nagl said:
> I am going to implement a localized search that shows a user the closest
> vendors for a special service.
>
> To realize this I have a database table containing vendors and their
> coordinates (latitude, longitude). The search results shall be presented
> ordered by distance. As the website only covers vendors in a rather small
> region it would be perfectly sufficiant to compute Euclidean distances.
> In MySQL syntax the query should look like this:
> SELECT ... ORDER BY SQRT(POW(lat - userlat, 2)*latweight + POW(lng - userlng,
> 2)*lngweight);
> in this query userlat and userlng would be the user's coordinates and
> latweight as well as lngweight the average distance between degrees of
> lat/longitude.
>
> My Question:
> Is it possible zu create such an ordering using the extbase query object or is
> it at least possible to inject the ordering-part of SQL code into a query
> object without creating the whole with the $query->statement() method.
>
> Cheers
>
> Matthias
Hi Matthias,
this is how I solved it:
public function findByDistance($lat, $lng, $distance, $group=NULL,
$metric = 'km', $items = '10') {
// $this->settings['search']['numberOfItems']
if ($metric == 'km') {
$metric = '6371'; // Kilometres
} else {
$metric = '3959'; // Miles
}
// Using the query statement is not an option. Unfortunately.
$result = $GLOBALS['TYPO3_DB']->sql_query('
SELECT uid,( ' . $metric . ' * acos( cos( radians(' . $lat . ') )
* cos( radians( lat ) ) * cos( radians( lng ) - radians(' . $lng . ') )
+ sin( radians(' . $lat . ') ) * sin( radians( lat ) ) ) ) AS distance
FROM tt_address
HAVING distance < ' . $distance . '
ORDER BY distance LIMIT 0,' . $items);
while ($row = mysql_fetch_assoc($result)) {
$uids[] = $row['uid'];
}
if (count($uids) > '0') {
$query = $this->createQuery();
if (empty($group)) {
$addresses = $query->matching($query->in('uid', $uids))->execute();
} else {
$groupRepository =
$this->objectManager->get('Tx_Googlelocator_Domain_Repository_AddressGroupRepository');
$group = $groupRepository->findOneByUid($group);
$constraints[] = $query->in('uid', $uids);
$constraints[] = $query->contains('addressgroup', $group);
$addresses = $query->matching($query->logicalAnd($constraints))->execute();
if (count($addresses) == '0')
$addresses = NULL;
}
} else {
$addresses = NULL;
}
return $addresses;
}
More information about the TYPO3-project-typo3v4mvc
mailing list