plugin:google_maps
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
plugin:google_maps [2009-02-07 15:02] – Added more tags 201.83.249.204 | plugin:google_maps [2019-04-22 09:45] (current) – [Bugs and ToDo] hua | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Google Maps plugin ====== | ||
+ | |||
+ | ---- plugin ---- | ||
+ | description: | ||
+ | author | ||
+ | email : dma_k@mail.ru | ||
+ | type : syntax | ||
+ | lastupdate : 2010-10-18 | ||
+ | compatible : 2009-12-25c, | ||
+ | depends | ||
+ | conflicts | ||
+ | similar | ||
+ | tags : media, maps, google, embed | ||
+ | |||
+ | downloadurl: | ||
+ | ---- | ||
+ | |||
+ | |||
+ | ===== Download and Installation ===== | ||
+ | |||
+ | Search and install the plugin using the [[plugin: | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | |||
+ | ===== Description & Requirements ===== | ||
+ | |||
+ | Plugin allows to embed Google map frames to the page or create external links to Google Maps service. Useful when listing addresses. | ||
+ | Works with any browser, where [[http:// | ||
+ | |||
+ | |||
+ | ===== Syntax ===== | ||
+ | |||
+ | Complete list of all possible options: | ||
+ | |||
+ | '' | ||
+ | |||
+ | Google maps plugin can generate google maps in embedded frame (when **type=embedded**) or as link to google maps (when **type** is not set // | ||
+ | |||
+ | Alternative text may include any other inline formatting supported by dokuwiki, and is rendered only for **default type** (if one specify alternative text then this type is forced, as there is no opportunity to render it in **embedded** mode). If **alternative text** is skipped then **address** is used as a link text. | ||
+ | |||
+ | **embedded type** supports several addresses to be marked on Google Maps (only first address will be used in **default type**). It is advised not to specify **zoom** in this case, which will be set automatically to optimal value to display all address markers on the map. | ||
+ | |||
+ | |||
+ | ==== Parameters ==== | ||
+ | |||
+ | ^ Parameter name ^ | ||
+ | | **zoom** | number from 1 to 19 which specifies the initial zoom; if not defined, | ||
+ | | **width** | size in px -- the width of embedded frame (overrides the default parameter value) | | ||
+ | | **height** | size in px -- the height of embedded frame (overrides the default parameter value) | | ||
+ | | **size** | **small** // | ||
+ | | **control** | **hierarchical** // | ||
+ | | **overviewmap** | **true** // | ||
+ | | **type** | **unset** // | ||
+ | |||
+ | |||
+ | ==== Default options ==== | ||
+ | |||
+ | ^ Parameter name ^ | ||
+ | | **google_api_key** | Valid Google API key for the current site. See [[# | ||
+ | | **small_width** | //(default is **425**)// size in px -- the width of small frame, if **size=small** was specified | | ||
+ | | **small_height** | //(default is **350**)// size in px -- the height of small frame, if **size=small** was specified | | ||
+ | | **large_width** | //(default is **550**)// size in px -- the width of large frame, if **size=large** was specified | | ||
+ | | **large_height** | //(default is **450**)// size in px -- the height of large frame, if **size=large** was specified | | ||
+ | |||
+ | |||
+ | ===== Demonstration ===== | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | |||
+ | ===== Configuration ===== | ||
+ | |||
+ | Important is to register your site at Google to receive an access to Google services. Registration is free: | ||
+ | * [[http:// | ||
+ | * Modify the configuration file and put a newly generated key to **google_api_key**. | ||
+ | |||
+ | |||
+ | ===== Documentation ===== | ||
+ | |||
+ | * Plugin uses the JSON (JavaScript Object Notation) technique (described in [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * [[http:// | ||
+ | * See also [[http:// | ||
+ | |||
+ | |||
+ | ===== Source ===== | ||
+ | |||
+ | ==== syntax/ | ||
+ | |||
+ | <code php> | ||
+ | <?php | ||
+ | /** | ||
+ | * Plugin google_maps: | ||
+ | | ||
+ | * @license | ||
+ | * @author | ||
+ | */ | ||
+ | |||
+ | if(!defined(' | ||
+ | if(!defined(' | ||
+ | require_once(DOKU_PLUGIN.' | ||
+ | |||
+ | /** | ||
+ | * All DokuWiki plugins to extend the parser/ | ||
+ | * need to inherit from this class | ||
+ | */ | ||
+ | class syntax_plugin_google_maps extends DokuWiki_Syntax_Plugin | ||
+ | { | ||
+ | private $RE_NON_SYNTAX_SEQ = ' | ||
+ | private $RE_PLUGIN_BODY; | ||
+ | |||
+ | function syntax_plugin_google_maps() | ||
+ | { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | function getInfo() | ||
+ | { | ||
+ | return array( | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | ' | ||
+ | | ||
+ | ' | ||
+ | ); | ||
+ | } | ||
+ | |||
+ | function getAllowedTypes() | ||
+ | { | ||
+ | return array(' | ||
+ | } | ||
+ | |||
+ | function getType() | ||
+ | { | ||
+ | return ' | ||
+ | } | ||
+ | |||
+ | function getSort() | ||
+ | { | ||
+ | return 159; | ||
+ | } | ||
+ | |||
+ | function connectTo($mode) | ||
+ | { | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | function postConnect() | ||
+ | { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | private function getConfigValue($options, | ||
+ | { | ||
+ | // Also escape HTML to protect the page: | ||
+ | return(htmlspecialchars( | ||
+ | isset($options[$option_name]) ? | ||
+ | $options[$option_name] : | ||
+ | $this-> | ||
+ | )); | ||
+ | } | ||
+ | |||
+ | function handle($match, | ||
+ | { | ||
+ | switch ($state) | ||
+ | { | ||
+ | case DOKU_LEXER_SPECIAL: | ||
+ | case DOKU_LEXER_ENTER: | ||
+ | $matches = array(); | ||
+ | |||
+ | if (!preg_match('/ | ||
+ | { | ||
+ | return array('' | ||
+ | } | ||
+ | |||
+ | $options = array(); | ||
+ | |||
+ | if (isset($matches[2])) | ||
+ | { | ||
+ | $entries = explode(',', | ||
+ | |||
+ | foreach ($entries as $entry) | ||
+ | { | ||
+ | $key_value = explode(' | ||
+ | |||
+ | $options[trim($key_value[0])] = trim($key_value[1]); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return array($state, | ||
+ | } | ||
+ | | ||
+ | return array($state, | ||
+ | } | ||
+ | |||
+ | function render($mode, | ||
+ | { | ||
+ | if ($mode == ' | ||
+ | { | ||
+ | list($state, | ||
+ | |||
+ | switch($state) | ||
+ | { | ||
+ | case DOKU_LEXER_SPECIAL: | ||
+ | case DOKU_LEXER_ENTER: | ||
+ | list($text, $options) = $match; | ||
+ | |||
+ | // All locations are in this array: | ||
+ | $locations = array(); | ||
+ | $i = 0; | ||
+ | |||
+ | foreach (explode(";", | ||
+ | { | ||
+ | $q = trim($q); | ||
+ | if (strlen($q)) | ||
+ | { | ||
+ | $locations[$i++] = htmlspecialchars(html_entity_decode($q)); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // This type is available only in DOKU_LEXER_SPECIAL state: | ||
+ | if ($state == DOKU_LEXER_SPECIAL && $options[' | ||
+ | { | ||
+ | // Dynamic injection of this script via JS causes FF to hang, so we have to include it for each map: | ||
+ | $renderer-> | ||
+ | |||
+ | // Default values: | ||
+ | $size = $this-> | ||
+ | $width | ||
+ | $height | ||
+ | |||
+ | // Embedded div: | ||
+ | $renderer-> | ||
+ | |||
+ | foreach ($locations as $i => $q) | ||
+ | { | ||
+ | $renderer-> | ||
+ | } | ||
+ | |||
+ | // Copy values into attributes: | ||
+ | foreach (array(' | ||
+ | { | ||
+ | $attr_value = $this-> | ||
+ | |||
+ | if (strlen($attr_value)) | ||
+ | { | ||
+ | $renderer-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | // Important to leave one hanging node inside < | ||
+ | $renderer-> | ||
+ | |||
+ | return true; | ||
+ | } | ||
+ | |||
+ | // If we are here it means: | ||
+ | // * state == DOKU_LEXER_SPECIAL and type != embedded ==> we render a link with a text equal to address, as there is no alternative text in this state | ||
+ | // * state == DOKU_LEXER_ENTER | ||
+ | // * state == DOKU_LEXER_ENTER | ||
+ | |||
+ | // Concat params: | ||
+ | $params = '&'; | ||
+ | // If not defined, Google Maps engine will automatically select the best zoom: | ||
+ | if ($options[' | ||
+ | { | ||
+ | $params .= " | ||
+ | } | ||
+ | |||
+ | // Query is already escaped, params are taken from options: | ||
+ | $url = "// | ||
+ | |||
+ | // External link: | ||
+ | $renderer-> | ||
+ | |||
+ | if ($state == DOKU_LEXER_SPECIAL) | ||
+ | { | ||
+ | | ||
+ | } | ||
+ | |||
+ | return true; | ||
+ | |||
+ | case DOKU_LEXER_UNMATCHED: | ||
+ | $renderer-> | ||
+ | return true; | ||
+ | | ||
+ | case DOKU_LEXER_EXIT: | ||
+ | $renderer-> | ||
+ | return true; | ||
+ | | ||
+ | default: | ||
+ | // | ||
+ | } | ||
+ | } | ||
+ | |||
+ | return false; | ||
+ | } | ||
+ | } | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== script.js ==== | ||
+ | |||
+ | <code javascript> | ||
+ | /** | ||
+ | * Plugin google_maps: | ||
+ | * | ||
+ | * @license | ||
+ | * @author | ||
+ | */ | ||
+ | |||
+ | (function() { | ||
+ | // Globals: | ||
+ | var GMAPS_MAX_RETRY_COUNT = 5; | ||
+ | var GMAPS_RETRY_DELAY = 100; | ||
+ | var GMAPS_MAX_GEO_RESULTS = 1; | ||
+ | var GMAPS_GEOCODER = null; | ||
+ | |||
+ | /* | ||
+ | * This function creates a new marker with a given HTML shown when a marker is clicked. | ||
+ | */ | ||
+ | function createMarker(point, | ||
+ | { | ||
+ | var marker = new GMarker(point); | ||
+ | |||
+ | // Note: Without wrapping into a function, listeners are added to the same objects! | ||
+ | GEvent.addListener(marker, | ||
+ | { | ||
+ | marker.openInfoWindowHtml(desc); | ||
+ | }); | ||
+ | |||
+ | return marker; | ||
+ | } | ||
+ | |||
+ | /* | ||
+ | * This recursive function sends an ansynchronous query to Google GeoCoder and marks results on the map. | ||
+ | */ | ||
+ | function queryGoogleGeo(map, | ||
+ | { | ||
+ | if (GMAPS_GEOCODER == null) | ||
+ | { | ||
+ | // Can be initialized only at this point, as Google libraries should have been included: | ||
+ | GMAPS_GEOCODER = new GClientGeocoder(); | ||
+ | } | ||
+ | |||
+ | GMAPS_GEOCODER.getLocations(locations[index], | ||
+ | function generateMarkersFromGoogleGeoResult(response) | ||
+ | { | ||
+ | // Was not able to locate any data: | ||
+ | if (response == null) | ||
+ | { | ||
+ | alert(" | ||
+ | return; | ||
+ | } | ||
+ | else if (response.Status.code == 602) | ||
+ | { | ||
+ | if (retry++ >= GMAPS_MAX_RETRY_COUNT) | ||
+ | { | ||
+ | alert(" | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | setTimeout(queryGoogleGeo, | ||
+ | return; | ||
+ | } | ||
+ | else if (response.Status.code != 200) | ||
+ | { | ||
+ | alert(" | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | var places = response.Placemark; | ||
+ | |||
+ | for (var i = 0; i < places.length && i < GMAPS_MAX_GEO_RESULTS; | ||
+ | { | ||
+ | var place = places[i]; | ||
+ | var point = new GLatLng(place.Point.coordinates[1], | ||
+ | |||
+ | bounds.extend(point); | ||
+ | |||
+ | map.addOverlay(createMarker(point, | ||
+ | + place.AddressDetails.Country.CountryNameCode | ||
+ | )); | ||
+ | } | ||
+ | |||
+ | if (index == locations.length - 1) | ||
+ | { | ||
+ | if (zoom == null) | ||
+ | { | ||
+ | if (!bounds.isEmpty()) | ||
+ | { | ||
+ | // We select the best zoom for the boundary: | ||
+ | zoom = map.getBoundsZoomLevel(bounds); | ||
+ | } | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // zoom is required to be an integer: | ||
+ | zoom = parseInt(zoom); | ||
+ | } | ||
+ | |||
+ | map.setCenter(bounds.getCenter(), | ||
+ | } | ||
+ | else | ||
+ | { | ||
+ | // Query recuresively other locations: | ||
+ | queryGoogleGeo(map, | ||
+ | } | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Initialisation function. Creates Gmap objects and loads Geo information. | ||
+ | */ | ||
+ | function loadMaps() | ||
+ | { | ||
+ | jQuery(' | ||
+ | var attrs = this.attributes; | ||
+ | |||
+ | // Create a map: | ||
+ | var map = new GMap2(this); | ||
+ | map.setCenter(new GLatLng(34, 0), 1); // default point | ||
+ | |||
+ | // left-top navigator and zoomer | ||
+ | if (attrs.size.value == ' | ||
+ | map.addControl(new GSmallMapControl()); | ||
+ | else if (attrs.size.value == ' | ||
+ | map.addControl(new GLargeMapControl()); | ||
+ | |||
+ | // right-top map type switch buttons | ||
+ | if (attrs.control.value == ' | ||
+ | map.addControl(new GHierarchicalMapTypeControl()); | ||
+ | else if (attrs.control.value == ' | ||
+ | map.addControl(new GMapTypeControl()); | ||
+ | |||
+ | // mini-map in the bottom-right corner | ||
+ | if (attrs.overviewmap.value == ' | ||
+ | { | ||
+ | var overviewMap = new GOverviewMapControl(); | ||
+ | map.addControl(overviewMap); | ||
+ | overviewMap.hide(); | ||
+ | } | ||
+ | |||
+ | map.enableScrollWheelZoom(); | ||
+ | |||
+ | var locations = new Array(); | ||
+ | |||
+ | var n = 0; | ||
+ | while (true) | ||
+ | { | ||
+ | if (attrs[' | ||
+ | { | ||
+ | break; | ||
+ | } | ||
+ | |||
+ | locations[n] = attrs[' | ||
+ | n++; | ||
+ | } | ||
+ | |||
+ | queryGoogleGeo(map, | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | // A special Wiki-wide function, defined in lib/ | ||
+ | jQuery(loadMaps); | ||
+ | })();</ | ||
+ | |||
+ | |||
+ | ==== style.css ==== | ||
+ | |||
+ | <code css> | ||
+ | a.gmaps_link { | ||
+ | background: transparent url(gmaps_link.png) no-repeat left center; /* " | ||
+ | padding: 1px 0px 1px 12px; | ||
+ | } | ||
+ | |||
+ | div.gmaps_frame { | ||
+ | border: 1px solid __border__; | ||
+ | } | ||
+ | |||
+ | div.gmaps_marker { | ||
+ | font-size: 90%; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | The latest source code can be taken from [[https:// | ||
+ | |||
+ | |||
+ | ===== Release History ===== | ||
+ | |||
+ | * 2008-03-17 (r05) --- Initial version. | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | |||
+ | ===== Bugs and ToDo ===== | ||
+ | |||
+ | Tested with IE 6.0 SP1, FF 3.5.x. No bugs at the moment. | ||
+ | |||
+ | There is nothing right now in my ToDo list. Please, add comment to this page. | ||
+ | |||
+ | Question:\\ | ||
+ | 1. Google API key should be placed in \doku\lib\plugins\google_maps\conf\default.php ?\\ | ||
+ | It doesn' | ||