138a47c60SMark Prins<?php 2a760825cSgithub-actions[bot] 338a47c60SMark Prins/* 4*f204b8caSMark Prins * Copyright (c) 2008-2023 Mark C. Prins <mprins@users.sf.net> 538a47c60SMark Prins * 638a47c60SMark Prins * Permission to use, copy, modify, and distribute this software for any 738a47c60SMark Prins * purpose with or without fee is hereby granted, provided that the above 838a47c60SMark Prins * copyright notice and this permission notice appear in all copies. 938a47c60SMark Prins * 1038a47c60SMark Prins * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 1138a47c60SMark Prins * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1238a47c60SMark Prins * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 1338a47c60SMark Prins * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1438a47c60SMark Prins * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1538a47c60SMark Prins * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 1638a47c60SMark Prins * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1757f8d5bbSMark Prins * 1857f8d5bbSMark Prins * @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps 1938a47c60SMark Prins */ 20a760825cSgithub-actions[bot]use dokuwiki\Extension\SyntaxPlugin; 213ebe658bSMark Prinsuse geoPHP\Geometry\Point; 22*f204b8caSMark Prinsuse dokuwiki\Logger; 233ebe658bSMark Prins 2438a47c60SMark Prins/** 25cc74a83cSMark Prins * DokuWiki Plugin openlayersmap (Syntax Component). 26cc74a83cSMark Prins * Provides for display of an OpenLayers based map in a wiki page. 27cc74a83cSMark Prins * 28cc74a83cSMark Prins * @author Mark Prins 2938a47c60SMark Prins */ 30a760825cSgithub-actions[bot]class syntax_plugin_openlayersmap_olmap extends SyntaxPlugin 31a760825cSgithub-actions[bot]{ 321c640875SMark Prins /** 331c640875SMark Prins * defaults of the known attributes of the olmap tag. 341c640875SMark Prins */ 35a760825cSgithub-actions[bot] private $dflt = ['id' => 'olmap', 'width' => '550px', 'height' => '450px', 'lat' => 50.0, 'lon' => 5.1, 'zoom' => 12, 'autozoom' => 1, 'controls' => true, 'baselyr' => 'OpenStreetMap', 'gpxfile' => '', 'kmlfile' => '', 'geojsonfile' => '', 'summary' => '']; 3638a47c60SMark Prins 3738a47c60SMark Prins /** 381c640875SMark Prins * 39cc74a83cSMark Prins * @see DokuWiki_Syntax_Plugin::getType() 4038a47c60SMark Prins */ 41a760825cSgithub-actions[bot] public function getType(): string 42a760825cSgithub-actions[bot] { 4375c98788SMark Prins return 'substition'; 4475c98788SMark Prins } 4538a47c60SMark Prins 4638a47c60SMark Prins /** 471c640875SMark Prins * 48cc74a83cSMark Prins * @see DokuWiki_Syntax_Plugin::getPType() 4938a47c60SMark Prins */ 50a760825cSgithub-actions[bot] public function getPType(): string 51a760825cSgithub-actions[bot] { 5275c98788SMark Prins return 'block'; 5375c98788SMark Prins } 5438a47c60SMark Prins 5538a47c60SMark Prins /** 561c640875SMark Prins * 57cc74a83cSMark Prins * @see Doku_Parser_Mode::getSort() 5838a47c60SMark Prins */ 59a760825cSgithub-actions[bot] public function getSort(): int 60a760825cSgithub-actions[bot] { 6175c98788SMark Prins return 901; 6275c98788SMark Prins } 63fc16f3cdSMark Prins 6438a47c60SMark Prins /** 651c640875SMark Prins * 66cc74a83cSMark Prins * @see Doku_Parser_Mode::connectTo() 6738a47c60SMark Prins */ 68a760825cSgithub-actions[bot] public function connectTo($mode) 69a760825cSgithub-actions[bot] { 7057f8d5bbSMark Prins $this->Lexer->addSpecialPattern( 71a760825cSgithub-actions[bot] '<olmap ?[^>\n]*>.*?</olmap>', 72a760825cSgithub-actions[bot] $mode, 7357f8d5bbSMark Prins 'plugin_openlayersmap_olmap' 7457f8d5bbSMark Prins ); 7538a47c60SMark Prins } 76fc16f3cdSMark Prins 7738a47c60SMark Prins /** 781c640875SMark Prins * 79cc74a83cSMark Prins * @see DokuWiki_Syntax_Plugin::handle() 8038a47c60SMark Prins */ 81a760825cSgithub-actions[bot] public function handle($match, $state, $pos, Doku_Handler $handler): array 82a760825cSgithub-actions[bot] { 833f760703SMark Prins // break matched data into its components 843f760703SMark Prins $_tag = explode('>', substr($match, 7, -9), 2); 853f760703SMark Prins $str_params = $_tag[0]; 863f760703SMark Prins if (array_key_exists(1, $_tag)) { 873f760703SMark Prins $str_points = $_tag[1]; 883f760703SMark Prins } else { 893f760703SMark Prins $str_points = ''; 903f760703SMark Prins } 91554f43b5SMark Prins // get the lat/lon for adding them to the metadata (used by geotag) 92d2f4772aSMark Prins preg_match('(lat[:|=]\"-?\d*\.?\d*\")', $match, $mainLat); 93d2f4772aSMark Prins preg_match('(lon[:|=]\"-?\d*\.?\d*\")', $match, $mainLon); 94554f43b5SMark Prins $mainLat = substr($mainLat [0], 5, -1); 95554f43b5SMark Prins $mainLon = substr($mainLon [0], 5, -1); 96d2f4772aSMark Prins if (!is_numeric($mainLat)) { 97d2f4772aSMark Prins $mainLat = $this->dflt ['lat']; 98d2f4772aSMark Prins } 99d2f4772aSMark Prins if (!is_numeric($mainLon)) { 100d2f4772aSMark Prins $mainLon = $this->dflt ['lon']; 101d2f4772aSMark Prins } 10238a47c60SMark Prins 10357f8d5bbSMark Prins $gmap = $this->extractParams($str_params); 10457f8d5bbSMark Prins $overlay = $this->extractPoints($str_points); 105fc16f3cdSMark Prins $_firstimageID = ''; 10638a47c60SMark Prins 1078e7c4263SMark Prins $_nocache = false; 108807d36baSMark Prins // choose maptype based on the specified tag 109628e43ccSMark Prins $imgUrl = "{{"; 110585afb49SMark Prins if (stripos($gmap ['baselyr'], 'google') !== false) { 1118e7c4263SMark Prins // Google 11257f8d5bbSMark Prins $imgUrl .= $this->getGoogle($gmap, $overlay); 1138e7c4263SMark Prins $imgUrl .= "&.png"; 114585afb49SMark Prins } elseif (stripos($gmap ['baselyr'], 'bing') !== false) { 1158e7c4263SMark Prins // Bing 116d974ea02SMark Prins if (!$this->getConf('bingAPIKey')) { 117d974ea02SMark Prins // in case there is no Bing api key we'll use OSM 11857f8d5bbSMark Prins $_firstimageID = $this->getStaticOSM($gmap, $overlay); 119d974ea02SMark Prins $imgUrl .= $_firstimageID; 120628e43ccSMark Prins if ($this->getConf('optionStaticMapGenerator') == 'remote') { 121628e43ccSMark Prins $imgUrl .= "&.png"; 122d974ea02SMark Prins } 123d974ea02SMark Prins } else { 1248e7c4263SMark Prins // seems that Bing doesn't like the DW client, turn off caching 1258e7c4263SMark Prins $_nocache = true; 12657f8d5bbSMark Prins $imgUrl .= $this->getBing($gmap, $overlay) . "&.png"; 127d974ea02SMark Prins } 128*f204b8caSMark Prins /* elseif (stripos ( $gmap ['baselyr'], 'mapquest' ) !== false) { 1298e7c4263SMark Prins // MapQuest 1308e7c4263SMark Prins if (! $this->getConf ( 'mapquestAPIKey' )) { 1318e7c4263SMark Prins // no API key for MapQuest, use OSM 13257f8d5bbSMark Prins $_firstimageID = $this->getStaticOSM ( $gmap, $overlay ); 133fc16f3cdSMark Prins $imgUrl .= $_firstimageID; 1348e7c4263SMark Prins if ($this->getConf ( 'optionStaticMapGenerator' ) == 'remote') { 1358e7c4263SMark Prins $imgUrl .= "&.png"; 136628e43ccSMark Prins } 13763037f21SMark Prins } else { 1388e7c4263SMark Prins $imgUrl .= $this->_getMapQuest ( $gmap, $overlay ); 1398e7c4263SMark Prins $imgUrl .= "&.png"; 1408e7c4263SMark Prins } 141*f204b8caSMark Prins } */ 142*f204b8caSMark Prins } else { 1438e7c4263SMark Prins // default OSM 14457f8d5bbSMark Prins $_firstimageID = $this->getStaticOSM($gmap, $overlay); 145fc16f3cdSMark Prins $imgUrl .= $_firstimageID; 14653bfe4a3SMark Prins if ($this->getConf('optionStaticMapGenerator') == 'remote') { 14753bfe4a3SMark Prins $imgUrl .= "&.png"; 14853bfe4a3SMark Prins } 14987d958d4SMark Prins } 15087d958d4SMark Prins 151628e43ccSMark Prins // append dw p_render specific params and render 15257f8d5bbSMark Prins $imgUrl .= "?" . str_replace("px", "", $gmap ['width']) . "x" 15357f8d5bbSMark Prins . str_replace("px", "", $gmap ['height']); 1546ba8d085SMark Prins $imgUrl .= "&nolink"; 1558e7c4263SMark Prins 1568e7c4263SMark Prins // add nocache option for selected services 1578e7c4263SMark Prins if ($_nocache) { 1588e7c4263SMark Prins $imgUrl .= "&nocache"; 1598e7c4263SMark Prins } 1608e7c4263SMark Prins 161fcd79b50SMark Prins $imgUrl .= " |" . $gmap ['summary'] . " }}"; 162fcd79b50SMark Prins 16338a47c60SMark Prins $mapid = $gmap ['id']; 16438a47c60SMark Prins // create a javascript parameter string for the map 16538a47c60SMark Prins $param = ''; 16638a47c60SMark Prins foreach ($gmap as $key => $val) { 16738a47c60SMark Prins $param .= is_numeric($val) ? "$key: $val, " : "$key: '" . hsc($val) . "', "; 16838a47c60SMark Prins } 16938a47c60SMark Prins if (!empty($param)) { 17045c50327SMark Prins $param = substr($param, 0, -2); 17138a47c60SMark Prins } 17238a47c60SMark Prins unset($gmap ['id']); 17338a47c60SMark Prins 17438a47c60SMark Prins // create a javascript serialisation of the point data 17538a47c60SMark Prins $poi = ''; 17645c50327SMark Prins $poitable = ''; 17745c50327SMark Prins $rowId = 0; 178a760825cSgithub-actions[bot] if ($overlay !== []) { 17938a47c60SMark Prins foreach ($overlay as $data) { 180a760825cSgithub-actions[bot] [$lat, $lon, $text, $angle, $opacity, $img] = $data; 18145c50327SMark Prins $rowId++; 18245c50327SMark Prins $poi .= ", {lat:$lat,lon:$lon,txt:'$text',angle:$angle,opacity:$opacity,img:'$img',rowId: $rowId}"; 1838c4eb2fdSMark Prins 1848c4eb2fdSMark Prins if ($this->getConf('displayformat') === 'DMS') { 1858c4eb2fdSMark Prins $lat = $this->convertLat($lat); 1868c4eb2fdSMark Prins $lon = $this->convertLon($lon); 1878c4eb2fdSMark Prins } else { 1888c4eb2fdSMark Prins $lat .= 'º'; 1898c4eb2fdSMark Prins $lon .= 'º'; 1908c4eb2fdSMark Prins } 1918c4eb2fdSMark Prins 192a757236dSMark Prins $poitable .= ' 193a757236dSMark Prins <tr> 194a757236dSMark Prins <td class="rowId">' . $rowId . '</td> 19557f8d5bbSMark Prins <td class="icon"><img src="' . DOKU_BASE . 'lib/plugins/openlayersmap/icons/' . $img . '" alt="' 19657f8d5bbSMark Prins . substr($img, 0, -4) . $this->getlang('alt_legend_poi') . '" /></td> 197a57aaf07SMark Prins <td class="lat" title="' . $this->getLang('olmapPOIlatTitle') . '">' . $lat . '</td> 198a57aaf07SMark Prins <td class="lon" title="' . $this->getLang('olmapPOIlonTitle') . '">' . $lon . '</td> 199a757236dSMark Prins <td class="txt">' . $text . '</td> 200a757236dSMark Prins </tr>'; 20138a47c60SMark Prins } 20245c50327SMark Prins $poi = substr($poi, 2); 20338a47c60SMark Prins } 204e61425c7SMark Prins if (!empty($gmap ['kmlfile'])) { 205e61425c7SMark Prins $poitable .= ' 206e61425c7SMark Prins <tr> 20757f8d5bbSMark Prins <td class="rowId"><img src="' . DOKU_BASE 20857f8d5bbSMark Prins . 'lib/plugins/openlayersmap/toolbar/kml_file.png" alt="KML file" /></td> 20957f8d5bbSMark Prins <td class="icon"><img src="' . DOKU_BASE . 'lib/plugins/openlayersmap/toolbar/kml_line.png" alt="' 21057f8d5bbSMark Prins . $this->getlang('alt_legend_kml') . '" /></td> 211cc74a83cSMark Prins <td class="txt" colspan="3">KML track: ' . $this->getFileName($gmap ['kmlfile']) . '</td> 212e61425c7SMark Prins </tr>'; 213e61425c7SMark Prins } 214e61425c7SMark Prins if (!empty($gmap ['gpxfile'])) { 215e61425c7SMark Prins $poitable .= ' 216e61425c7SMark Prins <tr> 21757f8d5bbSMark Prins <td class="rowId"><img src="' . DOKU_BASE 21857f8d5bbSMark Prins . 'lib/plugins/openlayersmap/toolbar/gpx_file.png" alt="GPX file" /></td> 21957f8d5bbSMark Prins <td class="icon"><img src="' . DOKU_BASE 22057f8d5bbSMark Prins . 'lib/plugins/openlayersmap/toolbar/gpx_line.png" alt="' 22157f8d5bbSMark Prins . $this->getlang('alt_legend_gpx') . '" /></td> 222cc74a83cSMark Prins <td class="txt" colspan="3">GPX track: ' . $this->getFileName($gmap ['gpxfile']) . '</td> 223e61425c7SMark Prins </tr>'; 224e61425c7SMark Prins } 2256914b920SMark Prins if (!empty($gmap ['geojsonfile'])) { 2266914b920SMark Prins $poitable .= ' 2276914b920SMark Prins <tr> 22857f8d5bbSMark Prins <td class="rowId"><img src="' . DOKU_BASE 22957f8d5bbSMark Prins . 'lib/plugins/openlayersmap/toolbar/geojson_file.png" alt="GeoJSON file" /></td> 23057f8d5bbSMark Prins <td class="icon"><img src="' . DOKU_BASE 23157f8d5bbSMark Prins . 'lib/plugins/openlayersmap/toolbar/geojson_line.png" alt="' 23257f8d5bbSMark Prins . $this->getlang('alt_legend_geojson') . '" /></td> 2336914b920SMark Prins <td class="txt" colspan="3">GeoJSON track: ' . $this->getFileName($gmap ['geojsonfile']) . '</td> 2346914b920SMark Prins </tr>'; 2356914b920SMark Prins } 236e61425c7SMark Prins 237c8eb1362SMark Prins $autozoom = empty($gmap ['autozoom']) ? $this->getConf('autoZoomMap') : $gmap ['autozoom']; 23857f8d5bbSMark Prins $js = "{mapOpts: {" . $param . ", displayformat: '" . $this->getConf('displayformat') 23957f8d5bbSMark Prins . "', autozoom: " . $autozoom . "}, poi: [$poi]};"; 240a757236dSMark Prins // unescape the json 241a757236dSMark Prins $poitable = stripslashes($poitable); 24238a47c60SMark Prins 243a760825cSgithub-actions[bot] return [$mapid, $js, $mainLat, $mainLon, $poitable, $gmap ['summary'], $imgUrl, $_firstimageID]; 24438a47c60SMark Prins } 24538a47c60SMark Prins 24638a47c60SMark Prins /** 24738a47c60SMark Prins * extract parameters for the map from the parameter string 24838a47c60SMark Prins * 2491c640875SMark Prins * @param string $str_params 2501c640875SMark Prins * string of key="value" pairs 25138a47c60SMark Prins * @return array associative array of parameters key=>value 25238a47c60SMark Prins */ 253a760825cSgithub-actions[bot] private function extractParams(string $str_params): array 254a760825cSgithub-actions[bot] { 255a760825cSgithub-actions[bot] $param = []; 25638a47c60SMark Prins preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER); 25738a47c60SMark Prins // parse match for instructions, break into key value pairs 25838a47c60SMark Prins $gmap = $this->dflt; 259c8eb1362SMark Prins foreach ($gmap as $key => &$value) { 260c8eb1362SMark Prins $defval = $this->getConf('default_' . $key); 261c8eb1362SMark Prins if ($defval !== '') { 262c8eb1362SMark Prins $value = $defval; 263c8eb1362SMark Prins } 264c8eb1362SMark Prins } 265c8eb1362SMark Prins unset($value); 26638a47c60SMark Prins foreach ($param as $kvpair) { 267a760825cSgithub-actions[bot] [$match, $key, $val] = $kvpair; 26838a47c60SMark Prins $key = strtolower($key); 26938a47c60SMark Prins if (isset($gmap [$key])) { 27045c50327SMark Prins if ($key == 'summary') { 27145c50327SMark Prins // preserve case for summary field 27245c50327SMark Prins $gmap [$key] = $val; 2731c640875SMark Prins } elseif ($key == 'id') { 2741c640875SMark Prins // preserve case for id field 2751c640875SMark Prins $gmap [$key] = $val; 27645c50327SMark Prins } else { 27738a47c60SMark Prins $gmap [$key] = strtolower($val); 27838a47c60SMark Prins } 27938a47c60SMark Prins } 28045c50327SMark Prins } 28138a47c60SMark Prins return $gmap; 28238a47c60SMark Prins } 28338a47c60SMark Prins 28438a47c60SMark Prins /** 28538a47c60SMark Prins * extract overlay points for the map from the wiki syntax data 28638a47c60SMark Prins * 2871c640875SMark Prins * @param string $str_points 2881c640875SMark Prins * multi-line string of lat,lon,text triplets 28938a47c60SMark Prins * @return array multi-dimensional array of lat,lon,text triplets 29038a47c60SMark Prins */ 291a760825cSgithub-actions[bot] private function extractPoints(string $str_points): array 292a760825cSgithub-actions[bot] { 293a760825cSgithub-actions[bot] $point = []; 29457f8d5bbSMark Prins // preg_match_all('/^([+-]?[0-9].*?),\s*([+-]?[0-9].*?),(.*?),(.*?),(.*?),(.*)$/um', 29557f8d5bbSMark Prins // $str_points, $point, PREG_SET_ORDER); 2967a3f422cSMark Prins /* 29757f8d5bbSMark Prins * group 1: ([+-]?[0-9]+(?:\.[0-9]*)?) 29857f8d5bbSMark Prins * group 2: ([+-]?[0-9]+(?:\.[0-9]*)?) 29957f8d5bbSMark Prins * group 3: (.*?) 30057f8d5bbSMark Prins * group 4: (.*?) 30157f8d5bbSMark Prins * group 5: (.*?) 30257f8d5bbSMark Prins * group 6: (.*) 3037a3f422cSMark Prins */ 30457f8d5bbSMark Prins preg_match_all( 30557f8d5bbSMark Prins '/^([+-]?[0-9]+(?:\.[0-9]*)?),\s*([+-]?[0-9]+(?:\.[0-9]*)?),(.*?),(.*?),(.*?),(.*)$/um', 306a760825cSgithub-actions[bot] $str_points, 307a760825cSgithub-actions[bot] $point, 308a760825cSgithub-actions[bot] PREG_SET_ORDER 30957f8d5bbSMark Prins ); 310554f43b5SMark Prins // create poi array 311a760825cSgithub-actions[bot] $overlay = []; 31238a47c60SMark Prins foreach ($point as $pt) { 313a760825cSgithub-actions[bot] [$match, $lat, $lon, $angle, $opacity, $img, $text] = $pt; 31438a47c60SMark Prins $lat = is_numeric($lat) ? $lat : 0; 31538a47c60SMark Prins $lon = is_numeric($lon) ? $lon : 0; 31638a47c60SMark Prins $angle = is_numeric($angle) ? $angle : 0; 31738a47c60SMark Prins $opacity = is_numeric($opacity) ? $opacity : 0.8; 31887d958d4SMark Prins // TODO validate using exist & set up default img? 3191c640875SMark Prins $img = trim($img); 3201c640875SMark Prins $text = p_get_instructions($text); 3211c640875SMark Prins // dbg ( $text ); 3221c640875SMark Prins $text = p_render("xhtml", $text, $info); 3231c640875SMark Prins // dbg ( $text ); 3241c640875SMark Prins $text = addslashes(str_replace("\n", "", $text)); 325a760825cSgithub-actions[bot] $overlay [] = [$lat, $lon, $text, $angle, $opacity, $img]; 32638a47c60SMark Prins } 32738a47c60SMark Prins return $overlay; 32838a47c60SMark Prins } 329fcd79b50SMark Prins 330fcd79b50SMark Prins /** 33157f8d5bbSMark Prins * Create a Google maps static image url w/ the poi. 33257f8d5bbSMark Prins * 33357f8d5bbSMark Prins * @param array $gmap 33457f8d5bbSMark Prins * @param array $overlay 33557f8d5bbSMark Prins */ 336a760825cSgithub-actions[bot] private function getGoogle(array $gmap, array $overlay): string 337a760825cSgithub-actions[bot] { 33857f8d5bbSMark Prins $sUrl = $this->getConf('iconUrlOverload'); 33957f8d5bbSMark Prins if (!$sUrl) { 34057f8d5bbSMark Prins $sUrl = DOKU_URL; 34157f8d5bbSMark Prins } 34257f8d5bbSMark Prins switch ($gmap ['baselyr']) { 34357f8d5bbSMark Prins case 'google hybrid': 34457f8d5bbSMark Prins $maptype = 'hybrid'; 34557f8d5bbSMark Prins break; 34657f8d5bbSMark Prins case 'google sat': 34757f8d5bbSMark Prins $maptype = 'satellite'; 34857f8d5bbSMark Prins break; 34957f8d5bbSMark Prins case 'terrain': 35057f8d5bbSMark Prins case 'google relief': 35157f8d5bbSMark Prins $maptype = 'terrain'; 35257f8d5bbSMark Prins break; 35357f8d5bbSMark Prins case 'google road': 35457f8d5bbSMark Prins default: 35557f8d5bbSMark Prins $maptype = 'roadmap'; 35657f8d5bbSMark Prins break; 35757f8d5bbSMark Prins } 35857f8d5bbSMark Prins // TODO maybe use viewport / visible instead of center/zoom, 35957f8d5bbSMark Prins // see: https://developers.google.com/maps/documentation/staticmaps/index#Viewports 36057f8d5bbSMark Prins // http://maps.google.com/maps/api/staticmap?center=51.565690,5.456756&zoom=16&size=600x400&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/marker.png|label:1|51.565690,5.456756&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/marker-blue.png|51.566197,5.458966|label:2&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.567177,5.457909|label:3&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.566283,5.457330|label:4&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.565630,5.457695|label:5&sensor=false&format=png&maptype=roadmap 36157f8d5bbSMark Prins $imgUrl = "https://maps.googleapis.com/maps/api/staticmap?"; 36257f8d5bbSMark Prins $imgUrl .= "&size=" . str_replace("px", "", $gmap ['width']) . "x" 36357f8d5bbSMark Prins . str_replace("px", "", $gmap ['height']); 36457f8d5bbSMark Prins //if (!$this->getConf( 'autoZoomMap')) { // no need for center & zoom params } 36557f8d5bbSMark Prins $imgUrl .= "¢er=" . $gmap ['lat'] . "," . $gmap ['lon']; 36657f8d5bbSMark Prins // max is 21 (== building scale), but that's overkill.. 36757f8d5bbSMark Prins if ($gmap ['zoom'] > 17) { 36857f8d5bbSMark Prins $imgUrl .= "&zoom=17"; 36957f8d5bbSMark Prins } else { 37057f8d5bbSMark Prins $imgUrl .= "&zoom=" . $gmap ['zoom']; 37157f8d5bbSMark Prins } 372a760825cSgithub-actions[bot] if ($overlay !== []) { 37357f8d5bbSMark Prins $rowId = 0; 37457f8d5bbSMark Prins foreach ($overlay as $data) { 375a760825cSgithub-actions[bot] [$lat, $lon, $text, $angle, $opacity, $img] = $data; 37657f8d5bbSMark Prins $imgUrl .= "&markers=icon%3a" . $sUrl . "lib/plugins/openlayersmap/icons/" . $img . "%7c" 37757f8d5bbSMark Prins . $lat . "," . $lon . "%7clabel%3a" . ++$rowId; 37857f8d5bbSMark Prins } 37957f8d5bbSMark Prins } 38057f8d5bbSMark Prins $imgUrl .= "&format=png&maptype=" . $maptype; 38157f8d5bbSMark Prins global $conf; 38257f8d5bbSMark Prins $imgUrl .= "&language=" . $conf ['lang']; 38357f8d5bbSMark Prins if ($this->getConf('googleAPIkey')) { 38457f8d5bbSMark Prins $imgUrl .= "&key=" . $this->getConf('googleAPIkey'); 38557f8d5bbSMark Prins } 38657f8d5bbSMark Prins return $imgUrl; 38757f8d5bbSMark Prins } 38857f8d5bbSMark Prins 38957f8d5bbSMark Prins /** 390fcd79b50SMark Prins * Create a MapQuest static map API image url. 3911c640875SMark Prins * 392fcd79b50SMark Prins * @param array $gmap 393fcd79b50SMark Prins * @param array $overlay 394fcd79b50SMark Prins */ 395e72390dbSMark Prins /* 396fcd79b50SMark Prins private function _getMapQuest($gmap, $overlay) { 397787a5195SMark Prins $sUrl = $this->getConf ( 'iconUrlOverload' ); 398787a5195SMark Prins if (! $sUrl) { 399787a5195SMark Prins $sUrl = DOKU_URL; 400787a5195SMark Prins } 40187d958d4SMark Prins switch ($gmap ['baselyr']) { 40294c2e868SMark Prins case 'mapquest hybrid' : 403837eba2fSMark Prins $maptype = 'hyb'; 40487d958d4SMark Prins break; 40518edeaa5SMark Prins case 'mapquest sat' : 40644aba0bcSMark Prins // because sat coverage is very limited use 'hyb' instead of 'sat' so we don't get a blank map 40744aba0bcSMark Prins $maptype = 'hyb'; 40887d958d4SMark Prins break; 40994c2e868SMark Prins case 'mapquest road' : 41087d958d4SMark Prins default : 41187d958d4SMark Prins $maptype = 'map'; 41287d958d4SMark Prins break; 41387d958d4SMark Prins } 414004ad4e2SMark Prins $imgUrl = "http://open.mapquestapi.com/staticmap/v4/getmap?declutter=true&"; 41544aba0bcSMark Prins if (count ( $overlay ) < 1) { 416787a5195SMark Prins $imgUrl .= "?center=" . $gmap ['lat'] . "," . $gmap ['lon']; 417787a5195SMark Prins // max level for mapquest is 16 418fcd79b50SMark Prins if ($gmap ['zoom'] > 16) { 419fcd79b50SMark Prins $imgUrl .= "&zoom=16"; 420fcd79b50SMark Prins } else { 421fcd79b50SMark Prins $imgUrl .= "&zoom=" . $gmap ['zoom']; 422fcd79b50SMark Prins } 42344aba0bcSMark Prins } 42444aba0bcSMark Prins // use bestfit instead of center/zoom, needs upperleft/lowerright corners 42557f8d5bbSMark Prins // $bbox=$this->calcBBOX($overlay, $gmap['lat'], $gmap['lon']); 42644aba0bcSMark Prins // $imgUrl .= "bestfit=".$bbox['minlat'].",".$bbox['maxlon'].",".$bbox['maxlat'].",".$bbox['minlon']; 42744aba0bcSMark Prins 42857f8d5bbSMark Prins // TODO declutter option works well for square maps but not for rectangular, maybe compensate for that 42957f8d5bbSMark Prins // or compensate the mbr.. 43057f8d5bbSMark Prins 43144aba0bcSMark Prins $imgUrl .= "&size=" . str_replace ( "px", "", $gmap ['width'] ) . "," . str_replace ("px","",$gmap['height']); 43244aba0bcSMark Prins 433fcd79b50SMark Prins // TODO mapquest allows using one image url with a multiplier $NUMBER eg: 434fcd79b50SMark Prins // $NUMBER = 2 43557f8d5bbSMark Prins // $imgUrl .= DOKU_URL."/".DOKU_PLUGIN."/".getPluginName()."/icons/".$img.",$NUMBER,C," 43657f8d5bbSMark Prins // .$lat1.",".$lon1.",0,0,0,0,C,".$lat2.",".$lon2.",0,0,0,0"; 437fcd79b50SMark Prins if (! empty ( $overlay )) { 438fcd79b50SMark Prins $imgUrl .= "&xis="; 439fcd79b50SMark Prins foreach ( $overlay as $data ) { 440fcd79b50SMark Prins list ( $lat, $lon, $text, $angle, $opacity, $img ) = $data; 44144aba0bcSMark Prins // $imgUrl .= $sUrl."lib/plugins/openlayersmap/icons/".$img.",1,C,".$lat.",".$lon.",0,0,0,0,"; 44244aba0bcSMark Prins $imgUrl .= $sUrl . "lib/plugins/openlayersmap/icons/" . $img . ",1,C," . $lat . "," . $lon . ","; 443fcd79b50SMark Prins } 444fcd79b50SMark Prins $imgUrl = substr ( $imgUrl, 0, - 1 ); 445fcd79b50SMark Prins } 44687d958d4SMark Prins $imgUrl .= "&imageType=png&type=" . $maptype; 447d974ea02SMark Prins $imgUrl .= "&key=".$this->getConf ( 'mapquestAPIKey' ); 448787a5195SMark Prins return $imgUrl; 449787a5195SMark Prins } 450e72390dbSMark Prins */ 451cc74a83cSMark Prins 4526e633dd6SMark Prins /** 45387d958d4SMark Prins * Create a static OSM map image url w/ the poi from http://staticmap.openstreetmap.de (staticMapLite) 454fcf646d2SMark Prins * use http://staticmap.openstreetmap.de "staticMapLite" or a local version 4551c640875SMark Prins * 45687d958d4SMark Prins * @param array $gmap 45787d958d4SMark Prins * @param array $overlay 458fcf646d2SMark Prins * 45957f8d5bbSMark Prins * @return false|string 460fcf646d2SMark Prins * @todo implementation for http://ojw.dev.openstreetmap.org/StaticMapDev/ 46187d958d4SMark Prins */ 462a760825cSgithub-actions[bot] private function getStaticOSM(array $gmap, array $overlay) 463a760825cSgithub-actions[bot] { 464fcf646d2SMark Prins global $conf; 465372f1508SMark Prins 466751c8ef2SMark Prins if ($this->getConf('optionStaticMapGenerator') === 'local') { 467d974ea02SMark Prins // using local basemap composer 468a760825cSgithub-actions[bot] if (($myMap = plugin_load('helper', 'openlayersmap_staticmap')) === null) { 469*f204b8caSMark Prins Logger::error( 470*f204b8caSMark Prins 'openlayersmap_staticmap plugin is not available for use.', 471*f204b8caSMark Prins $myMap 47257f8d5bbSMark Prins ); 47353bfe4a3SMark Prins } 474a760825cSgithub-actions[bot] if (($geophp = plugin_load('helper', 'geophp')) === null) { 475*f204b8caSMark Prins Logger::debug('geophp plugin is not available for use.', $geophp); 47653bfe4a3SMark Prins } 47757f8d5bbSMark Prins $size = str_replace("px", "", $gmap ['width']) . "x" 47857f8d5bbSMark Prins . str_replace("px", "", $gmap ['height']); 47953bfe4a3SMark Prins 480a760825cSgithub-actions[bot] $markers = []; 481a760825cSgithub-actions[bot] if ($overlay !== []) { 48253bfe4a3SMark Prins foreach ($overlay as $data) { 483a760825cSgithub-actions[bot] [$lat, $lon, $text, $angle, $opacity, $img] = $data; 484751c8ef2SMark Prins $iconStyle = substr($img, 0, -4); 485a760825cSgithub-actions[bot] $markers [] = ['lat' => $lat, 'lon' => $lon, 'type' => $iconStyle]; 48653bfe4a3SMark Prins } 487372f1508SMark Prins } 488372f1508SMark Prins 489d2f4772aSMark Prins $apikey = ''; 49018edeaa5SMark Prins switch ($gmap ['baselyr']) { 49118edeaa5SMark Prins case 'mapnik': 492fcf646d2SMark Prins case 'openstreetmap': 493fcf646d2SMark Prins $maptype = 'openstreetmap'; 49418edeaa5SMark Prins break; 495fcf646d2SMark Prins case 'transport': 496fcf646d2SMark Prins $maptype = 'transport'; 497b63742deSMark Prins $apikey = '?apikey=' . $this->getConf('tfApiKey'); 498fcf646d2SMark Prins break; 499fcf646d2SMark Prins case 'landscape': 500fcf646d2SMark Prins $maptype = 'landscape'; 501b63742deSMark Prins $apikey = '?apikey=' . $this->getConf('tfApiKey'); 502d2f4772aSMark Prins break; 503d2f4772aSMark Prins case 'outdoors': 504d2f4772aSMark Prins $maptype = 'outdoors'; 505b63742deSMark Prins $apikey = '?apikey=' . $this->getConf('tfApiKey'); 50618edeaa5SMark Prins break; 50718edeaa5SMark Prins case 'cycle map': 50818edeaa5SMark Prins $maptype = 'cycle'; 509b63742deSMark Prins $apikey = '?apikey=' . $this->getConf('tfApiKey'); 510372f1508SMark Prins break; 511fcf646d2SMark Prins case 'hike and bike map': 512fcf646d2SMark Prins $maptype = 'hikeandbike'; 513fcf646d2SMark Prins break; 514fcf646d2SMark Prins case 'mapquest hybrid': 515fcf646d2SMark Prins case 'mapquest road': 516fcf646d2SMark Prins case 'mapquest sat': 517fcf646d2SMark Prins $maptype = 'mapquest'; 518fcf646d2SMark Prins break; 51918edeaa5SMark Prins default: 52018edeaa5SMark Prins $maptype = ''; 52118edeaa5SMark Prins break; 52218edeaa5SMark Prins } 523d974ea02SMark Prins 52457f8d5bbSMark Prins $result = $myMap->getMap( 525a760825cSgithub-actions[bot] $gmap ['lat'], 526a760825cSgithub-actions[bot] $gmap ['lon'], 527a760825cSgithub-actions[bot] $gmap ['zoom'], 528a760825cSgithub-actions[bot] $size, 529a760825cSgithub-actions[bot] $maptype, 530a760825cSgithub-actions[bot] $markers, 531a760825cSgithub-actions[bot] $gmap ['gpxfile'], 532a760825cSgithub-actions[bot] $gmap ['kmlfile'], 533a760825cSgithub-actions[bot] $gmap ['geojsonfile'], 534a760825cSgithub-actions[bot] $apikey 53557f8d5bbSMark Prins ); 536d974ea02SMark Prins } else { 537d974ea02SMark Prins // using external basemap composer 538d974ea02SMark Prins 53957f8d5bbSMark Prins // https://staticmap.openstreetmap.de/staticmap.php?center=47.000622235634,10 54057f8d5bbSMark Prins //.117187497601&zoom=5&size=500x350 54157f8d5bbSMark Prins // &markers=48.999812532766,8.3593749976708,lightblue1|43.154850037315,17.499999997306, 54257f8d5bbSMark Prins // lightblue1|49.487527053077,10.820312497573,ltblu-pushpin|47.951071133739,15.917968747369, 54357f8d5bbSMark Prins // ol-marker|47.921629720114,18.027343747285,ol-marker-gold|47.951071133739,19.257812497236, 54457f8d5bbSMark Prins // ol-marker-blue|47.180141361692,19.257812497236,ol-marker-green 54557f8d5bbSMark Prins $imgUrl = "https://staticmap.openstreetmap.de/staticmap.php"; 546d974ea02SMark Prins $imgUrl .= "?center=" . $gmap ['lat'] . "," . $gmap ['lon']; 54757f8d5bbSMark Prins $imgUrl .= "&size=" . str_replace("px", "", $gmap ['width']) . "x" 54857f8d5bbSMark Prins . str_replace("px", "", $gmap ['height']); 549d974ea02SMark Prins 550d974ea02SMark Prins if ($gmap ['zoom'] > 16) { 551d974ea02SMark Prins // actually this could even be 18, but that seems overkill 552d974ea02SMark Prins $imgUrl .= "&zoom=16"; 553d974ea02SMark Prins } else { 554d974ea02SMark Prins $imgUrl .= "&zoom=" . $gmap ['zoom']; 555d974ea02SMark Prins } 55618edeaa5SMark Prins 557a760825cSgithub-actions[bot] if ($overlay !== []) { 55887d958d4SMark Prins $rowId = 0; 55987d958d4SMark Prins $imgUrl .= "&markers="; 56087d958d4SMark Prins foreach ($overlay as $data) { 561a760825cSgithub-actions[bot] [$lat, $lon, $text, $angle, $opacity, $img] = $data; 56287d958d4SMark Prins $rowId++; 56353bfe4a3SMark Prins $iconStyle = "lightblue$rowId"; 56487d958d4SMark Prins $imgUrl .= "$lat,$lon,$iconStyle%7c"; 56587d958d4SMark Prins } 56687d958d4SMark Prins $imgUrl = substr($imgUrl, 0, -3); 56787d958d4SMark Prins } 56887d958d4SMark Prins 569f4b9bdacSMark Prins $result = $imgUrl; 570628e43ccSMark Prins } 571628e43ccSMark Prins return $result; 572628e43ccSMark Prins } 573628e43ccSMark Prins 57444aba0bcSMark Prins /** 57557f8d5bbSMark Prins * Create a Bing maps static image url w/ the poi. 57657f8d5bbSMark Prins * 57757f8d5bbSMark Prins * @param array $gmap 57857f8d5bbSMark Prins * @param array $overlay 57957f8d5bbSMark Prins */ 580a760825cSgithub-actions[bot] private function getBing(array $gmap, array $overlay): string 581a760825cSgithub-actions[bot] { 58257f8d5bbSMark Prins switch ($gmap ['baselyr']) { 58357f8d5bbSMark Prins case 've hybrid': 58457f8d5bbSMark Prins case 'bing hybrid': 58557f8d5bbSMark Prins $maptype = 'AerialWithLabels'; 58657f8d5bbSMark Prins break; 58757f8d5bbSMark Prins case 've sat': 58857f8d5bbSMark Prins case 'bing sat': 58957f8d5bbSMark Prins $maptype = 'Aerial'; 59057f8d5bbSMark Prins break; 59157f8d5bbSMark Prins case 've normal': 59257f8d5bbSMark Prins case 've road': 59357f8d5bbSMark Prins case 've': 59457f8d5bbSMark Prins case 'bing road': 59557f8d5bbSMark Prins default: 59657f8d5bbSMark Prins $maptype = 'Road'; 59757f8d5bbSMark Prins break; 59857f8d5bbSMark Prins } 59957f8d5bbSMark Prins $imgUrl = "https://dev.virtualearth.net/REST/v1/Imagery/Map/" . $maptype;// . "/"; 60057f8d5bbSMark Prins if ($this->getConf('autoZoomMap')) { 60157f8d5bbSMark Prins $bbox = $this->calcBBOX($overlay, $gmap ['lat'], $gmap ['lon']); 60257f8d5bbSMark Prins //$imgUrl .= "?ma=" . $bbox ['minlat'] . "," . $bbox ['minlon'] . "," 60357f8d5bbSMark Prins // . $bbox ['maxlat'] . "," . $bbox ['maxlon']; 60457f8d5bbSMark Prins $imgUrl .= "?ma=" . $bbox ['minlat'] . "%2C" . $bbox ['minlon'] . "%2C" . $bbox ['maxlat'] 60557f8d5bbSMark Prins . "%2C" . $bbox ['maxlon']; 60657f8d5bbSMark Prins $imgUrl .= "&dcl=1"; 60757f8d5bbSMark Prins } 60857f8d5bbSMark Prins if (strpos($imgUrl, "?") === false) 60957f8d5bbSMark Prins $imgUrl .= "?"; 61057f8d5bbSMark Prins 61157f8d5bbSMark Prins //$imgUrl .= "&ms=" . str_replace ( "px", "", $gmap ['width'] ) . "," 61257f8d5bbSMark Prins // . str_replace ( "px", "", $gmap ['height'] ); 61357f8d5bbSMark Prins $imgUrl .= "&ms=" . str_replace("px", "", $gmap ['width']) . "%2C" 61457f8d5bbSMark Prins . str_replace("px", "", $gmap ['height']); 61557f8d5bbSMark Prins $imgUrl .= "&key=" . $this->getConf('bingAPIKey'); 616a760825cSgithub-actions[bot] if ($overlay !== []) { 61757f8d5bbSMark Prins $rowId = 0; 61857f8d5bbSMark Prins foreach ($overlay as $data) { 619a760825cSgithub-actions[bot] [$lat, $lon, $text, $angle, $opacity, $img] = $data; 62057f8d5bbSMark Prins // TODO icon style lookup, see: http://msdn.microsoft.com/en-us/library/ff701719.aspx for iconStyle 62157f8d5bbSMark Prins $iconStyle = 32; 62257f8d5bbSMark Prins $rowId++; 62357f8d5bbSMark Prins // NOTE: the max number of pushpins is 18! or we have to use POST 62457f8d5bbSMark Prins // (http://msdn.microsoft.com/en-us/library/ff701724.aspx) 62557f8d5bbSMark Prins if ($rowId == 18) { 62657f8d5bbSMark Prins break; 62757f8d5bbSMark Prins } 62857f8d5bbSMark Prins //$imgUrl .= "&pp=$lat,$lon;$iconStyle;$rowId"; 62957f8d5bbSMark Prins $imgUrl .= "&pp=$lat%2C$lon%3B$iconStyle%3B$rowId"; 63057f8d5bbSMark Prins } 63157f8d5bbSMark Prins } 63257f8d5bbSMark Prins global $conf; 63357f8d5bbSMark Prins $imgUrl .= "&fmt=png"; 63457f8d5bbSMark Prins $imgUrl .= "&c=" . $conf ['lang']; 63557f8d5bbSMark Prins return $imgUrl; 63657f8d5bbSMark Prins } 63757f8d5bbSMark Prins 63857f8d5bbSMark Prins /** 63944aba0bcSMark Prins * Calculate the minimum bbox for a start location + poi. 64044aba0bcSMark Prins * 6411c640875SMark Prins * @param array $overlay 6421c640875SMark Prins * multi-dimensional array of array($lat, $lon, $text, $angle, $opacity, $img) 6431c640875SMark Prins * @param float $lat 6441c640875SMark Prins * latitude for map center 6451c640875SMark Prins * @param float $lon 6461c640875SMark Prins * longitude for map center 64757f8d5bbSMark Prins * @return array :float array describing the mbr and center point 64844aba0bcSMark Prins */ 649a760825cSgithub-actions[bot] private function calcBBOX(array $overlay, float $lat, float $lon): array 650a760825cSgithub-actions[bot] { 651a760825cSgithub-actions[bot] $lats = [$lat]; 652a760825cSgithub-actions[bot] $lons = [$lon]; 653837eba2fSMark Prins foreach ($overlay as $data) { 654a760825cSgithub-actions[bot] [$lat, $lon, $text, $angle, $opacity, $img] = $data; 655837eba2fSMark Prins $lats [] = $lat; 656837eba2fSMark Prins $lons [] = $lon; 657837eba2fSMark Prins } 658837eba2fSMark Prins sort($lats); 659837eba2fSMark Prins sort($lons); 66044aba0bcSMark Prins // TODO: make edge/wrap around cases work 66144aba0bcSMark Prins $centerlat = $lats [0] + ($lats [count($lats) - 1] - $lats [0]); 66244aba0bcSMark Prins $centerlon = $lons [0] + ($lons [count($lats) - 1] - $lons [0]); 663a760825cSgithub-actions[bot] return ['minlat' => $lats [0], 'minlon' => $lons [0], 'maxlat' => $lats [count($lats) - 1], 'maxlon' => $lons [count($lats) - 1], 'centerlat' => $centerlat, 'centerlon' => $centerlon]; 66487d958d4SMark Prins } 665cc74a83cSMark Prins 666cc74a83cSMark Prins /** 66757f8d5bbSMark Prins * convert latitude in decimal degrees to DMS+hemisphere. 6681c640875SMark Prins * 66957f8d5bbSMark Prins * @param float $decimaldegrees 67057f8d5bbSMark Prins * @todo move this into a shared library 671cc74a83cSMark Prins */ 672a760825cSgithub-actions[bot] private function convertLat(float $decimaldegrees): string 673a760825cSgithub-actions[bot] { 67457f8d5bbSMark Prins if (strpos($decimaldegrees, '-') !== false) { 67557f8d5bbSMark Prins $latPos = "S"; 67657f8d5bbSMark Prins } else { 67757f8d5bbSMark Prins $latPos = "N"; 67857f8d5bbSMark Prins } 67957f8d5bbSMark Prins $dms = $this->convertDDtoDMS(abs($decimaldegrees)); 68057f8d5bbSMark Prins return hsc($dms . $latPos); 681cc74a83cSMark Prins } 6828c4eb2fdSMark Prins 6838c4eb2fdSMark Prins /** 6848c4eb2fdSMark Prins * Convert decimal degrees to degrees, minutes, seconds format 6858c4eb2fdSMark Prins * 6868c4eb2fdSMark Prins * @param float $decimaldegrees 6878c4eb2fdSMark Prins * @return string dms 68857f8d5bbSMark Prins * @todo move this into a shared library 6898c4eb2fdSMark Prins */ 690a760825cSgithub-actions[bot] private function convertDDtoDMS(float $decimaldegrees): string 691a760825cSgithub-actions[bot] { 6928c4eb2fdSMark Prins $dms = floor($decimaldegrees); 6938c4eb2fdSMark Prins $secs = ($decimaldegrees - $dms) * 3600; 6948c4eb2fdSMark Prins $min = floor($secs / 60); 6958c4eb2fdSMark Prins $sec = round($secs - ($min * 60), 3); 6968c4eb2fdSMark Prins $dms .= 'º' . $min . '\'' . $sec . '"'; 6978c4eb2fdSMark Prins return $dms; 6988c4eb2fdSMark Prins } 6998c4eb2fdSMark Prins 7008c4eb2fdSMark Prins /** 7018c4eb2fdSMark Prins * convert longitude in decimal degrees to DMS+hemisphere. 7028c4eb2fdSMark Prins * 7038c4eb2fdSMark Prins * @param float $decimaldegrees 70457f8d5bbSMark Prins * @todo move this into a shared library 7058c4eb2fdSMark Prins */ 706a760825cSgithub-actions[bot] private function convertLon(float $decimaldegrees): string 707a760825cSgithub-actions[bot] { 7088c4eb2fdSMark Prins if (strpos($decimaldegrees, '-') !== false) { 7098c4eb2fdSMark Prins $lonPos = "W"; 7108c4eb2fdSMark Prins } else { 7118c4eb2fdSMark Prins $lonPos = "E"; 7128c4eb2fdSMark Prins } 71357f8d5bbSMark Prins $dms = $this->convertDDtoDMS(abs($decimaldegrees)); 7148c4eb2fdSMark Prins return hsc($dms . $lonPos); 7158c4eb2fdSMark Prins } 71657f8d5bbSMark Prins 71757f8d5bbSMark Prins /** 71857f8d5bbSMark Prins * Figures out the base filename of a media path. 71957f8d5bbSMark Prins * 72057f8d5bbSMark Prins * @param string $mediaLink 72157f8d5bbSMark Prins */ 722a760825cSgithub-actions[bot] private function getFileName(string $mediaLink): string 723a760825cSgithub-actions[bot] { 72457f8d5bbSMark Prins $mediaLink = str_replace('[[', '', $mediaLink); 72557f8d5bbSMark Prins $mediaLink = str_replace(']]', '', $mediaLink); 72657f8d5bbSMark Prins $mediaLink = substr($mediaLink, 0, -4); 727a760825cSgithub-actions[bot] 72857f8d5bbSMark Prins $parts = explode(':', $mediaLink); 72957f8d5bbSMark Prins $mediaLink = end($parts); 73057f8d5bbSMark Prins return str_replace('_', ' ', $mediaLink); 73157f8d5bbSMark Prins } 73257f8d5bbSMark Prins 73357f8d5bbSMark Prins /** 73457f8d5bbSMark Prins * 73557f8d5bbSMark Prins * @see DokuWiki_Syntax_Plugin::render() 73657f8d5bbSMark Prins */ 737a760825cSgithub-actions[bot] public function render($format, Doku_Renderer $renderer, $data): bool 738a760825cSgithub-actions[bot] { 73957f8d5bbSMark Prins // set to true after external scripts tags are written 74057f8d5bbSMark Prins static $initialised = false; 74157f8d5bbSMark Prins // incremented for each map tag in the page source so we can keep track of each map in this page 74257f8d5bbSMark Prins static $mapnumber = 0; 74357f8d5bbSMark Prins 744a760825cSgithub-actions[bot] [$mapid, $param, $mainLat, $mainLon, $poitable, $poitabledesc, $staticImgUrl, $_firstimage] = $data; 74557f8d5bbSMark Prins 746751c8ef2SMark Prins if ($format === 'xhtml') { 74757f8d5bbSMark Prins $olscript = ''; 748751c8ef2SMark Prins $stadiaEnable = $this->getConf('enableStadia'); 74957f8d5bbSMark Prins $osmEnable = $this->getConf('enableOSM'); 75057f8d5bbSMark Prins $enableBing = $this->getConf('enableBing'); 75157f8d5bbSMark Prins 75257f8d5bbSMark Prins $scriptEnable = ''; 75357f8d5bbSMark Prins if (!$initialised) { 75457f8d5bbSMark Prins $initialised = true; 7557390889dSMark Prins // render necessary script tags only once 756660554e1SMark Prins $olscript = '<script defer="defer" src="' . DOKU_BASE . 'lib/plugins/openlayersmap/ol/ol.js"></script> 757660554e1SMark Prins<script defer="defer" src="' . DOKU_BASE . 'lib/plugins/openlayersmap/ol/ol-layerswitcher.js"></script>'; 75857f8d5bbSMark Prins 75957f8d5bbSMark Prins $scriptEnable = '<script defer="defer" src="data:text/javascript;base64,'; 7607390889dSMark Prins $scriptSrc = $olscript ? 'const olEnable=true;' : 'const olEnable=false;'; 7617390889dSMark Prins $scriptSrc .= 'const osmEnable=' . ($osmEnable ? 'true' : 'false') . ';'; 762751c8ef2SMark Prins $scriptSrc .= 'const stadiaEnable=' . ($stadiaEnable ? 'true' : 'false') . ';'; 7637390889dSMark Prins $scriptSrc .= 'const bEnable=' . ($enableBing ? 'true' : 'false') . ';'; 7647390889dSMark Prins $scriptSrc .= 'const bApiKey="' . $this->getConf('bingAPIKey') . '";'; 7657390889dSMark Prins $scriptSrc .= 'const tfApiKey="' . $this->getConf('tfApiKey') . '";'; 7667390889dSMark Prins $scriptSrc .= 'const gApiKey="' . $this->getConf('googleAPIkey') . '";'; 7677390889dSMark Prins $scriptSrc .= 'olMapData = []; let olMaps = {}; let olMapOverlays = {};'; 76857f8d5bbSMark Prins $scriptEnable .= base64_encode($scriptSrc); 76957f8d5bbSMark Prins $scriptEnable .= '"></script>'; 77057f8d5bbSMark Prins } 7717390889dSMark Prins $renderer->doc .= "$olscript\n$scriptEnable"; 77257f8d5bbSMark Prins $renderer->doc .= '<div class="olMapHelp">' . $this->locale_xhtml("help") . '</div>'; 77357f8d5bbSMark Prins if ($this->getConf('enableA11y')) { 77457f8d5bbSMark Prins $renderer->doc .= '<div id="' . $mapid . '-static" class="olStaticMap">' 77557f8d5bbSMark Prins . p_render($format, p_get_instructions($staticImgUrl), $info) . '</div>'; 77657f8d5bbSMark Prins } 77757f8d5bbSMark Prins $renderer->doc .= '<div id="' . $mapid . '-clearer" class="clearer"><p> </p></div>'; 77857f8d5bbSMark Prins if ($this->getConf('enableA11y')) { 77957f8d5bbSMark Prins // render a table of the POI for the print and a11y presentation, it is hidden using javascript 7807390889dSMark Prins $renderer->doc .= ' 7813f760703SMark Prins <div id="' . $mapid . '-table-span" class="olPOItableSpan"> 7823f760703SMark Prins <table id="' . $mapid . '-table" class="olPOItable"> 78357f8d5bbSMark Prins <caption class="olPOITblCaption">' . $this->getLang('olmapPOItitle') . '</caption> 78457f8d5bbSMark Prins <thead class="olPOITblHeader"> 78557f8d5bbSMark Prins <tr> 78657f8d5bbSMark Prins <th class="rowId" scope="col">id</th> 78757f8d5bbSMark Prins <th class="icon" scope="col">' . $this->getLang('olmapPOIicon') . '</th> 78857f8d5bbSMark Prins <th class="lat" scope="col" title="' . $this->getLang('olmapPOIlatTitle') . '">' 78957f8d5bbSMark Prins . $this->getLang('olmapPOIlat') . '</th> 79057f8d5bbSMark Prins <th class="lon" scope="col" title="' . $this->getLang('olmapPOIlonTitle') . '">' 79157f8d5bbSMark Prins . $this->getLang('olmapPOIlon') . '</th> 79257f8d5bbSMark Prins <th class="txt" scope="col">' . $this->getLang('olmapPOItxt') . '</th> 79357f8d5bbSMark Prins </tr> 79457f8d5bbSMark Prins </thead>'; 79557f8d5bbSMark Prins if ($poitabledesc != '') { 79657f8d5bbSMark Prins $renderer->doc .= '<tfoot class="olPOITblFooter"><tr><td colspan="5">' . $poitabledesc 79757f8d5bbSMark Prins . '</td></tr></tfoot>'; 79857f8d5bbSMark Prins } 79957f8d5bbSMark Prins $renderer->doc .= '<tbody class="olPOITblBody">' . $poitable . '</tbody> 8007390889dSMark Prins </table> 8017390889dSMark Prins </div>'; 8027390889dSMark Prins $renderer->doc .= "\n"; 80357f8d5bbSMark Prins } 80457f8d5bbSMark Prins // render inline mapscript parts 80557f8d5bbSMark Prins $renderer->doc .= '<script defer="defer" src="data:text/javascript;base64,'; 80657f8d5bbSMark Prins $renderer->doc .= base64_encode("olMapData[$mapnumber] = $param"); 80757f8d5bbSMark Prins $renderer->doc .= '"></script>'; 80857f8d5bbSMark Prins $mapnumber++; 80957f8d5bbSMark Prins return true; 810751c8ef2SMark Prins } elseif ($format === 'metadata') { 81157f8d5bbSMark Prins if (!(($this->dflt ['lat'] == $mainLat) && ($this->dflt ['lon'] == $mainLon))) { 81257f8d5bbSMark Prins // render geo metadata, unless they are the default 81357f8d5bbSMark Prins $renderer->meta ['geo'] ['lat'] = $mainLat; 81457f8d5bbSMark Prins $renderer->meta ['geo'] ['lon'] = $mainLon; 815a760825cSgithub-actions[bot] if (($geophp = plugin_load('helper', 'geophp')) !== null) { 81657f8d5bbSMark Prins // if we have the geoPHP helper, add the geohash 817*f204b8caSMark Prins try { 818*f204b8caSMark Prins $renderer->meta['geo']['geohash'] = (new Point($mainLon, $mainLat))->out('geohash'); 819*f204b8caSMark Prins } catch (Exception $e) { 820*f204b8caSMark Prins Logger::error("Failed to create geohash for: $mainLat, $mainLon"); 821*f204b8caSMark Prins } 82257f8d5bbSMark Prins } 82357f8d5bbSMark Prins } 82457f8d5bbSMark Prins 82557f8d5bbSMark Prins if (($this->getConf('enableA11y')) && (!empty($_firstimage))) { 82657f8d5bbSMark Prins // add map local image into relation/firstimage if not already filled and when it is a local image 82757f8d5bbSMark Prins 82857f8d5bbSMark Prins global $ID; 82957f8d5bbSMark Prins $rel = p_get_metadata($ID, 'relation', METADATA_RENDER_USING_CACHE); 83068188742SMark Prins // $img = $rel ['firstimage']; 83168188742SMark Prins if (empty($rel ['firstimage']) /* || $img == $_firstimage*/) { 832*f204b8caSMark Prins //Logger::debug( 833*f204b8caSMark Prins // 'olmap::render#rendering image relation metadata for _firstimage as $img was empty or same.', 834*f204b8caSMark Prins // $_firstimage); 835*f204b8caSMark Prins 83657f8d5bbSMark Prins // This seems to never work; the firstimage entry in the .meta file is empty 83757f8d5bbSMark Prins // $renderer->meta['relation']['firstimage'] = $_firstimage; 83857f8d5bbSMark Prins // ... and neither does this; the firstimage entry in the .meta file is empty 83957f8d5bbSMark Prins // $relation = array('relation'=>array('firstimage'=>$_firstimage)); 84057f8d5bbSMark Prins // p_set_metadata($ID, $relation, false, false); 84157f8d5bbSMark Prins // ... this works 84257f8d5bbSMark Prins $renderer->internalmedia($_firstimage, $poitabledesc); 84357f8d5bbSMark Prins } 84457f8d5bbSMark Prins } 84557f8d5bbSMark Prins return true; 84657f8d5bbSMark Prins } 84757f8d5bbSMark Prins return false; 84857f8d5bbSMark Prins } 84938a47c60SMark Prins} 850