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