1
|
|
|
<?php |
2
|
|
|
namespace sibilino\yii2\openlayers; |
3
|
|
|
|
4
|
|
|
use yii\base\Widget; |
5
|
|
|
use yii\helpers\Html; |
6
|
|
|
use yii\helpers\Json; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Yii 2 widget encapsulating OpenLayers 3 and offering simplified option specification. |
10
|
|
|
* @link https://github.com/Sibilino/yii2-openlayers |
11
|
|
|
* @copyright Copyright (c) 2015 Luis Hernández Hernández |
12
|
|
|
* @license http://opensource.org/licenses/MIT MIT |
13
|
|
|
*/ |
14
|
|
|
class OpenLayers extends Widget |
15
|
|
|
{ |
16
|
|
|
/** |
17
|
|
|
* @var array the HTML attributes for the container div of this widget. |
18
|
|
|
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered. |
19
|
|
|
*/ |
20
|
|
|
public $options = []; |
21
|
|
|
/** |
22
|
|
|
* The properties to be passed to the OpenLayers Map() constructor. In order to ease passing complex JavaScript structures, some simplifications are supported. |
23
|
|
|
* See {@link OpenLayers::processMapOptions} for details on simplified option specification. |
24
|
|
|
* @var array |
25
|
|
|
*/ |
26
|
|
|
public $mapOptions = []; |
27
|
|
|
/** |
28
|
|
|
* The scripts that operate with the olwidget.js module, e. g. to apply map configuration in plain JavaScript. |
29
|
|
|
* Can be array to register multiple scripts. If the array is given string keys, they will be passed to [[yii\web\View::registerJsFile()]]. |
30
|
|
|
* @var string|array |
31
|
|
|
*/ |
32
|
|
|
public $mapOptionScript = []; |
33
|
|
|
|
34
|
|
|
public function init() |
35
|
|
|
{ |
36
|
|
|
if (!isset($this->options['id'])) { |
37
|
|
|
$this->options['id'] = $this->getId(); |
38
|
|
|
} |
39
|
|
|
$this->mapOptions['target'] = $this->options['id']; |
40
|
|
|
OpenLayersBundle::register($this->view); |
41
|
|
|
OLModuleBundle::register($this->view); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
public function run() |
45
|
|
|
{ |
46
|
|
|
$this->processMapOptions(); |
47
|
|
|
|
48
|
|
|
$scripts = is_array($this->mapOptionScript) ? $this->mapOptionScript : [$this->mapOptionScript]; |
49
|
|
|
foreach ($scripts as $key => $script) { |
50
|
|
|
if (!is_string($key)) { |
51
|
|
|
$key = null; // Dont specify a key for non-associative array of scripts |
52
|
|
|
} |
53
|
|
|
$this->view->registerJsFile($script, ['depends'=>OLModuleBundle::className()], $key); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
$script = 'sibilino.olwidget.createMap('.Json::encode($this->mapOptions).', "'.$this->options['id'].'")'; |
57
|
|
|
$this->view->registerJs($script); |
58
|
|
|
|
59
|
|
|
return Html::tag('div', '', $this->options); |
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Checks whether several "complex" options have been specified as a key => value pair where key is a string. |
64
|
|
|
* If found, those properies will be automatically turned into the JavaScript expression that instantiates the corresponding OpenLayers object, thus eliminating the need to manually create a JsExpression object. |
65
|
|
|
* The value for these processed keys will be passed as options to the constructor of the OpenLayers object. |
66
|
|
|
* Supported simplified properties are: |
67
|
|
|
* <ul> |
68
|
|
|
* <li><b>view</b>: Can be specified as 'view' => $optionArray. |
69
|
|
|
* For example, <code>['view' => ['center'=>[0,0],'zoom'=>2]]</code> will produce this JS: <code>new ol.View({"center":[0,0], "zoom":2})</code> |
70
|
|
|
* <li><b>layers</b>: Each layer in the array can be specified as $type => $options, where $type is a string. |
71
|
|
|
* For example, <code>['layers' => ['Tile' => ['visible' => false]</code> will produce this JS: <code>new ol.layer.Tile({"visible": false})</code> |
72
|
|
|
* <li><b>layer sources</b>: In addition, when a layer's $type => $option pair are both strings, the $option is considered the layer's "source", and will also be converted to the corresponding object. |
73
|
|
|
* For example, <code>['layers' => ['Tile' => 'OSM']</code> will produce this JS: <code>new ol.layer.Tile({"source": new ol.source.OSM()})</code> |
74
|
|
|
* </li> |
75
|
|
|
* </ul> |
76
|
|
|
* If these simplifications are not enough to avoid using complex JsExpression structures, make sure to see the {@link OL} class for an abbreviated way of specifying OpenLayers object instances. |
77
|
|
|
* @see OL |
78
|
|
|
*/ |
79
|
|
|
protected function processMapOptions() |
80
|
|
|
{ |
81
|
|
|
if (isset($this->mapOptions['view']) && is_array($this->mapOptions['view'])) { |
82
|
|
|
$this->mapOptions['view'] = new OL('View', $this->mapOptions['view']); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
if (isset($this->mapOptions['layers'])) { |
86
|
|
|
$this->processSimplifiedLayers(); |
87
|
|
|
} |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Takes each key => value pair in $this->mapOptions['layers'] and checks if key is a string. In that case, a new Layer OL object will created for this layer. |
92
|
|
|
* Then, if the value is also a string, the corresponding Source OL object is created as well. |
93
|
|
|
*/ |
94
|
|
|
protected function processSimplifiedLayers() |
95
|
|
|
{ |
96
|
|
|
$processedLayers = []; |
97
|
|
|
foreach ($this->mapOptions['layers'] as $type => $options) { |
98
|
|
|
if (is_string($type)) { |
99
|
|
|
if (is_string($options)) { |
100
|
|
|
$options = ['source' => new OL("source.$options")]; |
101
|
|
|
} |
102
|
|
|
$processedLayers []= new OL("layer.$type", $options); |
103
|
|
|
} else { // Therefore $type is simply an integer array key |
104
|
|
|
$processedLayers []= $options; |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
$this->mapOptions['layers'] = $processedLayers; |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
|