Skip to content

Commit

Permalink
Nearly there, just need to get searching by miles to work
Browse files Browse the repository at this point in the history
  • Loading branch information
Tam committed Nov 3, 2017
1 parent 3e35846 commit 5cbeb9d
Showing 1 changed file with 54 additions and 26 deletions.
80 changes: 54 additions & 26 deletions src/services/MapService.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ class MapService extends Component
// -------------------------------------------------------------------------

public $searchLatLng;
public $searchEarthRad;
public $searchDistanceUnit;

// Private Props
Expand Down Expand Up @@ -196,11 +195,18 @@ public function modifyElementsQuery (ElementQueryInterface $query, $value)
$query->join(
'JOIN',
"{$tableName} simplemap",
"[[elements.id]] = [[simplemap.ownerId]]"
[
'and',
'[[elements.id]] = [[simplemap.ownerId]]',
'[[elements_sites.siteId]] = [[simplemap.ownerSiteId]]',
]
);

if (array_key_exists('location', $value))
if (array_key_exists('location', $value)) {
$this->_searchLocation($query, $value);
} else if (array_key_exists('distance', $query->orderBy)) {
$this->_replaceOrderBy($query);
}

return;
}
Expand Down Expand Up @@ -360,7 +366,7 @@ private function _formatLocaleForMap ($locale)
*/
private function _calculateDistance (Map $map)
{
if (!$this->searchLatLng || !$this->searchEarthRad) return null;
if (!$this->searchLatLng || !$this->searchDistanceUnit) return null;

$lt1 = $this->searchLatLng['lat'];
$ln1 = $this->searchLatLng['lng'];
Expand Down Expand Up @@ -401,7 +407,9 @@ private function _searchLocation (ElementQuery $query, $value)
if (!is_numeric($radius)) $radius = (float)$radius;
if (!is_numeric($radius)) $radius = 50.0;

if (!in_array($unit, array('km', 'mi'))) $unit = 'km';
if ($unit == 'miles') $unit = 'mi';
else if ($unit == 'kilometers') $unit = 'km';
else if (!in_array($unit, ['km', 'mi'])) $unit = 'km';

if (is_string($location))
$location = self::getLatLngFromAddress($location);
Expand All @@ -416,8 +424,9 @@ private function _searchLocation (ElementQuery $query, $value)
}

if ($location == null) {
$query->addSelect("(0) AS [[distance]]");
$query->subQuery->addSelect("(0) AS [[distance]]");
if (array_key_exists('distance', $query->orderBy)) {
$this->_replaceOrderBy($query, false);
}
return;
}

Expand All @@ -427,22 +436,20 @@ private function _searchLocation (ElementQuery $query, $value)
$this->searchLatLng = $location;
$this->searchDistanceUnit = $distanceUnit;

$haversine = "
(
$distanceUnit
* DEGREES(
ACOS(
COS(RADIANS($location[lat]))
* COS(RADIANS([[simplemap.lat]]))
* COS(RADIANS($location[lng]) - RADIANS([[simplemap.lng]]))
+ SIN(RADIANS($location[lat]))
* SIN(RADIANS([[simplemap.lat]]))
)
)
)
";

$haversine = str_replace(["\r", "\n", "\t"], '', $haversine);
$distanceSearch = "(
$distanceUnit
* DEGREES(
ACOS(
COS(RADIANS($location[lat]))
* COS(RADIANS([[simplemap.lat]]))
* COS(RADIANS($location[lng]) - RADIANS([[simplemap.lng]]))
+ SIN(RADIANS($location[lat]))
* SIN(RADIANS([[simplemap.lat]]))
)
)
)";

$distanceSearch = str_replace(["\r", "\n", "\t"], '', $distanceSearch);

$restrict = [
'and',
Expand All @@ -458,13 +465,34 @@ private function _searchLocation (ElementQuery $query, $value)
]
];

$query->addSelect($haversine . ' AS [[distance]]');
\Craft::dd([$distanceSearch, $restrict]);

if (array_key_exists('distance', $query->orderBy)) {
$this->_replaceOrderBy($query, $distanceSearch);
}

$query
->subQuery
->addSelect("(0) AS [[distance]]")
->andWhere($restrict)
->andWhere("$haversine <= $radius");
->andWhere("$distanceSearch <= $radius");
}

/**
* Replaces the *distance* orderBy
*
* @param ElementQuery $query
* @param bool|string $distanceSearch
*/
private function _replaceOrderBy (ElementQuery $query, $distanceSearch = false)
{
$nextOrder = [];

foreach ($query->orderBy as $order => $sort) {
if ($order == 'distance' && $distanceSearch) $nextOrder[$distanceSearch] = $sort;
elseif ($order != 'distance') $nextOrder[$order] = $sort;
}

$query->orderBy($nextOrder);
}

}

0 comments on commit 5cbeb9d

Please sign in to comment.