Add support for distance filter for the marker layer.

This commit is contained in:
David Molineus
2018-10-30 10:48:38 +01:00
parent 314e2d21ee
commit 2108de32d9
4 changed files with 74 additions and 13 deletions

View File

@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Custom route to load map data.
- Add distance filter support for the marker layer (Bounds Mode "fit" has to be enabled).
### Deprecated

View File

@@ -93,4 +93,24 @@ class DistanceFilter implements Filter
'center' => $this->center,
];
}
/**
* Get the center coordinate.
*
* @return LatLng
*/
public function getCenter(): LatLng
{
return $this->center;
}
/**
* Get the distance radius.
*
* @return int
*/
public function getRadius(): int
{
return $this->radius;
}
}

View File

@@ -185,7 +185,7 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
{
$repository = $this->repositoryManager->getRepository(MarkerModel::class);
if ($model->boundsMode == 'fit') {
if ($model->boundsMode === 'fit') {
return $repository->findByFilter($model->id, $request->getFilter());
}

View File

@@ -12,9 +12,12 @@
namespace Netzmacht\Contao\Leaflet\Model;
use Contao\Model\Collection;
use Netzmacht\Contao\Leaflet\Filter\BboxFilter;
use Netzmacht\Contao\Leaflet\Filter\DistanceFilter;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\LeafletPHP\Value\LatLngBounds;
use function var_dump;
/**
* Class MarkerModel for the tl_leaflet_marker table.
@@ -33,21 +36,24 @@ class MarkerModel extends AbstractActiveModel
/**
* Find by a filter.
*
* @param int $pid The parent id.
* @param Filter $filter The filter.
* @param int $pid The parent id.
* @param Filter|null $filter The filter.
*
* @return \Contao\Model\Collection|null
* @return Collection|null
*/
public static function findByFilter($pid, Filter $filter = null)
public static function findByFilter($pid, ?Filter $filter = null)
{
if (!$filter) {
return static::findActiveBy('pid', $pid, ['order' => 'sorting']);
}
switch ($filter->getName()) {
case 'bbox':
switch (true) {
case $filter instanceof BboxFilter:
return static::findByBBoxFilter($pid, $filter);
case $filter instanceof DistanceFilter:
return static::findByDistanceFilter($pid, $filter);
default:
return null;
}
@@ -59,15 +65,16 @@ class MarkerModel extends AbstractActiveModel
* @param int $pid The layer id.
* @param BboxFilter $filter The bbox filter.
*
* @return \Contao\Model\Collection|null
* @return Collection|null|MarkerModel[]
*/
public static function findByBBoxFilter($pid, BboxFilter $filter)
{
$table = static::getTable();
$columns = [
'active=1',
'pid=?',
'latitude > ? AND latitude < ?',
'longitude > ? AND longitude < ?',
$table . '.active=1',
$table . '.pid=?',
$table . '.latitude > ? AND ' . $table . '.latitude < ?',
$table . '.longitude > ? AND ' . $table . '.longitude < ?',
];
/** @var LatLngBounds $bounds */
@@ -80,6 +87,39 @@ class MarkerModel extends AbstractActiveModel
$bounds->getNorthEast()->getLongitude(),
];
return static::findBy($columns, $values, ['order' => 'sorting']);
return static::findBy($columns, $values, ['order' => $table . '.sorting']);
}
/**
* Find marker by distance filter.
*
* @param int $pid The layer id.
* @param DistanceFilter $filter THe distance filter.
*
* @return Collection|null|MarkerModel[]
*/
public static function findByDistanceFilter($pid, DistanceFilter $filter): ?Collection
{
$table = static::getTable();
$query = <<<SQL
round(
sqrt(
power( 2 * pi() / 360 * (? - {$table}.latitude) * 6371,2)
+ power( 2 * pi() / 360 * (? - {$table}.longitude) * 6371 * COS( 2 * pi() / 360 * (? + {$table}.latitude) * 0.5 ),2)
)
) <= ?
SQL;
$center = $filter->getCenter();
$latitude = $center->getLatitude();
$longitude = $center->getLongitude();
$values = [$pid, $latitude, $longitude, $latitude, $filter->getRadius()];
$columns = [
$table . '.active=1',
$table . '.pid=?',
$query
];
return static::findBy($columns, $values, ['order' => $table . '.sorting']);
}
}