xref: /plugin/openlayersmap/syntax/olmap.php (revision 38a47c60cc6e07c37451d90f3ec54a36e64048ad)
1<?php
2/*
3 * Copyright (c) 2008-2011 Mark C. Prins <mc.prins@gmail.com>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/**
19 * Plugin OL Maps: Allow Display of a OpenLayers Map in a wiki page.
20 *
21 * @author Mark Prins
22 */
23
24if (!defined('DOKU_INC'))
25define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
26if (!defined('DOKU_PLUGIN'))
27define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
28require_once (DOKU_PLUGIN . 'syntax.php');
29
30/**
31 * All DokuWiki plugins to extend the parser/rendering mechanism
32 * need to inherit from this class
33 */
34class syntax_plugin_openlayersmap_olmap extends DokuWiki_Syntax_Plugin {
35	/** defaults of the recognized attributes of the olmap tag. */
36	private $dflt = array (
37		'id' => 'olmap',
38		'width' => '550px',
39		'height' => '450px',
40		'lat' => 50.0,
41		'lon' => 5.1,
42		'zoom' => 12,
43		'toolbar' => true,
44		'statusbar' => true,
45		'controls' => true,
46		'poihoverstyle' => false,
47		'baselyr'=>'OpenStreetMap',
48	 	'gpxfile' => '',
49 		'kmlfile' => ''
50 		);
51
52 		/**
53 		 * Return the type of syntax this plugin defines.
54 		 * @Override
55 		 */
56 		function getType() {
57 			return 'substition';
58 		}
59
60 		/**
61 		 * Defines how this syntax is handled regarding paragraphs.
62 		 * @Override
63 		 */
64 		function getPType() {
65 			return 'block';
66 		}
67
68 		/**
69 		 * Returns a number used to determine in which order modes are added.
70 		 * @Override
71 		 */
72 		function getSort() {
73 			return 901;
74 		}
75
76 		/**
77 		 * This function is inherited from Doku_Parser_Mode.
78 		 * Here is the place to register the regular expressions needed
79 		 * to match your syntax.
80 		 * @Override
81 		 */
82 		function connectTo($mode) {
83 			$this->Lexer->addSpecialPattern('<olmap ?[^>\n]*>.*?</olmap>', $mode, 'plugin_openlayersmap_olmap');
84 		}
85
86 		/**
87 		 * handle each olmap tag. prepare the matched syntax for use in the renderer.
88 		 * @Override
89 		 */
90 		function handle($match, $state, $pos, & $handler) {
91 			// break matched cdata into its components
92 			list ($str_params, $str_points) = explode('>', substr($match, 7, -9), 2);
93
94 			$gmap = $this->_extract_params($str_params);
95 			$overlay = $this->_extract_points($str_points);
96
97 			$mapid = $gmap['id'];
98
99 			// determine width and height (inline styles) for the map image
100 			if ($gmap['width'] || $gmap['height']) {
101 				$style = $gmap['width'] ? 'width: ' . $gmap['width'] . ";" : "";
102 				$style .= $gmap['height'] ? 'height: ' . $gmap['height'] . ";" : "";
103 				$style = "style='$style'";
104 			} else {
105 				$style = '';
106 			}
107
108 			// unset gmap values for width and height - they don't go into javascript
109 			unset ($gmap['width'], $gmap['height']);
110
111 			// create a javascript parameter string for the map
112 			$param = '';
113 			foreach ($gmap as $key => $val) {
114 				$param .= is_numeric($val) ? "$key:$val," : "$key:'" . hsc($val) . "',";
115 			}
116 			if (!empty ($param)) {
117 				$param = substr($param, 0, -1);
118 			}
119 			unset ($gmap['id']);
120
121 			// create a javascript serialisation of the point data
122 			$poi = '';
123 			if (!empty ($overlay)) {
124 				foreach ($overlay as $data) {
125 					list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
126 					$poi .= ",{lat: $lat, lon: $lon, txt: '$text', angle: $angle, opacity: $opacity, img: '$img'}";
127 				}
128 				$poi = substr($poi, 1);
129 			}
130 			$js .= "createMap({" . $param . " },[$poi]);";
131
132 			return array (
133 			$mapid,
134 			$style,
135 			$js
136 			);
137 		}
138
139 		/**
140 		 * render html tag/output. render the content.
141 		 * @Override
142 		 */
143 		function render($mode, & $renderer, $data) {
144 			static $initialised = false; // set to true after script initialisation
145 			if ($mode == 'xhtml') {
146 				list ($mapid, $style, $param) = $data;
147 				$olscript = '';
148 				$olEnable = false;
149 				$gscript = '';
150 				$gEnable = false;
151 				$vscript = '';
152 				$vEnable = false;
153 				$yscript = '';
154 				$yEnable = false;
155
156 				$scriptEnable = '';
157
158 				if (!$initialised) {
159 					$initialised = true;
160
161 					$gscript = $this->getConf('googleScriptUrl');
162 					$gscript = $gscript ? '<script type="text/javascript" src="' . $gscript . '"></script>' : "";
163
164 					$vscript = $this->getConf('veScriptUrl');
165 					$vscript = $vscript ? '<script type="text/javascript" src="' . $vscript . '"></script>' : "";
166
167 					$yscript = $this->getConf('yahooScriptUrl');
168 					$yscript = $yscript ? '<script type="text/javascript" src="' . $yscript . '"></script>' : "";
169
170 					$olscript = $this->getConf('olScriptUrl');
171 					$olscript = $olscript ? '<script type="text/javascript" src="' . $olscript . '"></script>' : "";
172 					$olscript = str_replace('DOKU_PLUGIN', DOKU_PLUGIN, $olscript);
173
174 					$scriptEnable = '<script type="text/javascript">' . "\n" . '//<![CDATA[' . "\n";
175 					$scriptEnable .= $olscript ? 'olEnable = true;' : 'olEnable = false;';
176 					$scriptEnable .= $yscript ? ' yEnable = true;' : ' yEnable = false;';
177 					$scriptEnable .= $vscript ? ' veEnable = true;' : ' veEnable = false;';
178 					$scriptEnable .= $gscript ? ' gEnable = true;' : ' gEnable = false;';
179 					$scriptEnable .= "\n" . '//]]>' . "\n" . '</script>';
180 				}
181 				$renderer->doc .= "
182 				$olscript
183 				$gscript
184 				$vscript
185 				$yscript
186 				$scriptEnable
187			    <div id='olContainer' class='olContainer'>
188			        <div id='$mapid-olToolbar' class='olToolbar'></div>
189			        <div style='clear:both;'></div>
190			        <div id='$mapid' $style ></div>
191			        <div id='$mapid-olStatusBar' class='olStatusBarContainer'>
192			            <div id='$mapid-statusbar-scale' class='olStatusBar olStatusBarScale'>scale</div>
193			            <div id='$mapid-statusbar-link' class='olStatusBar olStatusBarPermalink'>
194			                <a href='' id='$mapid-statusbar-link-ref'>map link</a>
195			            </div>
196			            <div id='$mapid-statusbar-mouseposition' class='olStatusBar olStatusBarMouseposition'></div>
197			            <div id='$mapid-statusbar-projection' class='olStatusBar olStatusBarProjection'>proj</div>
198			            <div id='$mapid-statusbar-text' class='olStatusBar olStatusBarText'>txt</div>
199			        </div>
200			    </div>
201			    <p>&nbsp;</p>
202			    <script type='text/javascript'>//<![CDATA[
203			    var $mapid = $param
204			   //]]></script>";
205 			}
206 			return false;
207 		}
208
209 		/**
210 		 * extract parameters for the map from the parameter string
211 		 *
212 		 * @param   string    $str_params   string of key="value" pairs
213 		 * @return  array                   associative array of parameters key=>value
214 		 */
215 		function _extract_params($str_params) {
216 			$param = array ();
217 			preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER);
218
219 			// parse match for instructions, break into key value pairs
220 			$gmap = $this->dflt;
221 			foreach ($param as $kvpair) {
222 				list ($match, $key, $val) = $kvpair;
223 				$key = strtolower($key);
224 				if (isset ($gmap[$key])){
225 					$gmap[$key] = strtolower($val);
226 				}
227 			}
228 			return $gmap;
229 		}
230
231 		/**
232 		 * extract overlay points for the map from the wiki syntax data
233 		 *
234 		 * @param   string    $str_points   multi-line string of lat,lon,text triplets
235 		 * @return  array                   multi-dimensional array of lat,lon,text triplets
236 		 */
237 		function _extract_points($str_points) {
238 			$point = array ();
239 			//preg_match_all('/^(.*?),(.*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER);
240 			preg_match_all('/^([+-]?[0-9].*?),([+-]?[0-9].*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER);
241
242 			$overlay = array ();
243 			foreach ($point as $pt) {
244 				list ($match, $lat, $lon, $angle, $opacity, $img, $text) = $pt;
245 				$lat = is_numeric($lat) ? $lat : 0;
246 				$lon = is_numeric($lon) ? $lon : 0;
247 				$angle = is_numeric($angle) ? $angle : 0;
248 				$opacity = is_numeric($opacity) ? $opacity : 0.8;
249 				$img = trim($img);
250 				// TODO validate & set up default img?
251 				$text = addslashes(str_replace("\n", "", p_render("xhtml", p_get_instructions($text), $info)));
252 				$overlay[] = array (
253 				$lat,
254 				$lon,
255 				$text,
256 				$angle,
257 				$opacity,
258 				$img
259 				);
260 			}
261 			return $overlay;
262 		}
263}