From 178da218954d6155a8ccc4e1f1e2b0b97744c495 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Thu, 22 Jan 2015 13:34:07 +0100 Subject: [PATCH] Implement the tile layer (Close #3). --- module/config/config.php | 7 +- module/dca/tl_leaflet_layer.php | 231 ++++++++++++++++++ module/languages/en/tl_leaflet_layer.php | 38 +++ .../Leaflet/Mapper/Layer/TileLayerMapper.php | 104 ++++++++ 4 files changed, 379 insertions(+), 1 deletion(-) create mode 100644 src/Netzmacht/Contao/Leaflet/Mapper/Layer/TileLayerMapper.php diff --git a/module/config/config.php b/module/config/config.php index a4380af..6cf48ca 100644 --- a/module/config/config.php +++ b/module/config/config.php @@ -87,6 +87,7 @@ $GLOBALS['LEAFLET_MAPPERS'] = array(); $GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\MapMapper'; // Layer mappers. +$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Layer\TileLayerMapper'; $GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Layer\ProviderLayerMapper'; $GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Layer\MarkersLayerMapper'; $GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\Layer\GroupLayerMapper'; @@ -215,7 +216,11 @@ $GLOBALS['LEAFLET_LAYERS'] = array ( 'children' => true, 'icon' => 'system/modules/leaflet/assets/img/cluster.png', - ) + ), + 'tile' => array( + 'children' => false, + 'icon' => 'system/modules/leaflet/assets/img/tile.png', + ), ); /* diff --git a/module/dca/tl_leaflet_layer.php b/module/dca/tl_leaflet_layer.php index 6fa2fd2..0757e87 100644 --- a/module/dca/tl_leaflet_layer.php +++ b/module/dca/tl_leaflet_layer.php @@ -175,6 +175,32 @@ $GLOBALS['TL_DCA']['tl_leaflet_layer'] = array 'disableDefaultStyle' ) ), + 'tile extends default' => array( + 'config' => array( + 'tileUrl', + 'subdomains', + 'attribution', + 'minZoom', + 'maxZoom', + ), + '+expert' => array( + 'errorTileUrl', + 'tileSize', + 'tms', + 'continuousWorld', + 'noWrap', + 'zoomReverse', + 'zoomOffset', + 'maxNativeZoom', + 'opacity', + 'zIndex', + 'unloadvisibleTiles', + 'updateWhenIdle', + 'detectRetina', + 'reuseTiles', + 'bounds' + ) + ) ), 'metasubselectpalettes' => array( @@ -510,5 +536,210 @@ $GLOBALS['TL_DCA']['tl_leaflet_layer'] = array 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''" ), + 'tileUrl' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['tileUrl'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => '', + 'eval' => array('maxlength' => 255, 'tl_class' => 'w50', 'mandatory' => true), + 'sql' => "varchar(255) NOT NULL default ''" + ), + 'minZoom' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['minZoom'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getZoomLevels'), + 'eval' => array( + 'maxlength' => 4, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + 'includeBlankOption' => true, + 'nullIfEmpty' => true + ), + 'sql' => "int(4) NULL" + ), + 'maxZoom' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['maxZoom'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getZoomLevels'), + 'eval' => array( + 'maxlength' => 4, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + 'includeBlankOption' => true, + 'nullIfEmpty' => true + ), + 'sql' => "int(4) NULL" + ), + 'maxNativeZoom' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['maxNativeZoom'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getZoomLevels'), + 'eval' => array( + 'maxlength' => 4, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + 'includeBlankOption' => true, + 'nullIfEmpty' => true + ), + 'sql' => "int(4) NULL" + ), + 'tileSize' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['tileSize'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => null, + 'eval' => array('maxlength' => 5, 'rgxp' => 'digit', 'tl_class' => 'w50', 'nullIfEmpty' => true), + 'sql' => "int(5) NULL" + ), + 'subdomains' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['subdomains'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => '', + 'eval' => array('maxlength' => 16, 'tl_class' => 'w50'), + 'sql' => "varchar(16) NOT NULL default ''" + ), + 'errorTileUrl' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['errorTileUrl'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => '', + 'eval' => array('maxlength' => 255, 'tl_class' => 'w50'), + 'sql' => "varchar(255) NOT NULL default ''" + ), + 'attribution' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['attribution'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => '', + 'eval' => array('maxlength' => 255, 'tl_class' => 'long', 'allowHtml' => true), + 'sql' => "varchar(255) NOT NULL default ''" + ), + 'tms' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['tms'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'continuousWorld' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['continuousWorld'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'noWrap' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['noWrap'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'zoomOffset' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['zoomOffset'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => null, + 'eval' => array('maxlength' => 5, 'rgxp' => 'digit', 'tl_class' => 'w50', 'nullIfEmpty' => true), + 'sql' => "int(5) NULL" + ), + 'zoomReverse' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['zoomReverse'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'opacity' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['opacity'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => '1.0', + 'eval' => array('mandatory' => false, 'maxlength' => 4, 'rgxp' => 'digit', 'tl_class' => 'w50 clr'), + 'sql' => "varchar(4) NOT NULL default ''" + ), + 'zIndex' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['zIndex'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => null, + 'eval' => array('maxlength' => 5, 'rgxp' => 'digit', 'tl_class' => 'w50', 'nullIfEmpty' => true), + 'sql' => "int(5) NULL" + ), + 'unloadvisibleTiles' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['unloadvisibleTiles'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'updateWhenIdle' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['updateWhenIdle'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'detectRetina' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['detectRetina'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'reuseTiles' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['reuseTiles'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'bounds' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_layer']['bounds'], + 'exclude' => true, + 'inputType' => 'text', + 'save_callback' => array( + ), + 'eval' => array( + 'maxlength' => 255, + 'multiple'=>true, + 'size'=>2, + 'tl_class' => 'long clr', + 'nullIfEmpty' => true, + ), + 'sql' => "mediumblob NULL" + ), ) ); diff --git a/module/languages/en/tl_leaflet_layer.php b/module/languages/en/tl_leaflet_layer.php index e13db4c..58817f4 100644 --- a/module/languages/en/tl_leaflet_layer.php +++ b/module/languages/en/tl_leaflet_layer.php @@ -78,6 +78,44 @@ $GLOBALS['TL_LANG']['tl_leaflet_layer']['disableDefaultStyle'][0] = 'Disa $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']['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'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['maxZoom'][1] = 'Minimum zoom number.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['maxNativeZoom'][0] = 'Maximum zoom where tiles are provided'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['maxNativeZoom'][1] = 'Maximum zoom number the tiles source has available. If it is specified, the tiles on all zoom levels higher than maxNativeZoom will be loaded from maxZoom level and auto-scaled.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['tileSize'][0] = 'Tile size'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['tileSize'][1] = 'Tile size (width and height in pixels, assuming tiles are square).'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['subdomains'][0] = 'Subdomain'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['subdomains'][1] = 'Subdomains of the tile service. Each letter is handled as a subdomain.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['errorTileUrl'][0] = 'Error url'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['errorTileUrl'][1] = 'URL to the tile image to show in place of the tile that failed to load.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['attribution'][0] = 'Attribution'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['attribution'][1] = 'The tile layer attribution. Be aware of the conditions of the tile providers!'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['tms'][0] = 'TMS Service'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['tms'][1] = 'Inverse the Y axis numbering for TMS services'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['continuousWorld'][0] = 'Continuous World'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['continuousWorld'][1] = 'If set to true, the tile coordinates won\'t be wrapped by world width (-180 to 180 longitude) or clamped to lie within world height (-90 to 90). Use this if you use Leaflet for maps that don\'t reflect the real world (e.g. game, indoor or photo maps).'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['noWrap'][0] = 'No wrap'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['noWrap'][1] = 'If set to true, the tiles just won\'t load outside the world width (-180 to 180 longitude) instead of repeating.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['zoomOffset'][0] = 'Zoom offset'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['zoomOffset'][1] = 'The zoom number used in tile URLs will be offset with this value.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['zoomReverse'][0] = 'Reserve zoom'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['zoomReverse'][1] = 'If set to true, the zoom number used in tile URLs will be reversed'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['opacity'][0] = 'Opacity'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['opacity'][1] = 'The opacity of the tile layer.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['zIndex'][0] = 'zIndex'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['zIndex'][1] = 'The explicit zIndex of the tile layer. Not set by default.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['unloadvisibleTiles'][0] = 'Unload not visible tiles'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['unloadvisibleTiles'][1] = 'If true, all the tiles that are not visible after panning are removed.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['updateWhenIdle'][0] = 'Update then idle'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['updateWhenIdle'][1] = 'If false, new tiles are loaded during panning, otherwise only after it '; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['detectRetina'][0] = 'Detect retina displays'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['detectRetina'][1] = 'If true and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['reuseTiles'][0] = 'Reuse tiles'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['reuseTiles'][1] = 'If true, all the tiles that are not visible after panning are placed in a reuse queue from which they will be fetched when new tiles become visible (as opposed to dynamically creating new ones).'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['bounds'][0] = 'Bounds'; +$GLOBALS['TL_LANG']['tl_leaflet_layer']['bounds'][1] = 'When this option is set, the TileLayer only loads tiles that are in the given geographical bounds. Each field defines a corner of the bounds as comma separated value (Latitude,longitude[,altitude]).'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['groupTypes']['layer'][0] = 'Layer group'; $GLOBALS['TL_LANG']['tl_leaflet_layer']['groupTypes']['layer'][1] = 'Basic layer group.
See http://leafletjs.com/reference.html#layergroup'; diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/Layer/TileLayerMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/TileLayerMapper.php new file mode 100644 index 0000000..827f84e --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Mapper/Layer/TileLayerMapper.php @@ -0,0 +1,104 @@ + + * @copyright 2015 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Mapper\Layer; + +use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper; +use Netzmacht\LeafletPHP\Definition; +use Netzmacht\LeafletPHP\Definition\Raster\TileLayer; +use Netzmacht\LeafletPHP\Definition\Type\LatLngBounds; + +/** + * Class TileLayerMapper maps the database model to the tile layer definition. + * + * @package Netzmacht\Contao\Leaflet\Mapper\Layer + */ +class TileLayerMapper extends AbstractLayerMapper +{ + /** + * The definition class. + * + * @var string + */ + protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Raster\TileLayer'; + + /** + * The layer type. + * + * @var string + */ + protected static $type = 'tile'; + + /** + * {@inheritdoc} + */ + protected function initialize() + { + parent::initialize(); + + $this->optionsBuilder + ->addConditionalOption('minZoom') + ->addConditionalOption('maxZoom') + ->addConditionalOption('maxNativeZoom') + ->addConditionalOption('tileSize') + ->addConditionalOption('subdomain') + ->addConditionalOption('errorTileUrl') + ->addOptions('attribution', 'tms', 'continuousWorld', 'noWrap', 'zoomReverse') + ->addConditionalOption('zoomOffset') + ->addConditionalOption('opacity') + ->addOption('zIndex') + ->addOptions('unloadvisibleTiles', 'updateWhenIdle', 'detectRetina', 'reuseTiles'); + } + + /** + * {@inheritdoc} + */ + protected function buildConstructArguments( + \Model $model, + DefinitionMapper $mapper, + LatLngBounds $bounds = null, + $elementId = null + ) { + $arguments = parent::buildConstructArguments($model, $mapper, $bounds, $elementId); + + $arguments[] = $model->tileUrl; + + return $arguments; + } + + /** + * {@inheritdoc} + */ + protected function build( + Definition $definition, + \Model $model, + DefinitionMapper $mapper, + LatLngBounds $bounds = null, + Definition $parent = null + ) { + parent::build($definition, $model, $mapper, $bounds, $parent); + + /** @var TileLayer $definition */ + $bounds = deserialize($model->bounds); + + if ($bounds[0] && $bounds[1]) { + $bounds = array_map( + function ($value) { + return explode(',', $value, 3); + }, + $bounds + ); + + $bounds = LatLngBounds::fromArray($bounds); + $definition->setBounds($bounds); + } + } +}