xref: /plugin/spatialhelper/action.php (revision 37f781979cbd041dcaac42d7da19b83a6b932c86)
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, '&amp;', 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'] . '&nbsp;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, '&amp;', 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'] . '&nbsp;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