diff --git a/assets/maps/contao-leaflet.js b/assets/maps/contao-leaflet.js index a9e5cdc..027245d 100644 --- a/assets/maps/contao-leaflet.js +++ b/assets/maps/contao-leaflet.js @@ -1 +1 @@ -L.Contao=L.Class.extend({includes:L.Mixin.Events,statics:{ATTRIBUTION:' | netzmacht creative'},maps:{},icons:{},initialize:function(){L.Icon.Default.imagePath="assets/leaflet/libs/leaflet/images",this.setGeoJsonListeners(L.GeoJSON)},addMap:function(t,e){return this.maps[t]=e,this.fire("map:added",{id:t,map:e}),this},getMap:function(t){return"undefined"==typeof this.maps[t]?null:this.maps[t]},addIcon:function(t,e){return this.icons[t]=e,this.fire("icon:added",{id:t,icon:e}),this},loadIcons:function(t){for(var e=0;ei&&(o[o.length]=[e,t].join("=")),document.location.pathname+o.join("&")}}),L.Contao.Attribution={setPrefix:function(t){return-1===t.indexOf(L.Contao.ATTRIBUTION)&&(t+=L.Contao.ATTRIBUTION),this.options.prefix=t,this._update(),this}},L.Control.Attribution.addInitHook(function(){this.options.prefix+=L.Contao.ATTRIBUTION}),L.Control.Attribution.include(L.Contao.Attribution),L.contao=new L.Contao,L.Map.include({_dynamicBounds:null,calculateFeatureBounds:function(t,e){if(t){if(!this.options.adjustBounds&&!e)return;this._scanForBounds(t)}else this.eachLayer(this._scanForBounds,this);this._dynamicBounds&&this.fitBounds(this._dynamicBounds)},_scanForBounds:function(t){var e;!t.feature||t.feature.properties&&t.feature.properties.ignoreForBounds?L.MarkerClusterGroup&&t instanceof L.MarkerClusterGroup&&t.options.affectBounds?(e=t.getBounds(),e.isValid()&&(this._dynamicBounds?this._dynamicBounds.extend(e):this._dynamicBounds=L.latLngBounds(e.getSouthWest(),e.getNorthEast()))):(!t.options||t.options&&t.options.affectBounds)&&t.eachLayer&&t.eachLayer(this._scanForBounds,this):t.getBounds?(e=t.getBounds(),e.isValid()&&(this._dynamicBounds?this._dynamicBounds.extend(e):this._dynamicBounds=L.latLngBounds(e.getSouthWest(),e.getNorthEast()))):t.getLatLng&&(e=t.getLatLng(),this._dynamicBounds?this._dynamicBounds.extend(e):this._dynamicBounds=L.latLngBounds(e,e))}}); \ No newline at end of file +L.Contao=L.Class.extend({includes:L.Mixin.Events,statics:{ATTRIBUTION:' | netzmacht creative'},maps:{},icons:{},initialize:function(){L.Icon.Default.imagePath="assets/leaflet/libs/leaflet/images",this.setGeoJsonListeners(L.GeoJSON)},addMap:function(t,e){return this.maps[t]=e,this.fire("map:added",{id:t,map:e}),this},getMap:function(t){return"undefined"==typeof this.maps[t]?null:this.maps[t]},addIcon:function(t,e){return this.icons[t]=e,this.fire("icon:added",{id:t,icon:e}),this},loadIcons:function(t){for(var e=0;er&&(i[i.length]=[n,t].join("=")),t=document.location.pathname+i.join("&")}return e&&e.options.dynamicLoad&&(o=e.getBounds(),t+="&f=bbox&v=",t+=o.getSouth()+","+o.getWest(),t+=","+o.getNorth()+","+o.getEast()),t}}),L.Contao.Attribution={setPrefix:function(t){return-1===t.indexOf(L.Contao.ATTRIBUTION)&&(t+=L.Contao.ATTRIBUTION),this.options.prefix=t,this._update(),this}},L.Control.Attribution.addInitHook(function(){this.options.prefix+=L.Contao.ATTRIBUTION}),L.Control.Attribution.include(L.Contao.Attribution),L.contao=new L.Contao,L.GeoJSON.include({refreshData:function(t){var e=L.geoJson(),o=this;e.on("ready",function(){var t,e=o.getLayers();for(t=0;t false, 'icon' => 'system/modules/leaflet/assets/img/markers.png', 'markers' => true, + 'boundsMode' => array( + 'extend' => true, + 'fit' => 'deferred' + ), 'label' => function ($row, $label) { $count = \Netzmacht\Contao\Leaflet\Model\MarkerModel::countBy('pid', $row['id']); $label .= sprintf( @@ -187,6 +191,9 @@ $GLOBALS['LEAFLET_LAYERS'] = array 'children' => false, 'icon' => 'system/modules/leaflet/assets/img/vectors.png', 'vectors' => true, + 'boundsMode' => array( + 'extend' => true, + ), 'label' => function ($row, $label) { $count = \Netzmacht\Contao\Leaflet\Model\VectorModel::countBy('pid', $row['id']); $label .= sprintf( @@ -307,3 +314,10 @@ $GLOBALS['LEAFLET_FEATURE_MODEL_PROPERTIES']['tl_leaflet_marker'][] = 'alias'; $GLOBALS['LEAFLET_FEATURE_MODEL_PROPERTIES']['tl_leaflet_vector'][] = 'id'; $GLOBALS['LEAFLET_FEATURE_MODEL_PROPERTIES']['tl_leaflet_vector'][] = 'title'; $GLOBALS['LEAFLET_FEATURE_MODEL_PROPERTIES']['tl_leaflet_vector'][] = 'alias'; + + +/* + * Filters can be passed to a data request to get only specific data from a layer. + */ +$GLOBALS['LEAFLET_FILTERS']['bbox'] = 'Netzmacht\Contao\Leaflet\Filter\BboxFilter'; +$GLOBALS['LEAFLET_FILTERS']['distance'] = 'Netzmacht\Contao\Leaflet\Filter\DistanceFilter'; diff --git a/module/dca/tl_leaflet_layer.php b/module/dca/tl_leaflet_layer.php index 98e9b8c..9c146e9 100644 --- a/module/dca/tl_leaflet_layer.php +++ b/module/dca/tl_leaflet_layer.php @@ -148,15 +148,15 @@ $GLOBALS['TL_DCA']['tl_leaflet_layer'] = array ), 'markers extends default' => array( '+expert' => array('pointToLayer'), - '+active' => array('deferred', 'affectBounds') + '+config' => array('deferred', 'boundsMode') ), 'group extends default' => array( '+title' => array('groupType'), - '+active' => array('affectBounds') + '+active' => array('boundsMode') ), 'vectors extends default' => array( '+expert' => array('onEachFeature', 'pointToLayer'), - '+active' => array('deferred', 'affectBounds'), + '+config' => array('deferred', 'boundsMode'), ), 'reference extends default' => array( '+title' => array('reference', 'standalone') @@ -335,7 +335,7 @@ $GLOBALS['TL_DCA']['tl_leaflet_layer'] = array 'exclude' => true, 'inputType' => 'checkbox', 'default' => true, - 'eval' => array('tl_class' => 'w50', 'submitOnChange' => false, 'isBoolean' => true), + 'eval' => array('tl_class' => 'w50 m12', 'submitOnChange' => true, 'isBoolean' => true), 'sql' => "char(1) NOT NULL default '1'" ), 'groupType' => array @@ -530,14 +530,14 @@ $GLOBALS['TL_DCA']['tl_leaflet_layer'] = array 'eval' => array('tl_class' => 'w50', 'submitOnChange' => false, 'isBoolean' => true), 'sql' => "char(1) NOT NULL default ''" ), - 'affectBounds' => array + 'boundsMode' => array ( - 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['affectBounds'], - 'exclude' => true, - 'inputType' => 'checkbox', - 'default' => false, - 'eval' => array('tl_class' => 'w50'), - 'sql' => "char(1) NOT NULL default ''" + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['boundsMode'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Layer', 'getBoundsModes'), + 'eval' => array('tl_class' => 'w50', 'includeBlankOption' => true), + 'sql' => "varchar(6) NOT NULL default ''" ), 'tileUrl' => array ( diff --git a/module/dca/tl_leaflet_map.php b/module/dca/tl_leaflet_map.php index 372c686..cd04eaf 100644 --- a/module/dca/tl_leaflet_map.php +++ b/module/dca/tl_leaflet_map.php @@ -94,7 +94,7 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'metapalettes' => array( 'default' => array( 'title' => array('title', 'alias'), - 'zoom' => array('center', 'zoom', 'adjustZoomExtra', 'adjustBounds'), + 'zoom' => array('center', 'zoom', 'adjustZoomExtra', 'adjustBounds', 'dynamicLoad'), 'locate' => array('locate'), 'layers' => array('layers'), 'interaction' => array( @@ -419,6 +419,15 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'eval' => array('tl_class' => 'clr w50', 'multiple' => true, 'helpwizard' => true), 'sql' => "varchar(255) NOT NULL default ''" ), + 'dynamicLoad' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['dynamicLoad'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => true, + 'eval' => array('tl_class' => 'w50', 'submitOnChange' => false), + 'sql' => "char(1) NOT NULL default ''" + ), 'locate' => array ( 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['locate'], diff --git a/module/dca/tl_leaflet_marker.php b/module/dca/tl_leaflet_marker.php index bcc5825..a46d585 100644 --- a/module/dca/tl_leaflet_marker.php +++ b/module/dca/tl_leaflet_marker.php @@ -176,18 +176,44 @@ $GLOBALS['TL_DCA']['tl_leaflet_marker'] = array 'exclude' => true, 'inputType' => 'text', 'save_callback' => array( - array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'validateCoordinate') + array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'validateCoordinate'), + array('Netzmacht\Contao\Leaflet\Dca\Marker', 'saveCoordinates') ), 'wizard' => array( array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getGeocoder') ), 'eval' => array( - 'maxlength' => 255, - 'tl_class' => 'long clr', - 'nullIfEmpty' => true, + 'maxlength' => 255, + 'tl_class' => 'long clr', + 'nullIfEmpty' => true, + 'doNotSaveEmpty' => true, ), 'sql' => "varchar(255) NULL" ), + 'latitude' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_marker']['latitude'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => array('mandatory' => false, 'maxlength' => 255, 'tl_class' => 'w50'), + 'sql' => "float NULL" + ), + 'longitude' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_marker']['longitude'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => array('mandatory' => false, 'maxlength' => 255, 'tl_class' => 'w50'), + 'sql' => "float NULL" + ), + 'altitude' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_marker']['altitude'], + 'exclude' => true, + 'inputType' => 'text', + 'eval' => array('mandatory' => false, 'maxlength' => 255, 'tl_class' => 'w50'), + 'sql' => "float NULL" + ), 'active' => array ( 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_marker']['active'], diff --git a/module/languages/en/tl_leaflet_layer.php b/module/languages/en/tl_leaflet_layer.php index 58817f4..df61b1f 100644 --- a/module/languages/en/tl_leaflet_layer.php +++ b/module/languages/en/tl_leaflet_layer.php @@ -76,8 +76,8 @@ $GLOBALS['TL_LANG']['tl_leaflet_layer']['iconCreateFunction'][0] = 'Crea $GLOBALS['TL_LANG']['tl_leaflet_layer']['iconCreateFunction'][1] = 'Function used to create the cluster icon.'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['disableDefaultStyle'][0] = 'Disable default style'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['disableDefaultStyle'][1] = 'Do not load default marker cluster stylesheets.'; -$GLOBALS['TL_LANG']['tl_leaflet_layer']['affectBounds'][0] = 'Affect map bounds'; -$GLOBALS['TL_LANG']['tl_leaflet_layer']['affectBounds'][1] = 'If the map support it the marker will be used to affect the initial map bounds.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['boundsMode'][0] = 'Bounds relation'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['boundsMode'][1] = 'Choose a mode how the layer data should affect the map bounds.'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['minZoom'][0] = 'Minimum zoom'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['minZoom'][1] = 'Minimum zoom number.'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['maxZoom'][0] = 'Maximum zoom'; diff --git a/src/Netzmacht/Contao/Leaflet/Dca/Layer.php b/src/Netzmacht/Contao/Leaflet/Dca/Layer.php index c2047af..a153a11 100644 --- a/src/Netzmacht/Contao/Leaflet/Dca/Layer.php +++ b/src/Netzmacht/Contao/Leaflet/Dca/Layer.php @@ -302,6 +302,30 @@ class Layer ->execute($dataContainer->id); } + /** + * Get bounds modes supported by the layer. + * + * @param \DataContainer $dataContainer The data container. + * + * @return array + */ + public function getBoundsModes($dataContainer) + { + $options = array(); + + if ($dataContainer->activeRecord && !empty($this->layers[$dataContainer->activeRecord->type]['boundsMode'])) { + foreach ($this->layers[$dataContainer->activeRecord->type]['boundsMode'] as $mode => $enabled) { + if ($enabled === true) { + $options[] = $mode; + } elseif ($enabled === 'deferred' && $dataContainer->activeRecord->deferred) { + $options[] = $mode; + } + } + } + + return $options; + } + /** * Generate a button. * diff --git a/src/Netzmacht/Contao/Leaflet/Dca/Marker.php b/src/Netzmacht/Contao/Leaflet/Dca/Marker.php index 6d666bb..cb11961 100644 --- a/src/Netzmacht/Contao/Leaflet/Dca/Marker.php +++ b/src/Netzmacht/Contao/Leaflet/Dca/Marker.php @@ -51,4 +51,37 @@ class Marker return $builder->getOptions(); } + + /** + * Save the coordinates. + * + * @param string $value The raw data. + * @param \DataContainer $dataContainer The data container driver. + * + * @return string + */ + public function saveCoordinates($value, $dataContainer) + { + $combined = array( + 'latitude' => null, + 'longitude' => null, + 'altitude' => null + ); + + $values = trimsplit(',', $value); + $keys = array_keys($combined); + + if (count($values) >= 2 && count($values) <= 3) { + for ($i = 0; $i < count($values); $i++) { + $combined[$keys[$i]] = $values[$i]; + } + } + + \Database::getInstance() + ->prepare('UPDATE tl_leaflet_marker %s WHERE id=?') + ->set($combined) + ->execute($dataContainer->id); + + return $value; + } } diff --git a/src/Netzmacht/Contao/Leaflet/Frontend/DataController.php b/src/Netzmacht/Contao/Leaflet/Frontend/DataController.php index 0ddd2c3..1b9d67b 100644 --- a/src/Netzmacht/Contao/Leaflet/Frontend/DataController.php +++ b/src/Netzmacht/Contao/Leaflet/Frontend/DataController.php @@ -11,8 +11,8 @@ namespace Netzmacht\Contao\Leaflet\Frontend; +use Netzmacht\Contao\Leaflet\Filter\Filter; use Netzmacht\Contao\Leaflet\MapService; -use Netzmacht\Contao\Leaflet\Model\LayerModel; /** * The data controller handles ajax request for sub data. @@ -36,7 +36,9 @@ class DataController private $input = array( 'format' => 'geojson', 'type' => 'layer', - 'id' => null + 'id' => null, + 'filter' => null, + 'values' => null ); /** @@ -61,7 +63,13 @@ class DataController public function execute() { try { - list($data, $error) = $this->loadData($this->input['type'], $this->input['id']); + if ($this->input['filter']) { + $filter = $this->createFilter(); + } else { + $filter = null; + } + + list($data, $error) = $this->loadData($this->input['type'], $this->input['id'], $filter); $this->encodeData($this->input['format'], $data); } catch (\Exception $e) { if (\Config::get('debugMode') || \Config::get('displayErrors')) { @@ -101,17 +109,18 @@ class DataController * * @param string $type The data type. * @param mixed $dataId The data id. + * @param Filter $filter Optional request filter. * * @return array */ - public function loadData($type, $dataId) + public function loadData($type, $dataId, Filter $filter = null) { $error = false; $data = null; switch ($type) { case 'layer': - $data = $this->mapService->getFeatureCollection($dataId); + $data = $this->mapService->getFeatureCollection($dataId, $filter); break; default: @@ -122,4 +131,24 @@ class DataController return array($data, $error); } + + /** + * Create a filter. + * + * @return Filter + * @throws \RuntimeException If the filter is not defined. + * + * @SuppressWarnings(PHPMD.Superglobals) + */ + private function createFilter() + { + if (!isset($GLOBALS['LEAFLET_FILTERS'][$this->input['filter']])) { + throw new \RuntimeException(sprintf('Undefined filter "%s".', $this->input['filter'])); + } + + /** @var Filter $filter */ + $filter = $GLOBALS['LEAFLET_FILTERS'][$this->input['filter']]; + + return $filter::fromRequest($this->input['values']); + } } diff --git a/src/Netzmacht/Contao/Leaflet/Frontend/HybridTrait.php b/src/Netzmacht/Contao/Leaflet/Frontend/HybridTrait.php index 65d9b98..2750b37 100644 --- a/src/Netzmacht/Contao/Leaflet/Frontend/HybridTrait.php +++ b/src/Netzmacht/Contao/Leaflet/Frontend/HybridTrait.php @@ -133,7 +133,7 @@ trait HybridTrait * * @return void * - * @throws \HttpRequestException If a bad leaflet param hash is given. + * @throws \RuntimeException If a bad leaflet param hash is given. * @SuppressWarnings(ExitExpression) */ private function handleAjaxRequest() @@ -142,13 +142,15 @@ trait HybridTrait // Handle ajax request. if ($input) { - $data = explode(',', base64_decode($input)); + $data = explode(',', base64_decode($input)); + $data[] = $this->input->get('f'); + $data[] = $this->input->get('v'); - if (count($data) != 4) { - throw new \HttpRequestException('Bad request. Could not resolve query params'); + if (count($data) != 6) { + throw new \RuntimeException('Bad request. Could not resolve query params'); } - $data = array_combine(array('for', 'type', 'id', 'format'), $data); + $data = array_combine(array('for', 'type', 'id', 'format', 'filter', 'values'), $data); $data = array_filter($data); if (empty($data['for']) || $data['for'] != $this->getIdentifier()) { diff --git a/src/Netzmacht/Contao/Leaflet/Frontend/RequestUrl.php b/src/Netzmacht/Contao/Leaflet/Frontend/RequestUrl.php index 20befaa..292a237 100644 --- a/src/Netzmacht/Contao/Leaflet/Frontend/RequestUrl.php +++ b/src/Netzmacht/Contao/Leaflet/Frontend/RequestUrl.php @@ -11,6 +11,8 @@ namespace Netzmacht\Contao\Leaflet\Frontend; +use Netzmacht\Contao\Leaflet\Filter\Filter; + /** * Class RequestUrl creates the request url. * @@ -39,6 +41,13 @@ class RequestUrl implements \JsonSerializable */ private $url; + /** + * Request filter. + * + * @var Filter|null + */ + private $filter; + /** * Create the request url. * @@ -47,10 +56,11 @@ class RequestUrl implements \JsonSerializable * @param int $dataId The data object id. * @param string|null $type Object type. If empty it assumes a layer. * @param string|null $format Data format. If empty it assumes geojson. + * @param Filter $filter Optional filter. * * @return RequestUrl */ - public static function create($dataId, $type = null, $format = null) + public static function create($dataId, $type = null, $format = null, Filter $filter = null) { $params = array( 'for' => static::$for, @@ -59,10 +69,16 @@ class RequestUrl implements \JsonSerializable 'format' => $format != 'geojson' ? $format : null ); - $hash = base64_encode(implode(',', $params)); - $url = \Config::get('websitePath') . '/' . \Frontend::addToUrl('leaflet=' . $hash, false); + $hash = base64_encode(implode(',', $params)); + $query = 'leaflet=' . $hash; - return new static($url, $hash); + if ($filter) { + $query .= '&f=' . $filter->getName() . '&v=' . $filter->toRequest(); + } + + $url = \Config::get('websitePath') . '/' . \Frontend::addToUrl($query, false); + + return new static($url, $hash, $filter); } /** @@ -109,6 +125,16 @@ class RequestUrl implements \JsonSerializable return $this->url; } + /** + * Get request filter. + * + * @return Filter|null + */ + public function getFilter() + { + return $this->filter; + } + /** * Convert to string will always return the whole url. * diff --git a/src/Netzmacht/Contao/Leaflet/MapService.php b/src/Netzmacht/Contao/Leaflet/MapService.php index db0a44a..d6ca02b 100644 --- a/src/Netzmacht/Contao/Leaflet/MapService.php +++ b/src/Netzmacht/Contao/Leaflet/MapService.php @@ -12,6 +12,7 @@ namespace Netzmacht\Contao\Leaflet; use Netzmacht\Contao\Leaflet\Event\GetJavascriptEvent; +use Netzmacht\Contao\Leaflet\Filter\Filter; use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper; use Netzmacht\Contao\Leaflet\Model\LayerModel; use Netzmacht\Contao\Leaflet\Model\MapModel; @@ -68,12 +69,12 @@ class MapService * Get map definition. * * @param MapModel|int $mapId The map database id. MapModel accepted as well. - * @param LatLngBounds $bounds Optional bounds where elements should be in. + * @param Filter $filter Optional request filter. * @param string $elementId Optional element id. If none given the mapId or alias is used. * * @return Map */ - public function getDefinition($mapId, LatLngBounds $bounds = null, $elementId = null) + public function getDefinition($mapId, Filter $filter = null, $elementId = null) { if ($mapId instanceof MapModel) { $model = $mapId; @@ -81,7 +82,7 @@ class MapService $model = $this->getModel($mapId); } - return $this->mapper->handle($model, $bounds, $elementId); + return $this->mapper->handle($model, $filter, $elementId); } /** @@ -150,13 +151,13 @@ class MapService * Get feature collection of a layer. * * @param LayerModel|int $layerId The layer database id or layer model. - * @param LatLngBounds $bounds Filter features in the bounds. + * @param Filter|null $filter Filter data. * * @return FeatureCollection * * @throws \InvalidArgumentException If a layer could not be found. */ - public function getFeatureCollection($layerId, LatLngBounds $bounds = null) + public function getFeatureCollection($layerId, Filter $filter = null) { if ($layerId instanceof LayerModel) { $model = $layerId; @@ -168,6 +169,6 @@ class MapService throw new \InvalidArgumentException(sprintf('Could not find layer "%s"', $layerId)); } - return $this->mapper->handleGeoJson($model, $bounds); + return $this->mapper->handleGeoJson($model, $filter); } } diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php index 967d5bf..d0244ef 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/MarkersLayerMapper.php @@ -57,21 +57,29 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper $elementId = null ) { if ($model->deferred) { - if ($model->pointToLayer || $model->affectBounds) { + if ($model->pointToLayer || $model->boundsMode) { $layer = new GeoJson($this->getElementId($model, $elementId)); if ($model->pointToLayer) { $layer->setPointToLayer(new Expression($model->pointToLayer)); } - if ($model->affectBounds) { - $layer->setOption('affectBounds', (bool) $model->affectBounds); + if ($model->boundsMode) { + $layer->setOption('boundsMode', $model->boundsMode); } - return array($this->getElementId($model, $elementId), RequestUrl::create($model->id), array(), $layer); + return array( + $this->getElementId($model, $elementId), + RequestUrl::create($model->id, null, null, $filter), + array(), + $layer + ); } - return array($this->getElementId($model, $elementId), RequestUrl::create($model->id)); + return array( + $this->getElementId($model, $elementId), + RequestUrl::create($model->id, null, null, $filter) + ); } return parent::buildConstructArguments($model, $mapper, $filter, $elementId); @@ -88,8 +96,8 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper Definition $parent = null ) { if ($definition instanceof GeoJson) { - if ($model->affectBounds) { - $definition->setOption('affectBounds', true); + if ($model->boundsMode) { + $definition->setOption('boundsMode', $model->boundsMode); } $collection = $this->loadMarkerModels($model); @@ -117,7 +125,7 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper public function handleGeoJson(\Model $model, DefinitionMapper $mapper, Filter $filter = null) { $feature = new FeatureCollection(); - $collection = $this->loadMarkerModels($model); + $collection = $this->loadMarkerModels($model, $filter); if ($collection) { foreach ($collection as $item) { @@ -136,12 +144,17 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper /** * Load all layer markers. * - * @param \Model $model The layer model. + * @param \Model $model The layer model. + * @param Filter $filter null The request filter. * * @return \Model\Collection|null */ - protected function loadMarkerModels(\Model $model) + protected function loadMarkerModels(\Model $model, Filter $filter = null) { - return MarkerModel::findActiveBy('pid', $model->id, array('order' => 'sorting')); + if ($model->boundsMode == 'fit') { + return MarkerModel::findByFilter($model->id, $filter); + } + + return MarkerModel::findByFilter($model->id); } } diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php index 94bf3fc..53c9551 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/VectorsLayerMapper.php @@ -68,18 +68,26 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper $options['onEachFeature'] = new Expression($model->onEachFeature); } - if ($model->affectBounds) { - $options['affectBounds'] = (bool) $model->affectBounds; + if ($model->boundsMode) { + $options['boundsMode'] = $model->boundsMode; } if (!empty($options)) { $layer = new GeoJson($this->getElementId($model, $elementId)); $layer->setOptions($options); - return array($this->getElementId($model, $elementId), RequestUrl::create($model->id), array(), $layer); + return array( + $this->getElementId($model, $elementId), + RequestUrl::create($model->id, null, null, $filter), + array(), + $layer + ); } - return array($this->getElementId($model, $elementId), RequestUrl::create($model->id)); + return array( + $this->getElementId($model, $elementId), + RequestUrl::create($model->id, null, null, $filter) + ); } return parent::buildConstructArguments($model, $mapper, $filter, $elementId); @@ -98,8 +106,8 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper if ($definition instanceof GeoJson) { $collection = $this->loadVectorModels($model); - if ($model->affectBounds) { - $definition->setOption('affectBounds', true); + if ($model->boundsMode) { + $definition->setOption('boundsMode', $model->boundsMode); } if ($collection) { diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php index 0e07d8b..1741e40 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php @@ -100,6 +100,8 @@ class MapMapper extends AbstractMapper if ($model->options) { $map->setOptions(json_decode($model->options, true)); } + + $map->setOption('dynamicLoad', (bool) $model->dynamicLoad); } /** diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/OptionsBuilder.php b/src/Netzmacht/Contao/Leaflet/Mapper/OptionsBuilder.php index d5d40b7..b935c0c 100644 --- a/src/Netzmacht/Contao/Leaflet/Mapper/OptionsBuilder.php +++ b/src/Netzmacht/Contao/Leaflet/Mapper/OptionsBuilder.php @@ -205,23 +205,38 @@ class OptionsBuilder public static function applyOptions($options, $definition, $model) { foreach ($options as $option => $mapping) { - $setter = 'set' . ucfirst($option); $default = static::getDefaultOption($option, $definition); if ($model->$mapping === '1' || $model->$mapping === '') { if (((bool) $model->$mapping) !== $default) { - $definition->$setter($model->$mapping); + static::applyOption($option, $model->$mapping, $definition); } } elseif (is_numeric($default)) { if ($model->$mapping != $default) { - $definition->$setter($model->$mapping); + static::applyOption($option, $model->$mapping, $definition); } } elseif ($model->$mapping !== $default) { - $definition->$setter($model->$mapping); + static::applyOption($option, $model->$mapping, $definition); } } } + /** + * @param $option + * @param $value + * @param Definition $definition + */ + private static function applyOption($option, $value, $definition) + { + $setter = 'set' . ucfirst($option); + + if (method_exists($definition, $setter)) { + $definition->$setter($value); + } else { + $definition->setOption($option, $value); + } + } + /** * Get default option value. * diff --git a/src/Netzmacht/Contao/Leaflet/Model/MarkerModel.php b/src/Netzmacht/Contao/Leaflet/Model/MarkerModel.php index 706e8c1..3631efc 100644 --- a/src/Netzmacht/Contao/Leaflet/Model/MarkerModel.php +++ b/src/Netzmacht/Contao/Leaflet/Model/MarkerModel.php @@ -11,6 +11,10 @@ namespace Netzmacht\Contao\Leaflet\Model; +use Netzmacht\Contao\Leaflet\Filter\BboxFilter; +use Netzmacht\Contao\Leaflet\Filter\Filter; +use Netzmacht\LeafletPHP\Definition\Type\LatLngBounds; + /** * Class MarkerModel for the tl_leaflet_marker table. * @@ -24,4 +28,53 @@ class MarkerModel extends AbstractActiveModel * @var string */ protected static $strTable = 'tl_leaflet_marker'; + + /** + * @param $pid + * @param Filter $filter + * + * @return \Model\Collection|null + */ + public static function findByFilter($pid, Filter $filter = null) + { + if (!$filter) { + return MarkerModel::findActiveBy('pid', $pid, array('order' => 'sorting')); + } + + switch ($filter->getName()) { + case 'bbox': + return static::findByBBoxFilter($pid, $filter); + + default: + return null; + } + } + + /** + * @param $pid + * @param BboxFilter $filter + * + * @return \Model\Collection|null + */ + public static function findByBBoxFilter($pid, BboxFilter $filter) + { + $columns = array( + 'active=1', + 'pid=?', + 'latitude > ? AND latitude < ?', + 'longitude > ? AND longitude < ?' + ); + + /** @var LatLngBounds $bounds */ + $bounds = $filter->getValues()['bounds']; + $values = array( + $pid, + $bounds->getSouthWest()->getLatitude(), + $bounds->getNorthEast()->getLatitude(), + $bounds->getSouthWest()->getLongitude(), + $bounds->getNorthEast()->getLongitude() + ); + + return static::findBy($columns, $values, array('order' => 'sorting')); + } }