Passed
Pull Request — master (#8)
by Mark
05:42 queued 02:48
created
icons/index.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -42,9 +42,9 @@
 block discarded – undo
42 42
 </head>
43 43
 <body>
44 44
 <div class="box"><?php
45
-    foreach(glob('*.png') as $img) {
46
-        echo '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" /> ';
47
-    }
48
-    ?></div>
45
+	foreach(glob('*.png') as $img) {
46
+		echo '<img src="' . $img . '" alt="' . $img . '" title="' . $img . '" /> ';
47
+	}
48
+	?></div>
49 49
 </body>
50 50
 </html>
Please login to merge, or discard this patch.
helper/staticmap.php 1 patch
Indentation   +116 added lines, -116 removed lines patch added patch discarded remove patch
@@ -25,127 +25,127 @@
 block discarded – undo
25 25
  */
26 26
 class helper_plugin_openlayersmap_staticmap extends DokuWiki_Plugin
27 27
 {
28
-    /** maximum width of the resulting image. */
29
-    private $maxWidth = 1024;
30
-    /** maximum heigth of the resulting image. */
31
-    private $maxHeight = 1024;
28
+	/** maximum width of the resulting image. */
29
+	private $maxWidth = 1024;
30
+	/** maximum heigth of the resulting image. */
31
+	private $maxHeight = 1024;
32 32
 
33
-    /**
34
-     * Provide metadata of the public methods of this class.
35
-     *
36
-     * @return array Information to all provided methods.
37
-     */
38
-    public function getMethods(): array
39
-    {
40
-        $result   = array();
41
-        $result[] = array(
42
-            'name'   => 'getMap',
43
-            'desc'   => 'returns url to the image',
44
-            'params' => array(
45
-                'lat'     => 'float',
46
-                'lon'     => 'float',
47
-                'zoom'    => 'integer',
48
-                'size'    => 'string',
49
-                'maptype' => 'string',
50
-                'markers' => 'string',
51
-                'gpx'     => 'string',
52
-                'kml'     => 'string',
53
-                'geojson' => 'string',
54
-                'apikey'  => 'string'
55
-            ),
56
-            'return' => array('image' => 'string'),
57
-        );
58
-        return $result;
59
-    }
33
+	/**
34
+	 * Provide metadata of the public methods of this class.
35
+	 *
36
+	 * @return array Information to all provided methods.
37
+	 */
38
+	public function getMethods(): array
39
+	{
40
+		$result   = array();
41
+		$result[] = array(
42
+			'name'   => 'getMap',
43
+			'desc'   => 'returns url to the image',
44
+			'params' => array(
45
+				'lat'     => 'float',
46
+				'lon'     => 'float',
47
+				'zoom'    => 'integer',
48
+				'size'    => 'string',
49
+				'maptype' => 'string',
50
+				'markers' => 'string',
51
+				'gpx'     => 'string',
52
+				'kml'     => 'string',
53
+				'geojson' => 'string',
54
+				'apikey'  => 'string'
55
+			),
56
+			'return' => array('image' => 'string'),
57
+		);
58
+		return $result;
59
+	}
60 60
 
61
-    /**
62
-     * Create the map.
63
-     *
64
-     * @param float  $lat     the latitude of the map's center, eg. 40.714728
65
-     * @param float  $lon     the longitude of the map's center, eg -73.998672
66
-     * @param int    $zoom    the zoom level in the tile cache, eg. 14
67
-     * @param string $size    the size in WxH px, eg. 512x512
68
-     * @param string $maptype the maptype, eg. cycle
69
-     * @param array  $markers associative array of markers, array('lat'=>$lat,'lon'=>$lon,'type'=>$iconStyle),
70
-     *                        eg. array('lat'=>40.702147,'lon'=>-74.015794,'type'=>lightblue1);
71
-     * @param string $gpx     media link
72
-     * @param string $kml     media link
73
-     * @param string $geojson media link
74
-     * @param string $apikey  optional API key eg. for Thunderforest maps
75
-     *
76
-     * @return string
77
-     */
78
-    public function getMap(
79
-        float $lat,
80
-        float $lon,
81
-        int $zoom,
82
-        string $size,
83
-        string $maptype,
84
-        array $markers,
85
-        string $gpx,
86
-        string $kml,
87
-        string $geojson,
88
-        string $apikey = ''
89
-    ): string {
90
-        global $conf;
91
-        // Logger::debug('helper_plugin_openlayersmap_staticmap::getMap: markers :',$markers);
61
+	/**
62
+	 * Create the map.
63
+	 *
64
+	 * @param float  $lat     the latitude of the map's center, eg. 40.714728
65
+	 * @param float  $lon     the longitude of the map's center, eg -73.998672
66
+	 * @param int    $zoom    the zoom level in the tile cache, eg. 14
67
+	 * @param string $size    the size in WxH px, eg. 512x512
68
+	 * @param string $maptype the maptype, eg. cycle
69
+	 * @param array  $markers associative array of markers, array('lat'=>$lat,'lon'=>$lon,'type'=>$iconStyle),
70
+	 *                        eg. array('lat'=>40.702147,'lon'=>-74.015794,'type'=>lightblue1);
71
+	 * @param string $gpx     media link
72
+	 * @param string $kml     media link
73
+	 * @param string $geojson media link
74
+	 * @param string $apikey  optional API key eg. for Thunderforest maps
75
+	 *
76
+	 * @return string
77
+	 */
78
+	public function getMap(
79
+		float $lat,
80
+		float $lon,
81
+		int $zoom,
82
+		string $size,
83
+		string $maptype,
84
+		array $markers,
85
+		string $gpx,
86
+		string $kml,
87
+		string $geojson,
88
+		string $apikey = ''
89
+	): string {
90
+		global $conf;
91
+		// Logger::debug('helper_plugin_openlayersmap_staticmap::getMap: markers :',$markers);
92 92
 
93
-        // normalize zoom
94
-        $zoom = $zoom ?: 0;
95
-        if ($zoom > 18) {
96
-            $zoom = 18;
97
-        }
98
-        // normalize WxH
99
-        list($width, $height) = explode('x', $size);
100
-        $width = (int)$width;
101
-        if ($width > $this->maxWidth) {
102
-            $width = $this->maxWidth;
103
-        }
104
-        $height = (int)$height;
105
-        if ($height > $this->maxHeight) {
106
-            $height = $this->maxHeight;
107
-        }
93
+		// normalize zoom
94
+		$zoom = $zoom ?: 0;
95
+		if ($zoom > 18) {
96
+			$zoom = 18;
97
+		}
98
+		// normalize WxH
99
+		list($width, $height) = explode('x', $size);
100
+		$width = (int)$width;
101
+		if ($width > $this->maxWidth) {
102
+			$width = $this->maxWidth;
103
+		}
104
+		$height = (int)$height;
105
+		if ($height > $this->maxHeight) {
106
+			$height = $this->maxHeight;
107
+		}
108 108
 
109
-        // cleanup/validate gpx/kml
110
-        $kml = $this->mediaIdToPath($kml);
111
-        // Logger::debug('helper_plugin_openlayersmap_staticmap::getMap: kml file:',$kml);
112
-        $gpx = $this->mediaIdToPath($gpx);
113
-        // Logger::debug('helper_plugin_openlayersmap_staticmap::getMap: gpx file:',$gpx);
114
-        $geojson = $this->mediaIdToPath($geojson);
109
+		// cleanup/validate gpx/kml
110
+		$kml = $this->mediaIdToPath($kml);
111
+		// Logger::debug('helper_plugin_openlayersmap_staticmap::getMap: kml file:',$kml);
112
+		$gpx = $this->mediaIdToPath($gpx);
113
+		// Logger::debug('helper_plugin_openlayersmap_staticmap::getMap: gpx file:',$gpx);
114
+		$geojson = $this->mediaIdToPath($geojson);
115 115
 
116
-        // create map
117
-        require_once DOKU_PLUGIN . 'openlayersmap/StaticMap.php';
118
-        $map = new StaticMap(
119
-            $lat, $lon, $zoom, $width, $height, $maptype,
120
-            $markers, $gpx, $kml, $geojson, $conf['mediadir'], $conf['cachedir'],
121
-            $this->getConf('autoZoomMap'), $apikey
122
-        );
116
+		// create map
117
+		require_once DOKU_PLUGIN . 'openlayersmap/StaticMap.php';
118
+		$map = new StaticMap(
119
+			$lat, $lon, $zoom, $width, $height, $maptype,
120
+			$markers, $gpx, $kml, $geojson, $conf['mediadir'], $conf['cachedir'],
121
+			$this->getConf('autoZoomMap'), $apikey
122
+		);
123 123
 
124
-        // return the media id url
125
-        // $mediaId = str_replace('/', ':', $map->getMap());
126
-        // if($this->startsWith($mediaId,':')) {
127
-        //     $mediaId = substr($mediaId, 1);
128
-        // }
129
-        // return $mediaId;
130
-        return str_replace('/', ':', $map->getMap());
131
-    }
124
+		// return the media id url
125
+		// $mediaId = str_replace('/', ':', $map->getMap());
126
+		// if($this->startsWith($mediaId,':')) {
127
+		//     $mediaId = substr($mediaId, 1);
128
+		// }
129
+		// return $mediaId;
130
+		return str_replace('/', ':', $map->getMap());
131
+	}
132 132
 
133
-    /**
134
-     * Constructs the path to a file.
135
-     * @param string $id the DW media id
136
-     * @return string the path to the file
137
-     */
138
-    private function mediaIdToPath(string $id): string
139
-    {
140
-        global $conf;
141
-        if (empty($id)) {
142
-            return "";
143
-        }
144
-        $id = str_replace(array("[[", "]]"), "", $id);
145
-        if ((strpos($id, ':') === 0)) {
146
-            $id = substr($id, 1);
147
-        }
148
-        $id = str_replace(":", "/", $id);
149
-        return $conf['mediadir'] . '/' . $id;
150
-    }
133
+	/**
134
+	 * Constructs the path to a file.
135
+	 * @param string $id the DW media id
136
+	 * @return string the path to the file
137
+	 */
138
+	private function mediaIdToPath(string $id): string
139
+	{
140
+		global $conf;
141
+		if (empty($id)) {
142
+			return "";
143
+		}
144
+		$id = str_replace(array("[[", "]]"), "", $id);
145
+		if ((strpos($id, ':') === 0)) {
146
+			$id = substr($id, 1);
147
+		}
148
+		$id = str_replace(":", "/", $id);
149
+		return $conf['mediadir'] . '/' . $id;
150
+	}
151 151
 }
Please login to merge, or discard this patch.
admin/purge.php 1 patch
Indentation   +97 added lines, -97 removed lines patch added patch discarded remove patch
@@ -27,108 +27,108 @@
 block discarded – undo
27 27
  */
28 28
 class admin_plugin_openlayersmap_purge extends DokuWiki_Admin_Plugin
29 29
 {
30
-    /**
31
-     * (non-PHPdoc)
32
-     * @see DokuWiki_Admin_Plugin::getMenuSort()
33
-     */
34
-    public function getMenuSort(): int
35
-    {
36
-        return 800;
37
-    }
30
+	/**
31
+	 * (non-PHPdoc)
32
+	 * @see DokuWiki_Admin_Plugin::getMenuSort()
33
+	 */
34
+	public function getMenuSort(): int
35
+	{
36
+		return 800;
37
+	}
38 38
 
39
-    public function getMenuIcon(): string
40
-    {
41
-        $plugin = $this->getPluginName();
42
-        return DOKU_PLUGIN . $plugin . '/admin/purge.svg';
43
-    }
39
+	public function getMenuIcon(): string
40
+	{
41
+		$plugin = $this->getPluginName();
42
+		return DOKU_PLUGIN . $plugin . '/admin/purge.svg';
43
+	}
44 44
 
45
-    /**
46
-     * (non-PHPdoc)
47
-     * @see DokuWiki_Admin_Plugin::handle()
48
-     */
49
-    public function handle(): void
50
-    {
51
-        global $conf;
52
-        if (!isset($_REQUEST['continue']) || !checkSecurityToken()) {
53
-            return;
54
-        }
55
-        if (isset($_REQUEST['purgetiles'])) {
56
-            $path = $conf['cachedir'] . '/olmaptiles';
57
-            if ($this->rrmdir($path)) {
58
-                msg($this->getLang('admin_purged_tiles'));
59
-            }
60
-        }
61
-        if (isset($_REQUEST['purgemaps'])) {
62
-            $path = $conf['mediadir'] . '/olmapmaps';
63
-            if ($this->rrmdir($path)) {
64
-                msg($this->getLang('admin_purged_maps'));
65
-            }
66
-        }
67
-    }
45
+	/**
46
+	 * (non-PHPdoc)
47
+	 * @see DokuWiki_Admin_Plugin::handle()
48
+	 */
49
+	public function handle(): void
50
+	{
51
+		global $conf;
52
+		if (!isset($_REQUEST['continue']) || !checkSecurityToken()) {
53
+			return;
54
+		}
55
+		if (isset($_REQUEST['purgetiles'])) {
56
+			$path = $conf['cachedir'] . '/olmaptiles';
57
+			if ($this->rrmdir($path)) {
58
+				msg($this->getLang('admin_purged_tiles'));
59
+			}
60
+		}
61
+		if (isset($_REQUEST['purgemaps'])) {
62
+			$path = $conf['mediadir'] . '/olmapmaps';
63
+			if ($this->rrmdir($path)) {
64
+				msg($this->getLang('admin_purged_maps'));
65
+			}
66
+		}
67
+	}
68 68
 
69
-    /**
70
-     * Recursively delete the directory.
71
-     * @param string $sDir directory path
72
-     * @return boolean true when succesful
73
-     */
74
-    private function rrmdir(string $sDir): bool
75
-    {
76
-        if (is_dir($sDir)) {
77
-            Logger::debug('admin_plugin_openlayersmap_purge::rrmdir: recursively removing path: ', $sDir);
78
-            $sDir = rtrim($sDir, '/');
79
-            $oDir = dir($sDir);
80
-            while (($sFile = $oDir->read()) !== false) {
81
-                if ($sFile !== '.' && $sFile !== '..') {
82
-                    (!is_link("$sDir/$sFile") && is_dir("$sDir/$sFile")) ?
83
-                        $this->rrmdir("$sDir/$sFile") : unlink("$sDir/$sFile");
84
-                }
85
-            }
86
-            $oDir->close();
87
-            rmdir($sDir);
88
-            return true;
89
-        }
90
-        return false;
91
-    }
69
+	/**
70
+	 * Recursively delete the directory.
71
+	 * @param string $sDir directory path
72
+	 * @return boolean true when succesful
73
+	 */
74
+	private function rrmdir(string $sDir): bool
75
+	{
76
+		if (is_dir($sDir)) {
77
+			Logger::debug('admin_plugin_openlayersmap_purge::rrmdir: recursively removing path: ', $sDir);
78
+			$sDir = rtrim($sDir, '/');
79
+			$oDir = dir($sDir);
80
+			while (($sFile = $oDir->read()) !== false) {
81
+				if ($sFile !== '.' && $sFile !== '..') {
82
+					(!is_link("$sDir/$sFile") && is_dir("$sDir/$sFile")) ?
83
+						$this->rrmdir("$sDir/$sFile") : unlink("$sDir/$sFile");
84
+				}
85
+			}
86
+			$oDir->close();
87
+			rmdir($sDir);
88
+			return true;
89
+		}
90
+		return false;
91
+	}
92 92
 
93
-    /**
94
-     * (non-PHPdoc)
95
-     * @see DokuWiki_Admin_Plugin::html()
96
-     */
97
-    public function html(): void
98
-    {
99
-        echo $this->locale_xhtml('admin_intro');
100
-        $form = new Doku_Form(array('id' => 'olmap_purgeform', 'method' => 'post'));
101
-        $form->addHidden('continue', 'go');
93
+	/**
94
+	 * (non-PHPdoc)
95
+	 * @see DokuWiki_Admin_Plugin::html()
96
+	 */
97
+	public function html(): void
98
+	{
99
+		echo $this->locale_xhtml('admin_intro');
100
+		$form = new Doku_Form(array('id' => 'olmap_purgeform', 'method' => 'post'));
101
+		$form->addHidden('continue', 'go');
102 102
 
103
-        $form->startFieldset($this->getLang('admin_tiles'));
104
-        $form->addElement('<p>');
105
-        $form->addElement(
106
-            '<input id="purgetiles" name="purgetiles" type="checkbox" value="1" class="checkbox" />'
107
-        );
108
-        $form->addElement(
109
-            '<label for="purgetiles" class="label">' . $this->getLang('admin_purge_tiles')
110
-            . '</label>'
111
-        );
112
-        $form->addElement('</p>');
113
-        $form->endFieldset();
103
+		$form->startFieldset($this->getLang('admin_tiles'));
104
+		$form->addElement('<p>');
105
+		$form->addElement(
106
+			'<input id="purgetiles" name="purgetiles" type="checkbox" value="1" class="checkbox" />'
107
+		);
108
+		$form->addElement(
109
+			'<label for="purgetiles" class="label">' . $this->getLang('admin_purge_tiles')
110
+			. '</label>'
111
+		);
112
+		$form->addElement('</p>');
113
+		$form->endFieldset();
114 114
 
115
-        $form->startFieldset($this->getLang('admin_maps'));
116
-        $form->addElement('<p>');
117
-        $form->addElement('<input id="purgemaps" name="purgemaps" type="checkbox" value="1" class="checkbox" />');
118
-        $form->addElement(
119
-            '<label for="purgemaps" class="label">' . $this->getLang('admin_purge_maps') . '</label>'
120
-        );
121
-        $form->addElement('</p>');
122
-        $form->endFieldset();
115
+		$form->startFieldset($this->getLang('admin_maps'));
116
+		$form->addElement('<p>');
117
+		$form->addElement('<input id="purgemaps" name="purgemaps" type="checkbox" value="1" class="checkbox" />');
118
+		$form->addElement(
119
+			'<label for="purgemaps" class="label">' . $this->getLang('admin_purge_maps') . '</label>'
120
+		);
121
+		$form->addElement('</p>');
122
+		$form->endFieldset();
123 123
 
124
-        $form->addElement(
125
-            form_makeButton(
126
-                'submit',
127
-                'admin',
128
-                $this->getLang('admin_submit'),
129
-                array('accesskey' => 'p', 'title' => $this->getLang('admin_submit'))
130
-            )
131
-        );
132
-        $form->printForm();
133
-    }
124
+		$form->addElement(
125
+			form_makeButton(
126
+				'submit',
127
+				'admin',
128
+				$this->getLang('admin_submit'),
129
+				array('accesskey' => 'p', 'title' => $this->getLang('admin_submit'))
130
+			)
131
+		);
132
+		$form->printForm();
133
+	}
134 134
 }
Please login to merge, or discard this patch.
_test/general.test.php 1 patch
Indentation   +39 added lines, -39 removed lines patch added patch discarded remove patch
@@ -25,48 +25,48 @@
 block discarded – undo
25 25
 class general_plugin_openlayersmap_test extends DokuWikiTest
26 26
 {
27 27
 
28
-    protected $pluginsEnabled = array('openlayersmap', 'geophp');
28
+	protected $pluginsEnabled = array('openlayersmap', 'geophp');
29 29
 
30
-    /**
31
-     * Simple test to make sure the plugin.info.txt is in correct format.
32
-     */
33
-    final public function test_plugininfo(): void
34
-    {
35
-        $file = __DIR__ . '/../plugin.info.txt';
36
-        self::assertFileExists($file);
30
+	/**
31
+	 * Simple test to make sure the plugin.info.txt is in correct format.
32
+	 */
33
+	final public function test_plugininfo(): void
34
+	{
35
+		$file = __DIR__ . '/../plugin.info.txt';
36
+		self::assertFileExists($file);
37 37
 
38
-        $info = confToHash($file);
38
+		$info = confToHash($file);
39 39
 
40
-        self::assertArrayHasKey('base', $info);
41
-        self::assertArrayHasKey('author', $info);
42
-        self::assertArrayHasKey('email', $info);
43
-        self::assertArrayHasKey('date', $info);
44
-        self::assertArrayHasKey('name', $info);
45
-        self::assertArrayHasKey('desc', $info);
46
-        self::assertArrayHasKey('url', $info);
40
+		self::assertArrayHasKey('base', $info);
41
+		self::assertArrayHasKey('author', $info);
42
+		self::assertArrayHasKey('email', $info);
43
+		self::assertArrayHasKey('date', $info);
44
+		self::assertArrayHasKey('name', $info);
45
+		self::assertArrayHasKey('desc', $info);
46
+		self::assertArrayHasKey('url', $info);
47 47
 
48
-        self::assertEquals('openlayersmap', $info['base']);
49
-        self::assertRegExp('/^https?:\/\//', $info['url']);
50
-        self::assertTrue(mail_isvalid($info['email']));
51
-        self::assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
52
-        self::assertTrue(false !== strtotime($info['date']));
53
-    }
48
+		self::assertEquals('openlayersmap', $info['base']);
49
+		self::assertRegExp('/^https?:\/\//', $info['url']);
50
+		self::assertTrue(mail_isvalid($info['email']));
51
+		self::assertRegExp('/^\d\d\d\d-\d\d-\d\d$/', $info['date']);
52
+		self::assertTrue(false !== strtotime($info['date']));
53
+	}
54 54
 
55
-    /**
56
-     * test if plugin is loaded.
57
-     */
58
-    final public function test_plugin_openlayersmap_isloaded(): void
59
-    {
60
-        global $plugin_controller;
61
-        self::assertContains(
62
-            'geophp',
63
-            $plugin_controller->getList(),
64
-            "geophp plugin is loaded"
65
-        );
66
-        self::assertContains(
67
-            'openlayersmap',
68
-            $plugin_controller->getList(),
69
-            "openlayersmap plugin is loaded"
70
-        );
71
-    }
55
+	/**
56
+	 * test if plugin is loaded.
57
+	 */
58
+	final public function test_plugin_openlayersmap_isloaded(): void
59
+	{
60
+		global $plugin_controller;
61
+		self::assertContains(
62
+			'geophp',
63
+			$plugin_controller->getList(),
64
+			"geophp plugin is loaded"
65
+		);
66
+		self::assertContains(
67
+			'openlayersmap',
68
+			$plugin_controller->getList(),
69
+			"openlayersmap plugin is loaded"
70
+		);
71
+	}
72 72
 }
Please login to merge, or discard this patch.
syntax/osmlayer.php 1 patch
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -22,110 +22,110 @@
 block discarded – undo
22 22
  */
23 23
 class syntax_plugin_openlayersmap_osmlayer extends DokuWiki_Syntax_Plugin
24 24
 {
25
-    private $dflt = array(
26
-        'id'          => 'olmap',
27
-        'name'        => '',
28
-        'url'         => '',
29
-        'opacity'     => 0.8,
30
-        'attribution' => '',
31
-        'visible'     => false,
32
-        'cors'        => null
33
-    );
25
+	private $dflt = array(
26
+		'id'          => 'olmap',
27
+		'name'        => '',
28
+		'url'         => '',
29
+		'opacity'     => 0.8,
30
+		'attribution' => '',
31
+		'visible'     => false,
32
+		'cors'        => null
33
+	);
34 34
 
35
-    /**
36
-     * (non-PHPdoc)
37
-     *
38
-     * @see DokuWiki_Syntax_Plugin::getPType()
39
-     */
40
-    public function getPType(): string
41
-    {
42
-        return 'block';
43
-    }
35
+	/**
36
+	 * (non-PHPdoc)
37
+	 *
38
+	 * @see DokuWiki_Syntax_Plugin::getPType()
39
+	 */
40
+	public function getPType(): string
41
+	{
42
+		return 'block';
43
+	}
44 44
 
45
-    /**
46
-     * (non-PHPdoc)
47
-     *
48
-     * @see DokuWiki_Syntax_Plugin::getType()
49
-     */
50
-    public function getType(): string
51
-    {
52
-        // return 'FIXME: container|baseonly|formatting|substition|protected|disabled|paragraphs';
53
-        return 'baseonly';
54
-    }
45
+	/**
46
+	 * (non-PHPdoc)
47
+	 *
48
+	 * @see DokuWiki_Syntax_Plugin::getType()
49
+	 */
50
+	public function getType(): string
51
+	{
52
+		// return 'FIXME: container|baseonly|formatting|substition|protected|disabled|paragraphs';
53
+		return 'baseonly';
54
+	}
55 55
 
56
-    /**
57
-     * (non-PHPdoc)
58
-     *
59
-     * @see Doku_Parser_Mode::getSort()
60
-     */
61
-    public function getSort(): int
62
-    {
63
-        return 902;
64
-    }
56
+	/**
57
+	 * (non-PHPdoc)
58
+	 *
59
+	 * @see Doku_Parser_Mode::getSort()
60
+	 */
61
+	public function getSort(): int
62
+	{
63
+		return 902;
64
+	}
65 65
 
66
-    /**
67
-     * Connect to our special pattern.
68
-     *
69
-     * @see Doku_Parser_Mode::connectTo()
70
-     */
71
-    public function connectTo($mode): void
72
-    {
73
-        // look for: <olmap_osmlayer id="olmap" name="sport" url="http://tiles.openseamap.org/sport/${z}/${x}/${y}.png"
74
-        // visible="false" opacity=0.6 attribution="Some attribution"></olmap_osmlayer>
75
-        $this->Lexer->addSpecialPattern(
76
-            '<olmap_osmlayer ?[^>\n]*>.*?</olmap_osmlayer>',
77
-            $mode,
78
-            'plugin_openlayersmap_osmlayer'
79
-        );
80
-    }
66
+	/**
67
+	 * Connect to our special pattern.
68
+	 *
69
+	 * @see Doku_Parser_Mode::connectTo()
70
+	 */
71
+	public function connectTo($mode): void
72
+	{
73
+		// look for: <olmap_osmlayer id="olmap" name="sport" url="http://tiles.openseamap.org/sport/${z}/${x}/${y}.png"
74
+		// visible="false" opacity=0.6 attribution="Some attribution"></olmap_osmlayer>
75
+		$this->Lexer->addSpecialPattern(
76
+			'<olmap_osmlayer ?[^>\n]*>.*?</olmap_osmlayer>',
77
+			$mode,
78
+			'plugin_openlayersmap_osmlayer'
79
+		);
80
+	}
81 81
 
82
-    /**
83
-     * (non-PHPdoc)
84
-     *
85
-     * @see DokuWiki_Syntax_Plugin::handle()
86
-     */
87
-    public function handle($match, $state, $pos, Doku_Handler $handler): array
88
-    {
89
-        $param = array();
90
-        $data  = $this->dflt;
82
+	/**
83
+	 * (non-PHPdoc)
84
+	 *
85
+	 * @see DokuWiki_Syntax_Plugin::handle()
86
+	 */
87
+	public function handle($match, $state, $pos, Doku_Handler $handler): array
88
+	{
89
+		$param = array();
90
+		$data  = $this->dflt;
91 91
 
92
-        preg_match_all('/(\w*)="(.*?)"/us', $match, $param, PREG_SET_ORDER);
92
+		preg_match_all('/(\w*)="(.*?)"/us', $match, $param, PREG_SET_ORDER);
93 93
 
94
-        foreach ($param as $kvpair) {
95
-            list ($matched, $key, $val) = $kvpair;
96
-            if (isset ($data [$key])) {
97
-                $key         = strtolower($key);
98
-                $data [$key] = $val;
99
-            }
100
-        }
101
-        // dbglog($data,'syntax_plugin_overlayer::handle: parsed data is:');
102
-        return $data;
103
-    }
94
+		foreach ($param as $kvpair) {
95
+			list ($matched, $key, $val) = $kvpair;
96
+			if (isset ($data [$key])) {
97
+				$key         = strtolower($key);
98
+				$data [$key] = $val;
99
+			}
100
+		}
101
+		// dbglog($data,'syntax_plugin_overlayer::handle: parsed data is:');
102
+		return $data;
103
+	}
104 104
 
105
-    /**
106
-     * (non-PHPdoc)
107
-     *
108
-     * @see DokuWiki_Syntax_Plugin::render()
109
-     */
110
-    public function render($format, Doku_Renderer $renderer, $data): bool
111
-    {
112
-        if ($format !== 'xhtml') {
113
-            return false;
114
-        }
105
+	/**
106
+	 * (non-PHPdoc)
107
+	 *
108
+	 * @see DokuWiki_Syntax_Plugin::render()
109
+	 */
110
+	public function render($format, Doku_Renderer $renderer, $data): bool
111
+	{
112
+		if ($format !== 'xhtml') {
113
+			return false;
114
+		}
115 115
 
116
-        // incremented for each olmap_osmlayer tag in the page source
117
-        static $overlaynumber = 0;
116
+		// incremented for each olmap_osmlayer tag in the page source
117
+		static $overlaynumber = 0;
118 118
 
119
-        list ($id, $url, $name, $visible) = $data;
120
-        $renderer->doc .= DOKU_LF . '<script defer="defer" src="data:text/javascript;base64,';
121
-        $str           = '{';
122
-        foreach ($data as $key => $val) {
123
-            $str .= "'" . $key . "' : '" . $val . "',";
124
-        }
125
-        $str           .= '"type":"osm"}';
126
-        $renderer->doc .= base64_encode("olMapOverlays['osm" . $overlaynumber . "'] = " . $str . ";")
127
-            . '"></script>';
128
-        $overlaynumber++;
129
-        return true;
130
-    }
119
+		list ($id, $url, $name, $visible) = $data;
120
+		$renderer->doc .= DOKU_LF . '<script defer="defer" src="data:text/javascript;base64,';
121
+		$str           = '{';
122
+		foreach ($data as $key => $val) {
123
+			$str .= "'" . $key . "' : '" . $val . "',";
124
+		}
125
+		$str           .= '"type":"osm"}';
126
+		$renderer->doc .= base64_encode("olMapOverlays['osm" . $overlaynumber . "'] = " . $str . ";")
127
+			. '"></script>';
128
+		$overlaynumber++;
129
+		return true;
130
+	}
131 131
 }
Please login to merge, or discard this patch.
syntax/agslayer.php 1 patch
Indentation   +100 added lines, -100 removed lines patch added patch discarded remove patch
@@ -22,114 +22,114 @@
 block discarded – undo
22 22
  */
23 23
 class syntax_plugin_openlayersmap_agslayer extends DokuWiki_Syntax_Plugin
24 24
 {
25
-    private $dflt = array(
26
-        'id'          => 'olmap',
27
-        'name'        => '',
28
-        'url'         => '',
29
-        'opacity'     => 0.8,
30
-        'attribution' => '',
31
-        'visible'     => false,
32
-        'layers'      => '',
33
-        'format'      => 'png',
34
-        'transparent' => 'true'
35
-    );
25
+	private $dflt = array(
26
+		'id'          => 'olmap',
27
+		'name'        => '',
28
+		'url'         => '',
29
+		'opacity'     => 0.8,
30
+		'attribution' => '',
31
+		'visible'     => false,
32
+		'layers'      => '',
33
+		'format'      => 'png',
34
+		'transparent' => 'true'
35
+	);
36 36
 
37
-    /**
38
-     * (non-PHPdoc)
39
-     *
40
-     * @see DokuWiki_Syntax_Plugin::getPType()
41
-     */
42
-    public function getPType(): string
43
-    {
44
-        return 'block';
45
-    }
37
+	/**
38
+	 * (non-PHPdoc)
39
+	 *
40
+	 * @see DokuWiki_Syntax_Plugin::getPType()
41
+	 */
42
+	public function getPType(): string
43
+	{
44
+		return 'block';
45
+	}
46 46
 
47
-    /**
48
-     * (non-PHPdoc)
49
-     *
50
-     * @see DokuWiki_Syntax_Plugin::getType()
51
-     */
52
-    public function getType(): string
53
-    {
54
-        // return 'FIXME: container|baseonly|formatting|substition|protected|disabled|paragraphs';
55
-        return 'baseonly';
56
-    }
47
+	/**
48
+	 * (non-PHPdoc)
49
+	 *
50
+	 * @see DokuWiki_Syntax_Plugin::getType()
51
+	 */
52
+	public function getType(): string
53
+	{
54
+		// return 'FIXME: container|baseonly|formatting|substition|protected|disabled|paragraphs';
55
+		return 'baseonly';
56
+	}
57 57
 
58
-    /**
59
-     * (non-PHPdoc)
60
-     *
61
-     * @see Doku_Parser_Mode::getSort()
62
-     */
63
-    public function getSort(): int
64
-    {
65
-        return 904;
66
-    }
58
+	/**
59
+	 * (non-PHPdoc)
60
+	 *
61
+	 * @see Doku_Parser_Mode::getSort()
62
+	 */
63
+	public function getSort(): int
64
+	{
65
+		return 904;
66
+	}
67 67
 
68
-    /**
69
-     * Connect to our special pattern.
70
-     *
71
-     * @see Doku_Parser_Mode::connectTo()
72
-     */
73
-    public function connectTo($mode): void
74
-    {
75
-        // look for: <olmap_agslayer id="olmap" name="cloud"
76
-        // url="http://geoservices2.wallonie.be/arcgis/rest/services/APP_KAYAK/KAYAK/MapServer/export"
77
-        // attribution="wallonie.be" visible="true" layers="show:0,1,2,3,4,7"></olmap_agslayer>
78
-        // sample:
79
-        // http://geoservices2.wallonie.be/arcgis/rest/services/APP_KAYAK/KAYAK/MapServer/export?LAYERS=show%3A0%2C1%2C2%2C3%2C4%2C7&TRANSPARENT=true&FORMAT=png&BBOX=643294.029959%2C6467184.088252%2C645740.014863%2C6469630.073157&SIZE=256%2C256&F=html&BBOXSR=3857&IMAGESR=3857
80
-        $this->Lexer->addSpecialPattern(
81
-            '<olmap_agslayer ?[^>\n]*>.*?</olmap_agslayer>',
82
-            $mode,
83
-            'plugin_openlayersmap_agslayer'
84
-        );
85
-    }
68
+	/**
69
+	 * Connect to our special pattern.
70
+	 *
71
+	 * @see Doku_Parser_Mode::connectTo()
72
+	 */
73
+	public function connectTo($mode): void
74
+	{
75
+		// look for: <olmap_agslayer id="olmap" name="cloud"
76
+		// url="http://geoservices2.wallonie.be/arcgis/rest/services/APP_KAYAK/KAYAK/MapServer/export"
77
+		// attribution="wallonie.be" visible="true" layers="show:0,1,2,3,4,7"></olmap_agslayer>
78
+		// sample:
79
+		// http://geoservices2.wallonie.be/arcgis/rest/services/APP_KAYAK/KAYAK/MapServer/export?LAYERS=show%3A0%2C1%2C2%2C3%2C4%2C7&TRANSPARENT=true&FORMAT=png&BBOX=643294.029959%2C6467184.088252%2C645740.014863%2C6469630.073157&SIZE=256%2C256&F=html&BBOXSR=3857&IMAGESR=3857
80
+		$this->Lexer->addSpecialPattern(
81
+			'<olmap_agslayer ?[^>\n]*>.*?</olmap_agslayer>',
82
+			$mode,
83
+			'plugin_openlayersmap_agslayer'
84
+		);
85
+	}
86 86
 
87
-    /**
88
-     * (non-PHPdoc)
89
-     *
90
-     * @see DokuWiki_Syntax_Plugin::handle()
91
-     */
92
-    public function handle($match, $state, $pos, Doku_Handler $handler): array
93
-    {
94
-        $param = array();
95
-        $data  = $this->dflt;
87
+	/**
88
+	 * (non-PHPdoc)
89
+	 *
90
+	 * @see DokuWiki_Syntax_Plugin::handle()
91
+	 */
92
+	public function handle($match, $state, $pos, Doku_Handler $handler): array
93
+	{
94
+		$param = array();
95
+		$data  = $this->dflt;
96 96
 
97
-        preg_match_all('/(\w*)="(.*?)"/us', $match, $param, PREG_SET_ORDER);
97
+		preg_match_all('/(\w*)="(.*?)"/us', $match, $param, PREG_SET_ORDER);
98 98
 
99
-        foreach ($param as $kvpair) {
100
-            list ($matched, $key, $val) = $kvpair;
101
-            if (isset ($data [$key])) {
102
-                $key         = strtolower($key);
103
-                $data [$key] = $val;
104
-            }
105
-        }
106
-        return $data;
107
-    }
99
+		foreach ($param as $kvpair) {
100
+			list ($matched, $key, $val) = $kvpair;
101
+			if (isset ($data [$key])) {
102
+				$key         = strtolower($key);
103
+				$data [$key] = $val;
104
+			}
105
+		}
106
+		return $data;
107
+	}
108 108
 
109
-    /**
110
-     * (non-PHPdoc)
111
-     *
112
-     * @see DokuWiki_Syntax_Plugin::render()
113
-     */
114
-    public function render($format, Doku_Renderer $renderer, $data): bool
115
-    {
116
-        if ($format !== 'xhtml') {
117
-            return false;
118
-        }
109
+	/**
110
+	 * (non-PHPdoc)
111
+	 *
112
+	 * @see DokuWiki_Syntax_Plugin::render()
113
+	 */
114
+	public function render($format, Doku_Renderer $renderer, $data): bool
115
+	{
116
+		if ($format !== 'xhtml') {
117
+			return false;
118
+		}
119 119
 
120
-        // incremented for each olmap_agslayer tag in the page source
121
-        static $overlaynumber = 0;
120
+		// incremented for each olmap_agslayer tag in the page source
121
+		static $overlaynumber = 0;
122 122
 
123
-        list ($id, $url, $name, $visible) = $data;
124
-        $renderer->doc .= DOKU_LF . '<script defer="defer" src="data:text/javascript;base64,';
125
-        $str           = '{';
126
-        foreach ($data as $key => $val) {
127
-            $str .= "'" . $key . "' : '" . $val . "',";
128
-        }
129
-        $str           .= "'type':'ags'}";
130
-        $renderer->doc .= base64_encode("olMapOverlays['ags" . $overlaynumber . "'] = " . $str . ";")
131
-            . '"></script>';
132
-        $overlaynumber++;
133
-        return true;
134
-    }
123
+		list ($id, $url, $name, $visible) = $data;
124
+		$renderer->doc .= DOKU_LF . '<script defer="defer" src="data:text/javascript;base64,';
125
+		$str           = '{';
126
+		foreach ($data as $key => $val) {
127
+			$str .= "'" . $key . "' : '" . $val . "',";
128
+		}
129
+		$str           .= "'type':'ags'}";
130
+		$renderer->doc .= base64_encode("olMapOverlays['ags" . $overlaynumber . "'] = " . $str . ";")
131
+			. '"></script>';
132
+		$overlaynumber++;
133
+		return true;
134
+	}
135 135
 }
Please login to merge, or discard this patch.
syntax/wmslayer.php 1 patch
Indentation   +99 added lines, -99 removed lines patch added patch discarded remove patch
@@ -22,113 +22,113 @@
 block discarded – undo
22 22
  */
23 23
 class syntax_plugin_openlayersmap_wmslayer extends DokuWiki_Syntax_Plugin
24 24
 {
25
-    private $dflt = array(
26
-        'id'          => 'olmap',
27
-        'name'        => '',
28
-        'url'         => '',
29
-        'opacity'     => 0.8,
30
-        'attribution' => '',
31
-        'visible'     => false,
32
-        'layers'      => '',
33
-        'version'     => '1.3.0',
34
-        'format'      => 'image/png',
35
-        'transparent' => 'true'
36
-    );
25
+	private $dflt = array(
26
+		'id'          => 'olmap',
27
+		'name'        => '',
28
+		'url'         => '',
29
+		'opacity'     => 0.8,
30
+		'attribution' => '',
31
+		'visible'     => false,
32
+		'layers'      => '',
33
+		'version'     => '1.3.0',
34
+		'format'      => 'image/png',
35
+		'transparent' => 'true'
36
+	);
37 37
 
38
-    /**
39
-     * (non-PHPdoc)
40
-     *
41
-     * @see DokuWiki_Syntax_Plugin::getPType()
42
-     */
43
-    public function getPType(): string
44
-    {
45
-        return 'block';
46
-    }
38
+	/**
39
+	 * (non-PHPdoc)
40
+	 *
41
+	 * @see DokuWiki_Syntax_Plugin::getPType()
42
+	 */
43
+	public function getPType(): string
44
+	{
45
+		return 'block';
46
+	}
47 47
 
48
-    /**
49
-     * (non-PHPdoc)
50
-     *
51
-     * @see DokuWiki_Syntax_Plugin::getType()
52
-     */
53
-    public function getType(): string
54
-    {
55
-        // return 'FIXME: container|baseonly|formatting|substition|protected|disabled|paragraphs';
56
-        return 'baseonly';
57
-    }
48
+	/**
49
+	 * (non-PHPdoc)
50
+	 *
51
+	 * @see DokuWiki_Syntax_Plugin::getType()
52
+	 */
53
+	public function getType(): string
54
+	{
55
+		// return 'FIXME: container|baseonly|formatting|substition|protected|disabled|paragraphs';
56
+		return 'baseonly';
57
+	}
58 58
 
59
-    /**
60
-     * (non-PHPdoc)
61
-     *
62
-     * @see Doku_Parser_Mode::getSort()
63
-     */
64
-    public function getSort(): int
65
-    {
66
-        return 902;
67
-    }
59
+	/**
60
+	 * (non-PHPdoc)
61
+	 *
62
+	 * @see Doku_Parser_Mode::getSort()
63
+	 */
64
+	public function getSort(): int
65
+	{
66
+		return 902;
67
+	}
68 68
 
69
-    /**
70
-     * Connect to our special pattern.
71
-     *
72
-     * @see Doku_Parser_Mode::connectTo()
73
-     */
74
-    public function connectTo($mode): void
75
-    {
76
-        // look for: <olmap_wmslayer id="olmap" name="cloud" url="http://openweathermap.org/t/tile.cgi?SERVICE=WMS"
77
-        // attribution="OpenWeatherMap" visible="true" layers="GLBETA_PR"></olmap_wmslayer>
78
-        $this->Lexer->addSpecialPattern(
79
-            '<olmap_wmslayer ?[^>\n]*>.*?</olmap_wmslayer>',
80
-            $mode,
81
-            'plugin_openlayersmap_wmslayer'
82
-        );
83
-    }
69
+	/**
70
+	 * Connect to our special pattern.
71
+	 *
72
+	 * @see Doku_Parser_Mode::connectTo()
73
+	 */
74
+	public function connectTo($mode): void
75
+	{
76
+		// look for: <olmap_wmslayer id="olmap" name="cloud" url="http://openweathermap.org/t/tile.cgi?SERVICE=WMS"
77
+		// attribution="OpenWeatherMap" visible="true" layers="GLBETA_PR"></olmap_wmslayer>
78
+		$this->Lexer->addSpecialPattern(
79
+			'<olmap_wmslayer ?[^>\n]*>.*?</olmap_wmslayer>',
80
+			$mode,
81
+			'plugin_openlayersmap_wmslayer'
82
+		);
83
+	}
84 84
 
85
-    /**
86
-     * (non-PHPdoc)
87
-     *
88
-     * @see DokuWiki_Syntax_Plugin::handle()
89
-     */
90
-    public function handle($match, $state, $pos, Doku_Handler $handler): array
91
-    {
92
-        $param = array();
93
-        $data  = $this->dflt;
85
+	/**
86
+	 * (non-PHPdoc)
87
+	 *
88
+	 * @see DokuWiki_Syntax_Plugin::handle()
89
+	 */
90
+	public function handle($match, $state, $pos, Doku_Handler $handler): array
91
+	{
92
+		$param = array();
93
+		$data  = $this->dflt;
94 94
 
95
-        preg_match_all('/(\w*)="(.*?)"/us', $match, $param, PREG_SET_ORDER);
95
+		preg_match_all('/(\w*)="(.*?)"/us', $match, $param, PREG_SET_ORDER);
96 96
 
97
-        foreach ($param as $kvpair) {
98
-            list ($matched, $key, $val) = $kvpair;
99
-            if (isset ($data [$key])) {
100
-                $key         = strtolower($key);
101
-                $data [$key] = $val;
102
-            }
103
-        }
104
-        // dbglog($data,'syntax_plugin_overlayer::handle: parsed data is:');
105
-        return $data;
106
-    }
97
+		foreach ($param as $kvpair) {
98
+			list ($matched, $key, $val) = $kvpair;
99
+			if (isset ($data [$key])) {
100
+				$key         = strtolower($key);
101
+				$data [$key] = $val;
102
+			}
103
+		}
104
+		// dbglog($data,'syntax_plugin_overlayer::handle: parsed data is:');
105
+		return $data;
106
+	}
107 107
 
108
-    /**
109
-     * (non-PHPdoc)
110
-     *
111
-     * @see DokuWiki_Syntax_Plugin::render()
112
-     */
113
-    public function render($format, Doku_Renderer $renderer, $data): bool
114
-    {
115
-        if ($format !== 'xhtml') {
116
-            return false;
117
-        }
108
+	/**
109
+	 * (non-PHPdoc)
110
+	 *
111
+	 * @see DokuWiki_Syntax_Plugin::render()
112
+	 */
113
+	public function render($format, Doku_Renderer $renderer, $data): bool
114
+	{
115
+		if ($format !== 'xhtml') {
116
+			return false;
117
+		}
118 118
 
119
-        // incremented for each olmap_wmslayer tag in the page source
120
-        static $overlaynumber = 0;
119
+		// incremented for each olmap_wmslayer tag in the page source
120
+		static $overlaynumber = 0;
121 121
 
122
-        list ($id, $url, $name, $visible) = $data;
123
-        $renderer->doc .= DOKU_LF . '<script defer="defer" src="data:text/javascript;base64,';
124
-        $str           = '{';
125
-        foreach ($data as $key => $val) {
126
-            $str .= "'" . $key . "' : '" . $val . "',";
127
-        }
128
-        $str           .= "'type':'wms'}";
129
-        $renderer->doc .= base64_encode("olMapOverlays['wms" . $overlaynumber . "'] = " . $str . ";")
130
-            . '"></script>';
131
-        $overlaynumber++;
132
-        return true;
133
-    }
122
+		list ($id, $url, $name, $visible) = $data;
123
+		$renderer->doc .= DOKU_LF . '<script defer="defer" src="data:text/javascript;base64,';
124
+		$str           = '{';
125
+		foreach ($data as $key => $val) {
126
+			$str .= "'" . $key . "' : '" . $val . "',";
127
+		}
128
+		$str           .= "'type':'wms'}";
129
+		$renderer->doc .= base64_encode("olMapOverlays['wms" . $overlaynumber . "'] = " . $str . ";")
130
+			. '"></script>';
131
+		$overlaynumber++;
132
+		return true;
133
+	}
134 134
 }
135 135
\ No newline at end of file
Please login to merge, or discard this patch.
StaticMap.php 1 patch
Indentation   +907 added lines, -907 removed lines patch added patch discarded remove patch
@@ -34,911 +34,911 @@
 block discarded – undo
34 34
 class StaticMap
35 35
 {
36 36
 
37
-    // the final output
38
-    private $tileSize = 256;
39
-    private $tileInfo = array(
40
-        // OSM sources
41
-        'openstreetmap' => array(
42
-            'txt'  => '(c) OpenStreetMap data/ODbl',
43
-            'logo' => 'osm_logo.png',
44
-            'url'  => 'https://tile.openstreetmap.org/{Z}/{X}/{Y}.png'
45
-        ),
46
-        // OCM sources
47
-        'cycle'         => array(
48
-            'txt'  => '(c) Thunderforest maps',
49
-            'logo' => 'tf_logo.png',
50
-            'url'  => 'https://tile.thunderforest.com/cycle/{Z}/{X}/{Y}.png'
51
-        ),
52
-        'transport'     => array(
53
-            'txt'  => '(c) Thunderforest maps',
54
-            'logo' => 'tf_logo.png',
55
-            'url'  => 'https://tile.thunderforest.com/transport/{Z}/{X}/{Y}.png'
56
-        ),
57
-        'landscape'     => array(
58
-            'txt'  => '(c) Thunderforest maps',
59
-            'logo' => 'tf_logo.png',
60
-            'url'  => 'https://tile.thunderforest.com/landscape/{Z}/{X}/{Y}.png'
61
-        ),
62
-        'outdoors'      => array(
63
-            'txt'  => '(c) Thunderforest maps',
64
-            'logo' => 'tf_logo.png',
65
-            'url'  => 'https://tile.thunderforest.com/outdoors/{Z}/{X}/{Y}.png'
66
-        ),
67
-        'toner-lite'    => array(
68
-            'txt'  => 'Stamen tiles',
69
-            'logo' => 'stamen.png',
70
-            'url'  => 'https://stamen-tiles.a.ssl.fastly.net/toner/{Z}/{X}/{Y}.png'
71
-        ),
72
-        'terrain'       => array(
73
-            'txt'  => 'Stamen tiles',
74
-            'logo' => 'stamen.png',
75
-            'url'  => 'https://stamen-tiles.a.ssl.fastly.net/terrain/{Z}/{X}/{Y}.jpg'
76
-        )
77
-        //,
78
-        // 'piste'=>array(
79
-        // 'txt'=>'OpenPisteMap tiles',
80
-        // 'logo'=>'piste_logo.png',
81
-        // 'url'=>''),
82
-        // 'sea'=>array(
83
-        // 'txt'=>'OpenSeaMap tiles',
84
-        // 'logo'=>'sea_logo.png',
85
-        // 'url'=>''),
86
-        // H&B sources
87
-        //          'hikeandbike' => array (
88
-        //                  'txt' => 'Hike & Bike Map',
89
-        //                  'logo' => 'hnb_logo.png',
90
-        //                  //'url' => 'http://toolserver.org/tiles/hikebike/{Z}/{X}/{Y}.png'
91
-        //                  //moved to: https://www.toolserver.org/tiles/hikebike/12/2105/1388.png
92
-        //                  'url' => 'http://c.tiles.wmflabs.org/hikebike/{Z}/{X}/{Y}.png'
93
-        //          )
94
-    );
95
-    private $tileDefaultSrc = 'openstreetmap';
96
-
97
-    // set up markers
98
-    private $markerPrototypes = array(
99
-        // found at http://www.mapito.net/map-marker-icons.html
100
-        // these are 17x19 px with a pointer at the bottom left
101
-        'lightblue' => array(
102
-            'regex'        => '/^lightblue([0-9]+)$/',
103
-            'extension'    => '.png',
104
-            'shadow'       => false,
105
-            'offsetImage'  => '0,-19',
106
-            'offsetShadow' => false
107
-        ),
108
-        // openlayers std markers are 21x25px with shadow
109
-        'ol-marker' => array(
110
-            'regex'        => '/^marker(|-blue|-gold|-green|-red)+$/',
111
-            'extension'    => '.png',
112
-            'shadow'       => 'marker_shadow.png',
113
-            'offsetImage'  => '-10,-25',
114
-            'offsetShadow' => '-1,-13'
115
-        ),
116
-        // these are 16x16 px
117
-        'ww_icon'   => array(
118
-            'regex'        => '/ww_\S+$/',
119
-            'extension'    => '.png',
120
-            'shadow'       => false,
121
-            'offsetImage'  => '-8,-8',
122
-            'offsetShadow' => false
123
-        ),
124
-        // assume these are 16x16 px
125
-        'rest'      => array(
126
-            'regex'        => '/^(?!lightblue([0-9]+)$)(?!(ww_\S+$))(?!marker(|-blue|-gold|-green|-red)+$)(.*)/',
127
-            'extension'    => '.png',
128
-            'shadow'       => 'marker_shadow.png',
129
-            'offsetImage'  => '-8,-8',
130
-            'offsetShadow' => '-1,-1'
131
-        )
132
-    );
133
-    private $centerX;
134
-    private $centerY;
135
-    private $offsetX;
136
-    private $offsetY;
137
-    private $image;
138
-    private $zoom;
139
-    private $lat;
140
-    private $lon;
141
-    private $width;
142
-    private $height;
143
-    private $markers;
144
-    private $maptype;
145
-    private $kmlFileName;
146
-    private $gpxFileName;
147
-    private $geojsonFileName;
148
-    private $autoZoomExtent;
149
-    private $apikey;
150
-    private $tileCacheBaseDir;
151
-    private $mapCacheBaseDir;
152
-    private $mediaBaseDir;
153
-    private $useTileCache;
154
-    private $mapCacheID = '';
155
-    private $mapCacheFile = '';
156
-    private $mapCacheExtension = 'png';
157
-
158
-    /**
159
-     * Constructor.
160
-     *
161
-     * @param float  $lat
162
-     *            Latitude (x) of center of map
163
-     * @param float  $lon
164
-     *            Longitude (y) of center of map
165
-     * @param int    $zoom
166
-     *            Zoomlevel
167
-     * @param int    $width
168
-     *            Width in pixels
169
-     * @param int    $height
170
-     *            Height in pixels
171
-     * @param string $maptype
172
-     *            Name of the map
173
-     * @param array  $markers
174
-     *            array of markers
175
-     * @param string $gpx
176
-     *            GPX filename
177
-     * @param string $kml
178
-     *            KML filename
179
-     * @param string $geojson
180
-     * @param string $mediaDir
181
-     *            Directory to store/cache maps
182
-     * @param string $tileCacheBaseDir
183
-     *            Directory to cache map tiles
184
-     * @param bool   $autoZoomExtent
185
-     *            Wheter or not to override zoom/lat/lon and zoom to the extent of gpx/kml and markers
186
-     * @param string $apikey
187
-     */
188
-    public function __construct(
189
-        float $lat,
190
-        float $lon,
191
-        int $zoom,
192
-        int $width,
193
-        int $height,
194
-        string $maptype,
195
-        array $markers,
196
-        string $gpx,
197
-        string $kml,
198
-        string $geojson,
199
-        string $mediaDir,
200
-        string $tileCacheBaseDir,
201
-        bool $autoZoomExtent = true,
202
-        string $apikey = ''
203
-    ) {
204
-        $this->zoom   = $zoom;
205
-        $this->lat    = $lat;
206
-        $this->lon    = $lon;
207
-        $this->width  = $width;
208
-        $this->height = $height;
209
-        // validate + set maptype
210
-        $this->maptype = $this->tileDefaultSrc;
211
-        if (array_key_exists($maptype, $this->tileInfo)) {
212
-            $this->maptype = $maptype;
213
-        }
214
-        $this->markers          = $markers;
215
-        $this->kmlFileName      = $kml;
216
-        $this->gpxFileName      = $gpx;
217
-        $this->geojsonFileName  = $geojson;
218
-        $this->mediaBaseDir     = $mediaDir;
219
-        $this->tileCacheBaseDir = $tileCacheBaseDir . '/olmaptiles';
220
-        $this->useTileCache     = $this->tileCacheBaseDir !== '';
221
-        $this->mapCacheBaseDir  = $mediaDir . '/olmapmaps';
222
-        $this->autoZoomExtent   = $autoZoomExtent;
223
-        $this->apikey           = $apikey;
224
-    }
225
-
226
-    /**
227
-     * get the map, this may return a reference to a cached copy.
228
-     *
229
-     * @return string url relative to media dir
230
-     */
231
-    public function getMap(): string
232
-    {
233
-        try {
234
-            if ($this->autoZoomExtent) {
235
-                $this->autoZoom();
236
-            }
237
-        } catch (Exception $e) {
238
-            Logger::debug($e);
239
-        }
240
-
241
-        // use map cache, so check cache for map
242
-        if (!$this->checkMapCache()) {
243
-            // map is not in cache, needs to be build
244
-            $this->makeMap();
245
-            $this->mkdirRecursive(dirname($this->mapCacheIDToFilename()), 0777);
246
-            imagepng($this->image, $this->mapCacheIDToFilename(), 9);
247
-        }
248
-        $doc = $this->mapCacheIDToFilename();
249
-        // make url relative to media dir
250
-        return str_replace($this->mediaBaseDir, '', $doc);
251
-    }
252
-
253
-    /**
254
-     * Calculate the lat/lon/zoom values to make sure that all of the markers and gpx/kml are on the map.
255
-     * can throw an error like
256
-     * "Fatal error: Uncaught Exception: Cannot create a collection with non-geometries in
257
-     * D:\www\wild-water.nl\www\dokuwiki\lib\plugins\geophp\geoPHP\lib\geometry\Collection.class.php:29"
258
-     *
259
-     * @param float $paddingFactor
260
-     *            buffer constant to enlarge (>1.0) the zoom level
261
-     * @throws Exception
262
-     */
263
-    private function autoZoom(float $paddingFactor = 1.0): void
264
-    {
265
-        $geoms    = array();
266
-        $geoms [] = new Point ($this->lon, $this->lat);
267
-        if (!empty ($this->markers)) {
268
-            foreach ($this->markers as $marker) {
269
-                $geoms [] = new Point ($marker ['lon'], $marker ['lat']);
270
-            }
271
-        }
272
-        if (file_exists($this->kmlFileName)) {
273
-            $g = geoPHP::load(file_get_contents($this->kmlFileName), 'kml');
274
-            if ($g !== false) {
275
-                $geoms [] = $g;
276
-            }
277
-        }
278
-        if (file_exists($this->gpxFileName)) {
279
-            $g = geoPHP::load(file_get_contents($this->gpxFileName), 'gpx');
280
-            if ($g !== false) {
281
-                $geoms [] = $g;
282
-            }
283
-        }
284
-        if (file_exists($this->geojsonFileName)) {
285
-            $g = geoPHP::load(file_get_contents($this->geojsonFileName), 'geojson');
286
-            if ($g !== false) {
287
-                $geoms [] = $g;
288
-            }
289
-        }
290
-
291
-        if (count($geoms) <= 1) {
292
-            Logger::debug("StaticMap::autoZoom: Skip setting autozoom options", $geoms);
293
-            return;
294
-        }
295
-
296
-        $geom     = new GeometryCollection ($geoms);
297
-        $centroid = $geom->centroid();
298
-        $bbox     = $geom->getBBox();
299
-
300
-        // determine vertical resolution, this depends on the distance from the equator
301
-        // $vy00 = log(tan(M_PI*(0.25 + $centroid->getY()/360)));
302
-        $vy0 = log(tan(M_PI * (0.25 + $bbox ['miny'] / 360)));
303
-        $vy1 = log(tan(M_PI * (0.25 + $bbox ['maxy'] / 360)));
304
-        Logger::debug("StaticMap::autoZoom: vertical resolution: $vy0, $vy1");
305
-        if ($vy1 - $vy0 === 0.0){
306
-            $resolutionVertical = 0;
307
-            Logger::debug("StaticMap::autoZoom: using $resolutionVertical");
308
-        } else {
309
-            $zoomFactorPowered  = ($this->height / 2) / (40.7436654315252 * ($vy1 - $vy0));
310
-            $resolutionVertical = 360 / ($zoomFactorPowered * $this->tileSize);
311
-        }
312
-        // determine horizontal resolution
313
-        $resolutionHorizontal = ($bbox ['maxx'] - $bbox ['minx']) / $this->width;
314
-        Logger::debug("StaticMap::autoZoom: using $resolutionHorizontal");
315
-        $resolution           = max($resolutionHorizontal, $resolutionVertical) * $paddingFactor;
316
-        $zoom                 = $this->zoom;
317
-        if ($resolution > 0){
318
-            $zoom             = log(360 / ($resolution * $this->tileSize), 2);
319
-        }
320
-
321
-        if (is_finite($zoom) && $zoom < 15 && $zoom > 2) {
322
-            $this->zoom = floor($zoom);
323
-        }
324
-        $this->lon = $centroid->getX();
325
-        $this->lat = $centroid->getY();
326
-        Logger::debug("StaticMap::autoZoom: Set autozoom options to: z: $this->zoom, lon: $this->lon, lat: $this->lat");
327
-    }
328
-
329
-    public function checkMapCache(): bool
330
-    {
331
-        // side effect: set the mapCacheID
332
-        $this->mapCacheID = md5($this->serializeParams());
333
-        $filename         = $this->mapCacheIDToFilename();
334
-        return file_exists($filename);
335
-    }
336
-
337
-    public function serializeParams(): string
338
-    {
339
-        return join(
340
-            "&", array(
341
-                   $this->zoom,
342
-                   $this->lat,
343
-                   $this->lon,
344
-                   $this->width,
345
-                   $this->height,
346
-                   serialize($this->markers),
347
-                   $this->maptype,
348
-                   $this->kmlFileName,
349
-                   $this->gpxFileName,
350
-                   $this->geojsonFileName
351
-               )
352
-        );
353
-    }
354
-
355
-    public function mapCacheIDToFilename(): string
356
-    {
357
-        if (!$this->mapCacheFile) {
358
-            $this->mapCacheFile = $this->mapCacheBaseDir . "/" . $this->maptype . "/" . $this->zoom . "/cache_"
359
-                . substr($this->mapCacheID, 0, 2) . "/" . substr($this->mapCacheID, 2, 2)
360
-                . "/" . substr($this->mapCacheID, 4);
361
-        }
362
-        return $this->mapCacheFile . "." . $this->mapCacheExtension;
363
-    }
364
-
365
-    /**
366
-     * make the map.
367
-     */
368
-    public function makeMap(): void
369
-    {
370
-        $this->initCoords();
371
-        $this->createBaseMap();
372
-        if (!empty ($this->markers)) {
373
-            $this->placeMarkers();
374
-        }
375
-        if (file_exists($this->kmlFileName)) {
376
-            try {
377
-                $this->drawKML();
378
-            } catch (exception $e) {
379
-                Logger::error('failed to load KML file', $e);
380
-            }
381
-        }
382
-        if (file_exists($this->gpxFileName)) {
383
-            try {
384
-                $this->drawGPX();
385
-            } catch (exception $e) {
386
-                Logger::error('failed to load GPX file', $e);
387
-            }
388
-        }
389
-        if (file_exists($this->geojsonFileName)) {
390
-            try {
391
-                $this->drawGeojson();
392
-            } catch (exception $e) {
393
-                Logger::error('failed to load GeoJSON file', $e);
394
-            }
395
-        }
396
-
397
-        $this->drawCopyright();
398
-    }
399
-
400
-    /**
401
-     */
402
-    public function initCoords(): void
403
-    {
404
-        $this->centerX = $this->lonToTile($this->lon, $this->zoom);
405
-        $this->centerY = $this->latToTile($this->lat, $this->zoom);
406
-        $this->offsetX = floor((floor($this->centerX) - $this->centerX) * $this->tileSize);
407
-        $this->offsetY = floor((floor($this->centerY) - $this->centerY) * $this->tileSize);
408
-    }
409
-
410
-    /**
411
-     *
412
-     * @param float $long
413
-     * @param int   $zoom
414
-     * @return float|int
415
-     */
416
-    public function lonToTile(float $long, int $zoom)
417
-    {
418
-        return (($long + 180) / 360) * pow(2, $zoom);
419
-    }
420
-
421
-    /**
422
-     *
423
-     * @param float $lat
424
-     * @param int   $zoom
425
-     * @return float|int
426
-     */
427
-    public function latToTile(float $lat, int $zoom)
428
-    {
429
-        return (1 - log(tan($lat * pi() / 180) + 1 / cos($lat * M_PI / 180)) / M_PI) / 2 * pow(2, $zoom);
430
-    }
431
-
432
-    /**
433
-     * make basemap image.
434
-     */
435
-    public function createBaseMap(): void
436
-    {
437
-        $this->image   = imagecreatetruecolor($this->width, $this->height);
438
-        $startX        = floor($this->centerX - ($this->width / $this->tileSize) / 2);
439
-        $startY        = floor($this->centerY - ($this->height / $this->tileSize) / 2);
440
-        $endX          = ceil($this->centerX + ($this->width / $this->tileSize) / 2);
441
-        $endY          = ceil($this->centerY + ($this->height / $this->tileSize) / 2);
442
-        $this->offsetX = -floor(($this->centerX - floor($this->centerX)) * $this->tileSize);
443
-        $this->offsetY = -floor(($this->centerY - floor($this->centerY)) * $this->tileSize);
444
-        $this->offsetX += floor($this->width / 2);
445
-        $this->offsetY += floor($this->height / 2);
446
-        $this->offsetX += floor($startX - floor($this->centerX)) * $this->tileSize;
447
-        $this->offsetY += floor($startY - floor($this->centerY)) * $this->tileSize;
448
-
449
-        for ($x = $startX; $x <= $endX; $x++) {
450
-            for ($y = $startY; $y <= $endY; $y++) {
451
-                $url = str_replace(
452
-                    array(
453
-                        '{Z}',
454
-                        '{X}',
455
-                        '{Y}'
456
-                    ),
457
-                    array(
458
-                        $this->zoom,
459
-                        $x,
460
-                        $y
461
-                    ),
462
-                    $this->tileInfo [$this->maptype] ['url']
463
-                );
464
-
465
-                $tileData = $this->fetchTile($url);
466
-                if ($tileData) {
467
-                    $tileImage = imagecreatefromstring($tileData);
468
-                } else {
469
-                    $tileImage = imagecreate($this->tileSize, $this->tileSize);
470
-                    $color     = imagecolorallocate($tileImage, 255, 255, 255);
471
-                    @imagestring($tileImage, 1, 127, 127, 'err', $color);
472
-                }
473
-                $destX = ($x - $startX) * $this->tileSize + $this->offsetX;
474
-                $destY = ($y - $startY) * $this->tileSize + $this->offsetY;
475
-                Logger::debug("imagecopy tile into image: $destX, $destY", $this->tileSize);
476
-                imagecopy(
477
-                    $this->image,
478
-                    $tileImage,
479
-                    $destX,
480
-                    $destY,
481
-                    0,
482
-                    0,
483
-                    $this->tileSize,
484
-                    $this->tileSize
485
-                );
486
-            }
487
-        }
488
-    }
489
-
490
-    /**
491
-     * Fetch a tile and (if configured) store it in the cache.
492
-     * @param string $url
493
-     * @return bool|string
494
-     * @todo refactor this to use dokuwiki\HTTP\HTTPClient or dokuwiki\HTTP\DokuHTTPClient
495
-     *          for better proxy handling...
496
-     */
497
-    public function fetchTile(string $url)
498
-    {
499
-        if ($this->useTileCache && ($cached = $this->checkTileCache($url))) {
500
-            return $cached;
501
-        }
502
-
503
-        $_UA = 'Mozilla/4.0 (compatible; DokuWikiSpatial HTTP Client; ' . PHP_OS . ')';
504
-        if (function_exists("curl_init")) {
505
-            // use cUrl
506
-            $ch = curl_init();
507
-            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
508
-            curl_setopt($ch, CURLOPT_USERAGENT, $_UA);
509
-            curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
510
-            curl_setopt($ch, CURLOPT_URL, $url . $this->apikey);
511
-            Logger::debug("StaticMap::fetchTile: getting: $url using curl_exec");
512
-            $tile = curl_exec($ch);
513
-            curl_close($ch);
514
-        } else {
515
-            // use file_get_contents
516
-            global $conf;
517
-            $opts = array(
518
-                'http' => array(
519
-                    'method'          => "GET",
520
-                    'header'          => "Accept-language: en\r\n" . "User-Agent: $_UA\r\n" . "accept: image/png\r\n",
521
-                    'request_fulluri' => true
522
-                )
523
-            );
524
-            if (isset($conf['proxy']['host'], $conf['proxy']['port'])
525
-                && $conf['proxy']['host'] !== ''
526
-                && $conf['proxy']['port'] !== '') {
527
-                $opts['http'] += ['proxy' => "tcp://" . $conf['proxy']['host'] . ":" . $conf['proxy']['port']];
528
-            }
529
-
530
-            $context = stream_context_create($opts);
531
-            Logger::debug(
532
-                "StaticMap::fetchTile: getting: $url . $this->apikey using file_get_contents and options $opts"
533
-            );
534
-            $tile = file_get_contents($url . $this->apikey, false, $context);
535
-        }
536
-        if ($tile && $this->useTileCache) {
537
-            $this->writeTileToCache($url, $tile);
538
-        }
539
-        return $tile;
540
-    }
541
-
542
-    /**
543
-     *
544
-     * @param string $url
545
-     * @return string|false
546
-     */
547
-    public function checkTileCache(string $url)
548
-    {
549
-        $filename = $this->tileUrlToFilename($url);
550
-        if (file_exists($filename)) {
551
-            return file_get_contents($filename);
552
-        }
553
-        return false;
554
-    }
555
-
556
-    /**
557
-     *
558
-     * @param string $url
559
-     * @return string
560
-     */
561
-    public function tileUrlToFilename(string $url): string
562
-    {
563
-        return $this->tileCacheBaseDir . "/" . substr($url, strpos($url, '/') + 1);
564
-    }
565
-
566
-    /**
567
-     * Write a tile into the cache.
568
-     *
569
-     * @param string $url
570
-     * @param mixed  $data
571
-     */
572
-    public function writeTileToCache(string $url, $data): void
573
-    {
574
-        $filename = $this->tileUrlToFilename($url);
575
-        $this->mkdirRecursive(dirname($filename), 0777);
576
-        file_put_contents($filename, $data);
577
-    }
578
-
579
-    /**
580
-     * Recursively create the directory.
581
-     *
582
-     * @param string $pathname
583
-     *            The directory path.
584
-     * @param int    $mode
585
-     *            File access mode. For more information on modes, read the details on the chmod manpage.
586
-     */
587
-    public function mkdirRecursive(string $pathname, int $mode): bool
588
-    {
589
-        is_dir(dirname($pathname)) || $this->mkdirRecursive(dirname($pathname), $mode);
590
-        return is_dir($pathname) || mkdir($pathname, $mode) || is_dir($pathname);
591
-    }
592
-
593
-    /**
594
-     * Place markers on the map and number them in the same order as they are listed in the html.
595
-     */
596
-    public function placeMarkers(): void
597
-    {
598
-        $count               = 0;
599
-        $color               = imagecolorallocate($this->image, 0, 0, 0);
600
-        $bgcolor             = imagecolorallocate($this->image, 200, 200, 200);
601
-        $markerBaseDir       = __DIR__ . '/icons';
602
-        $markerImageOffsetX  = 0;
603
-        $markerImageOffsetY  = 0;
604
-        $markerShadowOffsetX = 0;
605
-        $markerShadowOffsetY = 0;
606
-        $markerShadowImg     = null;
607
-        // loop thru marker array
608
-        foreach ($this->markers as $marker) {
609
-            // set some local variables
610
-            $markerLat  = $marker ['lat'];
611
-            $markerLon  = $marker ['lon'];
612
-            $markerType = $marker ['type'];
613
-            // clear variables from previous loops
614
-            $markerFilename = '';
615
-            $markerShadow   = '';
616
-            $matches        = false;
617
-            // check for marker type, get settings from markerPrototypes
618
-            if ($markerType) {
619
-                foreach ($this->markerPrototypes as $markerPrototype) {
620
-                    if (preg_match($markerPrototype ['regex'], $markerType, $matches)) {
621
-                        $markerFilename = $matches [0] . $markerPrototype ['extension'];
622
-                        if ($markerPrototype ['offsetImage']) {
623
-                            list ($markerImageOffsetX, $markerImageOffsetY) = explode(
624
-                                ",",
625
-                                $markerPrototype ['offsetImage']
626
-                            );
627
-                        }
628
-                        $markerShadow = $markerPrototype ['shadow'];
629
-                        if ($markerShadow) {
630
-                            list ($markerShadowOffsetX, $markerShadowOffsetY) = explode(
631
-                                ",",
632
-                                $markerPrototype ['offsetShadow']
633
-                            );
634
-                        }
635
-                    }
636
-                }
637
-            }
638
-            // create img resource
639
-            if (file_exists($markerBaseDir . '/' . $markerFilename)) {
640
-                $markerImg = imagecreatefrompng($markerBaseDir . '/' . $markerFilename);
641
-            } else {
642
-                $markerImg = imagecreatefrompng($markerBaseDir . '/marker.png');
643
-            }
644
-            // check for shadow + create shadow recource
645
-            if ($markerShadow && file_exists($markerBaseDir . '/' . $markerShadow)) {
646
-                $markerShadowImg = imagecreatefrompng($markerBaseDir . '/' . $markerShadow);
647
-            }
648
-            // calc position
649
-            $destX = floor(
650
-                ($this->width / 2) -
651
-                $this->tileSize * ($this->centerX - $this->lonToTile($markerLon, $this->zoom))
652
-            );
653
-            $destY = floor(
654
-                ($this->height / 2) -
655
-                $this->tileSize * ($this->centerY - $this->latToTile($markerLat, $this->zoom))
656
-            );
657
-            // copy shadow on basemap
658
-            if ($markerShadow && $markerShadowImg) {
659
-                imagecopy(
660
-                    $this->image,
661
-                    $markerShadowImg,
662
-                    $destX + (int)$markerShadowOffsetX,
663
-                    $destY + (int)$markerShadowOffsetY,
664
-                    0,
665
-                    0,
666
-                    imagesx($markerShadowImg),
667
-                    imagesy($markerShadowImg)
668
-                );
669
-            }
670
-            // copy marker on basemap above shadow
671
-            imagecopy(
672
-                $this->image,
673
-                $markerImg,
674
-                $destX + (int)$markerImageOffsetX,
675
-                $destY + (int)$markerImageOffsetY,
676
-                0,
677
-                0,
678
-                imagesx($markerImg),
679
-                imagesy($markerImg)
680
-            );
681
-            // add label
682
-            imagestring(
683
-                $this->image,
684
-                3,
685
-                $destX - imagesx($markerImg) + 1,
686
-                $destY + (int)$markerImageOffsetY + 1,
687
-                ++$count,
688
-                $bgcolor
689
-            );
690
-            imagestring(
691
-                $this->image,
692
-                3,
693
-                $destX - imagesx($markerImg),
694
-                $destY + (int)$markerImageOffsetY,
695
-                $count,
696
-                $color
697
-            );
698
-        }
699
-    }
700
-
701
-    /**
702
-     * Draw kml trace on the map.
703
-     * @throws exception if loading the specified KML fails
704
-     */
705
-    public function drawKML(): void
706
-    {
707
-        // TODO get colour from kml node (not currently supported in geoPHP)
708
-        $col     = imagecolorallocatealpha($this->image, 255, 0, 0, .4 * 127);
709
-        $kmlgeom = geoPHP::load(file_get_contents($this->kmlFileName), 'kml');
710
-        $this->drawGeometry($kmlgeom, $col);
711
-    }
712
-
713
-    /**
714
-     * Draw geometry or geometry collection on the map.
715
-     *
716
-     * @param Geometry|GeometryCollection|MultiPolygon|MultiLineString|MultiPoint|Polygon|LineString|Point $geom
717
-     * @param int                                                                                          $colour
718
-     *            drawing colour
719
-     */
720
-    private function drawGeometry(Geometry $geom, int $colour): void
721
-    {
722
-        if (empty($geom)) {
723
-            return;
724
-        }
725
-
726
-        switch ($geom->geometryType()) {
727
-            case 'GeometryCollection' :
728
-                // recursively draw part of the collection
729
-                for ($i = 1; $i < $geom->numGeometries() + 1; $i++) {
730
-                    $_geom = $geom->geometryN($i);
731
-                    $this->drawGeometry($_geom, $colour);
732
-                }
733
-                break;
734
-            case 'MultiPolygon' :
735
-            case 'MultiLineString' :
736
-            case 'MultiPoint' :
737
-                // TODO implement / do nothing
738
-                break;
739
-            case 'Polygon' :
740
-                $this->drawPolygon($geom, $colour);
741
-                break;
742
-            case 'LineString' :
743
-                $this->drawLineString($geom, $colour);
744
-                break;
745
-            case 'Point' :
746
-                $this->drawPoint($geom, $colour);
747
-                break;
748
-            default :
749
-                // draw nothing
750
-                break;
751
-        }
752
-    }
753
-
754
-    /**
755
-     * Draw a polygon on the map.
756
-     *
757
-     * @param Polygon $polygon
758
-     * @param int     $colour
759
-     *            drawing colour
760
-     */
761
-    private function drawPolygon(Polygon $polygon, int $colour)
762
-    {
763
-        // TODO implementation of drawing holes,
764
-        // maybe draw the polygon to an in-memory image and use imagecopy, draw polygon in col., draw holes in bgcol?
765
-
766
-        // print_r('Polygon:<br />');
767
-        // print_r($polygon);
768
-        $extPoints = array();
769
-        // extring is a linestring actually..
770
-        $extRing = $polygon->exteriorRing();
771
-
772
-        for ($i = 1; $i < $extRing->numGeometries(); $i++) {
773
-            $p1           = $extRing->geometryN($i);
774
-            $x            = floor(
775
-                ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($p1->x(), $this->zoom))
776
-            );
777
-            $y            = floor(
778
-                ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($p1->y(), $this->zoom))
779
-            );
780
-            $extPoints [] = $x;
781
-            $extPoints [] = $y;
782
-        }
783
-        // print_r('points:('.($i-1).')<br />');
784
-        // print_r($extPoints);
785
-        // imagepolygon ($this->image, $extPoints, $i-1, $colour );
786
-        imagefilledpolygon($this->image, $extPoints, $i - 1, $colour);
787
-    }
788
-
789
-    /**
790
-     * Draw a line on the map.
791
-     *
792
-     * @param LineString $line
793
-     * @param int        $colour
794
-     *            drawing colour
795
-     */
796
-    private function drawLineString(LineString $line, int $colour)
797
-    {
798
-        imagesetthickness($this->image, 2);
799
-        for ($p = 1; $p < $line->numGeometries(); $p++) {
800
-            // get first pair of points
801
-            $p1 = $line->geometryN($p);
802
-            $p2 = $line->geometryN($p + 1);
803
-            // translate to paper space
804
-            $x1 = floor(
805
-                ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($p1->x(), $this->zoom))
806
-            );
807
-            $y1 = floor(
808
-                ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($p1->y(), $this->zoom))
809
-            );
810
-            $x2 = floor(
811
-                ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($p2->x(), $this->zoom))
812
-            );
813
-            $y2 = floor(
814
-                ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($p2->y(), $this->zoom))
815
-            );
816
-            // draw to image
817
-            imageline($this->image, $x1, $y1, $x2, $y2, $colour);
818
-        }
819
-        imagesetthickness($this->image, 1);
820
-    }
821
-
822
-    /**
823
-     * Draw a point on the map.
824
-     *
825
-     * @param Point $point
826
-     * @param int   $colour
827
-     *            drawing colour
828
-     */
829
-    private function drawPoint(Point $point, int $colour)
830
-    {
831
-        imagesetthickness($this->image, 2);
832
-        // translate to paper space
833
-        $cx = floor(
834
-            ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($point->x(), $this->zoom))
835
-        );
836
-        $cy = floor(
837
-            ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($point->y(), $this->zoom))
838
-        );
839
-        $r  = 5;
840
-        // draw to image
841
-        // imageellipse($this->image, $cx, $cy,$r, $r, $colour);
842
-        imagefilledellipse($this->image, $cx, $cy, $r, $r, $colour);
843
-        // don't use imageellipse because the imagesetthickness function has
844
-        // no effect. So the better workaround is to use imagearc.
845
-        imagearc($this->image, $cx, $cy, $r, $r, 0, 359, $colour);
846
-        imagesetthickness($this->image, 1);
847
-    }
848
-
849
-    /**
850
-     * Draw gpx trace on the map.
851
-     * @throws exception if loading the specified GPX fails
852
-     */
853
-    public function drawGPX()
854
-    {
855
-        $col     = imagecolorallocatealpha($this->image, 0, 0, 255, .4 * 127);
856
-        $gpxgeom = geoPHP::load(file_get_contents($this->gpxFileName), 'gpx');
857
-        $this->drawGeometry($gpxgeom, $col);
858
-    }
859
-
860
-    /**
861
-     * Draw geojson on the map.
862
-     * @throws exception if loading the specified GeoJSON fails
863
-     */
864
-    public function drawGeojson()
865
-    {
866
-        $col     = imagecolorallocatealpha($this->image, 255, 0, 255, .4 * 127);
867
-        $gpxgeom = geoPHP::load(file_get_contents($this->geojsonFileName), 'json');
868
-        $this->drawGeometry($gpxgeom, $col);
869
-    }
870
-
871
-    /**
872
-     * add copyright and origin notice and icons to the map.
873
-     */
874
-    public function drawCopyright()
875
-    {
876
-        $logoBaseDir = dirname(__FILE__) . '/' . 'logo/';
877
-        $logoImg     = imagecreatefrompng($logoBaseDir . $this->tileInfo ['openstreetmap'] ['logo']);
878
-        $textcolor   = imagecolorallocate($this->image, 0, 0, 0);
879
-        $bgcolor     = imagecolorallocate($this->image, 200, 200, 200);
880
-
881
-        imagecopy(
882
-            $this->image,
883
-            $logoImg,
884
-            0,
885
-            imagesy($this->image) - imagesy($logoImg),
886
-            0,
887
-            0,
888
-            imagesx($logoImg),
889
-            imagesy($logoImg)
890
-        );
891
-        imagestring(
892
-            $this->image,
893
-            1,
894
-            imagesx($logoImg) + 2,
895
-            imagesy($this->image) - imagesy($logoImg) + 1,
896
-            $this->tileInfo ['openstreetmap'] ['txt'],
897
-            $bgcolor
898
-        );
899
-        imagestring(
900
-            $this->image,
901
-            1,
902
-            imagesx($logoImg) + 1,
903
-            imagesy($this->image) - imagesy($logoImg),
904
-            $this->tileInfo ['openstreetmap'] ['txt'],
905
-            $textcolor
906
-        );
907
-
908
-        // additional tile source info, ie. who created/hosted the tiles
909
-        $xIconOffset = 0;
910
-        if ($this->maptype === 'openstreetmap') {
911
-            $mapAuthor = "(c) OpenStreetMap maps/CC BY-SA";
912
-        } else {
913
-            $mapAuthor   = $this->tileInfo [$this->maptype] ['txt'];
914
-            $iconImg     = imagecreatefrompng($logoBaseDir . $this->tileInfo [$this->maptype] ['logo']);
915
-            $xIconOffset = imagesx($iconImg);
916
-            imagecopy(
917
-                $this->image,
918
-                $iconImg,
919
-                imagesx($logoImg) + 1,
920
-                imagesy($this->image) - imagesy($iconImg),
921
-                0,
922
-                0,
923
-                imagesx($iconImg),
924
-                imagesy($iconImg)
925
-            );
926
-        }
927
-        imagestring(
928
-            $this->image,
929
-            1,
930
-            imagesx($logoImg) + $xIconOffset + 4,
931
-            imagesy($this->image) - ceil(imagesy($logoImg) / 2) + 1,
932
-            $mapAuthor,
933
-            $bgcolor
934
-        );
935
-        imagestring(
936
-            $this->image,
937
-            1,
938
-            imagesx($logoImg) + $xIconOffset + 3,
939
-            imagesy($this->image) - ceil(imagesy($logoImg) / 2),
940
-            $mapAuthor,
941
-            $textcolor
942
-        );
943
-    }
37
+	// the final output
38
+	private $tileSize = 256;
39
+	private $tileInfo = array(
40
+		// OSM sources
41
+		'openstreetmap' => array(
42
+			'txt'  => '(c) OpenStreetMap data/ODbl',
43
+			'logo' => 'osm_logo.png',
44
+			'url'  => 'https://tile.openstreetmap.org/{Z}/{X}/{Y}.png'
45
+		),
46
+		// OCM sources
47
+		'cycle'         => array(
48
+			'txt'  => '(c) Thunderforest maps',
49
+			'logo' => 'tf_logo.png',
50
+			'url'  => 'https://tile.thunderforest.com/cycle/{Z}/{X}/{Y}.png'
51
+		),
52
+		'transport'     => array(
53
+			'txt'  => '(c) Thunderforest maps',
54
+			'logo' => 'tf_logo.png',
55
+			'url'  => 'https://tile.thunderforest.com/transport/{Z}/{X}/{Y}.png'
56
+		),
57
+		'landscape'     => array(
58
+			'txt'  => '(c) Thunderforest maps',
59
+			'logo' => 'tf_logo.png',
60
+			'url'  => 'https://tile.thunderforest.com/landscape/{Z}/{X}/{Y}.png'
61
+		),
62
+		'outdoors'      => array(
63
+			'txt'  => '(c) Thunderforest maps',
64
+			'logo' => 'tf_logo.png',
65
+			'url'  => 'https://tile.thunderforest.com/outdoors/{Z}/{X}/{Y}.png'
66
+		),
67
+		'toner-lite'    => array(
68
+			'txt'  => 'Stamen tiles',
69
+			'logo' => 'stamen.png',
70
+			'url'  => 'https://stamen-tiles.a.ssl.fastly.net/toner/{Z}/{X}/{Y}.png'
71
+		),
72
+		'terrain'       => array(
73
+			'txt'  => 'Stamen tiles',
74
+			'logo' => 'stamen.png',
75
+			'url'  => 'https://stamen-tiles.a.ssl.fastly.net/terrain/{Z}/{X}/{Y}.jpg'
76
+		)
77
+		//,
78
+		// 'piste'=>array(
79
+		// 'txt'=>'OpenPisteMap tiles',
80
+		// 'logo'=>'piste_logo.png',
81
+		// 'url'=>''),
82
+		// 'sea'=>array(
83
+		// 'txt'=>'OpenSeaMap tiles',
84
+		// 'logo'=>'sea_logo.png',
85
+		// 'url'=>''),
86
+		// H&B sources
87
+		//          'hikeandbike' => array (
88
+		//                  'txt' => 'Hike & Bike Map',
89
+		//                  'logo' => 'hnb_logo.png',
90
+		//                  //'url' => 'http://toolserver.org/tiles/hikebike/{Z}/{X}/{Y}.png'
91
+		//                  //moved to: https://www.toolserver.org/tiles/hikebike/12/2105/1388.png
92
+		//                  'url' => 'http://c.tiles.wmflabs.org/hikebike/{Z}/{X}/{Y}.png'
93
+		//          )
94
+	);
95
+	private $tileDefaultSrc = 'openstreetmap';
96
+
97
+	// set up markers
98
+	private $markerPrototypes = array(
99
+		// found at http://www.mapito.net/map-marker-icons.html
100
+		// these are 17x19 px with a pointer at the bottom left
101
+		'lightblue' => array(
102
+			'regex'        => '/^lightblue([0-9]+)$/',
103
+			'extension'    => '.png',
104
+			'shadow'       => false,
105
+			'offsetImage'  => '0,-19',
106
+			'offsetShadow' => false
107
+		),
108
+		// openlayers std markers are 21x25px with shadow
109
+		'ol-marker' => array(
110
+			'regex'        => '/^marker(|-blue|-gold|-green|-red)+$/',
111
+			'extension'    => '.png',
112
+			'shadow'       => 'marker_shadow.png',
113
+			'offsetImage'  => '-10,-25',
114
+			'offsetShadow' => '-1,-13'
115
+		),
116
+		// these are 16x16 px
117
+		'ww_icon'   => array(
118
+			'regex'        => '/ww_\S+$/',
119
+			'extension'    => '.png',
120
+			'shadow'       => false,
121
+			'offsetImage'  => '-8,-8',
122
+			'offsetShadow' => false
123
+		),
124
+		// assume these are 16x16 px
125
+		'rest'      => array(
126
+			'regex'        => '/^(?!lightblue([0-9]+)$)(?!(ww_\S+$))(?!marker(|-blue|-gold|-green|-red)+$)(.*)/',
127
+			'extension'    => '.png',
128
+			'shadow'       => 'marker_shadow.png',
129
+			'offsetImage'  => '-8,-8',
130
+			'offsetShadow' => '-1,-1'
131
+		)
132
+	);
133
+	private $centerX;
134
+	private $centerY;
135
+	private $offsetX;
136
+	private $offsetY;
137
+	private $image;
138
+	private $zoom;
139
+	private $lat;
140
+	private $lon;
141
+	private $width;
142
+	private $height;
143
+	private $markers;
144
+	private $maptype;
145
+	private $kmlFileName;
146
+	private $gpxFileName;
147
+	private $geojsonFileName;
148
+	private $autoZoomExtent;
149
+	private $apikey;
150
+	private $tileCacheBaseDir;
151
+	private $mapCacheBaseDir;
152
+	private $mediaBaseDir;
153
+	private $useTileCache;
154
+	private $mapCacheID = '';
155
+	private $mapCacheFile = '';
156
+	private $mapCacheExtension = 'png';
157
+
158
+	/**
159
+	 * Constructor.
160
+	 *
161
+	 * @param float  $lat
162
+	 *            Latitude (x) of center of map
163
+	 * @param float  $lon
164
+	 *            Longitude (y) of center of map
165
+	 * @param int    $zoom
166
+	 *            Zoomlevel
167
+	 * @param int    $width
168
+	 *            Width in pixels
169
+	 * @param int    $height
170
+	 *            Height in pixels
171
+	 * @param string $maptype
172
+	 *            Name of the map
173
+	 * @param array  $markers
174
+	 *            array of markers
175
+	 * @param string $gpx
176
+	 *            GPX filename
177
+	 * @param string $kml
178
+	 *            KML filename
179
+	 * @param string $geojson
180
+	 * @param string $mediaDir
181
+	 *            Directory to store/cache maps
182
+	 * @param string $tileCacheBaseDir
183
+	 *            Directory to cache map tiles
184
+	 * @param bool   $autoZoomExtent
185
+	 *            Wheter or not to override zoom/lat/lon and zoom to the extent of gpx/kml and markers
186
+	 * @param string $apikey
187
+	 */
188
+	public function __construct(
189
+		float $lat,
190
+		float $lon,
191
+		int $zoom,
192
+		int $width,
193
+		int $height,
194
+		string $maptype,
195
+		array $markers,
196
+		string $gpx,
197
+		string $kml,
198
+		string $geojson,
199
+		string $mediaDir,
200
+		string $tileCacheBaseDir,
201
+		bool $autoZoomExtent = true,
202
+		string $apikey = ''
203
+	) {
204
+		$this->zoom   = $zoom;
205
+		$this->lat    = $lat;
206
+		$this->lon    = $lon;
207
+		$this->width  = $width;
208
+		$this->height = $height;
209
+		// validate + set maptype
210
+		$this->maptype = $this->tileDefaultSrc;
211
+		if (array_key_exists($maptype, $this->tileInfo)) {
212
+			$this->maptype = $maptype;
213
+		}
214
+		$this->markers          = $markers;
215
+		$this->kmlFileName      = $kml;
216
+		$this->gpxFileName      = $gpx;
217
+		$this->geojsonFileName  = $geojson;
218
+		$this->mediaBaseDir     = $mediaDir;
219
+		$this->tileCacheBaseDir = $tileCacheBaseDir . '/olmaptiles';
220
+		$this->useTileCache     = $this->tileCacheBaseDir !== '';
221
+		$this->mapCacheBaseDir  = $mediaDir . '/olmapmaps';
222
+		$this->autoZoomExtent   = $autoZoomExtent;
223
+		$this->apikey           = $apikey;
224
+	}
225
+
226
+	/**
227
+	 * get the map, this may return a reference to a cached copy.
228
+	 *
229
+	 * @return string url relative to media dir
230
+	 */
231
+	public function getMap(): string
232
+	{
233
+		try {
234
+			if ($this->autoZoomExtent) {
235
+				$this->autoZoom();
236
+			}
237
+		} catch (Exception $e) {
238
+			Logger::debug($e);
239
+		}
240
+
241
+		// use map cache, so check cache for map
242
+		if (!$this->checkMapCache()) {
243
+			// map is not in cache, needs to be build
244
+			$this->makeMap();
245
+			$this->mkdirRecursive(dirname($this->mapCacheIDToFilename()), 0777);
246
+			imagepng($this->image, $this->mapCacheIDToFilename(), 9);
247
+		}
248
+		$doc = $this->mapCacheIDToFilename();
249
+		// make url relative to media dir
250
+		return str_replace($this->mediaBaseDir, '', $doc);
251
+	}
252
+
253
+	/**
254
+	 * Calculate the lat/lon/zoom values to make sure that all of the markers and gpx/kml are on the map.
255
+	 * can throw an error like
256
+	 * "Fatal error: Uncaught Exception: Cannot create a collection with non-geometries in
257
+	 * D:\www\wild-water.nl\www\dokuwiki\lib\plugins\geophp\geoPHP\lib\geometry\Collection.class.php:29"
258
+	 *
259
+	 * @param float $paddingFactor
260
+	 *            buffer constant to enlarge (>1.0) the zoom level
261
+	 * @throws Exception
262
+	 */
263
+	private function autoZoom(float $paddingFactor = 1.0): void
264
+	{
265
+		$geoms    = array();
266
+		$geoms [] = new Point ($this->lon, $this->lat);
267
+		if (!empty ($this->markers)) {
268
+			foreach ($this->markers as $marker) {
269
+				$geoms [] = new Point ($marker ['lon'], $marker ['lat']);
270
+			}
271
+		}
272
+		if (file_exists($this->kmlFileName)) {
273
+			$g = geoPHP::load(file_get_contents($this->kmlFileName), 'kml');
274
+			if ($g !== false) {
275
+				$geoms [] = $g;
276
+			}
277
+		}
278
+		if (file_exists($this->gpxFileName)) {
279
+			$g = geoPHP::load(file_get_contents($this->gpxFileName), 'gpx');
280
+			if ($g !== false) {
281
+				$geoms [] = $g;
282
+			}
283
+		}
284
+		if (file_exists($this->geojsonFileName)) {
285
+			$g = geoPHP::load(file_get_contents($this->geojsonFileName), 'geojson');
286
+			if ($g !== false) {
287
+				$geoms [] = $g;
288
+			}
289
+		}
290
+
291
+		if (count($geoms) <= 1) {
292
+			Logger::debug("StaticMap::autoZoom: Skip setting autozoom options", $geoms);
293
+			return;
294
+		}
295
+
296
+		$geom     = new GeometryCollection ($geoms);
297
+		$centroid = $geom->centroid();
298
+		$bbox     = $geom->getBBox();
299
+
300
+		// determine vertical resolution, this depends on the distance from the equator
301
+		// $vy00 = log(tan(M_PI*(0.25 + $centroid->getY()/360)));
302
+		$vy0 = log(tan(M_PI * (0.25 + $bbox ['miny'] / 360)));
303
+		$vy1 = log(tan(M_PI * (0.25 + $bbox ['maxy'] / 360)));
304
+		Logger::debug("StaticMap::autoZoom: vertical resolution: $vy0, $vy1");
305
+		if ($vy1 - $vy0 === 0.0){
306
+			$resolutionVertical = 0;
307
+			Logger::debug("StaticMap::autoZoom: using $resolutionVertical");
308
+		} else {
309
+			$zoomFactorPowered  = ($this->height / 2) / (40.7436654315252 * ($vy1 - $vy0));
310
+			$resolutionVertical = 360 / ($zoomFactorPowered * $this->tileSize);
311
+		}
312
+		// determine horizontal resolution
313
+		$resolutionHorizontal = ($bbox ['maxx'] - $bbox ['minx']) / $this->width;
314
+		Logger::debug("StaticMap::autoZoom: using $resolutionHorizontal");
315
+		$resolution           = max($resolutionHorizontal, $resolutionVertical) * $paddingFactor;
316
+		$zoom                 = $this->zoom;
317
+		if ($resolution > 0){
318
+			$zoom             = log(360 / ($resolution * $this->tileSize), 2);
319
+		}
320
+
321
+		if (is_finite($zoom) && $zoom < 15 && $zoom > 2) {
322
+			$this->zoom = floor($zoom);
323
+		}
324
+		$this->lon = $centroid->getX();
325
+		$this->lat = $centroid->getY();
326
+		Logger::debug("StaticMap::autoZoom: Set autozoom options to: z: $this->zoom, lon: $this->lon, lat: $this->lat");
327
+	}
328
+
329
+	public function checkMapCache(): bool
330
+	{
331
+		// side effect: set the mapCacheID
332
+		$this->mapCacheID = md5($this->serializeParams());
333
+		$filename         = $this->mapCacheIDToFilename();
334
+		return file_exists($filename);
335
+	}
336
+
337
+	public function serializeParams(): string
338
+	{
339
+		return join(
340
+			"&", array(
341
+				   $this->zoom,
342
+				   $this->lat,
343
+				   $this->lon,
344
+				   $this->width,
345
+				   $this->height,
346
+				   serialize($this->markers),
347
+				   $this->maptype,
348
+				   $this->kmlFileName,
349
+				   $this->gpxFileName,
350
+				   $this->geojsonFileName
351
+			   )
352
+		);
353
+	}
354
+
355
+	public function mapCacheIDToFilename(): string
356
+	{
357
+		if (!$this->mapCacheFile) {
358
+			$this->mapCacheFile = $this->mapCacheBaseDir . "/" . $this->maptype . "/" . $this->zoom . "/cache_"
359
+				. substr($this->mapCacheID, 0, 2) . "/" . substr($this->mapCacheID, 2, 2)
360
+				. "/" . substr($this->mapCacheID, 4);
361
+		}
362
+		return $this->mapCacheFile . "." . $this->mapCacheExtension;
363
+	}
364
+
365
+	/**
366
+	 * make the map.
367
+	 */
368
+	public function makeMap(): void
369
+	{
370
+		$this->initCoords();
371
+		$this->createBaseMap();
372
+		if (!empty ($this->markers)) {
373
+			$this->placeMarkers();
374
+		}
375
+		if (file_exists($this->kmlFileName)) {
376
+			try {
377
+				$this->drawKML();
378
+			} catch (exception $e) {
379
+				Logger::error('failed to load KML file', $e);
380
+			}
381
+		}
382
+		if (file_exists($this->gpxFileName)) {
383
+			try {
384
+				$this->drawGPX();
385
+			} catch (exception $e) {
386
+				Logger::error('failed to load GPX file', $e);
387
+			}
388
+		}
389
+		if (file_exists($this->geojsonFileName)) {
390
+			try {
391
+				$this->drawGeojson();
392
+			} catch (exception $e) {
393
+				Logger::error('failed to load GeoJSON file', $e);
394
+			}
395
+		}
396
+
397
+		$this->drawCopyright();
398
+	}
399
+
400
+	/**
401
+	 */
402
+	public function initCoords(): void
403
+	{
404
+		$this->centerX = $this->lonToTile($this->lon, $this->zoom);
405
+		$this->centerY = $this->latToTile($this->lat, $this->zoom);
406
+		$this->offsetX = floor((floor($this->centerX) - $this->centerX) * $this->tileSize);
407
+		$this->offsetY = floor((floor($this->centerY) - $this->centerY) * $this->tileSize);
408
+	}
409
+
410
+	/**
411
+	 *
412
+	 * @param float $long
413
+	 * @param int   $zoom
414
+	 * @return float|int
415
+	 */
416
+	public function lonToTile(float $long, int $zoom)
417
+	{
418
+		return (($long + 180) / 360) * pow(2, $zoom);
419
+	}
420
+
421
+	/**
422
+	 *
423
+	 * @param float $lat
424
+	 * @param int   $zoom
425
+	 * @return float|int
426
+	 */
427
+	public function latToTile(float $lat, int $zoom)
428
+	{
429
+		return (1 - log(tan($lat * pi() / 180) + 1 / cos($lat * M_PI / 180)) / M_PI) / 2 * pow(2, $zoom);
430
+	}
431
+
432
+	/**
433
+	 * make basemap image.
434
+	 */
435
+	public function createBaseMap(): void
436
+	{
437
+		$this->image   = imagecreatetruecolor($this->width, $this->height);
438
+		$startX        = floor($this->centerX - ($this->width / $this->tileSize) / 2);
439
+		$startY        = floor($this->centerY - ($this->height / $this->tileSize) / 2);
440
+		$endX          = ceil($this->centerX + ($this->width / $this->tileSize) / 2);
441
+		$endY          = ceil($this->centerY + ($this->height / $this->tileSize) / 2);
442
+		$this->offsetX = -floor(($this->centerX - floor($this->centerX)) * $this->tileSize);
443
+		$this->offsetY = -floor(($this->centerY - floor($this->centerY)) * $this->tileSize);
444
+		$this->offsetX += floor($this->width / 2);
445
+		$this->offsetY += floor($this->height / 2);
446
+		$this->offsetX += floor($startX - floor($this->centerX)) * $this->tileSize;
447
+		$this->offsetY += floor($startY - floor($this->centerY)) * $this->tileSize;
448
+
449
+		for ($x = $startX; $x <= $endX; $x++) {
450
+			for ($y = $startY; $y <= $endY; $y++) {
451
+				$url = str_replace(
452
+					array(
453
+						'{Z}',
454
+						'{X}',
455
+						'{Y}'
456
+					),
457
+					array(
458
+						$this->zoom,
459
+						$x,
460
+						$y
461
+					),
462
+					$this->tileInfo [$this->maptype] ['url']
463
+				);
464
+
465
+				$tileData = $this->fetchTile($url);
466
+				if ($tileData) {
467
+					$tileImage = imagecreatefromstring($tileData);
468
+				} else {
469
+					$tileImage = imagecreate($this->tileSize, $this->tileSize);
470
+					$color     = imagecolorallocate($tileImage, 255, 255, 255);
471
+					@imagestring($tileImage, 1, 127, 127, 'err', $color);
472
+				}
473
+				$destX = ($x - $startX) * $this->tileSize + $this->offsetX;
474
+				$destY = ($y - $startY) * $this->tileSize + $this->offsetY;
475
+				Logger::debug("imagecopy tile into image: $destX, $destY", $this->tileSize);
476
+				imagecopy(
477
+					$this->image,
478
+					$tileImage,
479
+					$destX,
480
+					$destY,
481
+					0,
482
+					0,
483
+					$this->tileSize,
484
+					$this->tileSize
485
+				);
486
+			}
487
+		}
488
+	}
489
+
490
+	/**
491
+	 * Fetch a tile and (if configured) store it in the cache.
492
+	 * @param string $url
493
+	 * @return bool|string
494
+	 * @todo refactor this to use dokuwiki\HTTP\HTTPClient or dokuwiki\HTTP\DokuHTTPClient
495
+	 *          for better proxy handling...
496
+	 */
497
+	public function fetchTile(string $url)
498
+	{
499
+		if ($this->useTileCache && ($cached = $this->checkTileCache($url))) {
500
+			return $cached;
501
+		}
502
+
503
+		$_UA = 'Mozilla/4.0 (compatible; DokuWikiSpatial HTTP Client; ' . PHP_OS . ')';
504
+		if (function_exists("curl_init")) {
505
+			// use cUrl
506
+			$ch = curl_init();
507
+			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
508
+			curl_setopt($ch, CURLOPT_USERAGENT, $_UA);
509
+			curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
510
+			curl_setopt($ch, CURLOPT_URL, $url . $this->apikey);
511
+			Logger::debug("StaticMap::fetchTile: getting: $url using curl_exec");
512
+			$tile = curl_exec($ch);
513
+			curl_close($ch);
514
+		} else {
515
+			// use file_get_contents
516
+			global $conf;
517
+			$opts = array(
518
+				'http' => array(
519
+					'method'          => "GET",
520
+					'header'          => "Accept-language: en\r\n" . "User-Agent: $_UA\r\n" . "accept: image/png\r\n",
521
+					'request_fulluri' => true
522
+				)
523
+			);
524
+			if (isset($conf['proxy']['host'], $conf['proxy']['port'])
525
+				&& $conf['proxy']['host'] !== ''
526
+				&& $conf['proxy']['port'] !== '') {
527
+				$opts['http'] += ['proxy' => "tcp://" . $conf['proxy']['host'] . ":" . $conf['proxy']['port']];
528
+			}
529
+
530
+			$context = stream_context_create($opts);
531
+			Logger::debug(
532
+				"StaticMap::fetchTile: getting: $url . $this->apikey using file_get_contents and options $opts"
533
+			);
534
+			$tile = file_get_contents($url . $this->apikey, false, $context);
535
+		}
536
+		if ($tile && $this->useTileCache) {
537
+			$this->writeTileToCache($url, $tile);
538
+		}
539
+		return $tile;
540
+	}
541
+
542
+	/**
543
+	 *
544
+	 * @param string $url
545
+	 * @return string|false
546
+	 */
547
+	public function checkTileCache(string $url)
548
+	{
549
+		$filename = $this->tileUrlToFilename($url);
550
+		if (file_exists($filename)) {
551
+			return file_get_contents($filename);
552
+		}
553
+		return false;
554
+	}
555
+
556
+	/**
557
+	 *
558
+	 * @param string $url
559
+	 * @return string
560
+	 */
561
+	public function tileUrlToFilename(string $url): string
562
+	{
563
+		return $this->tileCacheBaseDir . "/" . substr($url, strpos($url, '/') + 1);
564
+	}
565
+
566
+	/**
567
+	 * Write a tile into the cache.
568
+	 *
569
+	 * @param string $url
570
+	 * @param mixed  $data
571
+	 */
572
+	public function writeTileToCache(string $url, $data): void
573
+	{
574
+		$filename = $this->tileUrlToFilename($url);
575
+		$this->mkdirRecursive(dirname($filename), 0777);
576
+		file_put_contents($filename, $data);
577
+	}
578
+
579
+	/**
580
+	 * Recursively create the directory.
581
+	 *
582
+	 * @param string $pathname
583
+	 *            The directory path.
584
+	 * @param int    $mode
585
+	 *            File access mode. For more information on modes, read the details on the chmod manpage.
586
+	 */
587
+	public function mkdirRecursive(string $pathname, int $mode): bool
588
+	{
589
+		is_dir(dirname($pathname)) || $this->mkdirRecursive(dirname($pathname), $mode);
590
+		return is_dir($pathname) || mkdir($pathname, $mode) || is_dir($pathname);
591
+	}
592
+
593
+	/**
594
+	 * Place markers on the map and number them in the same order as they are listed in the html.
595
+	 */
596
+	public function placeMarkers(): void
597
+	{
598
+		$count               = 0;
599
+		$color               = imagecolorallocate($this->image, 0, 0, 0);
600
+		$bgcolor             = imagecolorallocate($this->image, 200, 200, 200);
601
+		$markerBaseDir       = __DIR__ . '/icons';
602
+		$markerImageOffsetX  = 0;
603
+		$markerImageOffsetY  = 0;
604
+		$markerShadowOffsetX = 0;
605
+		$markerShadowOffsetY = 0;
606
+		$markerShadowImg     = null;
607
+		// loop thru marker array
608
+		foreach ($this->markers as $marker) {
609
+			// set some local variables
610
+			$markerLat  = $marker ['lat'];
611
+			$markerLon  = $marker ['lon'];
612
+			$markerType = $marker ['type'];
613
+			// clear variables from previous loops
614
+			$markerFilename = '';
615
+			$markerShadow   = '';
616
+			$matches        = false;
617
+			// check for marker type, get settings from markerPrototypes
618
+			if ($markerType) {
619
+				foreach ($this->markerPrototypes as $markerPrototype) {
620
+					if (preg_match($markerPrototype ['regex'], $markerType, $matches)) {
621
+						$markerFilename = $matches [0] . $markerPrototype ['extension'];
622
+						if ($markerPrototype ['offsetImage']) {
623
+							list ($markerImageOffsetX, $markerImageOffsetY) = explode(
624
+								",",
625
+								$markerPrototype ['offsetImage']
626
+							);
627
+						}
628
+						$markerShadow = $markerPrototype ['shadow'];
629
+						if ($markerShadow) {
630
+							list ($markerShadowOffsetX, $markerShadowOffsetY) = explode(
631
+								",",
632
+								$markerPrototype ['offsetShadow']
633
+							);
634
+						}
635
+					}
636
+				}
637
+			}
638
+			// create img resource
639
+			if (file_exists($markerBaseDir . '/' . $markerFilename)) {
640
+				$markerImg = imagecreatefrompng($markerBaseDir . '/' . $markerFilename);
641
+			} else {
642
+				$markerImg = imagecreatefrompng($markerBaseDir . '/marker.png');
643
+			}
644
+			// check for shadow + create shadow recource
645
+			if ($markerShadow && file_exists($markerBaseDir . '/' . $markerShadow)) {
646
+				$markerShadowImg = imagecreatefrompng($markerBaseDir . '/' . $markerShadow);
647
+			}
648
+			// calc position
649
+			$destX = floor(
650
+				($this->width / 2) -
651
+				$this->tileSize * ($this->centerX - $this->lonToTile($markerLon, $this->zoom))
652
+			);
653
+			$destY = floor(
654
+				($this->height / 2) -
655
+				$this->tileSize * ($this->centerY - $this->latToTile($markerLat, $this->zoom))
656
+			);
657
+			// copy shadow on basemap
658
+			if ($markerShadow && $markerShadowImg) {
659
+				imagecopy(
660
+					$this->image,
661
+					$markerShadowImg,
662
+					$destX + (int)$markerShadowOffsetX,
663
+					$destY + (int)$markerShadowOffsetY,
664
+					0,
665
+					0,
666
+					imagesx($markerShadowImg),
667
+					imagesy($markerShadowImg)
668
+				);
669
+			}
670
+			// copy marker on basemap above shadow
671
+			imagecopy(
672
+				$this->image,
673
+				$markerImg,
674
+				$destX + (int)$markerImageOffsetX,
675
+				$destY + (int)$markerImageOffsetY,
676
+				0,
677
+				0,
678
+				imagesx($markerImg),
679
+				imagesy($markerImg)
680
+			);
681
+			// add label
682
+			imagestring(
683
+				$this->image,
684
+				3,
685
+				$destX - imagesx($markerImg) + 1,
686
+				$destY + (int)$markerImageOffsetY + 1,
687
+				++$count,
688
+				$bgcolor
689
+			);
690
+			imagestring(
691
+				$this->image,
692
+				3,
693
+				$destX - imagesx($markerImg),
694
+				$destY + (int)$markerImageOffsetY,
695
+				$count,
696
+				$color
697
+			);
698
+		}
699
+	}
700
+
701
+	/**
702
+	 * Draw kml trace on the map.
703
+	 * @throws exception if loading the specified KML fails
704
+	 */
705
+	public function drawKML(): void
706
+	{
707
+		// TODO get colour from kml node (not currently supported in geoPHP)
708
+		$col     = imagecolorallocatealpha($this->image, 255, 0, 0, .4 * 127);
709
+		$kmlgeom = geoPHP::load(file_get_contents($this->kmlFileName), 'kml');
710
+		$this->drawGeometry($kmlgeom, $col);
711
+	}
712
+
713
+	/**
714
+	 * Draw geometry or geometry collection on the map.
715
+	 *
716
+	 * @param Geometry|GeometryCollection|MultiPolygon|MultiLineString|MultiPoint|Polygon|LineString|Point $geom
717
+	 * @param int                                                                                          $colour
718
+	 *            drawing colour
719
+	 */
720
+	private function drawGeometry(Geometry $geom, int $colour): void
721
+	{
722
+		if (empty($geom)) {
723
+			return;
724
+		}
725
+
726
+		switch ($geom->geometryType()) {
727
+			case 'GeometryCollection' :
728
+				// recursively draw part of the collection
729
+				for ($i = 1; $i < $geom->numGeometries() + 1; $i++) {
730
+					$_geom = $geom->geometryN($i);
731
+					$this->drawGeometry($_geom, $colour);
732
+				}
733
+				break;
734
+			case 'MultiPolygon' :
735
+			case 'MultiLineString' :
736
+			case 'MultiPoint' :
737
+				// TODO implement / do nothing
738
+				break;
739
+			case 'Polygon' :
740
+				$this->drawPolygon($geom, $colour);
741
+				break;
742
+			case 'LineString' :
743
+				$this->drawLineString($geom, $colour);
744
+				break;
745
+			case 'Point' :
746
+				$this->drawPoint($geom, $colour);
747
+				break;
748
+			default :
749
+				// draw nothing
750
+				break;
751
+		}
752
+	}
753
+
754
+	/**
755
+	 * Draw a polygon on the map.
756
+	 *
757
+	 * @param Polygon $polygon
758
+	 * @param int     $colour
759
+	 *            drawing colour
760
+	 */
761
+	private function drawPolygon(Polygon $polygon, int $colour)
762
+	{
763
+		// TODO implementation of drawing holes,
764
+		// maybe draw the polygon to an in-memory image and use imagecopy, draw polygon in col., draw holes in bgcol?
765
+
766
+		// print_r('Polygon:<br />');
767
+		// print_r($polygon);
768
+		$extPoints = array();
769
+		// extring is a linestring actually..
770
+		$extRing = $polygon->exteriorRing();
771
+
772
+		for ($i = 1; $i < $extRing->numGeometries(); $i++) {
773
+			$p1           = $extRing->geometryN($i);
774
+			$x            = floor(
775
+				($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($p1->x(), $this->zoom))
776
+			);
777
+			$y            = floor(
778
+				($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($p1->y(), $this->zoom))
779
+			);
780
+			$extPoints [] = $x;
781
+			$extPoints [] = $y;
782
+		}
783
+		// print_r('points:('.($i-1).')<br />');
784
+		// print_r($extPoints);
785
+		// imagepolygon ($this->image, $extPoints, $i-1, $colour );
786
+		imagefilledpolygon($this->image, $extPoints, $i - 1, $colour);
787
+	}
788
+
789
+	/**
790
+	 * Draw a line on the map.
791
+	 *
792
+	 * @param LineString $line
793
+	 * @param int        $colour
794
+	 *            drawing colour
795
+	 */
796
+	private function drawLineString(LineString $line, int $colour)
797
+	{
798
+		imagesetthickness($this->image, 2);
799
+		for ($p = 1; $p < $line->numGeometries(); $p++) {
800
+			// get first pair of points
801
+			$p1 = $line->geometryN($p);
802
+			$p2 = $line->geometryN($p + 1);
803
+			// translate to paper space
804
+			$x1 = floor(
805
+				($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($p1->x(), $this->zoom))
806
+			);
807
+			$y1 = floor(
808
+				($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($p1->y(), $this->zoom))
809
+			);
810
+			$x2 = floor(
811
+				($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($p2->x(), $this->zoom))
812
+			);
813
+			$y2 = floor(
814
+				($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($p2->y(), $this->zoom))
815
+			);
816
+			// draw to image
817
+			imageline($this->image, $x1, $y1, $x2, $y2, $colour);
818
+		}
819
+		imagesetthickness($this->image, 1);
820
+	}
821
+
822
+	/**
823
+	 * Draw a point on the map.
824
+	 *
825
+	 * @param Point $point
826
+	 * @param int   $colour
827
+	 *            drawing colour
828
+	 */
829
+	private function drawPoint(Point $point, int $colour)
830
+	{
831
+		imagesetthickness($this->image, 2);
832
+		// translate to paper space
833
+		$cx = floor(
834
+			($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile($point->x(), $this->zoom))
835
+		);
836
+		$cy = floor(
837
+			($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile($point->y(), $this->zoom))
838
+		);
839
+		$r  = 5;
840
+		// draw to image
841
+		// imageellipse($this->image, $cx, $cy,$r, $r, $colour);
842
+		imagefilledellipse($this->image, $cx, $cy, $r, $r, $colour);
843
+		// don't use imageellipse because the imagesetthickness function has
844
+		// no effect. So the better workaround is to use imagearc.
845
+		imagearc($this->image, $cx, $cy, $r, $r, 0, 359, $colour);
846
+		imagesetthickness($this->image, 1);
847
+	}
848
+
849
+	/**
850
+	 * Draw gpx trace on the map.
851
+	 * @throws exception if loading the specified GPX fails
852
+	 */
853
+	public function drawGPX()
854
+	{
855
+		$col     = imagecolorallocatealpha($this->image, 0, 0, 255, .4 * 127);
856
+		$gpxgeom = geoPHP::load(file_get_contents($this->gpxFileName), 'gpx');
857
+		$this->drawGeometry($gpxgeom, $col);
858
+	}
859
+
860
+	/**
861
+	 * Draw geojson on the map.
862
+	 * @throws exception if loading the specified GeoJSON fails
863
+	 */
864
+	public function drawGeojson()
865
+	{
866
+		$col     = imagecolorallocatealpha($this->image, 255, 0, 255, .4 * 127);
867
+		$gpxgeom = geoPHP::load(file_get_contents($this->geojsonFileName), 'json');
868
+		$this->drawGeometry($gpxgeom, $col);
869
+	}
870
+
871
+	/**
872
+	 * add copyright and origin notice and icons to the map.
873
+	 */
874
+	public function drawCopyright()
875
+	{
876
+		$logoBaseDir = dirname(__FILE__) . '/' . 'logo/';
877
+		$logoImg     = imagecreatefrompng($logoBaseDir . $this->tileInfo ['openstreetmap'] ['logo']);
878
+		$textcolor   = imagecolorallocate($this->image, 0, 0, 0);
879
+		$bgcolor     = imagecolorallocate($this->image, 200, 200, 200);
880
+
881
+		imagecopy(
882
+			$this->image,
883
+			$logoImg,
884
+			0,
885
+			imagesy($this->image) - imagesy($logoImg),
886
+			0,
887
+			0,
888
+			imagesx($logoImg),
889
+			imagesy($logoImg)
890
+		);
891
+		imagestring(
892
+			$this->image,
893
+			1,
894
+			imagesx($logoImg) + 2,
895
+			imagesy($this->image) - imagesy($logoImg) + 1,
896
+			$this->tileInfo ['openstreetmap'] ['txt'],
897
+			$bgcolor
898
+		);
899
+		imagestring(
900
+			$this->image,
901
+			1,
902
+			imagesx($logoImg) + 1,
903
+			imagesy($this->image) - imagesy($logoImg),
904
+			$this->tileInfo ['openstreetmap'] ['txt'],
905
+			$textcolor
906
+		);
907
+
908
+		// additional tile source info, ie. who created/hosted the tiles
909
+		$xIconOffset = 0;
910
+		if ($this->maptype === 'openstreetmap') {
911
+			$mapAuthor = "(c) OpenStreetMap maps/CC BY-SA";
912
+		} else {
913
+			$mapAuthor   = $this->tileInfo [$this->maptype] ['txt'];
914
+			$iconImg     = imagecreatefrompng($logoBaseDir . $this->tileInfo [$this->maptype] ['logo']);
915
+			$xIconOffset = imagesx($iconImg);
916
+			imagecopy(
917
+				$this->image,
918
+				$iconImg,
919
+				imagesx($logoImg) + 1,
920
+				imagesy($this->image) - imagesy($iconImg),
921
+				0,
922
+				0,
923
+				imagesx($iconImg),
924
+				imagesy($iconImg)
925
+			);
926
+		}
927
+		imagestring(
928
+			$this->image,
929
+			1,
930
+			imagesx($logoImg) + $xIconOffset + 4,
931
+			imagesy($this->image) - ceil(imagesy($logoImg) / 2) + 1,
932
+			$mapAuthor,
933
+			$bgcolor
934
+		);
935
+		imagestring(
936
+			$this->image,
937
+			1,
938
+			imagesx($logoImg) + $xIconOffset + 3,
939
+			imagesy($this->image) - ceil(imagesy($logoImg) / 2),
940
+			$mapAuthor,
941
+			$textcolor
942
+		);
943
+	}
944 944
 }
Please login to merge, or discard this patch.
conf/metadata.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -22,65 +22,65 @@
 block discarded – undo
22 22
  */
23 23
 
24 24
 $meta['enableOSM']                = array(
25
-    'onoff'
25
+	'onoff'
26 26
 );
27 27
 $meta['enableStamen']             = array(
28
-    'onoff'
28
+	'onoff'
29 29
 );
30 30
 $meta['enableGoogle']             = array(
31
-    'onoff'
31
+	'onoff'
32 32
 );
33 33
 $meta['googleAPIkey']             = array(
34
-    'string'
34
+	'string'
35 35
 );
36 36
 $meta['enableBing']               = array(
37
-    'onoff'
37
+	'onoff'
38 38
 );
39 39
 $meta['bingAPIKey']               = array(
40
-    'string'
40
+	'string'
41 41
 );
42 42
 $meta['tfApiKey']                 = array(
43
-    'string'
43
+	'string'
44 44
 );
45 45
 $meta['iconUrlOverload']          = array(
46
-    'string'
46
+	'string'
47 47
 );
48 48
 $meta['enableA11y']               = array(
49
-    'onoff'
49
+	'onoff'
50 50
 );
51 51
 $meta['optionStaticMapGenerator'] = array(
52
-    'multichoice',
53
-    '_choices' => array('local', 'remote')
52
+	'multichoice',
53
+	'_choices' => array('local', 'remote')
54 54
 );
55 55
 $meta['autoZoomMap']              = array(
56
-    'onoff'
56
+	'onoff'
57 57
 );
58 58
 $meta ['displayformat']           = array(
59
-    'multichoice',
60
-    '_choices' => array('DD', 'DMS')
59
+	'multichoice',
60
+	'_choices' => array('DD', 'DMS')
61 61
 );
62 62
 
63 63
 $meta ['default_width']         = array(
64
-    'string'
64
+	'string'
65 65
 );
66 66
 $meta ['default_height']        = array(
67
-    'string'
67
+	'string'
68 68
 );
69 69
 $meta ['default_zoom']          = array(
70
-    'string'
70
+	'string'
71 71
 );
72 72
 $meta ['default_autozoom']      = array(
73
-    'onoff'
73
+	'onoff'
74 74
 );
75 75
 $meta ['default_controls']      = array(
76
-    'onoff'
76
+	'onoff'
77 77
 );
78 78
 $meta ['default_kmlfile']       = array(
79
-    'string'
79
+	'string'
80 80
 );
81 81
 $meta ['default_gpxfile']       = array(
82
-    'string'
82
+	'string'
83 83
 );
84 84
 $meta ['default_geojsonfile']   = array(
85
-    'string'
85
+	'string'
86 86
 );
Please login to merge, or discard this patch.