Skip to content

Instantly share code, notes, and snippets.

@FabianSchmick
Created May 25, 2020 12:57
Show Gist options
  • Save FabianSchmick/a3c04e344195f127ff0de54f82b6fb5a to your computer and use it in GitHub Desktop.
Save FabianSchmick/a3c04e344195f127ff0de54f82b6fb5a to your computer and use it in GitHub Desktop.
Map geo radius search
<?php
namespace App\Service;
use App\Entity\Address;
use Doctrine\ORM\EntityManagerInterface;
use Geocoder\Provider\Nominatim\Nominatim;
use Geocoder\Query\GeocodeQuery;
use Geocoder\StatefulGeocoder;
use Http\Adapter\Guzzle6\Client;
use League\Geotools\Coordinate\Coordinate;
use League\Geotools\Geotools;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
class MapService
{
/**
* @var StatefulGeocoder
*/
private $geocoder;
public function __construct(RequestStack $requestStack)
{
$server = 'https://nominatim.openstreetmap.org';
$userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36';
$httpClient = new Client();
$provider = new Nominatim($httpClient, $server, $userAgent);
$locale = $requestStack->getCurrentRequest() ? $requestStack->getCurrentRequest()->getLocale() : 'DE-de';
$this->geocoder = new StatefulGeocoder($provider, $locale);
}
public function getCoordinatesFromAddress(Address $address)
{
$data = [
$address->getNumber(),
$address->getStreet(),
$address->getCity(),
$address->getZip(),
'Deutschland',
];
$address = implode(array_filter($data), ', ');
$geocode = $this->geocoder->geocodeQuery(GeocodeQuery::create($address));
if (!$geocode->isEmpty()) {
$coordinates = $geocode->first()->getCoordinates();
return [
'lat' => $coordinates->getLatitude(),
'lng' => $coordinates->getLongitude(),
];
}
return [];
}
public function filterUsersByRadiusSearch($users, $searchZip, $distanceKm = 10)
{
$geotools = new Geotools();
$address = new Address();
$address->setZip($searchZip);
$coordinates = $this->getCoordinatesFromAddress($address);
if (!$coordinates) {
throw new NotFoundHttpException();
}
$users = array_filter($users, function($user) use ($geotools, $coordinates, $distanceKm) {
/** @var Address $address */
$address = $user->getOfficeAddress() ? $user->getOfficeAddress() : $user->getAddress();
$target = new Coordinate(array_values($coordinates));
$location = new Coordinate([$address->getLat(), $address->getLng()]);
$distance = $geotools
->distance()
->in('km')
->setFrom($target)
->setTo($location);
return ($distance->flat() <= $distanceKm);
});
return $users;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment