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