googlemaps plugin by Chris Smith
Allows any number of Google maps to be added to a wiki page.
Last updated on 2006-10-15. Provides Syntax.
Compatible with DokuWiki 2006-03-05, 2006-11-06.
Similar to itrackviewer.
When getting your key from Google you must specify a directory, choose your web root (e.g. ”/”). If you do want to be more specific, you can choose the path normally used to access DokuWiki.
<googlemap parameter="value" parameter="value"> lat,lon,text lat,lon,text </googlemap>
The lines of “lat,lon,text” represent the individual overlay markers. Each marker must have its own line and be the only information on that line. “lat” and “lon” are the latitude and longtitude of the marker. “text” is the text to be displayed in the popup when the marker is clicked. The text can include wiki markup.
The parameters can be in any order.
See the page in action here
Plugin sources:
If your wiki uses either the plugin manager or the darcs plugin you can use them with the links above to install the plugin.
To install the plugin manually, download the source to your plugin folder, lib/plugins and extract its contents. That will create a new plugin folder, lib/plugins/googlemaps, and install the plugin.
The folder will contain:
script.js javascript to interface with google maps style.css styles for the map containing element syntax/googlemap.php plugin script conf/metadata.php configuration metadata conf/default.php default values for configuration settings lang/xx/settings.php language strings used for configuration settings
The plugin is now installed.
The plugin has two configuration constants:
These two constants can be modified via the Configuration Settings in the Admin menu.
The plugin consists of seven files, the plugin php scripts syntax/gmap.php & syntax/googlemap.php, javascript to interface with google maps in script.css, default styles for the map containing element in style.css and three files (not shown below) used to make the plugin's two settings editable via the DokuWiki's Configuration Settings option.
<?php /** * Plugin Google Maps: Allow Display of a Google Map in a wiki page. * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Christopher Smith <chris@jalakai.co.uk> */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); // !!!!!! required for DW2006-03-xx versions only, remove after next release !!!!!! if (!function_exists('hsc')) { function hsc($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } } // ---------- [ Settings ] ----------------------------------------- /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_googlemaps_googlemap extends DokuWiki_Syntax_Plugin { var $dflt = array( 'type' => 'map', 'width' => '', 'height' => '', 'lat' => -4.25, 'lon' => 55.833, 'zoom' => 8, 'controls' => 'on' ); function getInfo(){ return array( 'author' => 'Christopher Smith', 'email' => 'chris@jalakai.co.uk', 'date' => '2006-10-15', 'name' => 'Google Maps Plugin', 'desc' => 'Add maps to your wiki Syntax: <googlemap params>overlaypoints</googlemap>', 'url' => 'http://www.dokuwiki.org/plugin:googlemaps', ); } function getType() { return 'substition'; } function getPType() { return 'block'; } function getSort() { return 900; } function connectTo($mode) { $this->Lexer->addSpecialPattern('<googlemap ?[^>\n]*>.*?</googlemap>',$mode,'plugin_googlemaps_googlemap'); } function handle($match, $state, $pos, &$handler){ // break matched cdata into its components list($str_params,$str_points) = explode('>',substr($match,10,-12),2); $gmap = $this->_extract_params($str_params); $overlay = $this->_extract_points($str_points); // determine width and height (inline styles) for the map image if ($gmap['width'] || $gmap['height']) { $style = $gmap['width'] ? 'width: '.$gmap['width'].";" : ""; $style .= $gmap['height'] ? 'height: '.$gmap['height'].";" : ""; $style = "style='$style'"; } else { $style = ''; } // unset gmap values for width and height - they don't go into javascript unset($gmap['width'],$gmap['height']); // create a javascript parameter string for the map $param = ''; foreach ($gmap as $key => $val) { $param .= is_numeric($val) ? " $key : $val," : "$key : '".hsc($val)."',"; } if (!empty($param)) $param = substr($param,0,-1); // create a javascript serialisation of the point data $points = ''; if (!empty($overlay)) { foreach ($overlay as $data) { list($lat,$lon,$text) = $data; $points .= ",{lat:$lat,lon:$lon,txt:'$text'}"; } $points = ", overlay : [ ".substr($points,1)." ]"; } $js = "googlemap[googlemap.length] = {".$param.$points." };"; return array($style, $js); } function render($mode, &$renderer, $data) { static $initialised = false; // set to true after script initialisation if ($mode == 'xhtml') { list($style, $param) = $data; $script = ''; if (!$initialised) { $initialised = true; $script = $this->getConf('script').$this->getConf('key'); $script = '<script type="text/javascript" src="'.$script.'"></script>'; } $renderer->doc .= " <div class='googlemap' $style> $script <script type='text/javascript'> $param </script> </div>"; } return false; } /** * extract parameters for the googlemap from the parameter string * * @param string $str_params string of key="value" pairs * @return array associative array of parameters key=>value */ function _extract_params($str_params) { $param = array(); preg_match_all('/(\w*)="(.*?)"/us',$str_params,$param,PREG_SET_ORDER); // parse match for instructions, break into key value pairs $gmap = $this->dflt; foreach($param as $kvpair) { list($match,$key,$val) = $kvpair; $key = strtolower($key); if (isset($gmap[$key])) $gmap[$key] = strtolower($val); } return $gmap; } /** * extract overlay points for the googlemap from the wiki syntax data * * @param string $str_points multi-line string of lat,lon,text triplets * @return array multi-dimensional array of lat,lon,text triplets */ function _extract_points($str_points) { $point = array(); preg_match_all('/^(.*?),(.*?),(.*)$/um',$str_points,$point,PREG_SET_ORDER); $overlay = array(); foreach ($point as $pt) { list($match,$lat,$lon,$text) = $pt; $lat = is_numeric($lat) ? $lat : 0; $lon = is_numeric($lon) ? $lon : 0; $text = addslashes(str_replace("\n","",p_render("xhtml",p_get_instructions($text),$info))); $overlay[] = array($lat,$lon,$text); } return $overlay; } }
This is the source for supporting the original plugin syntax - now obsolete.
<?php /** * Plugin Google Maps: Allow Display of a Google Map in a wiki page. * * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) * @author Christopher Smith <chris@jalakai.co.uk> */ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); require_once(DOKU_PLUGIN.'syntax.php'); // !!!!!! required for DW2006-03-xx versions only, remove after next release !!!!!! if (!function_exists('hsc')) { function hsc($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } } // ---------- [ Settings ] ----------------------------------------- /** * All DokuWiki plugins to extend the parser/rendering mechanism * need to inherit from this class */ class syntax_plugin_googlemaps_gmap extends DokuWiki_Syntax_Plugin { var $dflt = array( 'type' => 'map', 'width' => '', 'height' => '', 'lat' => -4.25, 'lon' => 55.833, 'zoom' => 8, 'controls' => 'on' ); function getInfo(){ return array( 'author' => 'Christopher Smith', 'email' => 'chris@jalakai.co.uk', 'date' => '2006-10-15', 'name' => 'Google Maps Plugin', 'desc' => 'Add maps to your wiki Syntax: <gmap>options</gmap>', 'url' => 'http://www.dokuwiki.org/plugin:googlemaps', ); } function getType() { return 'substition'; } function getPType() { return 'block'; } function getSort() { return 900; } function connectTo($mode) { $this->Lexer->addSpecialPattern('<gmap>.*?</gmap>',$mode,'plugin_googlemaps_gmap'); } function handle($match, $state, $pos, &$handler){ // parse match for instructions, break into key value pairs $param = explode('|', substr($match, 6, -7)); $gmap = $this->dflt; foreach($param as $kvpair) { list($key,$val) = explode('=',$kvpair); $key = strtolower($key); if (isset($gmap[$key])) $gmap[$key] = strtolower($val); } if ($gmap['width'] || $gmap['height']) { $style = $gmap['width'] ? 'width: '.$gmap['width'].";" : ""; $style .= $gmap['height'] ? 'height: '.$gmap['height'].";" : ""; $style = "style='$style'"; } else { $style = ''; } unset($gmap['width'],$gmap['height']); $param = ''; foreach ($gmap as $key => $val) { $param .= is_numeric($val) ? "$key : $val," : "$key : '".hsc($val)."',"; } $param = "googlemap[googlemap.length] = { ".substr($param,0,-1)." };"; return array($style, $param); } function render($mode, &$renderer, $data) { static $initialised = false; // set to true after script initialisation if ($mode == 'xhtml') { list($style, $param) = $data; $script = ''; if (!$initialised) { $initialised = true; $script = $this->getConf('script').$this->getConf('key'); $script = '<script type="text/javascript" src="'.$script.'"></script>'; } $renderer->doc .= " <div class='googlemap' $style> $script <script type='text/javascript'> $param </script> </div>"; } return false; } /* * !!!!!! ---------------------------------------------------------------- !!!!!! * method overloading to provide config functions to 2006-03-09 DokuWiki versions * not required for DokuWiki dev version * remove after next major release * !!!!!! ---------------------------------------------------------------- !!!!!! */ // configuration methods /** * getConf($setting) * * use this function to access plugin configuration variables */ function getConf($setting){ if (!$this->configloaded){ $this->loadConfig(); } return $this->conf[$setting]; } /** * loadConfig() * merges the plugin's default settings with any local settings * this function is automatically called through getConf() */ function loadConfig(){ global $conf; $defaults = $this->readDefaultSettings(); $plugin = $this->getPluginName(); foreach ($defaults as $key => $value) { if (isset($conf['plugin'][$plugin][$key])) continue; $conf['plugin'][$plugin][$key] = $value; } $this->configloaded = true; $this->conf =& $conf['plugin'][$plugin]; } /** * read the plugin's default configuration settings from conf/default.php * this function is automatically called through getConf() * * @return array setting => value */ function readDefaultSettings() { $path = DOKU_PLUGIN.$this->getPluginName().'/conf/'; $conf = array(); if (@file_exists($path.'default.php')) { include($path.'default.php'); } return $conf; } }
/* * Javascript associated with googlemaps plugin */ function in_array(needle, haystack) { for (var i=0; i<haystack.length; i++) if (haystack[i] == needle) return true; return false; } // Creates a marker at the given point with the given number label // from http://www.google.com/apis/maps/documentation/#Display_Info_Windows_Above_Markers // with minor modifications function create_marker(point, text) { var marker = new GMarker(point); GEvent.addListener(marker, "click", function() { marker.openInfoWindowHtml(text); }); return marker; } function init_googlemaps() { // nothing to do? if (googlemap.length == 0) return; var maptypes = { map : G_NORMAL_MAP, normal : G_NORMAL_MAP, hybrid : G_HYBRID_MAP, satellite : G_SATELLITE_MAP }; // retrieve all google map containers var nodes = document.body.getElementsByTagName('div'); var i=0; for (var j=0; j<nodes.length; j++) { if (nodes[j].className.match(/\bgooglemap\b/)) { googlemap[i++].node = nodes[j]; } } // iterate through all the map containers and set up each map for (i=0; i<googlemap.length; i++) { googlemap[i].map = new GMap2(googlemap[i].node); with (googlemap[i]) { if (controls == 'on') { map.addControl(new GSmallMapControl()); map.addControl(new GMapTypeControl()); } map.setCenter(new GLatLng(lat, lon), zoom); var supported = map.getMapTypes(); var requested = maptypes[type]; map.setMapType(in_array(requested,supported) ? requested : supported[0]); if (googlemap[i].overlay && overlay.length > 0) { for (j=0; j<overlay.length; j++) { map.addOverlay(create_marker(new GLatLng(overlay[j].lat,overlay[j].lon),overlay[j].txt)); } } } } addEvent(document.body, 'unload', GUnload); } var googlemap = new Array(); addInitEvent(init_googlemaps);
These may be modified to suit your own requirements.
/* plugin: googlemaps */ .googlemap { width: 400px; height: 300px; border: 1px solid #333; } /* end plugin: googlemaps */
KML file support can be included as follows:
1. Add in googlemap.php a default value vor a new parameter 'kml': This kml parameter takes the URL of your KML-file, e.g. kml=“http://mydomain.tl/mymap.kml” :
var $dflt = array(
...
'controls' => 'on',
'kml' => 'off'
);
2. Add in script.js after the map.addOverlay-block concerning the markers:
if (kml != 'off') {
var geoXml = new GGeoXml(kml);
map.addOverlay(geoXml);
}
3. Correct the config parameter for the API link from v=2 to v=2.x
http://maps.google.com/maps?file=api&v=2.x&key=
This works in general, but there remains a slight problem: Direct links to Google-Maps like this one do not work. Does anybody have an idea on this issue??
You can see the extended plugin in action here...
How about loggin user IP's and then generating the map based on them. Like here: Ip based google map?
Thank you for you efort, but google_maps won't work in my wiki (dokuwiki 2006 11 03). caii
Installed dev today (aug 2nd), had the empty frame issue. touch dokuwiki.php helped me. Thx for a great plugin.
I still have the empty frame issue. I guess the cache is not at fault, since the maps are correctly displayed in preview mode. But as soon as I save the page and display it, the frame come just blank. Any idea?
– kilian 2006-10-13 15:57
There was a bug causing the recent empty frame problems. I have made appropriate corrections and updated the sources, please update your plugin. If you installed the plugin with the plugin manager, you should be able to use the “update” button. — Christopher Smith 2006-10-15 11:50
Indeed, an update resolved the issue. Thanks a lot! – kilian 2006-10-15 13:17
Do you plan any support for Geocoding? i.e. entering an address instead of lat/lon. That would be a great addition! ben 2006-12-30 0:56
you have a typo in the url encoded into the plugin: it leads ppl to googlemaps instead of google_maps. On a different note, is it possible to somehow display names on the placemarks instead of just in info boxes? a bit like on google earth. but i don't even know if the API currently supports that. — Jan(the name, not the month
) 2007-04-02 23:09
seems not really possible, but maybe at least something like those custom tooltips? — Jan 2007-04-03 00:18
Why can't we use addresses ? Inserting geocodes is way too complicated ! The plugin should use the geocoder API ! Is it difficult ?
—
Hi, my name is Bernhard. Great plugin! I use it with the new DokuWiki Release 2007-06-26. Works fine! ( Hav a look at http://wiki.aktiv-gegen-kinderarbeit.de/deutschland/landkarte )
BTW: Google is asking to cache the geocoded addresses, so it should not be generated each time, somebody is opening you page wit the googlemap. If you have a lot of points (addresses) to geocode, it could happen, that google is blocking your account for 24 hours! (Further Info: Google Maps API Terms of Use, §1.6)
I made a simple modification in the JavaScript script.js, to choose the small map controls or the large map controls by the additional values “small” and “large” for the “controls”-parameter:
// iterate through all the map containers and set up each map
for (i=0; i<googlemap.length; i++) {
googlemap[i].map = new GMap2(googlemap[i].node);
with (googlemap[i]) {
/* this part of the code is substituted with the switch
if (controls == 'on') {
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
}
*/
/* start to choose small or large MapControl */
switch (controls){
case "on":
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
break;
case "small":
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());
break;
case "large":
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
break;
}
/* end to choose small or large MapControl */
map.setCenter(new GLatLng(lat, lon), zoom);
If controls=“on” the default small MapControl is used. \\— Bernhard 2007-07-04 9:43
I work on a “standalone” (because i haven't bring it into dokuwiki) html page to bring some geocode advance to the generation of google maps on DokuWiki.
You can hack the page as you want, just see the source (not really fun actually;…
)
Just take an adress, click on the marker, move the marker, etc…
the page : http://jm.massou.free.fr/geocoder.html
More information soon… in french but look down and you have the wiki googlemap syntax….
Is it possible to cache the Maps? We have a page in our Wiki using quite a few Maps ( http://studiwiki.uni-dortmund.de/leben/wohnheime ) and it takes a few seconds until the page is loaded. Does anyone know how to speed up this process?
I've added or changed the information as specified in the instructions above but am not seeing my overlay. I'm not entirely certain I put the script.js change in the correct place…
if (googlemap[i].overlay && overlay.length > 0) { for (j=0; j<overlay.length; j++) { map.addOverlay(create_marker(new GLatLng(overlay[j].lat,overlay[j].lon),overlay[j].txt)); if (kml != 'off') { var geoXml = new GGeoXml(kml); map.addOverlay(geoXml); } } }
The wiki code I've used to embed is…
<googlemap lat="41.9983" lon="-74.3854" type="hybrid" height="500px" width="600px" kml="http://maps.eleventwentytwo.com/hiking.kml" zoom="12"></googlemap>
Have I made any mistakes? — Carl Manzi 2007-10-08 20:41
I had a look at the waidlerwiki's script.js here. There it looks as follows:
if (googlemap[i].overlay && overlay.length > 0) { for (j=0; j<overlay.length; j++) { map.addOverlay(create_marker(new GLatLng(overlay[j].lat,overlay[j].lon),overlay[j].txt)); } } if (kml != 'off') { var geoXml = new GGeoXml(kml); map.addOverlay(geoXml); }
Thank you, my anonymous hero. Moving that and clearing the cache has solved my problem. — Carl Manzi 2007-10-12 02:47
The possibility to create own maps – not a worldmap but a map coming from RPGs – would be very welcome.
(For me this possibility is the reason why I decide to learn how a wiki works)
The best explanation of what I would like to see in DokuWiki can be found here:
http://www.mediawiki.org/wiki/Extension:Google_Maps
If this feature is possible without the google code, it would be even more welcome.
Maybe some useful things can be found here:
http://maptools.org
&
http://www.nabble.com/GIS-f1188.html