DokuWiki

It's better when it's simple

User Tools

Site Tools


plugin:googlemaps

Google Maps plugin

Compatible with DokuWiki

2008-05-05 thru 2006-11-06

plugin Allows any number of Google maps to be added to a wiki page.

Last updated on
2008-11-11
Provides
Syntax

Requirements

  • A DokuWiki installation :)
    • 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.
  • A Client Web browser that supports Javascript with XMLHTTP (Ajax). If you can view googlemaps normally, you will be able to view them in the wiki.

Syntax

<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.

Parameters

  • width — 999[css length unit*] (e.g. 500px, 50%) width of the Google map, default is “400px”.
  • height — 999[css length unit*] (e.g. 500px, 30em) height of the Google map, default is “300px”.
  • type — values: map | satellite | hybrid. default map.
  • lat — values: -90.0 - 90.0; latitude of map centre, negative values are south.
  • lon — values: -180.0 - 180.0; longitude of map centre, negative values are west.
  • zoom — integer, zoom level, default value 8. Valid values depend on the map and location.
  • controls — values on | off. default on. Whether or not to show controls for zooming and panning on the map.
  • kml — values: off | [URL of kml file].

The parameters can be in any order.

(*) For width and height any valid CSS length unit can be used. The common ones are px and em, plus % for widths. In general don't use percents for height as in most cases the value is likely to be undefined. For more details refer to the CSS Specification.

Demonstration

See the page in action here, (try here if previous link does not work)

Installation

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.

Configuration

The plugin has two configuration constants:

  • GMAP_KEY — Your Google Maps API Key. To access Google Maps data you need a key. That key is unique to the URL (domain + path/to/folder) used for the page which accesses Google Maps. You can get your key from the Google Map API Key Signup page.
  • GMAP_SCRIPT — The location of the Google maps JavaScript. This will only need to be changed if Google change the name, location or query string for accessing the script.

These two constants can be modified via the Configuration Settings in the Admin menu.

Details

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.

syntax/googlemap.php

<?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');
 
// ---------- [ 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',
      'kml' => 'off',
    );
 
    function getInfo(){
      return array(
        'author' => 'Christopher Smith',
        'email'  => 'chris@jalakai.co.uk',
        'date'   => '2008-11-11',
        '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;
    }
 
}

script.js

/*
 *  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));
        }
      }
      if (kml != 'off') {
        var geoXml = new GGeoXml(kml);
        map.addOverlay(geoXml);
      }
 
    }
  }
 
 
  addEvent(document.body, 'unload', GUnload);
}
 
 
var googlemap = new Array();
addInitEvent(init_googlemaps);

style.css

These may be modified to suit your own requirements.

/* plugin: googlemaps */
.googlemap {
  width: 400px;
  height: 300px;
  border: 1px solid #333;
}
/* end plugin: googlemaps */

Revision History

  • 2008-11-11
    • Remove obsolete code for V1 of Googlemaps and DokuWiki 2006-03-09
    • Add support for KML (thanks to Martin at meggle-freund.de)
  • 2006-10-15 — Fix bug that prevented the plugin working with DokuWiki rc20060928
    • made Googlemaps V2 version of the plugin compatible with DokuWiki 2006-03xx versions
  • 2006-07-24 — Major revision
    • added support for overlays with markers
    • changes to syntax to handle overlays
    • fix bug which prevented correct interpretation of map type
  • 2006-05-22 — Updated to Google Maps API version 2.
  • 2006-05-01 — (darcs only, other versions to follow) Settings altered to use common plugin functions - which will make them editable via the configuration manager in the admin menu.
  • 2006-02-18 — Initial release

To Do

  • — add directions support (link)
  • allow user to switch between built-in controls e.g. GLargeMapControl via Gui

Bugs

in this code, there is no px unit. so if you have trouble with width and height, fix the syntax.php like this

        $style = $gmap['width'] ? 'width: '.$gmap['width']."px;" : "";
        $style .= $gmap['height'] ? 'height: '.$gmap['height']."px;" : "";
This isn't a bug, you need to supply the unit with the width/height. The intent is to allow the author to specify the height in percent or any other valid CSS unit (e.g. em, ex, cm, etc). — Christopher Smith 2009/01/25 02:41
I was so confused.Thanx. you made it clearly. At result, it is different of image wiki syntax. ppl must write css unit with this plugin. — undeadWk 2009/02/25 12:23

Invalid XHTML

lib/plugins/googlemaps/syntax/googlemap.php should have:

$renderer->doc .= "
<div class='googlemap' $style>
$script
<script type='text/javascript'>
//<![CDATA[
$param
//]]></script>
</div>";

KML (Overlay) Support

KML file support is now included in the plugin.

[original note from author of KML modifications]

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...

martin [at] meggle [dash] freund [dot] de

Discussion

How about loggin user IPs and then generating the map based on them. Like here: Ip based google map?

Thank you for you effort, 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. Thanks 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 people 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! (Have 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

Geocoder for Google Map DokuWiki

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;… LOL)

Just take an address, 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….

Caching

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?

Own & User- interactive map

The possibility to create own maps – not a world map 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

There is an alternative based upon OpenLayers: http://openlayersmap.sourceforge.net/


Hi. Has anyone tried making this work in conjunction with the data plugin? I have lat, long coordinates embedded in pages using the data plugin but I couldn't find a way to make map generation automatic using sql queries. Mister Tumnus 2009/01/24 20:44

direction support

If the direction support is not added, a link to google map could be a good idea. When you click on the “link” in google map, they give you the html code for an embedded map. This code include a link (“View Larger Map”) to google map right under the map.

It could be a nice idea to display that kind of link, so people could use the direction option (super useful since google map offer direction for the subway/bus in many cities).

WikiJapon

KML file url problem (info AT netlamps DOT org)

Have a look at: http://netlamps.org/doku.php?id=testing

It seems that using a “normal” url (such as: http://netlamps.org/NetLAMPS/pub/segnalazioni.kml) the plugin does NOT work, while using a “dokuwiki” url (such as: http://netlamps.org/lib/exe/fetch.php?media=segnalazioni.kml) the plugin DOES work.

Both urls are valid, if you follow them with the browser you get the same file.

Any idea?

Thank you

Caching problem? (info AT netlamps DOT org)

This page is generated by a script every now and then and copied into the data dir in dokuwiki. It happens that the maps are NOT updated when I update the kml files even if clicking on the kml url (see the page) the right (updated) file is present. I used the NOCACHE pragma on the page.

Any idea?

Thank you

Overview

is it possible to get an overview-amp? thx

GoogleMap API key problem

I keep getting error messages about the key “this web site needs a different google maps API key”

default.php file keeps beeing empty although I did save configuration in dokuwiki conf settings $ tail -2 default.php $conf['key'] = ''; $conf['script'] = 'http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=';

is this normal ?

I must admit that my DNS conf is not simple, www.reve.fr has 157.159.11.54 ip address, but the hostname that serves www.reve.fr is wheberges.it-sudparis.eu which also has 157.159.11.54, but reverse DNS lookup points 157.159.11.54 to wheberges.it-sudparis.eu, then for which domain should I register a key !? (I tried both whitout success …), does googlemaps check reverse IP ? Thanks .

Google has more info about this: http://code.google.com/intl/nl-NL/apis/maps/faq.html#keysystem
You should register your key for every different (base)url of your site. Check the examples on the faq.
- Klap-in
plugin/googlemaps.txt · Last modified: 2013/02/15 00:33 by Klap-in