Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

LeafLet.php 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2013-2015 2amigOS! Consulting Group LLC
  4. * @link http://2amigos.us
  5. * @license http://www.opensource.org/licenses/bsd-license.php New BSD License
  6. */
  7. namespace dosamigos\leaflet;
  8. use dosamigos\leaflet\controls\Control;
  9. use dosamigos\leaflet\layers\Layer;
  10. use dosamigos\leaflet\layers\LayerGroup;
  11. use dosamigos\leaflet\layers\TileLayer;
  12. use dosamigos\leaflet\layers\Polygon;
  13. use dosamigos\leaflet\types\LatLng;
  14. use dosamigos\leaflet\widgets\Map;
  15. use yii\base\Component;
  16. use yii\base\InvalidConfigException;
  17. use yii\base\InvalidParamException;
  18. use yii\helpers\ArrayHelper;
  19. /**
  20. * Class LeafLet
  21. * @package dosamigos\leaflet
  22. */
  23. /**
  24. * @property LatLng $center
  25. *
  26. */
  27. class LeafLet extends Component
  28. {
  29. // JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_NUMERIC_CHECK
  30. const JSON_OPTIONS = 352;
  31. /**
  32. * @var integer a counter used to generate [[name]] for layers.
  33. * @internal
  34. */
  35. public static $counter = 0;
  36. /**
  37. * @var string the prefix to the automatically generated object names.
  38. * @see [[generateName()]]
  39. */
  40. public static $autoNamePrefix = 'l';
  41. /**
  42. * @var string the name to give to the variable. The name of the map specified on the
  43. * [[TileLayer]] component overrides this one.
  44. */
  45. public $name = 'map';
  46. /**
  47. * @var int the zoom level of the map
  48. */
  49. public $zoom = 13;
  50. /**
  51. * @var array the options for the underlying LeafLetJs JS component.
  52. * Please refer to the LeafLetJs api reference for possible
  53. * [options](http://leafletjs.com/reference.html).
  54. */
  55. public $clientOptions = [];
  56. /**
  57. * @var array the event handlers for the underlying LeafletJs JS plugin.
  58. * Please refer to the LeafLetJs js api object options for possible events.
  59. */
  60. public $clientEvents = [];
  61. /**
  62. * @var Layer[] holding ui layers (do not confuse with map layers, these are markers, popups, polygons, etc)
  63. */
  64. private $_layers = [];
  65. /**
  66. * @var LayerGroup[] holding layer groups
  67. */
  68. private $_layerGroups = [];
  69. /**
  70. * @var LatLng sets the center of the map
  71. */
  72. private $_center;
  73. /**
  74. * Returns the center of the map.
  75. * @return LatLng center of the map.
  76. */
  77. public function getCenter()
  78. {
  79. return $this->_center;
  80. }
  81. /**
  82. * Sets the center of the map.
  83. *
  84. * @param LatLng $value center of the map.
  85. */
  86. public function setCenter(LatLng $value)
  87. {
  88. $this->_center = $value;
  89. }
  90. /**
  91. * @var Control[] holding controls to be added to the map.
  92. */
  93. private $_controls = [];
  94. /**
  95. * @param \dosamigos\leaflet\controls\Control[] $controls
  96. *
  97. * @throws \yii\base\InvalidParamException
  98. */
  99. public function setControls(array $controls)
  100. {
  101. foreach ($controls as $control) {
  102. if (!($control instanceof Control)) {
  103. throw new InvalidParamException("All controls must be of type Control.");
  104. }
  105. }
  106. $this->_controls = $controls;
  107. }
  108. /**
  109. * @return \dosamigos\leaflet\controls\Control[]
  110. */
  111. public function getControls()
  112. {
  113. return $this->_controls;
  114. }
  115. /**
  116. * @param Control $control
  117. */
  118. public function addControl(Control $control)
  119. {
  120. $this->_controls[] = $control;
  121. }
  122. /**
  123. * @var \dosamigos\leaflet\layers\TileLayer
  124. */
  125. private $_tileLayer;
  126. /**
  127. * @param \dosamigos\leaflet\layers\TileLayer $tileLayer
  128. *
  129. * @return static the component itself
  130. */
  131. public function setTileLayer(TileLayer $tileLayer)
  132. {
  133. if (!empty($tileLayer->map) && strcmp($tileLayer->map, $this->name) !== 0) {
  134. $this->name = $tileLayer->map;
  135. }
  136. if (empty($tileLayer->map)) {
  137. $tileLayer->map = $this->name;
  138. }
  139. $this->_tileLayer = $tileLayer;
  140. return $this;
  141. }
  142. /**
  143. * @return \dosamigos\leaflet\layers\TileLayer
  144. */
  145. public function getTileLayer()
  146. {
  147. return $this->_tileLayer;
  148. }
  149. /**
  150. * @var array holds the js script lines to be registered.
  151. */
  152. private $_js = [];
  153. /**
  154. * @param string|array $js custom javascript code to be registered.
  155. * *Warning*: This method overrides any previous settings.
  156. *
  157. * @return static the component itself
  158. */
  159. public function setJs($js)
  160. {
  161. $this->_js = is_array($js) ? $js : [$js];
  162. return $this;
  163. }
  164. /**
  165. * @param string $js appends javascript code to be registered.
  166. *
  167. * @return static the component itself
  168. */
  169. public function appendJs($js)
  170. {
  171. $this->_js[] = $js;
  172. return $this;
  173. }
  174. /**
  175. * @return array the queued javascript code to be registered.
  176. * *Warning*: This method does not include map initialization.
  177. */
  178. public function getJs()
  179. {
  180. $js = [];
  181. foreach ($this->getLayers() as $layer) {
  182. if ($layer instanceof Polygon) {
  183. $layerJs = $layer->encode();
  184. $insertAtTheBottom = $layer->insertAtTheBottom ? 'true' : 'false';
  185. $js[] = "$this->name.addLayer($layerJs, $insertAtTheBottom);";
  186. continue;
  187. }
  188. $layer->map = $this->name;
  189. $js[] = $layer->encode();
  190. }
  191. $groups = $this->getEncodedLayerGroups($this->getLayerGroups());
  192. $controls = $this->getEncodedControls($this->getControls());
  193. $plugins = $this->getEncodedPlugins($this->getPlugins()->getInstalledPlugins());
  194. $js = ArrayHelper::merge($js, $groups);
  195. $js = ArrayHelper::merge($js, $controls);
  196. $js = ArrayHelper::merge($js, $plugins);
  197. $js = ArrayHelper::merge($js, $this->_js);
  198. return $js;
  199. }
  200. /**
  201. * @var PluginManager
  202. */
  203. private $_plugins;
  204. /**
  205. * @return PluginManager
  206. */
  207. public function getPlugins()
  208. {
  209. return $this->_plugins;
  210. }
  211. /**
  212. * Installs a plugin
  213. *
  214. * @param Plugin $plugin
  215. */
  216. public function installPlugin(Plugin $plugin)
  217. {
  218. $plugin->map = $this->name;
  219. $this->getPlugins()->install($plugin);
  220. }
  221. /**
  222. * Removes an installed plugin
  223. *
  224. * @param $plugin
  225. *
  226. * @return mixed|null
  227. */
  228. public function removePlugin($plugin)
  229. {
  230. return $this->getPlugins()->remove($plugin);
  231. }
  232. /**
  233. * Initializes the widget.
  234. */
  235. public function init()
  236. {
  237. parent::init();
  238. if (empty($this->center) || empty($this->zoom)) {
  239. throw new InvalidConfigException("'center' and/or 'zoom' attributes cannot be empty.");
  240. }
  241. $this->_plugins = new PluginManager();
  242. $this->clientOptions['center'] = $this->center->toArray(true);
  243. $this->clientOptions['zoom'] = $this->zoom;
  244. }
  245. /**
  246. * Helper method to render the widget. It is also possible to use the widget directly:
  247. * ```
  248. * echo Map::widget(['leafLet' => $leafLetObject, ...]);
  249. * ```
  250. *
  251. * @param array $config
  252. *
  253. * @return string
  254. */
  255. public function widget($config = [])
  256. {
  257. ob_start();
  258. ob_implicit_flush(false);
  259. $config['leafLet'] = $this;
  260. $widget = new Map($config);
  261. $out = $widget->run();
  262. return ob_get_clean() . $out;
  263. }
  264. /**
  265. * @param Layer $layer the layer script to add to the js script code. It could be any object extending from [[Layer]]
  266. * component (markers, polylines, popup, etc)
  267. *
  268. * @return static the component itself
  269. */
  270. public function addLayer(Layer $layer)
  271. {
  272. $this->_layers[] = $layer;
  273. return $this;
  274. }
  275. /**
  276. * @return Layer[] the stored layers
  277. */
  278. public function getLayers()
  279. {
  280. return $this->_layers;
  281. }
  282. /**
  283. * @param LayerGroup $group sets a layer group
  284. *
  285. * @return static the component itself
  286. */
  287. public function addLayerGroup(LayerGroup $group)
  288. {
  289. $this->_layerGroups[] = $group;
  290. return $this;
  291. }
  292. /**
  293. * @return layers\LayerGroup[] all stored layer groups
  294. */
  295. public function getLayerGroups()
  296. {
  297. return $this->_layerGroups;
  298. }
  299. /**
  300. * Clears all stored layer groups
  301. * @return static the component itself
  302. */
  303. public function clearLayerGroups()
  304. {
  305. $this->_layerGroups = [];
  306. return $this;
  307. }
  308. /**
  309. * @param Control[] $controls
  310. *
  311. * @return array
  312. */
  313. public function getEncodedControls($controls)
  314. {
  315. return $this->getEncodedObjects($controls);
  316. }
  317. /**
  318. * @param LayerGroup[] $groups
  319. *
  320. * @return array
  321. */
  322. public function getEncodedLayerGroups($groups)
  323. {
  324. return $this->getEncodedObjects($groups);
  325. }
  326. /**
  327. * @param Plugin[] $plugins
  328. *
  329. * @return array
  330. */
  331. public function getEncodedPlugins($plugins)
  332. {
  333. return $this->getEncodedObjects($plugins);
  334. }
  335. /**
  336. * @return string
  337. */
  338. public static function generateName()
  339. {
  340. return self::$autoNamePrefix . self::$counter++;
  341. }
  342. /**
  343. * @param $objects
  344. *
  345. * @return array
  346. */
  347. protected function getEncodedObjects($objects)
  348. {
  349. $js = [];
  350. foreach ((array)$objects as $object) {
  351. if (property_exists($object, 'map')) {
  352. $object->map = $this->name;
  353. }
  354. $js[] = method_exists($object, 'encode') ? $object->encode() : null;
  355. }
  356. return array_filter($js);
  357. }
  358. }