1<?php 2/** 3 * Plugin OpenStreetMap: Allow Display of a OpenStreetMap in a wiki page. 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Michael Hamann <michael@content-space.de> 7 * @author Christopher Smith <chris@jalakai.co.uk> 8 */ 9 10if(!defined('DOKU_INC')) define('DOKU_INC', realpath(dirname(__FILE__).'/../../').'/'); 11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/'); 12require_once(DOKU_PLUGIN.'syntax.php'); 13 14/** 15 * All DokuWiki plugins to extend the parser/rendering mechanism 16 * need to inherit from this class 17 */ 18class syntax_plugin_osm extends DokuWiki_Syntax_Plugin { 19 var $defaults = array 20 ( 21 'width' => 450, 22 'height' => 320, 23 'lat' => -4.25, 24 'lon' => 55.833, 25 'zoom' => 8, 26 'layer' => 'mapnik' 27 ); 28 var $constraints = array 29 ( 30 'width' => array('min' => 100, 'max' => 1000), 31 'height' => array('min' => 99, 'max' => 1500), 32 'zoom' => array('min' => 0, 'max' => 18), 33 'lat' => array('min' => -90, 'max' => 90), 34 'lon' => array('min' => -180, 'max' => 180), 35 ); 36 37 var $urlMappings = array 38 ( 39 'zoom' => 'z', 40 'width' => 'w', 41 'height' => 'h', 42 'lon' => 'long' 43 ); 44 45 46 var $layers = array('osmarender', 'mapnik'); 47 48 function getType() { return 'substition'; } 49 function getPType() { return 'block'; } 50 function getSort() { return 900; } 51 52 function connectTo($mode) { 53 $this->Lexer->addSpecialPattern('<osm ?[^>\n]*>.*?</osm>', $mode, 'plugin_osm'); 54 } 55 56 function handle($match, $state, $pos, Doku_Handler $handler) { 57 58 // break matched cdata into its components 59 list($str_params, $str_markers) = explode('>', substr($match, 4, -6), 2); 60 61 $param = array(); 62 preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER); 63 64 $opts = array(); 65 66 foreach($param as $kvpair) { 67 list($match, $key, $val) = $kvpair; 68 $key = strtolower($key); 69 switch ($key) { 70 case 'layer': 71 if (in_array($val, $this->layers)) 72 $opts['layer'] = $val; 73 break; 74 case 'lon': 75 case 'lat': 76 $val = (float) $val; 77 if ($val >= $this->constraints[$key]['min'] && $val <= $this->constraints[$key]['max']) 78 $opts[$key] = $val; 79 break; 80 case 'width': 81 case 'height': 82 case 'zoom': 83 $val = (int) $val; 84 if ($val >= $this->constraints[$key]['min'] && $val <= $this->constraints[$key]['max']) 85 $opts[$key] = $val; 86 break; 87 } 88 } 89 90 $markers = $this->_extract_markers($str_markers); 91 92 return array($opts, $markers); 93 } 94 95 function render($mode, Doku_Renderer $renderer, $data) { 96 if ($mode == 'xhtml') { 97 list($options, $markers) = $data; 98 99 $options = array_merge($this->defaults, $options); 100 101 $json = new JSON(); 102 103 $renderer->doc .= '<div class="openstreetmap" style="width: '.$options['width'].'px; height: '.$options['height'].'px;">'.DOKU_LF; 104 $renderer->doc .= "<a href=\"".$this->getLinkURL($options)."\" title=\"See this map on OpenStreetMap.org\">".DOKU_LF; 105 $renderer->doc .= "<img alt=\"OpenStreetMap\" src=\"".$this->getImageURL($options)."\" />".DOKU_LF; 106 $renderer->doc .= "</a>".DOKU_LF; 107 $renderer->doc .= "<!-- ".$json->encode($markers)." -->"; 108 $renderer->doc .= "</div>".DOKU_LF; 109 return true; 110 } 111 112 return false; 113 } 114 115 /** 116 * extract markers for the osm from the wiki syntax data 117 * 118 * @param string $str_markers multi-line string of lat,lon,txt triplets 119 * @return array array of markers as associative array 120 */ 121 function _extract_markers($str_markers) { 122 123 $point = array(); 124 preg_match_all('/^(.*?),(.*?),(.*)$/um', $str_markers, $point, PREG_SET_ORDER); 125 126 $overlay = array(); 127 foreach ($point as $pt) { 128 list($match, $lat, $lon, $txt) = $pt; 129 130 $lat = is_numeric($lat) ? (float)$lat : 0; 131 $lon = is_numeric($lon) ? (float)$lon : 0; 132 $txt = addslashes(str_replace("\n", "", p_render("xhtml", p_get_instructions($txt), $info))); 133 134 $overlay[] = compact('lat', 'lon', 'txt'); 135 } 136 137 return $overlay; 138 } 139 140 /** 141 * Generates the image URL for the map using the given mapserver. 142 * 143 * @param array $options The options to send 144 * @return string The URL to the static image of this map. 145 */ 146 function getImageURL($options) { 147 // create the query string 148 $query_params = array('format=jpeg'); 149 foreach ($options as $option => $value) { 150 $query_params[] = (array_key_exists($option, $this->urlMappings) ? $this->urlMappings[$option] : $option).'='.$value; 151 } 152 153 return ml(hsc($this->getConf('map_service_url'))."?".implode('&', $query_params), array('cache' => 'recache')); 154 } 155 156 /** 157 * Generates the link url for this map. 158 * 159 * @param array $options The options that shall be included in the url 160 * @return string The link url. 161 */ 162 function getLinkURL($options) { 163 $link_query = array(); 164 165 foreach ($options as $option => $value) { 166 $link_query[] = "$option=$value"; 167 } 168 return 'http://www.openstreetmap.org/?'.implode('&', $link_query); 169 } 170} 171 172 173// vim:ts=4:sw=4:et: 174