1bd120a73SMark C. Prins<?php 2bd120a73SMark C. Prins/* 3e48b49c1SMark Prins * Copyright (c) 2011-2020 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 */ 17e48b49c1SMark Prins 18e48b49c1SMark Prinsuse dokuwiki\Sitemap\Item; 19bd120a73SMark C. Prins 20a9441f7dSMark C. Prins/** 21a9441f7dSMark C. Prins * DokuWiki Plugin dokuwikispatial (Action Component). 22a9441f7dSMark C. Prins * 23a9441f7dSMark C. Prins * @license BSD license 24a9441f7dSMark C. Prins * @author Mark C. Prins <mprins@users.sf.net> 25a9441f7dSMark C. Prins */ 26bd120a73SMark C. Prinsclass action_plugin_spatialhelper extends DokuWiki_Action_Plugin { 27bd120a73SMark C. Prins 28bd120a73SMark C. Prins /** 29bd120a73SMark C. Prins * Register for events. 30bd120a73SMark C. Prins * 31a9441f7dSMark C. Prins * @param Doku_Event_Handler $controller 32a9441f7dSMark C. Prins * DokuWiki's event controller object. Also available as global $EVENT_HANDLER 33bd120a73SMark C. Prins */ 3436e7539bSMark C. Prins public function register(Doku_Event_Handler $controller) { 357c452997SMark C. Prins // listen for page add / delete events 36bd120a73SMark C. Prins // http://www.dokuwiki.org/devel:event:indexer_page_add 37817f8be5SMark Prins $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'handleIndexerPageAdd'); 38817f8be5SMark Prins $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'removeFromIndex'); 39a9441f7dSMark C. Prins 40bd120a73SMark C. Prins // http://www.dokuwiki.org/devel:event:sitemap_generate 41817f8be5SMark Prins $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSitemapGenerateBefore'); 427c452997SMark C. Prins // using after will only trigger us if a sitemap was actually created 43817f8be5SMark Prins $controller->register_hook('SITEMAP_GENERATE', 'AFTER', $this, 'handleSitemapGenerateAfter'); 447c452997SMark C. Prins 45a9441f7dSMark C. Prins // handle actions we know of 46817f8be5SMark Prins $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleActionActPreprocess', array()); 47f8fde0daSMark C. Prins // handle HTML eg. /dokuwiki/doku.php?id=start&do=findnearby&geohash=u15vk4 48*37f78197SMark Prins $controller->register_hook( 49*37f78197SMark Prins 'TPL_ACT_UNKNOWN', 'BEFORE', $this, 'findnearby', array( 503e83b370SMark C. Prins 'format' => 'HTML' 51*37f78197SMark Prins ) 52*37f78197SMark Prins ); 53f8fde0daSMark C. Prins // handles AJAX/json eg: jQuery.post("/dokuwiki/lib/exe/ajax.php?id=start&call=findnearby&geohash=u15vk4"); 54*37f78197SMark Prins $controller->register_hook( 55*37f78197SMark Prins 'AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'findnearby', array( 563e83b370SMark C. Prins 'format' => 'JSON' 57*37f78197SMark Prins ) 58*37f78197SMark Prins ); 597c452997SMark C. Prins 60a9441f7dSMark C. Prins // listen for media uploads and deletes 61817f8be5SMark Prins $controller->register_hook('MEDIA_UPLOAD_FINISH', 'BEFORE', $this, 'handleMediaUploaded', array()); 62817f8be5SMark Prins $controller->register_hook('MEDIA_DELETE_FILE', 'BEFORE', $this, 'handleMediaDeleted', array()); 6302c45c98SMark C. Prins 64817f8be5SMark Prins $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleMetaheaderOutput'); 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 */ 75817f8be5SMark Prins public function handleIndexerPageAdd(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 78817f8be5SMark Prins // $event→data['metadata'] – the metadata that shall be indexed. This is an array where the keys are the 79817f8be5SMark Prins // metadata indexes and the value a string or an array of strings with the values. 80817f8be5SMark Prins // title and relation_references will already be set. 819af1cdd4SMark C. Prins $id = $event->data ['page']; 8202c45c98SMark C. Prins $indexer = &plugin_load('helper', 'spatialhelper_index'); 83bd120a73SMark C. Prins $entries = $indexer->updateSpatialIndex($id); 84bd120a73SMark C. Prins } 85bd120a73SMark C. Prins 86bd120a73SMark C. Prins /** 8734fb1e15SMark C. Prins * Update the spatial index, removing the page. 88a9441f7dSMark C. Prins * 89a9441f7dSMark C. Prins * @param Doku_Event $event 90a9441f7dSMark C. Prins * event object by reference 91a9441f7dSMark C. Prins * @param object $param 92a9441f7dSMark C. Prins * the parameters passed to register_hook when this handler was registered 9334fb1e15SMark C. Prins */ 94817f8be5SMark Prins public function removeFromIndex(Doku_Event &$event, $param) { 957c452997SMark C. Prins // event data: 967c452997SMark C. Prins // $data[0] – The raw arguments for io_saveFile as an array. Do not change file path. 977c452997SMark C. Prins // $data[0][0] – the file path. 987c452997SMark C. Prins // $data[0][1] – the content to be saved, and may be modified. 997c452997SMark C. Prins // $data[1] – ns: The colon separated namespace path minus the trailing page name. (false if root ns) 1007c452997SMark C. Prins // $data[2] – page_name: The wiki page name. 1017c452997SMark C. Prins // $data[3] – rev: The page revision, false for current wiki pages. 1027c452997SMark C. Prins 103817f8be5SMark Prins dbglog($event->data, "Event data in removeFromIndex."); 10434fb1e15SMark C. Prins if(@file_exists($event->data [0] [0])) { 10534fb1e15SMark C. Prins // file not new 10634fb1e15SMark C. Prins if(!$event->data [0] [1]) { 10734fb1e15SMark C. Prins // file is empty, page is being deleted 10834fb1e15SMark C. Prins if(empty ($event->data [1])) { 10934fb1e15SMark C. Prins // root namespace 11034fb1e15SMark C. Prins $id = $event->data [2]; 11134fb1e15SMark C. Prins } else { 11234fb1e15SMark C. Prins $id = $event->data [1] . ":" . $event->data [2]; 11334fb1e15SMark C. Prins } 11402c45c98SMark C. Prins $indexer = &plugin_load('helper', 'spatialhelper_index'); 11534fb1e15SMark C. Prins if($indexer) { 11634fb1e15SMark C. Prins $indexer->deleteFromIndex($id); 11734fb1e15SMark C. Prins } 11834fb1e15SMark C. Prins } 11934fb1e15SMark C. Prins } 12034fb1e15SMark C. Prins } 12134fb1e15SMark C. Prins 12234fb1e15SMark C. Prins /** 12302c45c98SMark C. Prins * Add a new SitemapItem object that points to the KML of public geocoded pages. 12402c45c98SMark C. Prins * 12502c45c98SMark C. Prins * @param Doku_Event $event 12602c45c98SMark C. Prins * @param unknown $param 12702c45c98SMark C. Prins */ 128817f8be5SMark Prins public function handleSitemapGenerateBefore(Doku_Event $event, $param) { 12900e20e07SMark C. Prins $path = mediaFN($this->getConf('media_kml')); 13002c45c98SMark C. Prins $lastmod = @filemtime($path); 131e48b49c1SMark Prins $event->data ['items'] [] = new Item(ml($this->getConf('media_kml'), '', true, '&', true), $lastmod); 132817f8be5SMark Prins //dbglog($event->data ['items'], 133817f8be5SMark Prins // "Added a new SitemapItem object that points to the KML of public geocoded pages."); 13402c45c98SMark C. Prins } 13502c45c98SMark C. Prins 13602c45c98SMark C. Prins /** 137a9441f7dSMark C. Prins * Create a spatial sitemap or attach the geo/kml map to the sitemap. 138a9441f7dSMark C. Prins * 139a9441f7dSMark C. Prins * @param Doku_Event $event 1403e83b370SMark C. Prins * event object by reference, not used 141a9441f7dSMark C. Prins * @param mixed $param 1423e83b370SMark C. Prins * parameter array, not used 143bd120a73SMark C. Prins */ 144817f8be5SMark Prins public function handleSitemapGenerateAfter(Doku_Event $event, $param) { 145817f8be5SMark Prins // $event→data['items']: Array of SitemapItem instances, the array of sitemap items that already 146817f8be5SMark Prins // 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 if($helper = &plugin_load('helper', 'spatialhelper_sitemap')) { 14996c9e758SMark Prins // dbglog($helper, "createSpatialSitemap loaded helper."); 15002c45c98SMark C. Prins 151f2601b07SMark C. Prins $kml = $helper->createKMLSitemap($this->getConf('media_kml')); 152f2601b07SMark C. Prins $rss = $helper->createGeoRSSSitemap($this->getConf('media_georss')); 15302c45c98SMark C. Prins 15496c9e758SMark Prins if(!empty ($this->getConf('sitemap_namespaces'))) { 15596c9e758SMark Prins $namespaces = array_map('trim', explode("\n", $this->getConf('sitemap_namespaces'))); 15696c9e758SMark Prins foreach($namespaces as $namespace) { 15796c9e758SMark Prins $kmlN = $helper->createKMLSitemap($namespace . $this->getConf('media_kml')); 15896c9e758SMark Prins $rssN = $helper->createGeoRSSSitemap($namespace . $this->getConf('media_georss')); 159817f8be5SMark Prins dbglog( 160817f8be5SMark Prins $kmlN && $rssN, 161817f8be5SMark Prins "handleSitemapGenerateAfter, created KML / GeoRSS sitemap in $namespace, succes: " 162817f8be5SMark Prins ); 16396c9e758SMark Prins } 16496c9e758SMark Prins } 16502c45c98SMark C. Prins return $kml && $rss; 16602c45c98SMark C. Prins } else { 16716d69598SMark Prins dbglog($helper, "createSpatialSitemap NOT loaded helper."); 16802c45c98SMark C. Prins } 1699af1cdd4SMark C. Prins } 1709af1cdd4SMark C. Prins 1719af1cdd4SMark C. Prins /** 1729af1cdd4SMark C. Prins * trap findnearby action. 17302c45c98SMark C. Prins * This addional handler is required as described at: https://www.dokuwiki.org/devel:event:tpl_act_unknown 174a9441f7dSMark C. Prins * 175a9441f7dSMark C. Prins * @param Doku_Event $event 176a9441f7dSMark C. Prins * event object by reference 177a9441f7dSMark C. Prins * @param mixed $param 178a9441f7dSMark C. Prins * not used 1799af1cdd4SMark C. Prins */ 180817f8be5SMark Prins public function handleActionActPreprocess(Doku_Event $event, $param) { 1815fe9bc3cSScrutinizer Auto-Fixer if($event->data != 'findnearby') { 182a9441f7dSMark C. Prins return; 1835fe9bc3cSScrutinizer Auto-Fixer } 1849af1cdd4SMark C. Prins $event->preventDefault(); 1859af1cdd4SMark C. Prins } 1869af1cdd4SMark C. Prins 1879af1cdd4SMark C. Prins /** 1889af1cdd4SMark C. Prins * handle findnearby action. 189a9441f7dSMark C. Prins * 190a9441f7dSMark C. Prins * @param Doku_Event $event 191a9441f7dSMark C. Prins * event object by reference 192e4020312SMark C. Prins * @param mixed $param 193e4020312SMark C. Prins * associative array with keys 1949bb9b388SMark C. Prins * 'format'=> HTML | JSON 1959af1cdd4SMark C. Prins */ 196817f8be5SMark Prins public function findnearby(Doku_Event &$event, $param) { 1975fe9bc3cSScrutinizer Auto-Fixer if($event->data != 'findnearby') { 198a9441f7dSMark C. Prins return; 1995fe9bc3cSScrutinizer Auto-Fixer } 2009af1cdd4SMark C. Prins $event->preventDefault(); 2019af1cdd4SMark C. Prins 2027c452997SMark C. Prins global $INPUT; 2039af1cdd4SMark C. Prins if($helper = &plugin_load('helper', 'spatialhelper_search')) { 204fd140697SMark C. Prins if($INPUT->has('lat') && $INPUT->has('lon')) { 2057c452997SMark C. Prins $results = $helper->findNearbyLatLon($INPUT->param('lat'), $INPUT->param('lon')); 206fd140697SMark C. Prins } elseif($INPUT->has('geohash')) { 207fd140697SMark C. Prins $results = $helper->findNearby($INPUT->str('geohash')); 2087c452997SMark C. Prins } else { 2093e83b370SMark C. Prins $results = array( 2103e83b370SMark C. Prins 'error' => hsc($this->getLang('invalidinput')) 2113e83b370SMark C. Prins ); 2129af1cdd4SMark C. Prins } 2139af1cdd4SMark C. Prins } 2149af1cdd4SMark C. Prins 2153e83b370SMark C. Prins $showMedia = $INPUT->bool('showMedia', true); 2163e83b370SMark C. Prins 217f8fde0daSMark C. Prins switch($param['format']) { 2183e83b370SMark C. Prins case 'JSON' : 2193e83b370SMark C. Prins $this->printJSON($results); 2203e83b370SMark C. Prins break; 2213e83b370SMark C. Prins case 'HTML' : 2229892789dSMark C. Prins // fall through to default 2233e83b370SMark C. Prins default : 2243e83b370SMark C. Prins $this->printHTML($results, $showMedia); 2253e83b370SMark C. Prins break; 2263e83b370SMark C. Prins } 2273e83b370SMark C. Prins } 2283e83b370SMark C. Prins 2293e83b370SMark C. Prins /** 2303e83b370SMark C. Prins * Print seachresults as HTML lists. 2313e83b370SMark C. Prins * 2323e83b370SMark C. Prins * @param array $searchresults 2333e83b370SMark C. Prins */ 2343e83b370SMark C. Prins private function printJSON($searchresults) { 2353e83b370SMark C. Prins require_once DOKU_INC . 'inc/JSON.php'; 2363e83b370SMark C. Prins $json = new JSON(); 2373e83b370SMark C. Prins header('Content-Type: application/json'); 2383e83b370SMark C. Prins print $json->encode($searchresults); 2393e83b370SMark C. Prins } 2403e83b370SMark C. Prins 2413e83b370SMark C. Prins /** 2423e83b370SMark C. Prins * Print seachresults as HTML lists. 2433e83b370SMark C. Prins * 2443e83b370SMark C. Prins * @param array $searchresults 2453e83b370SMark C. Prins * @param boolean $showMedia 2463e83b370SMark C. Prins */ 2473e83b370SMark C. Prins private function printHTML($searchresults, $showMedia = true) { 2483e83b370SMark C. Prins $pages = (array) ($searchresults ['pages']); 2493e83b370SMark C. Prins $media = (array) $searchresults ['media']; 250594a0ef1SMark C. Prins $lat = (float) $searchresults ['lat']; 251594a0ef1SMark C. Prins $lon = (float) $searchresults ['lon']; 2523e83b370SMark C. Prins $geohash = (string) $searchresults ['geohash']; 2533e83b370SMark C. Prins 2543e83b370SMark C. Prins if(isset ($searchresults ['error'])) { 2553e83b370SMark C. Prins print '<div class="level1"><p>' . hsc($results ['error']) . '</p></div>'; 2563e83b370SMark C. Prins return; 2573e83b370SMark C. Prins } 2583e83b370SMark C. Prins 2593e83b370SMark C. Prins // print a HTML list 2607c452997SMark C. Prins print '<h1>' . $this->getLang('results_header') . '</h1>' . DOKU_LF; 2619af1cdd4SMark C. Prins print '<div class="level1">' . DOKU_LF; 2627c452997SMark C. Prins if(!empty ($pages)) { 2637c452997SMark C. Prins $pagelist = '<ol>' . DOKU_LF; 2647c452997SMark C. Prins foreach($pages as $page) { 265*37f78197SMark Prins $pagelist .= '<li>' . html_wikilink( 266*37f78197SMark Prins ':' . $page ['id'], useHeading('navigation') ? null : 267*37f78197SMark Prins noNS($page ['id']) 268*37f78197SMark Prins ) . ' (' . $this->getLang('results_distance_prefix') 269817f8be5SMark Prins . $page ['distance'] . ' m) ' . $page ['description'] . '</li>' . DOKU_LF; 2707c452997SMark C. Prins } 2717c452997SMark C. Prins $pagelist .= '</ol>' . DOKU_LF; 2727c452997SMark C. Prins 273*37f78197SMark Prins print '<h2>' . $this->getLang('results_pages') . hsc( 274*37f78197SMark Prins ' lat;lon: ' . $lat . ';' . $lon 275*37f78197SMark Prins . ' (geohash: ' . $geohash . ')' 276*37f78197SMark Prins ) . '</h2>'; 2777c452997SMark C. Prins print '<div class="level2">' . DOKU_LF; 2787c452997SMark C. Prins print $pagelist; 2799af1cdd4SMark C. Prins print '</div>' . DOKU_LF; 2809af1cdd4SMark C. Prins } else { 2817c452997SMark C. Prins print '<p>' . hsc($this->getLang('nothingfound')) . '</p>'; 2829af1cdd4SMark C. Prins } 283e4020312SMark C. Prins 2843e83b370SMark C. Prins if(!empty ($media) && $showMedia) { 2857c452997SMark C. Prins $pagelist = '<ol>' . DOKU_LF; 2867c452997SMark C. Prins foreach($media as $m) { 2877c452997SMark C. Prins $opts = array(); 2887c452997SMark C. Prins $link = ml($m ['id'], $opts, false, '&', false); 2899bb9b388SMark C. Prins $opts ['w'] = '100'; 2907c452997SMark C. Prins $src = ml($m ['id'], $opts); 291817f8be5SMark Prins $pagelist .= '<li><a href="' . $link . '"><img src="' . $src . '"></a> (' 292817f8be5SMark Prins . $this->getLang('results_distance_prefix') . $page ['distance'] . ' m) ' . hsc($desc) 293817f8be5SMark Prins . '</li>' . DOKU_LF; 294bd120a73SMark C. Prins } 2957c452997SMark C. Prins $pagelist .= '</ol>' . DOKU_LF; 2967c452997SMark C. Prins 297*37f78197SMark Prins print '<h2>' . $this->getLang('results_media') . hsc( 298*37f78197SMark Prins ' lat;lon: ' . $lat . ';' . $lon 299*37f78197SMark Prins . ' (geohash: ' . $geohash . ')' 300*37f78197SMark Prins ) . '</h2>' . DOKU_LF; 3017c452997SMark C. Prins print '<div class="level2">' . DOKU_LF; 3027c452997SMark C. Prins print $pagelist; 3037c452997SMark C. Prins print '</div>' . DOKU_LF; 3047c452997SMark C. Prins } 305594a0ef1SMark C. Prins print '<p>' . $this->getLang('results_precision') . $searchresults ['precision'] . ' m. '; 306594a0ef1SMark C. Prins if(strlen($geohash) > 1) { 307*37f78197SMark Prins $url = wl( 308*37f78197SMark Prins getID(), array( 309594a0ef1SMark C. Prins 'do' => 'findnearby', 310594a0ef1SMark C. Prins 'geohash' => substr($geohash, 0, -1) 311*37f78197SMark Prins ) 312*37f78197SMark Prins ); 313817f8be5SMark Prins print '<a href="' . $url . '" class="findnearby">' . $this->getLang('search_largerarea') . '</a>.</p>' 314817f8be5SMark Prins . DOKU_LF; 315594a0ef1SMark C. Prins } 3167c452997SMark C. Prins print '</div>' . DOKU_LF; 3177c452997SMark C. Prins } 3183e83b370SMark C. Prins 3197c452997SMark C. Prins /** 3207c452997SMark C. Prins * add media to spatial index. 3217c452997SMark C. Prins * 3227c452997SMark C. Prins * @param Doku_Event $event 3237c452997SMark C. Prins * event object by reference 3247c452997SMark C. Prins * @param unknown $param 325a9441f7dSMark C. Prins */ 326817f8be5SMark Prins public function handleMediaUploaded(Doku_Event &$event, $param) { 3277c452997SMark C. Prins // data[0] temporary file name (read from $_FILES) 3287c452997SMark C. Prins // data[1] file name of the file being uploaded 3297c452997SMark C. Prins // data[2] future directory id of the file being uploaded 3307c452997SMark C. Prins // data[3] the mime type of the file being uploaded 3317c452997SMark C. Prins // data[4] true if the uploaded file exists already 3327c452997SMark C. Prins // data[5] (since 2011-02-06) the PHP function used to move the file to the correct location 33302c45c98SMark C. Prins 334817f8be5SMark Prins dbglog($event->data, "handleMediaUploaded::event data"); 335a9441f7dSMark C. Prins 336a9441f7dSMark C. Prins // check the list of mimetypes 337a9441f7dSMark C. Prins // if it's a supported type call appropriate index function 3387c452997SMark C. Prins if(substr_compare($event->data [3], 'image/jpeg', 0)) { 339a9441f7dSMark C. Prins $indexer = plugin_load('helper', 'spatialhelper_index'); 340a9441f7dSMark C. Prins if($indexer) { 341a9441f7dSMark C. Prins $indexer->indexImage($event->data [2], $event->data [1]); 342a9441f7dSMark C. Prins } 343a9441f7dSMark C. Prins } 3447c452997SMark C. Prins // TODO add image/tiff 345a9441f7dSMark C. Prins // TODO kml, gpx, geojson... 346a9441f7dSMark C. Prins } 347a9441f7dSMark C. Prins 348a9441f7dSMark C. Prins /** 349a9441f7dSMark C. Prins * removes the media from the index. 350a9441f7dSMark C. Prins */ 351817f8be5SMark Prins public function handleMediaDeleted(Doku_Event &$event, $param) { 3527c452997SMark C. Prins // data['id'] ID data['unl'] unlink return code 3537c452997SMark C. Prins // data['del'] Namespace directory unlink return code 3547c452997SMark C. Prins // data['name'] file name data['path'] full path to the file 3557c452997SMark C. Prins // data['size'] file size 35602c45c98SMark C. Prins 357817f8be5SMark Prins dbglog($event->data, "handleMediaDeleted::event data"); 3587c452997SMark C. Prins 3597c452997SMark C. Prins // remove the media id from the index 36002c45c98SMark C. Prins $indexer = &plugin_load('helper', 'spatialhelper_index'); 361a9441f7dSMark C. Prins if($indexer) { 3627c452997SMark C. Prins $indexer->deleteFromIndex('media__' . $event->data ['id']); 363a9441f7dSMark C. Prins } 364a9441f7dSMark C. Prins } 3657c452997SMark C. Prins 3667c452997SMark C. Prins /** 36702c45c98SMark C. Prins * add a link to the spatial sitemap files in the header. 36802c45c98SMark C. Prins * 36902c45c98SMark C. Prins * @param Doku_Event $event 37002c45c98SMark C. Prins * the DokuWiki event. $event->data is a two-dimensional 37102c45c98SMark C. Prins * array of all meta headers. The keys are meta, link and script. 37202c45c98SMark C. Prins * @param unknown_type $param 37302c45c98SMark C. Prins * 37402c45c98SMark C. Prins * @see http://www.dokuwiki.org/devel:event:tpl_metaheader_output 37502c45c98SMark C. Prins */ 376817f8be5SMark Prins public function handleMetaheaderOutput(Doku_Event $event, $param) { 37702c45c98SMark C. Prins // TODO maybe test for exist 37802c45c98SMark C. Prins $event->data ["link"] [] = array( 37902c45c98SMark C. Prins "type" => "application/atom+xml", 38002c45c98SMark C. Prins "rel" => "alternate", 38100e20e07SMark C. Prins "href" => ml($this->getConf('media_georss')), 38202c45c98SMark C. Prins "title" => "Spatial ATOM Feed" 38302c45c98SMark C. Prins ); 38402c45c98SMark C. Prins $event->data ["link"] [] = array( 38502c45c98SMark C. Prins "type" => "application/vnd.google-earth.kml+xml", 38602c45c98SMark C. Prins "rel" => "alternate", 38700e20e07SMark C. Prins "href" => ml($this->getConf('media_kml')), 38802c45c98SMark C. Prins "title" => "KML Sitemap" 38902c45c98SMark C. Prins ); 39002c45c98SMark C. Prins } 39102c45c98SMark C. Prins 39202c45c98SMark C. Prins /** 3937c452997SMark C. Prins * Calculate a new coordinate based on start, distance and bearing 3947c452997SMark C. Prins * 3957c452997SMark C. Prins * @param $start array 3967c452997SMark C. Prins * - start coordinate as decimal lat/lon pair 3977c452997SMark C. Prins * @param $dist float 3987c452997SMark C. Prins * - distance in kilometers 3997c452997SMark C. Prins * @param $brng float 4007c452997SMark C. Prins * - bearing in degrees (compass direction) 4017c452997SMark C. Prins */ 402817f8be5SMark Prins private function geoDestination($start, $dist, $brng) { 403817f8be5SMark Prins $lat1 = toRad($start [0]); 404817f8be5SMark Prins $lon1 = toRad($start [1]); 4057c452997SMark C. Prins // http://en.wikipedia.org/wiki/Earth_radius 4067c452997SMark C. Prins // average earth radius in km 4077c452997SMark C. Prins $dist = $dist / 6371.01; 408817f8be5SMark Prins $brng = toRad($brng); 4097c452997SMark C. Prins 4107c452997SMark C. Prins $lon2 = $lon1 + atan2(sin($brng) * sin($dist) * cos($lat1), cos($dist) - sin($lat1) * sin($lat2)); 4117c452997SMark C. Prins $lon2 = fmod(($lon2 + 3 * pi()), (2 * pi())) - pi(); 4127c452997SMark C. Prins 4137c452997SMark C. Prins return array( 414817f8be5SMark Prins toDeg($lat2), 415817f8be5SMark Prins toDeg($lon2) 4167c452997SMark C. Prins ); 4177c452997SMark C. Prins } 418*37f78197SMark Prins 419817f8be5SMark Prins private function toRad($deg) { 4207c452997SMark C. Prins return $deg * pi() / 180; 4217c452997SMark C. Prins } 422*37f78197SMark Prins 423817f8be5SMark Prins private function toDeg($rad) { 4247c452997SMark C. Prins return $rad * 180 / pi(); 4257c452997SMark C. Prins } 426bd120a73SMark C. Prins} 427