xref: /plugin/spatialhelper/action.php (revision f2601b074259891798291068b04d670f6e4871ea) !
1bd120a73SMark C. Prins<?php
2bd120a73SMark C. Prins/*
3a9441f7dSMark C. Prins * Copyright (c) 2011-2014 Mark C. Prins <mprins@users.sf.net>
4bd120a73SMark C. Prins *
5bd120a73SMark C. Prins * Permission to use, copy, modify, and distribute this software for any
6bd120a73SMark C. Prins * purpose with or without fee is hereby granted, provided that the above
7bd120a73SMark C. Prins * copyright notice and this permission notice appear in all copies.
8bd120a73SMark C. Prins *
9bd120a73SMark C. Prins * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10bd120a73SMark C. Prins * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11bd120a73SMark C. Prins * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12bd120a73SMark C. Prins * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13bd120a73SMark C. Prins * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14bd120a73SMark C. Prins * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15bd120a73SMark C. Prins * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16bd120a73SMark C. Prins */
17a9441f7dSMark C. Prinsif (! defined ( 'DOKU_INC' ))
18a9441f7dSMark C. Prins	die ();
19a9441f7dSMark C. Prinsif (! defined ( 'DOKU_PLUGIN' ))
20a9441f7dSMark C. Prins	define ( 'DOKU_PLUGIN', DOKU_INC . 'lib/plugins/' );
217c452997SMark C. Prinsif (! defined ( 'DOKU_LF' ))
227c452997SMark C. Prins	define ( 'DOKU_LF', "\n" );
23bd120a73SMark C. Prinsrequire_once (DOKU_PLUGIN . 'action.php');
24bd120a73SMark C. Prins
25a9441f7dSMark C. Prins/**
26a9441f7dSMark C. Prins * DokuWiki Plugin dokuwikispatial (Action Component).
27a9441f7dSMark C. Prins *
28a9441f7dSMark C. Prins * @license BSD license
29a9441f7dSMark C. Prins * @author Mark C. Prins <mprins@users.sf.net>
30a9441f7dSMark C. Prins */
31bd120a73SMark C. Prinsclass action_plugin_spatialhelper extends DokuWiki_Action_Plugin {
32bd120a73SMark C. Prins
3302c45c98SMark C. Prins	// TODO add configurable namespace, NOTE if $mediaID is namespaced the directory may need to be created
3402c45c98SMark C. Prins	private $media_kml = ':sitemap.kml';
3502c45c98SMark C. Prins	private $media_georss = ':sitemap.georss';
3602c45c98SMark C. Prins
37bd120a73SMark C. Prins	/**
38bd120a73SMark C. Prins	 * Register for events.
39bd120a73SMark C. Prins	 *
40a9441f7dSMark C. Prins	 * @param Doku_Event_Handler $controller
41a9441f7dSMark C. Prins	 *        	DokuWiki's event controller object. Also available as global $EVENT_HANDLER
42bd120a73SMark C. Prins	 */
43bd120a73SMark C. Prins	public function register(Doku_Event_Handler &$controller) {
447c452997SMark C. Prins		// listen for page add / delete events
45bd120a73SMark C. Prins		// http://www.dokuwiki.org/devel:event:indexer_page_add
4602c45c98SMark C. Prins		$controller->register_hook ( 'INDEXER_PAGE_ADD', 'BEFORE', $this, 'handle_indexer_page_add' );
4734fb1e15SMark C. Prins		$controller->register_hook ( 'IO_WIKIPAGE_WRITE', 'BEFORE', $this, '_removeFromIndex' );
48a9441f7dSMark C. Prins
49bd120a73SMark C. Prins		// http://www.dokuwiki.org/devel:event:sitemap_generate
5002c45c98SMark C. Prins		$controller->register_hook ( 'SITEMAP_GENERATE', 'BEFORE', $this, 'handle_sitemap_generate_before' );
517c452997SMark C. Prins		// using after will only trigger us if a sitemap was actually created
5202c45c98SMark C. Prins		$controller->register_hook ( 'SITEMAP_GENERATE', 'AFTER', $this, 'handle_sitemap_generate_after' );
537c452997SMark C. Prins
54a9441f7dSMark C. Prins		// handle actions we know of
5502c45c98SMark C. Prins		$controller->register_hook ( 'ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_action_act_preprocess', array () );
563e83b370SMark C. Prins		$controller->register_hook ( 'TPL_ACT_UNKNOWN', 'BEFORE', $this, '_findnearby', array (
573e83b370SMark C. Prins				'format' => 'HTML'
583e83b370SMark C. Prins		) );
593e83b370SMark C. Prins
603e83b370SMark C. Prins		$controller->register_hook ( 'AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_findnearby', array (
613e83b370SMark C. Prins				'format' => 'JSON'
623e83b370SMark C. Prins		) );
637c452997SMark C. Prins
64a9441f7dSMark C. Prins		// listen for media uploads and deletes
65a9441f7dSMark C. Prins		$controller->register_hook ( 'MEDIA_UPLOAD_FINISH', 'BEFORE', $this, '_handle_media_uploaded', array () );
66a9441f7dSMark C. Prins		$controller->register_hook ( 'MEDIA_DELETE_FILE', 'BEFORE', $this, '_handle_media_deleted', array () );
6702c45c98SMark C. Prins
6802c45c98SMark C. Prins		$controller->register_hook ( 'TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handle_metaheader_output' );
69bd120a73SMark C. Prins	}
70bd120a73SMark C. Prins
71bd120a73SMark C. Prins	/**
72bd120a73SMark C. Prins	 * Update the spatial index for the page.
73a9441f7dSMark C. Prins	 *
74a9441f7dSMark C. Prins	 * @param Doku_Event $event
75a9441f7dSMark C. Prins	 *        	event object by reference
76a9441f7dSMark C. Prins	 * @param object $param
77a9441f7dSMark C. Prins	 *        	the parameters passed to register_hook when this handler was registered
78bd120a73SMark C. Prins	 */
7902c45c98SMark C. Prins	function handle_indexer_page_add(Doku_Event &$event, $param) {
807c452997SMark C. Prins		// $event→data['page'] – the page id
817c452997SMark C. Prins		// $event→data['body'] – empty, can be filled by additional content to index by your plugin
827c452997SMark C. Prins		// $event→data['metadata'] – the metadata that shall be indexed. This is an array where the keys are the metadata indexes and the value a string or an array of strings with the values. title and relation_references will already be set.
839af1cdd4SMark C. Prins		$id = $event->data ['page'];
8402c45c98SMark C. Prins		$indexer = & plugin_load ( 'helper', 'spatialhelper_index' );
85bd120a73SMark C. Prins		$entries = $indexer->updateSpatialIndex ( $id );
86bd120a73SMark C. Prins	}
87bd120a73SMark C. Prins
88bd120a73SMark C. Prins	/**
8934fb1e15SMark C. Prins	 * Update the spatial index, removing the page.
90a9441f7dSMark C. Prins	 *
91a9441f7dSMark C. Prins	 * @param Doku_Event $event
92a9441f7dSMark C. Prins	 *        	event object by reference
93a9441f7dSMark C. Prins	 * @param object $param
94a9441f7dSMark C. Prins	 *        	the parameters passed to register_hook when this handler was registered
9534fb1e15SMark C. Prins	 */
9634fb1e15SMark C. Prins	function _removeFromIndex(Doku_Event &$event, $param) {
977c452997SMark C. Prins		// event data:
987c452997SMark C. Prins		// $data[0] – The raw arguments for io_saveFile as an array. Do not change file path.
997c452997SMark C. Prins		// $data[0][0] – the file path.
1007c452997SMark C. Prins		// $data[0][1] – the content to be saved, and may be modified.
1017c452997SMark C. Prins		// $data[1] – ns: The colon separated namespace path minus the trailing page name. (false if root ns)
1027c452997SMark C. Prins		// $data[2] – page_name: The wiki page name.
1037c452997SMark C. Prins		// $data[3] – rev: The page revision, false for current wiki pages.
1047c452997SMark C. Prins
10502c45c98SMark C. Prins		// dbglog ( $event->data, "Event data in _removeFromIndex." );
10634fb1e15SMark C. Prins		if (@file_exists ( $event->data [0] [0] )) {
10734fb1e15SMark C. Prins			// file not new
10834fb1e15SMark C. Prins			if (! $event->data [0] [1]) {
10934fb1e15SMark C. Prins				// file is empty, page is being deleted
11034fb1e15SMark C. Prins				if (empty ( $event->data [1] )) {
11134fb1e15SMark C. Prins					// root namespace
11234fb1e15SMark C. Prins					$id = $event->data [2];
11334fb1e15SMark C. Prins				} else {
11434fb1e15SMark C. Prins					$id = $event->data [1] . ":" . $event->data [2];
11534fb1e15SMark C. Prins				}
11602c45c98SMark C. Prins				$indexer = & plugin_load ( 'helper', 'spatialhelper_index' );
11734fb1e15SMark C. Prins				if ($indexer) {
11834fb1e15SMark C. Prins					$indexer->deleteFromIndex ( $id );
11934fb1e15SMark C. Prins				}
12034fb1e15SMark C. Prins			}
12134fb1e15SMark C. Prins		}
12234fb1e15SMark C. Prins	}
12334fb1e15SMark C. Prins
12434fb1e15SMark C. Prins	/**
12502c45c98SMark C. Prins	 * Add a new SitemapItem object that points to the KML of public geocoded pages.
12602c45c98SMark C. Prins	 *
12702c45c98SMark C. Prins	 * @param Doku_Event $event
12802c45c98SMark C. Prins	 * @param unknown $param
12902c45c98SMark C. Prins	 */
13002c45c98SMark C. Prins	function handle_sitemap_generate_before(Doku_Event &$event, $param) {
13102c45c98SMark C. Prins		$path = mediaFN ( $this->media_kml );
13202c45c98SMark C. Prins		$lastmod = @filemtime ( $path );
13302c45c98SMark C. Prins		$event->data ['items'] [] = new SitemapItem ( ml ( $this->media_kml, '', true, '&amp;', true ), $lastmod );
13402c45c98SMark C. Prins		// dbglog ( $event->data ['items'], "Added a new SitemapItem object that points to the KML of public geocoded pages." );
13502c45c98SMark C. Prins	}
13602c45c98SMark C. Prins
13702c45c98SMark C. Prins	/**
138a9441f7dSMark C. Prins	 * Create a spatial sitemap or attach the geo/kml map to the sitemap.
139a9441f7dSMark C. Prins	 *
140a9441f7dSMark C. Prins	 * @param Doku_Event $event
1413e83b370SMark C. Prins	 *        	event object by reference, not used
142a9441f7dSMark C. Prins	 * @param mixed $param
1433e83b370SMark C. Prins	 *        	parameter array, not used
144bd120a73SMark C. Prins	 */
14502c45c98SMark C. Prins	function handle_sitemap_generate_after(Doku_Event &$event, $param) {
1467c452997SMark C. Prins		// $event→data['items']: Array of SitemapItem instances, the array of sitemap items that already contains all public pages of the wiki
1477c452997SMark C. Prins		// $event→data['sitemap']: The path of the file the sitemap will be saved to.
14802c45c98SMark C. Prins
14902c45c98SMark C. Prins		// dbglog ($event->data['items'], "createSpatialSitemap loading helper" );
15002c45c98SMark C. Prins		if ($helper = & plugin_load ( 'helper', 'spatialhelper_sitemap' )) {
15102c45c98SMark C. Prins			// dbglog ( $helper, "createSpatialSitemap loaded helper." );
15202c45c98SMark C. Prins
153*f2601b07SMark C. Prins			$kml = $helper->createKMLSitemap ( $this->getConf('media_kml') );
154*f2601b07SMark C. Prins			$rss = $helper->createGeoRSSSitemap ( $this->getConf('media_georss') );
15502c45c98SMark C. Prins
15602c45c98SMark C. Prins			return $kml && $rss;
15702c45c98SMark C. Prins		} else {
15802c45c98SMark C. Prins			// dbglog ( $helper, "createSpatialSitemap NOT loaded helper." );
15902c45c98SMark C. Prins		}
1609af1cdd4SMark C. Prins	}
1619af1cdd4SMark C. Prins
1629af1cdd4SMark C. Prins	/**
1639af1cdd4SMark C. Prins	 * trap findnearby action.
16402c45c98SMark C. Prins	 * This addional handler is required as described at: https://www.dokuwiki.org/devel:event:tpl_act_unknown
165a9441f7dSMark C. Prins	 *
166a9441f7dSMark C. Prins	 * @param Doku_Event $event
167a9441f7dSMark C. Prins	 *        	event object by reference
168a9441f7dSMark C. Prins	 * @param mixed $param
169a9441f7dSMark C. Prins	 *        	not used
1709af1cdd4SMark C. Prins	 */
17102c45c98SMark C. Prins	function handle_action_act_preprocess(Doku_Event &$event, $param) {
172a9441f7dSMark C. Prins		if ($event->data != 'findnearby')
173a9441f7dSMark C. Prins			return;
1749af1cdd4SMark C. Prins		$event->preventDefault ();
1759af1cdd4SMark C. Prins	}
1769af1cdd4SMark C. Prins
1779af1cdd4SMark C. Prins	/**
1789af1cdd4SMark C. Prins	 * handle findnearby action.
179a9441f7dSMark C. Prins	 *
180a9441f7dSMark C. Prins	 * @param Doku_Event $event
181a9441f7dSMark C. Prins	 *        	event object by reference
182a9441f7dSMark C. Prins	 * @param mixed $param
1833e83b370SMark C. Prins	 *        	'format'=>
1849af1cdd4SMark C. Prins	 */
185a9441f7dSMark C. Prins	function _findnearby(Doku_Event &$event, $param) {
186a9441f7dSMark C. Prins		if ($event->data != 'findnearby')
187a9441f7dSMark C. Prins			return;
1889af1cdd4SMark C. Prins		$event->preventDefault ();
1899af1cdd4SMark C. Prins
1907c452997SMark C. Prins		global $INPUT;
1917c452997SMark C. Prins		$dist_prefix = '';
1929af1cdd4SMark C. Prins		if ($helper = & plugin_load ( 'helper', 'spatialhelper_search' )) {
1937c452997SMark C. Prins			if ($INPUT->has ( 'geohash' )) {
1947c452997SMark C. Prins				$results = $helper->findNearby ( $INPUT->str ( 'geohash' ) );
1957c452997SMark C. Prins				$dist_prefix = hsc ( $this->getLang ( 'result_distance_prefix' ) ) . ' ';
1967c452997SMark C. Prins			} elseif ($INPUT->has ( 'lat' ) && $INPUT->has ( 'lon' )) {
1977c452997SMark C. Prins				$results = $helper->findNearbyLatLon ( $INPUT->param ( 'lat' ), $INPUT->param ( 'lon' ) );
1987c452997SMark C. Prins			} else {
1993e83b370SMark C. Prins				$results = array (
2003e83b370SMark C. Prins						'error' => hsc ( $this->getLang ( 'invalidinput' ) )
2013e83b370SMark C. Prins				);
2029af1cdd4SMark C. Prins			}
2039af1cdd4SMark C. Prins		}
2049af1cdd4SMark C. Prins
2053e83b370SMark C. Prins		$showMedia = $INPUT->bool ( 'showMedia', true );
2063e83b370SMark C. Prins
2073e83b370SMark C. Prins		switch ($param ['format']) {
2083e83b370SMark C. Prins			case 'JSON' :
2093e83b370SMark C. Prins				$this->printJSON ( $results );
2103e83b370SMark C. Prins				break;
2113e83b370SMark C. Prins			case 'HTML' :
2123e83b370SMark C. Prins			default :
2133e83b370SMark C. Prins				$this->printHTML ( $results, $showMedia );
2143e83b370SMark C. Prins				break;
2153e83b370SMark C. Prins		}
2163e83b370SMark C. Prins	}
2173e83b370SMark C. Prins
2183e83b370SMark C. Prins	/**
2193e83b370SMark C. Prins	 * Print seachresults as HTML lists.
2203e83b370SMark C. Prins	 *
2213e83b370SMark C. Prins	 * @param array $searchresults
2223e83b370SMark C. Prins	 */
2233e83b370SMark C. Prins	private function printJSON($searchresults) {
2243e83b370SMark C. Prins		require_once DOKU_INC . 'inc/JSON.php';
2253e83b370SMark C. Prins		$json = new JSON ();
2263e83b370SMark C. Prins
2273e83b370SMark C. Prins		header ( 'Content-Type: application/json' );
2283e83b370SMark C. Prins		print $json->encode ( $searchresults );
2293e83b370SMark C. Prins	}
2303e83b370SMark C. Prins
2313e83b370SMark C. Prins	/**
2323e83b370SMark C. Prins	 * Print seachresults as HTML lists.
2333e83b370SMark C. Prins	 *
2343e83b370SMark C. Prins	 * @param array $searchresults
2353e83b370SMark C. Prins	 * @param boolean $showMedia
2363e83b370SMark C. Prins	 */
2373e83b370SMark C. Prins	private function printHTML($searchresults, $showMedia = true) {
2383e83b370SMark C. Prins		$pages = ( array ) ($searchresults ['pages']);
2393e83b370SMark C. Prins		$media = ( array ) $searchresults ['media'];
2403e83b370SMark C. Prins		$location = ( string ) $searchresults ['latlon'];
2413e83b370SMark C. Prins		$geohash = ( string ) $searchresults ['geohash'];
2423e83b370SMark C. Prins
2433e83b370SMark C. Prins		if (isset ( $searchresults ['error'] )) {
2443e83b370SMark C. Prins			print '<div class="level1"><p>' . hsc ( $results ['error'] ) . '</p></div>';
2453e83b370SMark C. Prins			return;
2463e83b370SMark C. Prins		}
2473e83b370SMark C. Prins
2483e83b370SMark C. Prins		// print a HTML list
2497c452997SMark C. Prins		print '<h1>' . $this->getLang ( 'results_header' ) . '</h1>' . DOKU_LF;
2509af1cdd4SMark C. Prins		print '<div class="level1">' . DOKU_LF;
2517c452997SMark C. Prins		if (! empty ( $pages )) {
2527c452997SMark C. Prins			$pagelist = '<ol>' . DOKU_LF;
2537c452997SMark C. Prins			foreach ( $pages as $page ) {
2547c452997SMark C. Prins				$pagelist .= '<li>' . html_wikilink ( ':' . $page ['id'], useHeading ( 'navigation' ) ? null : noNS ( $page ['id'] ) ) . ' (' . $dist_prefix . $page ['distance'] . 'm) ' . $page ['description'] . '</li>' . DOKU_LF;
2557c452997SMark C. Prins			}
2567c452997SMark C. Prins			$pagelist .= '</ol>' . DOKU_LF;
2577c452997SMark C. Prins
2587c452997SMark C. Prins			print '<h2>' . $this->getLang ( 'results_pages' ) . hsc ( ' lat,lon: ' . $location . ' (geohash: ' . $geohash . ')' ) . '</h2>';
2597c452997SMark C. Prins			print '<div class="level2">' . DOKU_LF;
2607c452997SMark C. Prins			print $pagelist;
2613e83b370SMark C. Prins			print '<p>Precision: ' . $searchresults ['precision'] . ' m</p>' . DOKU_LF;
2629af1cdd4SMark C. Prins			print '</div>' . DOKU_LF;
2639af1cdd4SMark C. Prins		} else {
2647c452997SMark C. Prins			print '<p>' . hsc ( $this->getLang ( 'nothingfound' ) ) . '</p>';
2659af1cdd4SMark C. Prins		}
2663e83b370SMark C. Prins
2673e83b370SMark C. Prins		if (! empty ( $media ) && $showMedia) {
2687c452997SMark C. Prins			$pagelist = '<ol>' . DOKU_LF;
2697c452997SMark C. Prins			foreach ( $media as $m ) {
2707c452997SMark C. Prins				$opts = array ();
2717c452997SMark C. Prins				$link = ml ( $m ['id'], $opts, false, '&amp;', false );
2727c452997SMark C. Prins				$opts ['w'] = '100px';
2737c452997SMark C. Prins				$src = ml ( $m ['id'], $opts );
2747c452997SMark C. Prins				$pagelist .= '<li><a href="' . $link . '"><img src="' . $src . '"></a> (' . $dist_prefix . $page ['distance'] . 'm) </li>' . DOKU_LF;
275bd120a73SMark C. Prins			}
2767c452997SMark C. Prins			$pagelist .= '</ol>' . DOKU_LF;
2777c452997SMark C. Prins
2787c452997SMark C. Prins			print '<h2>' . $this->getLang ( 'results_media' ) . hsc ( ' lat,lon: ' . $location . ' (geohash: ' . $geohash . ')' ) . '</h2>' . DOKU_LF;
2797c452997SMark C. Prins			print '<div class="level2">' . DOKU_LF;
2807c452997SMark C. Prins			print $pagelist;
2813e83b370SMark C. Prins			print '<p>Precision: ' . $searchresults ['precision'] . ' m</p>' . DOKU_LF;
2827c452997SMark C. Prins			print '</div>' . DOKU_LF;
2837c452997SMark C. Prins		}
2847c452997SMark C. Prins		print '</div>' . DOKU_LF;
2857c452997SMark C. Prins	}
2863e83b370SMark C. Prins
2877c452997SMark C. Prins	/**
2887c452997SMark C. Prins	 * add media to spatial index.
2897c452997SMark C. Prins	 *
2907c452997SMark C. Prins	 * @param Doku_Event $event
2917c452997SMark C. Prins	 *        	event object by reference
2927c452997SMark C. Prins	 * @param unknown $param
293a9441f7dSMark C. Prins	 */
2947c452997SMark C. Prins	function _handle_media_uploaded(Doku_Event &$event, $param) {
2957c452997SMark C. Prins		// data[0] temporary file name (read from $_FILES)
2967c452997SMark C. Prins		// data[1] file name of the file being uploaded
2977c452997SMark C. Prins		// data[2] future directory id of the file being uploaded
2987c452997SMark C. Prins		// data[3] the mime type of the file being uploaded
2997c452997SMark C. Prins		// data[4] true if the uploaded file exists already
3007c452997SMark C. Prins		// data[5] (since 2011-02-06) the PHP function used to move the file to the correct location
30102c45c98SMark C. Prins
30202c45c98SMark C. Prins		// dbglog ( $event->data, "_handle_media_uploaded::event data" );
303a9441f7dSMark C. Prins
304a9441f7dSMark C. Prins		// check the list of mimetypes
305a9441f7dSMark C. Prins		// if it's a supported type call appropriate index function
3067c452997SMark C. Prins		if (substr_compare ( $event->data [3], 'image/jpeg', 0 )) {
307a9441f7dSMark C. Prins			$indexer = plugin_load ( 'helper', 'spatialhelper_index' );
308a9441f7dSMark C. Prins			if ($indexer) {
309a9441f7dSMark C. Prins				$indexer->indexImage ( $event->data [2], $event->data [1] );
310a9441f7dSMark C. Prins			}
311a9441f7dSMark C. Prins		}
3127c452997SMark C. Prins		// TODO add image/tiff
313a9441f7dSMark C. Prins		// TODO kml, gpx, geojson...
314a9441f7dSMark C. Prins	}
315a9441f7dSMark C. Prins
316a9441f7dSMark C. Prins	/**
317a9441f7dSMark C. Prins	 * removes the media from the index.
318a9441f7dSMark C. Prins	 */
319a9441f7dSMark C. Prins	function _handle_media_deleted(Doku_Event &$event, $param) {
3207c452997SMark C. Prins		// data['id'] ID data['unl'] unlink return code
3217c452997SMark C. Prins		// data['del'] Namespace directory unlink return code
3227c452997SMark C. Prins		// data['name'] file name data['path'] full path to the file
3237c452997SMark C. Prins		// data['size'] file size
32402c45c98SMark C. Prins
32502c45c98SMark C. Prins		// dbglog ( $event->data, "_handle_media_deleted::event data" );
3267c452997SMark C. Prins
3277c452997SMark C. Prins		// remove the media id from the index
32802c45c98SMark C. Prins		$indexer = & plugin_load ( 'helper', 'spatialhelper_index' );
329a9441f7dSMark C. Prins		if ($indexer) {
3307c452997SMark C. Prins			$indexer->deleteFromIndex ( 'media__' . $event->data ['id'] );
331a9441f7dSMark C. Prins		}
332a9441f7dSMark C. Prins	}
3337c452997SMark C. Prins
3347c452997SMark C. Prins	/**
33502c45c98SMark C. Prins	 * add a link to the spatial sitemap files in the header.
33602c45c98SMark C. Prins	 *
33702c45c98SMark C. Prins	 * @param Doku_Event $event
33802c45c98SMark C. Prins	 *        	the DokuWiki event. $event->data is a two-dimensional
33902c45c98SMark C. Prins	 *        	array of all meta headers. The keys are meta, link and script.
34002c45c98SMark C. Prins	 * @param unknown_type $param
34102c45c98SMark C. Prins	 *
34202c45c98SMark C. Prins	 * @see http://www.dokuwiki.org/devel:event:tpl_metaheader_output
34302c45c98SMark C. Prins	 */
34402c45c98SMark C. Prins	public function handle_metaheader_output(Doku_Event &$event, $param) {
34502c45c98SMark C. Prins		// TODO maybe test for exist
34602c45c98SMark C. Prins		$event->data ["link"] [] = array (
34702c45c98SMark C. Prins				"type" => "application/atom+xml",
34802c45c98SMark C. Prins				"rel" => "alternate",
34902c45c98SMark C. Prins				"href" => ml ( $this->media_georss ),
35002c45c98SMark C. Prins				"title" => "Spatial ATOM Feed"
35102c45c98SMark C. Prins		);
35202c45c98SMark C. Prins		$event->data ["link"] [] = array (
35302c45c98SMark C. Prins				"type" => "application/vnd.google-earth.kml+xml",
35402c45c98SMark C. Prins				"rel" => "alternate",
35502c45c98SMark C. Prins				"href" => ml ( $this->media_kml ),
35602c45c98SMark C. Prins				"title" => "KML Sitemap"
35702c45c98SMark C. Prins		);
35802c45c98SMark C. Prins	}
35902c45c98SMark C. Prins
36002c45c98SMark C. Prins	/**
3617c452997SMark C. Prins	 * Calculate a new coordinate based on start, distance and bearing
3627c452997SMark C. Prins	 *
3637c452997SMark C. Prins	 * @param $start array
3647c452997SMark C. Prins	 *        	- start coordinate as decimal lat/lon pair
3657c452997SMark C. Prins	 * @param $dist float
3667c452997SMark C. Prins	 *        	- distance in kilometers
3677c452997SMark C. Prins	 * @param $brng float
3687c452997SMark C. Prins	 *        	- bearing in degrees (compass direction)
3697c452997SMark C. Prins	 */
3707c452997SMark C. Prins	private function _geo_destination($start, $dist, $brng) {
3717c452997SMark C. Prins		$lat1 = _toRad ( $start [0] );
3727c452997SMark C. Prins		$lon1 = _toRad ( $start [1] );
3737c452997SMark C. Prins		// http://en.wikipedia.org/wiki/Earth_radius
3747c452997SMark C. Prins		// average earth radius in km
3757c452997SMark C. Prins		$dist = $dist / 6371.01;
3767c452997SMark C. Prins		$brng = _toRad ( $brng );
3777c452997SMark C. Prins
3787c452997SMark C. Prins		$lon2 = $lon1 + atan2 ( sin ( $brng ) * sin ( $dist ) * cos ( $lat1 ), cos ( $dist ) - sin ( $lat1 ) * sin ( $lat2 ) );
3797c452997SMark C. Prins		$lon2 = fmod ( ($lon2 + 3 * pi ()), (2 * pi ()) ) - pi ();
3807c452997SMark C. Prins
3817c452997SMark C. Prins		return array (
3827c452997SMark C. Prins				_toDeg ( $lat2 ),
3837c452997SMark C. Prins				_toDeg ( $lon2 )
3847c452997SMark C. Prins		);
3857c452997SMark C. Prins	}
3867c452997SMark C. Prins	private function _toRad($deg) {
3877c452997SMark C. Prins		return $deg * pi () / 180;
3887c452997SMark C. Prins	}
3897c452997SMark C. Prins	private function _toDeg($rad) {
3907c452997SMark C. Prins		return $rad * 180 / pi ();
3917c452997SMark C. Prins	}
392bd120a73SMark C. Prins}