|
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
|
|
|
|