xref: /plugin/spatialhelper/action.php (revision e4020312292687cfe1a51c232888014705999d15)
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
33bd120a73SMark C. Prins	/**
34bd120a73SMark C. Prins	 * Register for events.
35bd120a73SMark C. Prins	 *
36a9441f7dSMark C. Prins	 * @param Doku_Event_Handler $controller
37a9441f7dSMark C. Prins	 *        	DokuWiki's event controller object. Also available as global $EVENT_HANDLER
38bd120a73SMark C. Prins	 */
39bd120a73SMark C. Prins	public function register(Doku_Event_Handler &$controller) {
407c452997SMark C. Prins		// listen for page add / delete events
41bd120a73SMark C. Prins		// http://www.dokuwiki.org/devel:event:indexer_page_add
4202c45c98SMark C. Prins		$controller->register_hook ( 'INDEXER_PAGE_ADD', 'BEFORE', $this, 'handle_indexer_page_add' );
4334fb1e15SMark C. Prins		$controller->register_hook ( 'IO_WIKIPAGE_WRITE', 'BEFORE', $this, '_removeFromIndex' );
44a9441f7dSMark C. Prins
45bd120a73SMark C. Prins		// http://www.dokuwiki.org/devel:event:sitemap_generate
4602c45c98SMark C. Prins		$controller->register_hook ( 'SITEMAP_GENERATE', 'BEFORE', $this, 'handle_sitemap_generate_before' );
477c452997SMark C. Prins		// using after will only trigger us if a sitemap was actually created
4802c45c98SMark C. Prins		$controller->register_hook ( 'SITEMAP_GENERATE', 'AFTER', $this, 'handle_sitemap_generate_after' );
497c452997SMark C. Prins
50a9441f7dSMark C. Prins		// handle actions we know of
5102c45c98SMark C. Prins		$controller->register_hook ( 'ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_action_act_preprocess', array () );
523e83b370SMark C. Prins		$controller->register_hook ( 'TPL_ACT_UNKNOWN', 'BEFORE', $this, '_findnearby', array (
533e83b370SMark C. Prins				'format' => 'HTML'
543e83b370SMark C. Prins		) );
553e83b370SMark C. Prins
563e83b370SMark C. Prins		$controller->register_hook ( 'AJAX_CALL_UNKNOWN', 'BEFORE', $this, '_findnearby', array (
573e83b370SMark C. Prins				'format' => 'JSON'
583e83b370SMark C. Prins		) );
597c452997SMark C. Prins
60a9441f7dSMark C. Prins		// listen for media uploads and deletes
61a9441f7dSMark C. Prins		$controller->register_hook ( 'MEDIA_UPLOAD_FINISH', 'BEFORE', $this, '_handle_media_uploaded', array () );
62a9441f7dSMark C. Prins		$controller->register_hook ( 'MEDIA_DELETE_FILE', 'BEFORE', $this, '_handle_media_deleted', array () );
6302c45c98SMark C. Prins
6402c45c98SMark C. Prins		$controller->register_hook ( 'TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handle_metaheader_output' );
65bd120a73SMark C. Prins	}
66bd120a73SMark C. Prins
67bd120a73SMark C. Prins	/**
68bd120a73SMark C. Prins	 * Update the spatial index for the page.
69a9441f7dSMark C. Prins	 *
70a9441f7dSMark C. Prins	 * @param Doku_Event $event
71a9441f7dSMark C. Prins	 *        	event object by reference
72a9441f7dSMark C. Prins	 * @param object $param
73a9441f7dSMark C. Prins	 *        	the parameters passed to register_hook when this handler was registered
74bd120a73SMark C. Prins	 */
7502c45c98SMark C. Prins	function handle_indexer_page_add(Doku_Event &$event, $param) {
767c452997SMark C. Prins		// $event→data['page'] – the page id
777c452997SMark C. Prins		// $event→data['body'] – empty, can be filled by additional content to index by your plugin
787c452997SMark 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.
799af1cdd4SMark C. Prins		$id = $event->data ['page'];
8002c45c98SMark C. Prins		$indexer = & plugin_load ( 'helper', 'spatialhelper_index' );
81bd120a73SMark C. Prins		$entries = $indexer->updateSpatialIndex ( $id );
82bd120a73SMark C. Prins	}
83bd120a73SMark C. Prins
84bd120a73SMark C. Prins	/**
8534fb1e15SMark C. Prins	 * Update the spatial index, removing the page.
86a9441f7dSMark C. Prins	 *
87a9441f7dSMark C. Prins	 * @param Doku_Event $event
88a9441f7dSMark C. Prins	 *        	event object by reference
89a9441f7dSMark C. Prins	 * @param object $param
90a9441f7dSMark C. Prins	 *        	the parameters passed to register_hook when this handler was registered
9134fb1e15SMark C. Prins	 */
9234fb1e15SMark C. Prins	function _removeFromIndex(Doku_Event &$event, $param) {
937c452997SMark C. Prins		// event data:
947c452997SMark C. Prins		// $data[0] – The raw arguments for io_saveFile as an array. Do not change file path.
957c452997SMark C. Prins		// $data[0][0] – the file path.
967c452997SMark C. Prins		// $data[0][1] – the content to be saved, and may be modified.
977c452997SMark C. Prins		// $data[1] – ns: The colon separated namespace path minus the trailing page name. (false if root ns)
987c452997SMark C. Prins		// $data[2] – page_name: The wiki page name.
997c452997SMark C. Prins		// $data[3] – rev: The page revision, false for current wiki pages.
1007c452997SMark C. Prins
10102c45c98SMark C. Prins		// dbglog ( $event->data, "Event data in _removeFromIndex." );
10234fb1e15SMark C. Prins		if (@file_exists ( $event->data [0] [0] )) {
10334fb1e15SMark C. Prins			// file not new
10434fb1e15SMark C. Prins			if (! $event->data [0] [1]) {
10534fb1e15SMark C. Prins				// file is empty, page is being deleted
10634fb1e15SMark C. Prins				if (empty ( $event->data [1] )) {
10734fb1e15SMark C. Prins					// root namespace
10834fb1e15SMark C. Prins					$id = $event->data [2];
10934fb1e15SMark C. Prins				} else {
11034fb1e15SMark C. Prins					$id = $event->data [1] . ":" . $event->data [2];
11134fb1e15SMark C. Prins				}
11202c45c98SMark C. Prins				$indexer = & plugin_load ( 'helper', 'spatialhelper_index' );
11334fb1e15SMark C. Prins				if ($indexer) {
11434fb1e15SMark C. Prins					$indexer->deleteFromIndex ( $id );
11534fb1e15SMark C. Prins				}
11634fb1e15SMark C. Prins			}
11734fb1e15SMark C. Prins		}
11834fb1e15SMark C. Prins	}
11934fb1e15SMark C. Prins
12034fb1e15SMark C. Prins	/**
12102c45c98SMark C. Prins	 * Add a new SitemapItem object that points to the KML of public geocoded pages.
12202c45c98SMark C. Prins	 *
12302c45c98SMark C. Prins	 * @param Doku_Event $event
12402c45c98SMark C. Prins	 * @param unknown $param
12502c45c98SMark C. Prins	 */
12602c45c98SMark C. Prins	function handle_sitemap_generate_before(Doku_Event &$event, $param) {
12700e20e07SMark C. Prins		$path = mediaFN ( $this->getConf ( 'media_kml' ) );
12802c45c98SMark C. Prins		$lastmod = @filemtime ( $path );
12900e20e07SMark C. Prins		$event->data ['items'] [] = new SitemapItem ( ml ( $this->getConf ( 'media_kml' ), '', true, '&amp;', true ), $lastmod );
13002c45c98SMark C. Prins		// dbglog ( $event->data ['items'], "Added a new SitemapItem object that points to the KML of public geocoded pages." );
13102c45c98SMark C. Prins	}
13202c45c98SMark C. Prins
13302c45c98SMark C. Prins	/**
134a9441f7dSMark C. Prins	 * Create a spatial sitemap or attach the geo/kml map to the sitemap.
135a9441f7dSMark C. Prins	 *
136a9441f7dSMark C. Prins	 * @param Doku_Event $event
1373e83b370SMark C. Prins	 *        	event object by reference, not used
138a9441f7dSMark C. Prins	 * @param mixed $param
1393e83b370SMark C. Prins	 *        	parameter array, not used
140bd120a73SMark C. Prins	 */
14102c45c98SMark C. Prins	function handle_sitemap_generate_after(Doku_Event &$event, $param) {
1427c452997SMark C. Prins		// $event→data['items']: Array of SitemapItem instances, the array of sitemap items that already contains all public pages of the wiki
1437c452997SMark C. Prins		// $event→data['sitemap']: The path of the file the sitemap will be saved to.
14402c45c98SMark C. Prins
14502c45c98SMark C. Prins		// dbglog ($event->data['items'], "createSpatialSitemap loading helper" );
14602c45c98SMark C. Prins		if ($helper = & plugin_load ( 'helper', 'spatialhelper_sitemap' )) {
14702c45c98SMark C. Prins			// dbglog ( $helper, "createSpatialSitemap loaded helper." );
14802c45c98SMark C. Prins
149f2601b07SMark C. Prins			$kml = $helper->createKMLSitemap ( $this->getConf ( 'media_kml' ) );
150f2601b07SMark C. Prins			$rss = $helper->createGeoRSSSitemap ( $this->getConf ( 'media_georss' ) );
15102c45c98SMark C. Prins
15202c45c98SMark C. Prins			return $kml && $rss;
15302c45c98SMark C. Prins		} else {
15402c45c98SMark C. Prins			// dbglog ( $helper, "createSpatialSitemap NOT loaded helper." );
15502c45c98SMark C. Prins		}
1569af1cdd4SMark C. Prins	}
1579af1cdd4SMark C. Prins
1589af1cdd4SMark C. Prins	/**
1599af1cdd4SMark C. Prins	 * trap findnearby action.
16002c45c98SMark C. Prins	 * This addional handler is required as described at: https://www.dokuwiki.org/devel:event:tpl_act_unknown
161a9441f7dSMark C. Prins	 *
162a9441f7dSMark C. Prins	 * @param Doku_Event $event
163a9441f7dSMark C. Prins	 *        	event object by reference
164a9441f7dSMark C. Prins	 * @param mixed $param
165a9441f7dSMark C. Prins	 *        	not used
1669af1cdd4SMark C. Prins	 */
16702c45c98SMark C. Prins	function handle_action_act_preprocess(Doku_Event &$event, $param) {
168a9441f7dSMark C. Prins		if ($event->data != 'findnearby')
169a9441f7dSMark C. Prins			return;
1709af1cdd4SMark C. Prins		$event->preventDefault ();
1719af1cdd4SMark C. Prins	}
1729af1cdd4SMark C. Prins
1739af1cdd4SMark C. Prins	/**
1749af1cdd4SMark C. Prins	 * handle findnearby action.
175a9441f7dSMark C. Prins	 *
176a9441f7dSMark C. Prins	 * @param Doku_Event $event
177a9441f7dSMark C. Prins	 *        	event object by reference
178*e4020312SMark C. Prins	 * @param mixed $param
179*e4020312SMark C. Prins	 *        	associative array with keys
1809bb9b388SMark C. Prins	 *        	'format'=> HTML | JSON
1819af1cdd4SMark C. Prins	 */
182a9441f7dSMark C. Prins	function _findnearby(Doku_Event &$event, $param) {
183a9441f7dSMark C. Prins		if ($event->data != 'findnearby')
184a9441f7dSMark C. Prins			return;
1859af1cdd4SMark C. Prins		$event->preventDefault ();
1869af1cdd4SMark C. Prins
1877c452997SMark C. Prins		global $INPUT;
1887c452997SMark C. Prins		$dist_prefix = '';
1899af1cdd4SMark C. Prins		if ($helper = & plugin_load ( 'helper', 'spatialhelper_search' )) {
1907c452997SMark C. Prins			if ($INPUT->has ( 'geohash' )) {
1917c452997SMark C. Prins				$results = $helper->findNearby ( $INPUT->str ( 'geohash' ) );
1927c452997SMark C. Prins				$dist_prefix = hsc ( $this->getLang ( 'result_distance_prefix' ) ) . ' ';
1937c452997SMark C. Prins			} elseif ($INPUT->has ( 'lat' ) && $INPUT->has ( 'lon' )) {
1947c452997SMark C. Prins				$results = $helper->findNearbyLatLon ( $INPUT->param ( 'lat' ), $INPUT->param ( 'lon' ) );
1957c452997SMark C. Prins			} else {
1963e83b370SMark C. Prins				$results = array (
1973e83b370SMark C. Prins						'error' => hsc ( $this->getLang ( 'invalidinput' ) )
1983e83b370SMark C. Prins				);
1999af1cdd4SMark C. Prins			}
2009af1cdd4SMark C. Prins		}
2019af1cdd4SMark C. Prins
2023e83b370SMark C. Prins		$showMedia = $INPUT->bool ( 'showMedia', true );
2033e83b370SMark C. Prins
2043e83b370SMark C. Prins		switch ($param ['format']) {
2053e83b370SMark C. Prins			case 'JSON' :
2063e83b370SMark C. Prins				$this->printJSON ( $results );
2073e83b370SMark C. Prins				break;
2083e83b370SMark C. Prins			case 'HTML' :
2093e83b370SMark C. Prins			default :
2103e83b370SMark C. Prins				$this->printHTML ( $results, $showMedia );
2113e83b370SMark C. Prins				break;
2123e83b370SMark C. Prins		}
2133e83b370SMark C. Prins	}
2143e83b370SMark C. Prins
2153e83b370SMark C. Prins	/**
2163e83b370SMark C. Prins	 * Print seachresults as HTML lists.
2173e83b370SMark C. Prins	 *
2183e83b370SMark C. Prins	 * @param array $searchresults
2193e83b370SMark C. Prins	 */
2203e83b370SMark C. Prins	private function printJSON($searchresults) {
2213e83b370SMark C. Prins		require_once DOKU_INC . 'inc/JSON.php';
2223e83b370SMark C. Prins		$json = new JSON ();
2233e83b370SMark C. Prins
2243e83b370SMark C. Prins		header ( 'Content-Type: application/json' );
2253e83b370SMark C. Prins		print $json->encode ( $searchresults );
2263e83b370SMark C. Prins	}
2273e83b370SMark C. Prins
2283e83b370SMark C. Prins	/**
2293e83b370SMark C. Prins	 * Print seachresults as HTML lists.
2303e83b370SMark C. Prins	 *
2313e83b370SMark C. Prins	 * @param array $searchresults
2323e83b370SMark C. Prins	 * @param boolean $showMedia
2333e83b370SMark C. Prins	 */
2343e83b370SMark C. Prins	private function printHTML($searchresults, $showMedia = true) {
2353e83b370SMark C. Prins		$pages = ( array ) ($searchresults ['pages']);
2363e83b370SMark C. Prins		$media = ( array ) $searchresults ['media'];
2373e83b370SMark C. Prins		$location = ( string ) $searchresults ['latlon'];
2383e83b370SMark C. Prins		$geohash = ( string ) $searchresults ['geohash'];
2393e83b370SMark C. Prins
2403e83b370SMark C. Prins		if (isset ( $searchresults ['error'] )) {
2413e83b370SMark C. Prins			print '<div class="level1"><p>' . hsc ( $results ['error'] ) . '</p></div>';
2423e83b370SMark C. Prins			return;
2433e83b370SMark C. Prins		}
2443e83b370SMark C. Prins
2453e83b370SMark C. Prins		// print a HTML list
2467c452997SMark C. Prins		print '<h1>' . $this->getLang ( 'results_header' ) . '</h1>' . DOKU_LF;
2479af1cdd4SMark C. Prins		print '<div class="level1">' . DOKU_LF;
2487c452997SMark C. Prins		if (! empty ( $pages )) {
2497c452997SMark C. Prins			$pagelist = '<ol>' . DOKU_LF;
2507c452997SMark C. Prins			foreach ( $pages as $page ) {
251*e4020312SMark C. Prins				$pagelist .= '<li>' . html_wikilink ( ':' . $page ['id'], useHeading ( 'navigation' ) ? null : noNS ( $page ['id'] ) ) . ' (' . $this->getLang ( 'results_distance_prefix' ) . $page ['distance'] . 'm) ' . $page ['description'] . '</li>' . DOKU_LF;
2527c452997SMark C. Prins			}
2537c452997SMark C. Prins			$pagelist .= '</ol>' . DOKU_LF;
2547c452997SMark C. Prins
2557c452997SMark C. Prins			print '<h2>' . $this->getLang ( 'results_pages' ) . hsc ( ' lat,lon: ' . $location . ' (geohash: ' . $geohash . ')' ) . '</h2>';
2567c452997SMark C. Prins			print '<div class="level2">' . DOKU_LF;
2577c452997SMark C. Prins			print $pagelist;
2583e83b370SMark C. Prins			print '<p>Precision: ' . $searchresults ['precision'] . ' m</p>' . DOKU_LF;
2599af1cdd4SMark C. Prins			print '</div>' . DOKU_LF;
2609af1cdd4SMark C. Prins		} else {
2617c452997SMark C. Prins			print '<p>' . hsc ( $this->getLang ( 'nothingfound' ) ) . '</p>';
2629af1cdd4SMark C. Prins		}
263*e4020312SMark C. Prins
2643e83b370SMark C. Prins		if (! empty ( $media ) && $showMedia) {
2657c452997SMark C. Prins			$pagelist = '<ol>' . DOKU_LF;
2667c452997SMark C. Prins			foreach ( $media as $m ) {
2677c452997SMark C. Prins				$opts = array ();
2687c452997SMark C. Prins				$link = ml ( $m ['id'], $opts, false, '&amp;', false );
2699bb9b388SMark C. Prins				$opts ['w'] = '100';
2707c452997SMark C. Prins				$src = ml ( $m ['id'], $opts );
271*e4020312SMark C. Prins				$pagelist .= '<li><a href="' . $link . '"><img src="' . $src . '"></a> (' . $this->getLang ( 'results_distance_prefix' ) . $page ['distance'] . 'm) ' . hsc ( $desc ) . '</li>' . DOKU_LF;
272bd120a73SMark C. Prins			}
2737c452997SMark C. Prins			$pagelist .= '</ol>' . DOKU_LF;
2747c452997SMark C. Prins
2757c452997SMark C. Prins			print '<h2>' . $this->getLang ( 'results_media' ) . hsc ( ' lat,lon: ' . $location . ' (geohash: ' . $geohash . ')' ) . '</h2>' . DOKU_LF;
2767c452997SMark C. Prins			print '<div class="level2">' . DOKU_LF;
2777c452997SMark C. Prins			print $pagelist;
2783e83b370SMark C. Prins			print '<p>Precision: ' . $searchresults ['precision'] . ' m</p>' . DOKU_LF;
2797c452997SMark C. Prins			print '</div>' . DOKU_LF;
2807c452997SMark C. Prins		}
2817c452997SMark C. Prins		print '</div>' . DOKU_LF;
2827c452997SMark C. Prins	}
2833e83b370SMark C. Prins
2847c452997SMark C. Prins	/**
2857c452997SMark C. Prins	 * add media to spatial index.
2867c452997SMark C. Prins	 *
2877c452997SMark C. Prins	 * @param Doku_Event $event
2887c452997SMark C. Prins	 *        	event object by reference
2897c452997SMark C. Prins	 * @param unknown $param
290a9441f7dSMark C. Prins	 */
2917c452997SMark C. Prins	function _handle_media_uploaded(Doku_Event &$event, $param) {
2927c452997SMark C. Prins		// data[0] temporary file name (read from $_FILES)
2937c452997SMark C. Prins		// data[1] file name of the file being uploaded
2947c452997SMark C. Prins		// data[2] future directory id of the file being uploaded
2957c452997SMark C. Prins		// data[3] the mime type of the file being uploaded
2967c452997SMark C. Prins		// data[4] true if the uploaded file exists already
2977c452997SMark C. Prins		// data[5] (since 2011-02-06) the PHP function used to move the file to the correct location
29802c45c98SMark C. Prins
29902c45c98SMark C. Prins		// dbglog ( $event->data, "_handle_media_uploaded::event data" );
300a9441f7dSMark C. Prins
301a9441f7dSMark C. Prins		// check the list of mimetypes
302a9441f7dSMark C. Prins		// if it's a supported type call appropriate index function
3037c452997SMark C. Prins		if (substr_compare ( $event->data [3], 'image/jpeg', 0 )) {
304a9441f7dSMark C. Prins			$indexer = plugin_load ( 'helper', 'spatialhelper_index' );
305a9441f7dSMark C. Prins			if ($indexer) {
306a9441f7dSMark C. Prins				$indexer->indexImage ( $event->data [2], $event->data [1] );
307a9441f7dSMark C. Prins			}
308a9441f7dSMark C. Prins		}
3097c452997SMark C. Prins		// TODO add image/tiff
310a9441f7dSMark C. Prins		// TODO kml, gpx, geojson...
311a9441f7dSMark C. Prins	}
312a9441f7dSMark C. Prins
313a9441f7dSMark C. Prins	/**
314a9441f7dSMark C. Prins	 * removes the media from the index.
315a9441f7dSMark C. Prins	 */
316a9441f7dSMark C. Prins	function _handle_media_deleted(Doku_Event &$event, $param) {
3177c452997SMark C. Prins		// data['id'] ID data['unl'] unlink return code
3187c452997SMark C. Prins		// data['del'] Namespace directory unlink return code
3197c452997SMark C. Prins		// data['name'] file name data['path'] full path to the file
3207c452997SMark C. Prins		// data['size'] file size
32102c45c98SMark C. Prins
32202c45c98SMark C. Prins		// dbglog ( $event->data, "_handle_media_deleted::event data" );
3237c452997SMark C. Prins
3247c452997SMark C. Prins		// remove the media id from the index
32502c45c98SMark C. Prins		$indexer = & plugin_load ( 'helper', 'spatialhelper_index' );
326a9441f7dSMark C. Prins		if ($indexer) {
3277c452997SMark C. Prins			$indexer->deleteFromIndex ( 'media__' . $event->data ['id'] );
328a9441f7dSMark C. Prins		}
329a9441f7dSMark C. Prins	}
3307c452997SMark C. Prins
3317c452997SMark C. Prins	/**
33202c45c98SMark C. Prins	 * add a link to the spatial sitemap files in the header.
33302c45c98SMark C. Prins	 *
33402c45c98SMark C. Prins	 * @param Doku_Event $event
33502c45c98SMark C. Prins	 *        	the DokuWiki event. $event->data is a two-dimensional
33602c45c98SMark C. Prins	 *        	array of all meta headers. The keys are meta, link and script.
33702c45c98SMark C. Prins	 * @param unknown_type $param
33802c45c98SMark C. Prins	 *
33902c45c98SMark C. Prins	 * @see http://www.dokuwiki.org/devel:event:tpl_metaheader_output
34002c45c98SMark C. Prins	 */
34102c45c98SMark C. Prins	public function handle_metaheader_output(Doku_Event &$event, $param) {
34202c45c98SMark C. Prins		// TODO maybe test for exist
34302c45c98SMark C. Prins		$event->data ["link"] [] = array (
34402c45c98SMark C. Prins				"type" => "application/atom+xml",
34502c45c98SMark C. Prins				"rel" => "alternate",
34600e20e07SMark C. Prins				"href" => ml ( $this->getConf ( 'media_georss' ) ),
34702c45c98SMark C. Prins				"title" => "Spatial ATOM Feed"
34802c45c98SMark C. Prins		);
34902c45c98SMark C. Prins		$event->data ["link"] [] = array (
35002c45c98SMark C. Prins				"type" => "application/vnd.google-earth.kml+xml",
35102c45c98SMark C. Prins				"rel" => "alternate",
35200e20e07SMark C. Prins				"href" => ml ( $this->getConf ( 'media_kml' ) ),
35302c45c98SMark C. Prins				"title" => "KML Sitemap"
35402c45c98SMark C. Prins		);
35502c45c98SMark C. Prins	}
35602c45c98SMark C. Prins
35702c45c98SMark C. Prins	/**
3587c452997SMark C. Prins	 * Calculate a new coordinate based on start, distance and bearing
3597c452997SMark C. Prins	 *
3607c452997SMark C. Prins	 * @param $start array
3617c452997SMark C. Prins	 *        	- start coordinate as decimal lat/lon pair
3627c452997SMark C. Prins	 * @param $dist float
3637c452997SMark C. Prins	 *        	- distance in kilometers
3647c452997SMark C. Prins	 * @param $brng float
3657c452997SMark C. Prins	 *        	- bearing in degrees (compass direction)
3667c452997SMark C. Prins	 */
3677c452997SMark C. Prins	private function _geo_destination($start, $dist, $brng) {
3687c452997SMark C. Prins		$lat1 = _toRad ( $start [0] );
3697c452997SMark C. Prins		$lon1 = _toRad ( $start [1] );
3707c452997SMark C. Prins		// http://en.wikipedia.org/wiki/Earth_radius
3717c452997SMark C. Prins		// average earth radius in km
3727c452997SMark C. Prins		$dist = $dist / 6371.01;
3737c452997SMark C. Prins		$brng = _toRad ( $brng );
3747c452997SMark C. Prins
3757c452997SMark C. Prins		$lon2 = $lon1 + atan2 ( sin ( $brng ) * sin ( $dist ) * cos ( $lat1 ), cos ( $dist ) - sin ( $lat1 ) * sin ( $lat2 ) );
3767c452997SMark C. Prins		$lon2 = fmod ( ($lon2 + 3 * pi ()), (2 * pi ()) ) - pi ();
3777c452997SMark C. Prins
3787c452997SMark C. Prins		return array (
3797c452997SMark C. Prins				_toDeg ( $lat2 ),
3807c452997SMark C. Prins				_toDeg ( $lon2 )
3817c452997SMark C. Prins		);
3827c452997SMark C. Prins	}
3837c452997SMark C. Prins	private function _toRad($deg) {
3847c452997SMark C. Prins		return $deg * pi () / 180;
3857c452997SMark C. Prins	}
3867c452997SMark C. Prins	private function _toDeg($rad) {
3877c452997SMark C. Prins		return $rad * 180 / pi ();
3887c452997SMark C. Prins	}
389bd120a73SMark C. Prins}