1<?php
2/*
3 * Copyright (c) 2008-2021 Mark C. Prins <mprins@users.sf.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
18 */
19
20/**
21 * DokuWiki Plugin openlayersmap (staticmap Helper Component).
22 * This provides the interface to generate a static map based on predefined OSM layers.
23 *
24 * @author Mark Prins
25 */
26class helper_plugin_openlayersmap_staticmap extends DokuWiki_Plugin {
27    /** maximum width of the resulting image. */
28    private $maxWidth = 1024;
29    /** maximum heigth of the resulting image. */
30    private $maxHeight = 1024;
31
32    /**
33     * Provide metadata of the public methods of this class.
34     *
35     * @return array Information to all provided methods.
36     */
37    public function getMethods(): array {
38        $result   = array();
39        $result[] = array(
40            'name'   => 'getMap',
41            'desc'   => 'returns url to the image',
42            'params' => array(
43                'lat'     => 'float',
44                'lon'     => 'float',
45                'zoom'    => 'integer',
46                'size'    => 'string',
47                'maptype' => 'string',
48                'markers' => 'string',
49                'gpx'     => 'string',
50                'kml'     => 'string',
51                'geojson' => 'string',
52                'apikey'  => 'string'
53            ),
54            'return' => array('image' => 'string'),
55        );
56        return $result;
57    }
58
59    /**
60     * Create the map.
61     *
62     * @param float  $lat     the latitude of the map's center, eg. 40.714728
63     * @param float  $lon     the longitude of the map's center, eg -73.998672
64     * @param int    $zoom    the zoom level in the tile cache, eg. 14
65     * @param string $size    the size in WxH px, eg. 512x512
66     * @param string $maptype the maptype, eg. cycle
67     * @param array  $markers associative array of markers, array('lat'=>$lat,'lon'=>$lon,'type'=>$iconStyle),
68     *                        eg. array('lat'=>40.702147,'lon'=>-74.015794,'type'=>lightblue1);
69     * @param string $gpx     media link
70     * @param string $kml     media link
71     * @param string $geojson media link
72     * @param string $apikey  optional API key eg. for Thunderforest maps
73     *
74     * @return string
75     */
76    public function getMap(
77        float $lat,
78        float $lon,
79        int $zoom,
80        string $size,
81        string $maptype,
82        array $markers,
83        string $gpx,
84        string $kml,
85        string $geojson,
86        string $apikey = ''
87    ): string {
88        global $conf;
89        // dbglog($markers,'helper_plugin_openlayersmap_staticmap::getMap: markers :');
90
91        // normalize zoom
92        $zoom = $zoom ?: 0;
93        if($zoom > 18) {
94            $zoom = 18;
95        }
96        // normalize WxH
97        list($width, $height) = explode('x', $size);
98        $width = (int) $width;
99        if($width > $this->maxWidth) {
100            $width = $this->maxWidth;
101        }
102        $height = (int) $height;
103        if($height > $this->maxHeight) {
104            $height = $this->maxHeight;
105        }
106
107        // cleanup/validate gpx/kml
108        $kml = $this->mediaIdToPath($kml);
109        // dbglog($kml,'helper_plugin_openlayersmap_staticmap::getMap: kml file:');
110        $gpx = $this->mediaIdToPath($gpx);
111        // dbglog($gpx,'helper_plugin_openlayersmap_staticmap::getMap: gpx file:');
112        $geojson = $this->mediaIdToPath($geojson);
113
114        // create map
115        require_once DOKU_PLUGIN . 'openlayersmap/StaticMap.php';
116        $map = new StaticMap(
117            $lat, $lon, $zoom, $width, $height, $maptype,
118            $markers, $gpx, $kml, $geojson, $conf['mediadir'], $conf['cachedir'],
119            $this->getConf('autoZoomMap'), $apikey
120        );
121
122        // return the media id url
123        // $mediaId = str_replace('/', ':', $map->getMap());
124        // if($this->startsWith($mediaId,':')) {
125        //     $mediaId = substr($mediaId, 1);
126        // }
127        // return $mediaId;
128        return str_replace('/', ':', $map->getMap());
129    }
130
131    /**
132     * Constructs the path to a file.
133     * @param string $id the DW media id
134     * @return string the path to the file
135     */
136    private function mediaIdToPath(string $id): string {
137        global $conf;
138        if(empty($id)) {
139            return "";
140        }
141        $id = str_replace(array("[[", "]]"), "", $id);
142        if((strpos($id, ':') === 0)) {
143            $id = substr($id, 1);
144        }
145        $id = str_replace(":", "/", $id);
146        return $conf['mediadir'] . '/' . $id;
147    }
148}
149