xref: /plugin/openlayersmap/syntax/olmap.php (revision e61425c75cd10f578fb12cf5549c27c36bd09b3a)
1<?php
2/*
3 * Copyright (c) 2008-2012 Mark C. Prins <mprins@users.sf.net>
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'))define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
25if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
26require_once (DOKU_PLUGIN . 'syntax.php');
27
28/**
29 * All DokuWiki plugins to extend the parser/rendering mechanism
30 * need to inherit from this class
31 */
32class syntax_plugin_openlayersmap_olmap extends DokuWiki_Syntax_Plugin {
33
34	/** defaults of the known attributes of the olmap tag. */
35	private $dflt = array (
36			'id'		=> 'olmap',
37			'width'		=> '550px',
38			'height'	=> '450px',
39			'lat'		=> 50.0,
40			'lon'		=> 5.1,
41			'zoom'		=> 12,
42			'toolbar'	=> true,
43			'statusbar'	=> true,
44			'controls'	=> true,
45			'poihoverstyle'	=> false,
46			'baselyr'	=> 'OpenStreetMap',
47			'gpxfile'	=> '',
48			'kmlfile'	=> '',
49			'summary'	=> ''
50	);
51
52	private $usingLocalStaticMap = false;
53
54	/**
55	 * Return the type of syntax this plugin defines.
56	 * @Override
57	 */
58	function getType() {
59		return 'substition';
60	}
61
62	/**
63	 * Defines how this syntax is handled regarding paragraphs.
64	 * @Override
65	 */
66	function getPType() {
67		//normal block stack
68		return 'block';
69	}
70
71	/**
72	 * Returns a number used to determine in which order modes are added.
73	 * @Override
74	 */
75	function getSort() {
76		return 901;
77	}
78
79	/**
80	 * This function is inherited from Doku_Parser_Mode.
81	 * Here is the place to register the regular expressions needed
82	 * to match your syntax.
83	 * @Override
84	 */
85	function connectTo($mode) {
86		$this->Lexer->addSpecialPattern('<olmap ?[^>\n]*>.*?</olmap>', $mode, 'plugin_openlayersmap_olmap');
87	}
88
89	/**
90	 * handle each olmap tag. prepare the matched syntax for use in the renderer.
91	 * @Override
92	 */
93	function handle($match, $state, $pos, &$handler) {
94		// break matched cdata into its components
95		list ($str_params, $str_points) = explode('>', substr($match, 7, -9), 2);
96		// get the lat/lon for adding them to the metadata (used by geotag)
97		preg_match('(lat[:|=]\"-?\d*\.\d*\")',$match,$mainLat);
98		preg_match('(lon[:|=]\"-?\d*\.\d*\")',$match,$mainLon);
99		$mainLat=substr($mainLat[0],5,-1);
100		$mainLon=substr($mainLon[0],5,-1);
101
102		$gmap = $this->_extract_params($str_params);
103		$overlay = $this->_extract_points($str_points);
104
105		// choose maptype based on tag
106		$imgUrl = "{{";
107		if (stripos($gmap['baselyr'],'google') !== false){
108			// use google
109			$imgUrl .= $this->_getGoogle($gmap, $overlay);
110			$imgUrl .="&.png";
111		} elseif (stripos($gmap['baselyr'],'ve') !== false){
112			// use bing
113			$imgUrl .= $this->_getBing($gmap, $overlay);
114			$imgUrl .="&.png";
115		} elseif (stripos($gmap['baselyr'],'bing') !== false){
116			// use bing
117			$imgUrl .= $this->_getBing($gmap, $overlay);
118			$imgUrl .="&.png";
119		} elseif (stripos($gmap['baselyr'],'mapquest') !== false){
120			if($this->getConf('optionStaticMapGenerator')=='remote'){
121				// use mapquest remote
122				$imgUrl .=$this->_getMapQuest($gmap,$overlay);
123				$imgUrl .="&.png";
124			} else{
125				$imgUrl .=$this->_getStaticOSM($gmap,$overlay);
126			}
127		} else {
128			$imgUrl .=$this->_getStaticOSM($gmap,$overlay);
129		}
130
131		// append dw p_render specific params and render
132		$imgUrl .="?".str_replace("px", "",$gmap['width'])."x".str_replace("px", "",$gmap['height']);
133		$imgUrl .= "&nolink";
134		$imgUrl .= " |".$gmap['summary']." }}";
135		$imgUrl=p_render("xhtml", p_get_instructions($imgUrl), $info);
136
137		$mapid = $gmap['id'];
138		// create a javascript parameter string for the map
139		$param = '';
140		foreach ($gmap as $key => $val) {
141			$param .= is_numeric($val) ? "$key: $val, " : "$key: '" . hsc($val) . "', ";
142		}
143		if (!empty ($param)) {
144			$param = substr($param, 0, -2);
145		}
146		unset ($gmap['id']);
147
148		// create a javascript serialisation of the point data
149		$poi = '';
150		$poitable='';
151		$rowId=0;
152		if (!empty ($overlay)) {
153			foreach ($overlay as $data) {
154				list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
155				$rowId++;
156				$poi .= ", {lat: $lat, lon: $lon, txt: '$text', angle: $angle, opacity: $opacity, img: '$img', rowId: $rowId}";
157				$poitable .='
158				<tr>
159				<td class="rowId">'.$rowId.'</td>
160				<td class="icon"><img src="'.DOKU_BASE.'lib/plugins/openlayersmap/icons/'.$img.'" alt="icon" /></td>
161				<td class="lat" title="'.$this->getLang('olmapPOIlatTitle').'">'.$lat.'</td>
162				<td class="lon" title="'.$this->getLang('olmapPOIlonTitle').'">'.$lon.'</td>
163				<td class="txt">'.$text.'</td>
164				</tr>';
165			}
166			$poi = substr($poi, 2);
167		}
168		if (!empty ($gmap['kmlfile'])) {
169			$poitable .='
170			<tr>
171			<td class="rowId"><img src="'.DOKU_BASE.'lib/plugins/openlayersmap/toolbar/kml_file.png" alt="KML icon" /></td>
172			<td class="icon"><img src="'.DOKU_BASE.'lib/plugins/openlayersmap/toolbar/kml_line.png" alt="icon" /></td>
173			<td class="txt" colspan="3">KML: '.$gmap['kmlfile'].'</td>
174			</tr>';
175		}
176		if (!empty ($gmap['gpxfile'])) {
177			$poitable .='
178			<tr>
179			<td class="rowId"><img src="'.DOKU_BASE.'lib/plugins/openlayersmap/toolbar/gpx_file.png" alt="GPX icon" /></td>
180			<td class="icon"><img src="'.DOKU_BASE.'lib/plugins/openlayersmap/toolbar/gpx_line.png" alt="icon" /></td>
181			<td class="txt" colspan="3">GPX: '.$gmap['gpxfile'].'</td>
182			</tr>';
183		}
184
185		$js .= "{mapOpts:{" . $param . " },poi:[$poi]};";
186		// unescape the json
187		$poitable = stripslashes($poitable);
188
189		return array($mapid,$js,$mainLat,$mainLon,$poitable,$gmap['summary'],$imgUrl);
190	}
191
192	/**
193	 * render html tag/output. render the content.
194	 * @Override
195	 */
196	function render($mode, &$renderer, $data) {
197		static $initialised = false; // set to true after script initialisation
198		static $mapnumber = 0; // incremented for each map tag in the page source
199		list ($mapid, $param, $mainLat, $mainLon, $poitable, $poitabledesc, $staticImgUrl) = $data;
200
201		if ($mode == 'xhtml') {
202			$olscript = '';
203			$olEnable = false;
204			$gscript = '';
205			$gEnable = $this->getConf('enableGoogle');
206			$mqEnable = $this->getConf('enableMapQuest');
207			$osmEnable = $this->getConf('enableOSM');
208			$enableBing = $this->getConf('enableBing');
209
210			$scriptEnable = '';
211
212			if (!$initialised) {
213				$initialised = true;
214				// render necessary script tags
215				if($gEnable){
216					$gscript ='<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.8&amp;sensor=false"></script>';
217				}
218				$olscript = $this->getConf('olScriptUrl');
219				$olscript = $olscript ? '<script type="text/javascript" src="' . $olscript . '"></script>' : "";
220				$olscript = str_replace('DOKU_BASE/', DOKU_BASE, $olscript);
221
222				$scriptEnable = '<script type="text/javascript"><!--//--><![CDATA[//><!--' . "\n";
223				$scriptEnable .= $olscript ? 'olEnable = true;' : 'olEnable = false;';
224				$scriptEnable .= 'gEnable = '.($gEnable ? 'true' : 'false').';';
225				$scriptEnable .= 'osmEnable = '.($osmEnable ? 'true' : 'false').';';
226				$scriptEnable .= 'mqEnable = '.($mqEnable ? 'true' : 'false').';';
227				$scriptEnable .= 'bEnable = '.($enableBing ? 'true' : 'false').';';
228				$scriptEnable .= 'bApiKey="'.$this->getConf('bingAPIKey').'";';
229				$scriptEnable .= 'OpenLayers.ImgPath = "'.DOKU_BASE.'lib/plugins/openlayersmap/lib/'.$this->getConf('olMapStyle').'/";';
230				$scriptEnable .= "\n" . '//--><!]]></script>';
231			}
232			$renderer->doc .= "
233			$gscript
234			$olscript
235			$scriptEnable";
236			if ($this->getConf('enableA11y')){
237				$renderer->doc .= '<div id="'.$mapid.'-static" class="olStaticMap">'.$staticImgUrl.'</div>';
238			}
239			$renderer->doc .= '<div id="'.$mapid.'-clearer" class="clearer"><p>&nbsp;</p></div>';
240			if ($this->getConf('enableA11y')){
241				// render a (initially hidden) table of the POI for the print and a11y presentation
242				$renderer->doc .= '<div class="olPOItableSpan" id="'.$mapid.'-table-span"><table class="olPOItable" id="'.$mapid.'-table" summary="'.$poitabledesc.'" title="'.$this->getLang('olmapPOItitle').'">
243				<caption class="olPOITblCaption">'.$this->getLang('olmapPOItitle').'</caption>
244				<thead class="olPOITblHeader">
245				<tr>
246				<th class="rowId" scope="col">id</th>
247				<th class="icon" scope="col">'.$this->getLang('olmapPOIicon').'</th>
248				<th class="lat" scope="col" title="'.$this->getLang('olmapPOIlatTitle').'">'.$this->getLang('olmapPOIlat').'</th>
249				<th class="lon" scope="col" title="'.$this->getLang('olmapPOIlonTitle').'">'.$this->getLang('olmapPOIlon').'</th>
250				<th class="txt" scope="col">'.$this->getLang('olmapPOItxt').'</th>
251				</tr>
252				</thead>';
253				if ($poitabledesc !=''){
254					$renderer->doc .='<tfoot class="olPOITblFooter"><tr><td colspan="5">'.$poitabledesc.'</td></tr></tfoot>';
255				}
256				$renderer->doc .='<tbody class="olPOITblBody">'.$poitable.'</tbody>
257				</table></div>';
258			}
259			// render inline mapscript
260			$renderer->doc .="\n		<script type='text/javascript'><!--//--><![CDATA[//><!--\n";
261			// var $mapid = $param
262			$renderer->doc .="		olMapData[$mapnumber] = $param
263			//--><!]]></script>";
264			$mapnumber++;
265			return true;
266		} elseif ($mode == 'metadata') {
267			// render metadata if available
268			if (!(($this->dflt['lat']==$mainLat)||($thisdflt['lon']==$mainLon))){
269				// unless they are the default
270				$renderer->meta['geo']['lat'] = $mainLat;
271				$renderer->meta['geo']['lon'] = $mainLon;
272			}
273			return true;
274		}
275		return false;
276	}
277
278	/**
279	 * extract parameters for the map from the parameter string
280	 *
281	 * @param   string    $str_params   string of key="value" pairs
282	 * @return  array                   associative array of parameters key=>value
283	 */
284	private function _extract_params($str_params) {
285		$param = array ();
286		preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER);
287		// parse match for instructions, break into key value pairs
288		$gmap = $this->dflt;
289		foreach ($param as $kvpair) {
290			list ($match, $key, $val) = $kvpair;
291			$key = strtolower($key);
292			if (isset ($gmap[$key])){
293				if ($key == 'summary'){
294					// preserve case for summary field
295					$gmap[$key] = $val;
296				}else {
297					$gmap[$key] = strtolower($val);
298				}
299			}
300		}
301		return $gmap;
302	}
303
304	/**
305	 * extract overlay points for the map from the wiki syntax data
306	 *
307	 * @param   string    $str_points   multi-line string of lat,lon,text triplets
308	 * @return  array                   multi-dimensional array of lat,lon,text triplets
309	 */
310	private function _extract_points($str_points) {
311		$point = array ();
312		//preg_match_all('/^([+-]?[0-9].*?),\s*([+-]?[0-9].*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER);
313		/*
314		group 1: ([+-]?[0-9]+(?:\.[0-9]*)?)
315		group 2: ([+-]?[0-9]+(?:\.[0-9]*)?)
316		group 3: (.*?)
317		group 4: (.*?)
318		group 5: (.*?)
319		group 6: (.*)
320		*/
321		preg_match_all('/^([+-]?[0-9]+(?:\.[0-9]*)?),\s*([+-]?[0-9]+(?:\.[0-9]*)?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER);
322		// create poi array
323		$overlay = array ();
324		foreach ($point as $pt) {
325			list ($match, $lat, $lon, $angle, $opacity, $img, $text) = $pt;
326			$lat = is_numeric($lat) ? $lat : 0;
327			$lon = is_numeric($lon) ? $lon : 0;
328			$angle = is_numeric($angle) ? $angle : 0;
329			$opacity = is_numeric($opacity) ? $opacity : 0.8;
330			$img = trim($img);
331			// TODO validate using exist & set up default img?
332			$text = addslashes(str_replace("\n", "", p_render("xhtml", p_get_instructions($text), $info)));
333			$overlay[] = array($lat, $lon, $text, $angle, $opacity, $img);
334		}
335		return $overlay;
336	}
337
338	/**
339	 * Create a MapQuest static map API image url.
340	 * @param array $gmap
341	 * @param array $overlay
342	 */
343	private function _getMapQuest($gmap,$overlay) {
344		$sUrl=$this->getConf('iconUrlOverload');
345		if (!$sUrl){
346			$sUrl=DOKU_URL;
347		}
348		switch ($gmap['baselyr']){
349			case 'mapquest hybrid':
350				$maptype='hyb';
351				break;
352			case 'mapquest sat':
353				// $maptype='sat'
354				// because sat coverage is very limited use 'hyb' instead of 'sat' so we don't get a blank map
355				$maptype='hyb';
356				break;
357			case 'mapquest road':
358			default:
359				$maptype='map';
360				break;
361		}
362		$imgUrl = "http://open.mapquestapi.com/staticmap/v3/getmap?declutter=true&";
363		if (count($overlay)< 1){
364			$imgUrl .= "?center=".$gmap['lat'].",".$gmap['lon'];
365			//max level for mapquest is 16
366			if ($gmap['zoom']>16) {
367				$imgUrl .= "&zoom=16";
368			} else			{
369				$imgUrl .= "&zoom=".$gmap['zoom'];
370			}
371		}
372		// use bestfit instead of center/zoom, needs upperleft/lowerright corners
373		//$bbox=$this->_calcBBOX($overlay, $gmap['lat'], $gmap['lon']);
374		//$imgUrl .= "bestfit=".$bbox['minlat'].",".$bbox['maxlon'].",".$bbox['maxlat'].",".$bbox['minlon'];
375
376		// TODO declutter option works well for square maps but not for rectangular, maybe compensate for that or compensate the mbr..
377		$imgUrl .= "&size=".str_replace("px", "",$gmap['width']).",".str_replace("px", "",$gmap['height']);
378
379		// TODO mapquest allows using one image url with a multiplier $NUMBER eg:
380		// $NUMBER = 2
381		// $imgUrl .= DOKU_URL."/".DOKU_PLUGIN."/".getPluginName()."/icons/".$img.",$NUMBER,C,".$lat1.",".$lon1.",0,0,0,0,C,".$lat2.",".$lon2.",0,0,0,0";
382		if (!empty ($overlay)) {
383			$imgUrl .= "&xis=";
384			foreach ($overlay as $data) {
385				list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
386				//$imgUrl .= $sUrl."lib/plugins/openlayersmap/icons/".$img.",1,C,".$lat.",".$lon.",0,0,0,0,";
387				$imgUrl .= $sUrl."lib/plugins/openlayersmap/icons/".$img.",1,C,".$lat.",".$lon.",";
388			}
389			$imgUrl = substr($imgUrl,0,-1);
390		}
391		$imgUrl .= "&imageType=png&type=".$maptype;
392		dbglog($imgUrl,'syntax_plugin_openlayersmap_olmap::_getMapQuest: MapQuest image url is:');
393		return $imgUrl;
394	}
395	/**
396	 *
397	 * Create a Google maps static image url w/ the poi.
398	 * @param array $gmap
399	 * @param array $overlay
400	 */
401	private function _getGoogle($gmap, $overlay){
402		$sUrl=$this->getConf('iconUrlOverload');
403		if (!$sUrl){
404			$sUrl=DOKU_URL;
405		}
406		switch ($gmap['baselyr']){
407			case 'google hybrid':
408				$maptype='hybrid';
409				break;
410			case 'google sat':
411				$maptype='satellite';
412				break;
413			case 'google relief':
414				$maptype='terrain';
415				break;
416			case 'google road':
417			default:
418				$maptype='roadmap';
419				break;
420		}
421		// TODO maybe use viewport / visible instead of center/zoom,
422		//		see: https://code.google.com/intl/nl/apis/maps/documentation/staticmaps/#ImplicitPositioning
423		//http://maps.google.com/maps/api/staticmap?center=51.565690,5.456756&zoom=16&size=600x400&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/marker.png|label:1|51.565690,5.456756&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/marker-blue.png|51.566197,5.458966|label:2&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.567177,5.457909|label:3&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.566283,5.457330|label:4&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.565630,5.457695|label:5&sensor=false&format=png&maptype=roadmap
424		$imgUrl = "http://maps.google.com/maps/api/staticmap?sensor=false";
425		$imgUrl .= "&size=".str_replace("px", "",$gmap['width'])."x".str_replace("px", "",$gmap['height']);
426		$imgUrl .= "&center=".$gmap['lat'].",".$gmap['lon'];
427		// max is 21 (== building scale), but that's overkill..
428		if ($gmap['zoom']>16) {
429			$imgUrl .= "&zoom=16";
430		} else			{
431			$imgUrl .= "&zoom=".$gmap['zoom'];
432		}
433
434		if (!empty ($overlay)) {
435			$rowId=0;
436			foreach ($overlay as $data) {
437				list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
438				$imgUrl .= "&markers=icon%3a".$sUrl."lib/plugins/openlayersmap/icons/".$img."%7c".$lat.",".$lon."%7clabel%3a".++$rowId;
439			}
440		}
441		$imgUrl .= "&format=png&maptype=".$maptype;
442		global $conf;
443		$imgUrl .= "&language=".$conf['lang'];
444		dbglog($imgUrl,'syntax_plugin_openlayersmap_olmap::_getGoogle: Google image url is:');
445		return $imgUrl;
446	}
447
448	/**
449	 *
450	 * Create a Bing maps static image url w/ the poi.
451	 * @param array $gmap
452	 * @param array $overlay
453	 */
454	private function _getBing($gmap, $overlay){
455		if(!$this->getConf('bingAPIKey')){
456			// in case there is no Bing api key
457			$this->_getMapQuest($gmap, $overlay);
458		}
459		switch ($gmap['baselyr']){
460			case 've hybrid':
461			case 'bing hybrid':
462				$maptype='AerialWithLabels';
463				break;
464			case 've sat':
465			case 'bing sat':
466				$maptype='Aerial';
467				break;
468			case 've normal':
469			case 've road':
470			case 've':
471			case 'bing road':
472			default:
473				$maptype='Road';
474				break;
475		}
476		$bbox=$this->_calcBBOX($overlay, $gmap['lat'], $gmap['lon']);
477		//$imgUrl = "http://dev.virtualearth.net/REST/v1/Imagery/Map/".$maptype."/".$gmap['lat'].",".$gmap['lon']."/".$gmap['zoom'];
478		$imgUrl = "http://dev.virtualearth.net/REST/v1/Imagery/Map/".$maptype."/";
479		$imgUrl .= "?mapArea=".$bbox['minlat'].",".$bbox['minlon'].",".$bbox['maxlat'].",".$bbox['maxlon'];
480		// TODO declutter option works well for square maps but not for rectangular, maybe compensate for that or compensate the mbr..
481		$imgUrl .= "&declutter=1";
482		$imgUrl .= "&ms=".str_replace("px", "",$gmap['width']).",".str_replace("px", "",$gmap['height']);
483		$imgUrl .= "&key=".$this->getConf('bingAPIKey');
484		if (!empty ($overlay)) {
485			$rowId=0;
486			foreach ($overlay as $data) {
487				list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
488				// TODO icon style lookup, see: http://msdn.microsoft.com/en-us/library/ff701719.aspx for iconStyle
489				$iconStyle=32;
490				$rowId++;
491				// NOTE: the max number of pushpins is 18!
492				if ($rowId==18) {
493					break;
494				}
495				$imgUrl .= "&pp=$lat,$lon;$iconStyle;$rowId";
496			}
497		}
498		dbglog($imgUrl,'syntax_plugin_openlayersmap_olmap::_getBing: bing image url is:');
499		return $imgUrl;
500	}
501
502	/**
503	 *
504	 * Create a static OSM map image url w/ the poi from http://staticmap.openstreetmap.de (staticMapLite)
505	 * use http://staticmap.openstreetmap.de "staticMapLite" or a local version
506	 * @param array $gmap
507	 * @param array $overlay
508	 *
509	 * @todo implementation for http://ojw.dev.openstreetmap.org/StaticMapDev/
510	 */
511	private function _getStaticOSM($gmap, $overlay){
512		//http://staticmap.openstreetmap.de/staticmap.php?center=47.000622235634,10.117187497601&zoom=5&size=500x350
513		// &markers=48.999812532766,8.3593749976708,lightblue1|43.154850037315,17.499999997306,lightblue1|49.487527053077,10.820312497573,ltblu-pushpin|47.951071133739,15.917968747369,ol-marker|47.921629720114,18.027343747285,ol-marker-gold|47.951071133739,19.257812497236,ol-marker-blue|47.180141361692,19.257812497236,ol-marker-green
514		global $conf;
515
516		switch ( $this->getConf('optionStaticMapGenerator')){
517			case 'local':
518				$imgUrl =$conf['baseurl']."/lib/plugins/openlayersmap/staticmap/map.php";
519				$imgUrl .= '?kml='.$gmap['kmlfile'];
520				$imgUrl .= '&gpx='.$gmap['gpxfile'];
521				break;
522			case 'remote':
523			default:
524				$imgUrl = "http://staticmap.openstreetmap.de/staticmap.php";
525		}
526
527		$imgUrl .= "&center=".$gmap['lat'].",".$gmap['lon'];
528		$imgUrl .= "&size=".str_replace("px", "",$gmap['width'])."x".str_replace("px", "",$gmap['height']);
529		$size =str_replace("px", "",$gmap['width'])."x".str_replace("px", "",$gmap['height']);
530
531		if ($gmap['zoom']>16) {
532			// actually this could even be 18, but that seems overkill
533			$imgUrl .= "&zoom=16";
534		} else {
535			$imgUrl .= "&zoom=".$gmap['zoom'];
536		}
537
538		switch ($gmap['baselyr']){
539			case 'mapnik':
540			case 'openstreetmap':
541				$maptype='openstreetmap';
542				break;
543			case 'transport':
544				$maptype='transport';
545				break;
546			case 'landscape':
547				$maptype='landscape';
548				break;
549			case 'cycle map':
550				$maptype='cycle';
551				break;
552			case 'cloudmade':
553				$maptype='cloudmade';
554				break;
555			case 'cloudmade fresh':
556				$maptype='fresh';
557				break;
558			case 'hike and bike map':
559				$maptype='hikeandbike';
560				break;
561			case 'mapquest hybrid':
562			case 'mapquest road':
563			case 'mapquest sat':
564				$maptype='mapquest';
565				break;
566			default:
567				$maptype='';
568				break;
569		}
570		$imgUrl .= "&maptype=".$maptype;
571
572		$markers='';
573		if (!empty ($overlay)) {
574			$rowId=0;
575			$imgUrl .= "&markers=";
576			foreach ($overlay as $data) {
577				list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
578				$rowId++;
579				if ($this->getConf('optionStaticMapGenerator')=='remote') $iconStyle = "lightblue$rowId";
580				if ($this->getConf('optionStaticMapGenerator')=='local') $iconStyle = substr($img, 0,strlen($img)-4);
581				$imgUrl .= "$lat,$lon,$iconStyle%7c";
582				$markers[] = array(
583						'lat'=>$lat,
584						'lon'=>$lon,
585						'type'=>$iconStyle);
586			}
587			$imgUrl = substr($imgUrl,0,-3);
588		}
589
590		if (!$my = &plugin_load('helper', 'openlayersmap_staticmap')){
591			dbglog($my,'syntax_plugin_openlayersmap_olmap::_getStaticOSM: openlayersmap_staticmap plugin is false');
592			return false;
593		}
594
595		if ($this->getConf('optionStaticMapGenerator')=='local') {
596			$result = $my->getMap($gmap['lat'],$gmap['lon'],$gmap['zoom'],$size,$maptype,$markers,$gmap['gpxfile'],$gmap['kmlfile']);
597		}else{
598			$result= $imgUrl;
599		}
600
601		dbglog($result,'syntax_plugin_openlayersmap_olmap::_getStaticOSM: osm image url is:');
602		return $result;
603	}
604
605	/**
606	 * Calculate the minimum bbox for a start location + poi.
607	 *
608	 * @param array $overlay  multi-dimensional array of array($lat, $lon, $text, $angle, $opacity, $img)
609	 * @param float $lat latitude for map center
610	 * @param float $lon longitude for map center
611	 * @return multitype:float array describing the mbr and center point
612	 */
613	private function _calcBBOX($overlay, $lat, $lon){
614		$lats[] = $lat;
615		$lons[] = $lon;
616		foreach ($overlay as $data) {
617			list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
618			$lats[] = $lat;
619			$lons[] = $lon;
620		}
621		sort($lats);
622		sort($lons);
623		// TODO: make edge/wrap around cases work
624		$centerlat = $lats[0]+($lats[count($lats)-1]-$lats[0]);
625		$centerlon = $lons[0]+($lons[count($lats)-1]-$lons[0]);
626		return array('minlat'=>$lats[0], 'minlon'=>$lons[0],
627				'maxlat'=>$lats[count($lats)-1], 'maxlon'=>$lons[count($lats)-1],
628				'centerlat'=>$centerlat,'centerlon'=>$centerlon);
629	}
630}