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-10-06 11:27] – tag cleanup laynee | plugin:google_maps [2019-04-22 09:45] (current) – [Bugs and ToDo] hua | ||
---|---|---|---|
Line 6: | Line 6: | ||
email : dma_k@mail.ru | email : dma_k@mail.ru | ||
type : syntax | type : syntax | ||
- | lastupdate : 2008-04-12 | + | lastupdate : 2010-10-18 |
- | compatible : 2008-05-05, 2006-11-06 | + | compatible : 2009-12-25c, |
depends | depends | ||
conflicts | conflicts | ||
similar | similar | ||
- | tags : | + | tags : |
+ | |||
+ | downloadurl: | ||
---- | ---- | ||
+ | |||
===== Download and Installation ===== | ===== Download and Installation ===== | ||
- | Download | + | Search |
- | The up-to-date version of the plugin and this description is [[http:// | + | [[https://www.centurion.link/w/ |
Line 29: | Line 32: | ||
===== Syntax ===== | ===== Syntax ===== | ||
- | Complete list: | + | Complete list of all possible options: |
- | '' | + | '' |
- | where: | + | Google maps plugin can generate google maps in embedded frame (when **type=embedded**) or as link to google maps (when **type** is not set // |
- | | **zoom**,**size**,**control**,**overviewmap** | see in [[# | + | 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. |
- | | **type** | **internal** -- show google maps in embedded frame \\ // | + | |
- | If **alternate text** is skipped then **address** is used. | + | **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 |
+ | |||
+ | |||
+ | ==== 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 | + | ==== Default |
^ Parameter name ^ | ^ Parameter name ^ | ||
- | | **google_api_key** | Valid Google API key for the current site. See [[# | + | | **google_api_key** | Valid Google API key for the current site. See [[# |
- | | **size** | **small** // | + | | **small_width** | //(default is **425**)// size in px -- the width of small frame, if **size=small** was specified | |
- | | **control** | **hierarchical** // | + | | **small_height** | //(default is **350**)// size in px -- the height of small frame, if **size=small** was specified | |
- | | **overviewmap** | **true** // | + | | **large_width** | //(default is **550**)// size in px -- the width of large frame, if **size=large** was specified | |
- | | **small_width** | //(default is **425**)// size in px -- the width of small frame, if **size=small** was specified | | + | | **large_height** | //(default is **450**)// size in px -- the height of large frame, if **size=large** 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 | + | |
- | | **zoom** | //(default is **15**)// number from 1 to 19 which specifies the initial zoom | | + | |
===== Demonstration ===== | ===== Demonstration ===== | ||
- | See [[http:// | + | [[https://www.centurion.link/w/ |
Line 63: | Line 73: | ||
Important is to register your site at Google to receive an access to Google services. Registration is free: | Important is to register your site at Google to receive an access to Google services. Registration is free: | ||
- | * Register your website | + | * [[http:// |
* Modify the configuration file and put a newly generated key to **google_api_key**. | * Modify the configuration file and put a newly generated key to **google_api_key**. | ||
Line 81: | Line 91: | ||
===== Source ===== | ===== Source ===== | ||
- | + | ==== syntax/maps.php ==== | |
- | ==== syntax.php ==== | + | |
<code php> | <code php> | ||
<?php | <?php | ||
/** | /** | ||
- | * Plugin | + | * Plugin |
| | ||
- | * @license | + | * @license |
* @author | * @author | ||
*/ | */ | ||
- | if(!defined(' | + | if(!defined(' |
if(!defined(' | if(!defined(' | ||
require_once(DOKU_PLUGIN.' | require_once(DOKU_PLUGIN.' | ||
Line 103: | Line 112: | ||
class syntax_plugin_google_maps extends DokuWiki_Syntax_Plugin | class syntax_plugin_google_maps extends DokuWiki_Syntax_Plugin | ||
{ | { | ||
- | private $config; | + | private $RE_NON_SYNTAX_SEQ |
- | private $re_non_syntax_seq | + | private $RE_PLUGIN_BODY; |
- | private $re_plugin_body; | + | |
- | + | ||
function syntax_plugin_google_maps() | function syntax_plugin_google_maps() | ||
{ | { | ||
- | $this->config | + | $this->RE_PLUGIN_BODY |
- | + | ||
- | | + | |
} | } | ||
Line 117: | Line 123: | ||
{ | { | ||
return array( | return array( | ||
- | 'author1' | + | 'author' |
- | 'email1' | + | 'email' |
- | ' | + | ' |
' | ' | ||
' | ' | ||
- | | + | |
' | ' | ||
); | ); | ||
} | } | ||
- | | + | |
- | { | + | { |
- | return array(' | + | return array(' |
- | } | + | } |
- | + | ||
- | function getType() | + | function getType() |
- | { | + | { |
- | return ' | + | return ' |
- | } | + | } |
- | + | ||
function getSort() | function getSort() | ||
{ | { | ||
Line 144: | Line 150: | ||
function connectTo($mode) | function connectTo($mode) | ||
{ | { | ||
- | $this-> | + | $this-> |
- | $this-> | + | $this-> |
} | } | ||
function postConnect() | function postConnect() | ||
{ | { | ||
- | $this-> | + | $this-> |
} | } | ||
Line 158: | Line 164: | ||
return(htmlspecialchars( | return(htmlspecialchars( | ||
isset($options[$option_name]) ? | isset($options[$option_name]) ? | ||
- | | + | |
- | $this->config[$config_prefix . $option_name] | + | $this->getConf($config_prefix . $option_name) |
)); | )); | ||
} | } | ||
- | function handle($match, | + | function handle($match, |
{ | { | ||
switch ($state) | switch ($state) | ||
Line 171: | Line 177: | ||
$matches = array(); | $matches = array(); | ||
- | if (!preg_match("/ | + | if (!preg_match('/ |
{ | { | ||
- | // syslog(LOG_DEBUG, | ||
return array('' | return array('' | ||
} | } | ||
Line 181: | Line 186: | ||
if (isset($matches[2])) | if (isset($matches[2])) | ||
{ | { | ||
- | preg_replace('/ | ||
$entries = explode(',', | $entries = explode(',', | ||
Line 188: | Line 192: | ||
$key_value = explode(' | $key_value = explode(' | ||
- | $options[$key_value[0]] = $key_value[1]; | + | $options[trim($key_value[0])] = trim($key_value[1]); |
} | } | ||
} | } | ||
Line 198: | Line 202: | ||
} | } | ||
- | function render($mode, | + | function render($mode, |
{ | { | ||
if ($mode == ' | if ($mode == ' | ||
Line 210: | Line 214: | ||
list($text, $options) = $match; | list($text, $options) = $match; | ||
- | $query = htmlspecialchars(html_entity_decode(trim($text))); | + | |
+ | | ||
+ | $i = 0; | ||
+ | |||
+ | foreach | ||
+ | { | ||
+ | $q = trim($q); | ||
+ | if (strlen($q)) | ||
+ | { | ||
+ | $locations[$i++] = htmlspecialchars(html_entity_decode($q)); | ||
+ | } | ||
+ | } | ||
// This type is available only in DOKU_LEXER_SPECIAL state: | // This type is available only in DOKU_LEXER_SPECIAL state: | ||
- | if ($state == DOKU_LEXER_SPECIAL && $options[' | + | if ($state == DOKU_LEXER_SPECIAL && $options[' |
{ | { | ||
- | // Injection | + | // Dynamic injection |
- | $renderer-> | + | $renderer-> |
// Default values: | // Default values: | ||
Line 223: | Line 238: | ||
$height | $height | ||
- | // Internal | + | // Embedded |
- | $renderer-> | + | $renderer-> |
+ | |||
+ | foreach ($locations as $i => $q) | ||
+ | { | ||
+ | $renderer-> | ||
+ | } | ||
// Copy values into attributes: | // Copy values into attributes: | ||
foreach (array(' | foreach (array(' | ||
{ | { | ||
- | $renderer-> | + | $attr_value |
+ | |||
+ | if (strlen($attr_value)) | ||
+ | { | ||
+ | $renderer-> | ||
+ | } | ||
} | } | ||
// Important to leave one hanging node inside < | // Important to leave one hanging node inside < | ||
- | // That is done implicitly here. | ||
$renderer-> | $renderer-> | ||
Line 239: | Line 263: | ||
} | } | ||
- | if ($options[' | + | |
+ | // * 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: | ||
+ | | ||
{ | { | ||
- | | + | $params .= " |
- | $params = '&'; | + | } |
- | // If not defined, Google Maps engine will automatically select the best zoom: | + | |
- | if ($options[' | + | |
- | { | + | |
- | | + | |
- | } | + | |
- | | + | |
- | $url = "http:// | + | $url = "// |
- | | + | |
- | $renderer-> | + | $renderer-> |
- | | + | |
- | { | + | { |
- | | + | |
- | } | + | |
- | + | ||
- | return true; | + | |
} | } | ||
- | return | + | return |
case DOKU_LEXER_UNMATCHED: | case DOKU_LEXER_UNMATCHED: | ||
Line 288: | Line 312: | ||
<code javascript> | <code javascript> | ||
- | var max_geo_results = 5; | + | /** |
+ | * 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, | function createMarker(point, | ||
{ | { | ||
Line 295: | Line 334: | ||
// Note: Without wrapping into a function, listeners are added to the same objects! | // Note: Without wrapping into a function, listeners are added to the same objects! | ||
- | GEvent.addListener(marker, | + | GEvent.addListener(marker, |
+ | | ||
marker.openInfoWindowHtml(desc); | marker.openInfoWindowHtml(desc); | ||
}); | }); | ||
Line 302: | Line 342: | ||
} | } | ||
- | function queryGoogleGeo(map, | + | /* |
+ | * This recursive function sends an ansynchronous query to Google GeoCoder and marks results on the map. | ||
+ | */ | ||
+ | function queryGoogleGeo(map, | ||
{ | { | ||
- | | + | |
+ | { | ||
+ | // Can be initialized only at this point, as Google libraries should have been included: | ||
+ | GMAPS_GEOCODER | ||
+ | } | ||
- | | + | |
function generateMarkersFromGoogleGeoResult(response) | function generateMarkersFromGoogleGeoResult(response) | ||
{ | { | ||
// Was not able to locate any data: | // Was not able to locate any data: | ||
- | if (response == null || response.Status.code != 200) { | + | if (response == null) |
- | alert(" | + | { |
+ | 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; | return; | ||
} | } | ||
Line 317: | Line 381: | ||
var places = response.Placemark; | var places = response.Placemark; | ||
- | for (var i = 0; i < places.length && i < max_geo_results; i++) { | + | for (var i = 0; i < places.length && i < GMAPS_MAX_GEO_RESULTS; i++) |
+ | | ||
var place = places[i]; | var place = places[i]; | ||
var point = new GLatLng(place.Point.coordinates[1], | var point = new GLatLng(place.Point.coordinates[1], | ||
- | | + | |
- | map.setCenter(point, zoom); | + | |
- | } | + | |
- | map.addOverlay(createMarker(point, | + | map.addOverlay(createMarker(point, |
+ place.AddressDetails.Country.CountryNameCode | + 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, | ||
} | } | ||
}); | }); | ||
Line 337: | Line 424: | ||
function loadMaps() | function loadMaps() | ||
{ | { | ||
- | | + | |
- | var divNodes | + | var attrs = this.attributes; |
- | for (var i = 0; i < divNodes.length; | + | // Create a map: |
- | | + | |
- | var attrs = divNodes[i].attributes; | + | |
- | | + | |
- | | + | if (attrs.size.value == ' |
- | map.setCenter(new GLatLng(34, 0), 1); // default point | + | map.addControl(new GSmallMapControl()); |
+ | else if (attrs.size.value == ' | ||
+ | map.addControl(new GLargeMapControl()); | ||
- | | + | |
- | if (attrs.size.value == 'small') | + | if (attrs.control.value == 'hierarchical') |
- | map.addControl(new | + | map.addControl(new |
- | else | + | else if (attrs.control.value == 'all') |
- | | + | map.addControl(new |
- | map.addControl(new | + | |
- | | + | |
- | if (attrs.control.value == 'hierarchical') | + | if (attrs.overviewmap.value == 'true') |
- | | + | { |
- | | + | var overviewMap = new GOverviewMapControl(); |
- | 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(); |
- | | + | |
- | | + | while (true) |
+ | { | ||
+ | | ||
+ | { | ||
+ | break; | ||
+ | } | ||
- | | + | |
- | | + | |
} | } | ||
- | | + | |
+ | queryGoogleGeo(map, | ||
+ | | ||
} | } | ||
// A special Wiki-wide function, defined in lib/ | // A special Wiki-wide function, defined in lib/ | ||
- | addInitEvent(loadMaps); | + | jQuery(loadMaps); |
- | </ | + | })();</ |
Line 388: | Line 479: | ||
<code css> | <code css> | ||
- | a.gmapsext | + | a.gmaps_link |
- | background: transparent url(gmaps_link.png) no-repeat left center; | + | background: transparent url(gmaps_link.png) no-repeat left center; |
padding: 1px 0px 1px 12px; | padding: 1px 0px 1px 12px; | ||
} | } | ||
- | div.gmapsint | + | div.gmaps_frame |
border: 1px solid __border__; | border: 1px solid __border__; | ||
} | } | ||
- | div.gmapsmarker | + | div.gmaps_marker |
font-size: 90%; | 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' | ||
plugin/google_maps.1254821279.txt.gz · Last modified: 2009-10-06 11:27 by laynee