xref: /plugin/openlayersmap/syntax/olmap.php (revision 554f43b5f550282ef680f43e9a8230a347b99811)
138a47c60SMark Prins<?php
238a47c60SMark Prins/*
338a47c60SMark Prins * Copyright (c) 2008-2011 Mark C. Prins <mc.prins@gmail.com>
438a47c60SMark Prins *
538a47c60SMark Prins * Permission to use, copy, modify, and distribute this software for any
638a47c60SMark Prins * purpose with or without fee is hereby granted, provided that the above
738a47c60SMark Prins * copyright notice and this permission notice appear in all copies.
838a47c60SMark Prins *
938a47c60SMark Prins * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1038a47c60SMark Prins * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1138a47c60SMark Prins * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1238a47c60SMark Prins * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1338a47c60SMark Prins * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1438a47c60SMark Prins * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1538a47c60SMark Prins * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1638a47c60SMark Prins */
1738a47c60SMark Prins
1838a47c60SMark Prins/**
1938a47c60SMark Prins * Plugin OL Maps: Allow Display of a OpenLayers Map in a wiki page.
2038a47c60SMark Prins *
2138a47c60SMark Prins * @author Mark Prins
2238a47c60SMark Prins */
2338a47c60SMark Prins
2438a47c60SMark Prinsif (!defined('DOKU_INC'))
2538a47c60SMark Prinsdefine('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
2638a47c60SMark Prinsif (!defined('DOKU_PLUGIN'))
2738a47c60SMark Prinsdefine('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
2838a47c60SMark Prinsrequire_once (DOKU_PLUGIN . 'syntax.php');
2938a47c60SMark Prins
3038a47c60SMark Prins/**
3138a47c60SMark Prins * All DokuWiki plugins to extend the parser/rendering mechanism
3238a47c60SMark Prins * need to inherit from this class
3338a47c60SMark Prins */
3438a47c60SMark Prinsclass syntax_plugin_openlayersmap_olmap extends DokuWiki_Syntax_Plugin {
3538a47c60SMark Prins	/** defaults of the recognized attributes of the olmap tag. */
3638a47c60SMark Prins	private $dflt = array (
3738a47c60SMark Prins		'id' => 'olmap',
3838a47c60SMark Prins		'width' => '550px',
3938a47c60SMark Prins		'height' => '450px',
4038a47c60SMark Prins		'lat' => 50.0,
4138a47c60SMark Prins		'lon' => 5.1,
4238a47c60SMark Prins		'zoom' => 12,
4338a47c60SMark Prins		'toolbar' => true,
4438a47c60SMark Prins		'statusbar' => true,
4538a47c60SMark Prins		'controls' => true,
4638a47c60SMark Prins		'poihoverstyle' => false,
4738a47c60SMark Prins		'baselyr'=>'OpenStreetMap',
4838a47c60SMark Prins	 	'gpxfile' => '',
4938a47c60SMark Prins 		'kmlfile' => ''
5038a47c60SMark Prins 		);
5138a47c60SMark Prins
5238a47c60SMark Prins 		/**
5338a47c60SMark Prins 		 * Return the type of syntax this plugin defines.
5438a47c60SMark Prins 		 * @Override
5538a47c60SMark Prins 		 */
5638a47c60SMark Prins 		function getType() {
5738a47c60SMark Prins 			return 'substition';
5838a47c60SMark Prins 		}
5938a47c60SMark Prins
6038a47c60SMark Prins 		/**
6138a47c60SMark Prins 		 * Defines how this syntax is handled regarding paragraphs.
6238a47c60SMark Prins 		 * @Override
6338a47c60SMark Prins 		 */
6438a47c60SMark Prins 		function getPType() {
6538a47c60SMark Prins 			return 'block';
6638a47c60SMark Prins 		}
6738a47c60SMark Prins
6838a47c60SMark Prins 		/**
6938a47c60SMark Prins 		 * Returns a number used to determine in which order modes are added.
7038a47c60SMark Prins 		 * @Override
7138a47c60SMark Prins 		 */
7238a47c60SMark Prins 		function getSort() {
7338a47c60SMark Prins 			return 901;
7438a47c60SMark Prins 		}
7538a47c60SMark Prins
7638a47c60SMark Prins 		/**
7738a47c60SMark Prins 		 * This function is inherited from Doku_Parser_Mode.
7838a47c60SMark Prins 		 * Here is the place to register the regular expressions needed
7938a47c60SMark Prins 		 * to match your syntax.
8038a47c60SMark Prins 		 * @Override
8138a47c60SMark Prins 		 */
8238a47c60SMark Prins 		function connectTo($mode) {
8338a47c60SMark Prins 			$this->Lexer->addSpecialPattern('<olmap ?[^>\n]*>.*?</olmap>', $mode, 'plugin_openlayersmap_olmap');
8438a47c60SMark Prins 		}
8538a47c60SMark Prins
8638a47c60SMark Prins 		/**
8738a47c60SMark Prins 		 * handle each olmap tag. prepare the matched syntax for use in the renderer.
8838a47c60SMark Prins 		 * @Override
8938a47c60SMark Prins 		 */
9038a47c60SMark Prins 		function handle($match, $state, $pos, &$handler) {
9138a47c60SMark Prins 			// break matched cdata into its components
9238a47c60SMark Prins 			list ($str_params, $str_points) = explode('>', substr($match, 7, -9), 2);
93*554f43b5SMark Prins 			// get the lat/lon for adding them to the metadata (used by geotag)
94*554f43b5SMark Prins 			preg_match('(lat[:|=]\"\d*\.\d*\")',$match,$mainLat);
95*554f43b5SMark Prins 			preg_match('(lon[:|=]\"\d*\.\d*\")',$match,$mainLon);
96*554f43b5SMark Prins 			$mainLat=substr($mainLat[0],5,-1);
97*554f43b5SMark Prins 			$mainLon=substr($mainLon[0],5,-1);
9838a47c60SMark Prins
9938a47c60SMark Prins 			$gmap = $this->_extract_params($str_params);
10038a47c60SMark Prins 			$overlay = $this->_extract_points($str_points);
10138a47c60SMark Prins
10238a47c60SMark Prins 			$mapid = $gmap['id'];
10338a47c60SMark Prins
10438a47c60SMark Prins 			// determine width and height (inline styles) for the map image
10538a47c60SMark Prins 			if ($gmap['width'] || $gmap['height']) {
10638a47c60SMark Prins 				$style = $gmap['width'] ? 'width: ' . $gmap['width'] . ";" : "";
10738a47c60SMark Prins 				$style .= $gmap['height'] ? 'height: ' . $gmap['height'] . ";" : "";
10838a47c60SMark Prins 				$style = "style='$style'";
10938a47c60SMark Prins 			} else {
11038a47c60SMark Prins 				$style = '';
11138a47c60SMark Prins 			}
11238a47c60SMark Prins
11338a47c60SMark Prins 			// unset gmap values for width and height - they don't go into javascript
11438a47c60SMark Prins 			unset ($gmap['width'], $gmap['height']);
11538a47c60SMark Prins
11638a47c60SMark Prins 			// create a javascript parameter string for the map
11738a47c60SMark Prins 			$param = '';
11838a47c60SMark Prins 			foreach ($gmap as $key => $val) {
11938a47c60SMark Prins 				$param .= is_numeric($val) ? "$key:$val," : "$key:'" . hsc($val) . "',";
12038a47c60SMark Prins 			}
12138a47c60SMark Prins 			if (!empty ($param)) {
12238a47c60SMark Prins 				$param = substr($param, 0, -1);
12338a47c60SMark Prins 			}
12438a47c60SMark Prins 			unset ($gmap['id']);
12538a47c60SMark Prins
12638a47c60SMark Prins 			// create a javascript serialisation of the point data
12738a47c60SMark Prins 			$poi = '';
12838a47c60SMark Prins 			if (!empty ($overlay)) {
12938a47c60SMark Prins 				foreach ($overlay as $data) {
13038a47c60SMark Prins 					list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
13138a47c60SMark Prins 					$poi .= ",{lat: $lat, lon: $lon, txt: '$text', angle: $angle, opacity: $opacity, img: '$img'}";
13238a47c60SMark Prins 				}
13338a47c60SMark Prins 				$poi = substr($poi, 1);
13438a47c60SMark Prins 			}
13538a47c60SMark Prins 			$js .= "createMap({" . $param . " },[$poi]);";
13638a47c60SMark Prins
13738a47c60SMark Prins 			return array (
13838a47c60SMark Prins 			$mapid,
13938a47c60SMark Prins 			$style,
140*554f43b5SMark Prins 			$js,
141*554f43b5SMark Prins 			$mainLat,
142*554f43b5SMark Prins 			$mainLon
14338a47c60SMark Prins 			);
14438a47c60SMark Prins 		}
14538a47c60SMark Prins
14638a47c60SMark Prins 		/**
14738a47c60SMark Prins 		 * render html tag/output. render the content.
14838a47c60SMark Prins 		 * @Override
14938a47c60SMark Prins 		 */
15038a47c60SMark Prins 		function render($mode, &$renderer, $data) {
15138a47c60SMark Prins 			static $initialised = false; // set to true after script initialisation
152*554f43b5SMark Prins 			list ($mapid, $style, $param, $mainLat, $mainLon) = $data;
153*554f43b5SMark Prins
15438a47c60SMark Prins 			if ($mode == 'xhtml') {
15538a47c60SMark Prins 				$olscript = '';
15638a47c60SMark Prins 				$olEnable = false;
15738a47c60SMark Prins 				$gscript = '';
15838a47c60SMark Prins 				$gEnable = false;
15938a47c60SMark Prins 				$vscript = '';
16038a47c60SMark Prins 				$vEnable = false;
16138a47c60SMark Prins 				$yscript = '';
16238a47c60SMark Prins 				$yEnable = false;
16338a47c60SMark Prins
16438a47c60SMark Prins 				$scriptEnable = '';
16538a47c60SMark Prins
16638a47c60SMark Prins 				if (!$initialised) {
16738a47c60SMark Prins 					$initialised = true;
16838a47c60SMark Prins
16938a47c60SMark Prins 					$gscript = $this->getConf('googleScriptUrl');
17038a47c60SMark Prins 					$gscript = $gscript ? '<script type="text/javascript" src="' . $gscript . '"></script>' : "";
17138a47c60SMark Prins
17238a47c60SMark Prins 					$vscript = $this->getConf('veScriptUrl');
17338a47c60SMark Prins 					$vscript = $vscript ? '<script type="text/javascript" src="' . $vscript . '"></script>' : "";
17438a47c60SMark Prins
17538a47c60SMark Prins 					$yscript = $this->getConf('yahooScriptUrl');
17638a47c60SMark Prins 					$yscript = $yscript ? '<script type="text/javascript" src="' . $yscript . '"></script>' : "";
17738a47c60SMark Prins
17838a47c60SMark Prins 					$olscript = $this->getConf('olScriptUrl');
17938a47c60SMark Prins 					$olscript = $olscript ? '<script type="text/javascript" src="' . $olscript . '"></script>' : "";
18038a47c60SMark Prins 					$olscript = str_replace('DOKU_PLUGIN', DOKU_PLUGIN, $olscript);
18138a47c60SMark Prins
18238a47c60SMark Prins 					$scriptEnable = '<script type="text/javascript">' . "\n" . '//<![CDATA[' . "\n";
18338a47c60SMark Prins 					$scriptEnable .= $olscript ? 'olEnable = true;' : 'olEnable = false;';
18438a47c60SMark Prins 					$scriptEnable .= $yscript ? ' yEnable = true;' : ' yEnable = false;';
18538a47c60SMark Prins 					$scriptEnable .= $vscript ? ' veEnable = true;' : ' veEnable = false;';
18638a47c60SMark Prins 					$scriptEnable .= $gscript ? ' gEnable = true;' : ' gEnable = false;';
18738a47c60SMark Prins 					$scriptEnable .= "\n" . '//]]>' . "\n" . '</script>';
18838a47c60SMark Prins 				}
18938a47c60SMark Prins 				$renderer->doc .= "
19038a47c60SMark Prins 				$olscript
19138a47c60SMark Prins 				$gscript
19238a47c60SMark Prins 				$vscript
19338a47c60SMark Prins 				$yscript
19438a47c60SMark Prins 				$scriptEnable
19538a47c60SMark Prins			    <div id='olContainer' class='olContainer'>
19638a47c60SMark Prins			        <div id='$mapid-olToolbar' class='olToolbar'></div>
19738a47c60SMark Prins			        <div style='clear:both;'></div>
19838a47c60SMark Prins			        <div id='$mapid' $style ></div>
19938a47c60SMark Prins			        <div id='$mapid-olStatusBar' class='olStatusBarContainer'>
20038a47c60SMark Prins			            <div id='$mapid-statusbar-scale' class='olStatusBar olStatusBarScale'>scale</div>
20138a47c60SMark Prins			            <div id='$mapid-statusbar-link' class='olStatusBar olStatusBarPermalink'>
20238a47c60SMark Prins			                <a href='' id='$mapid-statusbar-link-ref'>map link</a>
20338a47c60SMark Prins			            </div>
20438a47c60SMark Prins			            <div id='$mapid-statusbar-mouseposition' class='olStatusBar olStatusBarMouseposition'></div>
20538a47c60SMark Prins			            <div id='$mapid-statusbar-projection' class='olStatusBar olStatusBarProjection'>proj</div>
20638a47c60SMark Prins			            <div id='$mapid-statusbar-text' class='olStatusBar olStatusBarText'>txt</div>
20738a47c60SMark Prins			        </div>
20838a47c60SMark Prins			    </div>
20938a47c60SMark Prins			    <p>&nbsp;</p>
21038a47c60SMark Prins			    <script type='text/javascript'>//<![CDATA[
21138a47c60SMark Prins			    var $mapid = $param
21238a47c60SMark Prins			   //]]></script>";
213*554f43b5SMark Prins 			} elseif ($mode == 'metadata') {
214*554f43b5SMark Prins 				// render metadata if available
215*554f43b5SMark Prins 				if (!(($this->dflt['lat']==$mainLat)||($thisdflt['lon']==$mainLon))){
216*554f43b5SMark Prins 					// unless they are the default
217*554f43b5SMark Prins 					$renderer->meta['geo']['lat'] = $mainLat;
218*554f43b5SMark Prins 					$renderer->meta['geo']['lon'] = $mainLon;
219*554f43b5SMark Prins 				}
220*554f43b5SMark Prins 				return true;
22138a47c60SMark Prins 			}
22238a47c60SMark Prins 			return false;
22338a47c60SMark Prins 		}
22438a47c60SMark Prins
22538a47c60SMark Prins 		/**
22638a47c60SMark Prins 		 * extract parameters for the map from the parameter string
22738a47c60SMark Prins 		 *
22838a47c60SMark Prins 		 * @param   string    $str_params   string of key="value" pairs
22938a47c60SMark Prins 		 * @return  array                   associative array of parameters key=>value
23038a47c60SMark Prins 		 */
23138a47c60SMark Prins 		function _extract_params($str_params) {
23238a47c60SMark Prins 			$param = array ();
23338a47c60SMark Prins 			preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER);
23438a47c60SMark Prins 			// parse match for instructions, break into key value pairs
23538a47c60SMark Prins 			$gmap = $this->dflt;
23638a47c60SMark Prins 			foreach ($param as $kvpair) {
23738a47c60SMark Prins 				list ($match, $key, $val) = $kvpair;
23838a47c60SMark Prins 				$key = strtolower($key);
23938a47c60SMark Prins 				if (isset ($gmap[$key])){
24038a47c60SMark Prins 					$gmap[$key] = strtolower($val);
24138a47c60SMark Prins 				}
24238a47c60SMark Prins 			}
24338a47c60SMark Prins 			return $gmap;
24438a47c60SMark Prins 		}
24538a47c60SMark Prins
24638a47c60SMark Prins 		/**
24738a47c60SMark Prins 		 * extract overlay points for the map from the wiki syntax data
24838a47c60SMark Prins 		 *
24938a47c60SMark Prins 		 * @param   string    $str_points   multi-line string of lat,lon,text triplets
25038a47c60SMark Prins 		 * @return  array                   multi-dimensional array of lat,lon,text triplets
25138a47c60SMark Prins 		 */
25238a47c60SMark Prins 		function _extract_points($str_points) {
25338a47c60SMark Prins 			$point = array ();
25438a47c60SMark Prins 			//preg_match_all('/^(.*?),(.*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER);
25538a47c60SMark Prins 			preg_match_all('/^([+-]?[0-9].*?),([+-]?[0-9].*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER);
256*554f43b5SMark Prins 			// create poi array
25738a47c60SMark Prins 			$overlay = array ();
25838a47c60SMark Prins 			foreach ($point as $pt) {
25938a47c60SMark Prins 				list ($match, $lat, $lon, $angle, $opacity, $img, $text) = $pt;
26038a47c60SMark Prins 				$lat = is_numeric($lat) ? $lat : 0;
26138a47c60SMark Prins 				$lon = is_numeric($lon) ? $lon : 0;
26238a47c60SMark Prins 				$angle = is_numeric($angle) ? $angle : 0;
26338a47c60SMark Prins 				$opacity = is_numeric($opacity) ? $opacity : 0.8;
26438a47c60SMark Prins 				$img = trim($img);
26538a47c60SMark Prins 				// TODO validate & set up default img?
26638a47c60SMark Prins 				$text = addslashes(str_replace("\n", "", p_render("xhtml", p_get_instructions($text), $info)));
26738a47c60SMark Prins 				$overlay[] = array (
26838a47c60SMark Prins 				$lat,
26938a47c60SMark Prins 				$lon,
27038a47c60SMark Prins 				$text,
27138a47c60SMark Prins 				$angle,
27238a47c60SMark Prins 				$opacity,
27338a47c60SMark Prins 				$img
27438a47c60SMark Prins 				);
27538a47c60SMark Prins 			}
27638a47c60SMark Prins 			return $overlay;
27738a47c60SMark Prins 		}
27838a47c60SMark Prins}