xref: /plugin/openlayersmap/StaticMap.php (revision e5840fc54fe591276a2e590c997c66d22de0b6c8)
1628e43ccSMark Prins<?php
2628e43ccSMark Prins/*
3c878d083SMark Prins * Copyright (c) 2012-2018 Mark C. Prins <mprins@users.sf.net>
4628e43ccSMark Prins *
5f4b9bdacSMark Prins * In part based on staticMapLite 0.03 available at http://staticmaplite.svn.sourceforge.net/viewvc/staticmaplite/
6628e43ccSMark Prins *
7628e43ccSMark Prins * Copyright (c) 2009 Gerhard Koch <gerhard.koch AT ymail.com>
8628e43ccSMark Prins *
9628e43ccSMark Prins * Licensed under the Apache License, Version 2.0 (the "License");
10628e43ccSMark Prins * you may not use this file except in compliance with the License.
11628e43ccSMark Prins * You may obtain a copy of the License at
12628e43ccSMark Prins *
13628e43ccSMark Prins *     http://www.apache.org/licenses/LICENSE-2.0
14628e43ccSMark Prins *
15628e43ccSMark Prins * Unless required by applicable law or agreed to in writing, software
16628e43ccSMark Prins * distributed under the License is distributed on an "AS IS" BASIS,
17628e43ccSMark Prins * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18628e43ccSMark Prins * See the License for the specific language governing permissions and
19628e43ccSMark Prins * limitations under the License.
20628e43ccSMark Prins */
21f4b9bdacSMark Prinsinclude_once (realpath ( dirname ( __FILE__ ) ) . '/../geophp/geoPHP/geoPHP.inc');
22628e43ccSMark Prins/**
23ab8cbd2bSMark Prins *
24628e43ccSMark Prins * @author Mark C. Prins <mprins@users.sf.net>
25628e43ccSMark Prins * @author Gerhard Koch <gerhard.koch AT ymail.com>
26628e43ccSMark Prins *
27628e43ccSMark Prins */
28628e43ccSMark Prinsclass StaticMap {
29ab8cbd2bSMark Prins	// this should probably not be changed
30628e43ccSMark Prins	protected $tileSize = 256;
31628e43ccSMark Prins
32628e43ccSMark Prins	// the final output
33628e43ccSMark Prins	var $doc = '';
34628e43ccSMark Prins
35628e43ccSMark Prins	protected $tileInfo = array (
36628e43ccSMark Prins			// OSM sources
37628e43ccSMark Prins			'openstreetmap' => array (
38628e43ccSMark Prins					'txt' => '(c) OpenStreetMap CC-BY-SA',
39628e43ccSMark Prins					'logo' => 'osm_logo.png',
40ab8cbd2bSMark Prins					'url' => 'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png'
41ab8cbd2bSMark Prins			),
42628e43ccSMark Prins			// OCM sources
43628e43ccSMark Prins			'cycle' => array (
44628e43ccSMark Prins					'txt' => 'OpenCycleMap tiles',
45628e43ccSMark Prins					'logo' => 'cycle_logo.png',
46c878d083SMark Prins					'url' => 'https://tile.thunderforest.com/cycle/{Z}/{X}/{Y}.png?apikey='
47ab8cbd2bSMark Prins			),
48628e43ccSMark Prins			'transport' => array (
49628e43ccSMark Prins					'txt' => 'OpenCycleMap tiles',
50628e43ccSMark Prins					'logo' => 'cycle_logo.png',
51c878d083SMark Prins					'url' => 'https://tile.thunderforest.com/transport/{Z}/{X}/{Y}.png?apikey='
52ab8cbd2bSMark Prins			),
53628e43ccSMark Prins			'landscape' => array (
54628e43ccSMark Prins					'txt' => 'OpenCycleMap tiles',
55628e43ccSMark Prins					'logo' => 'cycle_logo.png',
56c878d083SMark Prins					'url' => 'https://tile.thunderforest.com/landscape/{Z}/{X}/{Y}.png?apikey='
575c603532SMark Prins			),
585c603532SMark Prins			'outdoors' => array (
595c603532SMark Prins					'txt' => 'OpenCycleMap tiles',
605c603532SMark Prins					'logo' => 'cycle_logo.png',
61c878d083SMark Prins					'url' => 'https://tile.thunderforest.com/outdoors/{Z}/{X}/{Y}.png?apikey='
62ab8cbd2bSMark Prins			),
63e72390dbSMark Prins			'toner-lite' => array (
645c603532SMark Prins					'txt' => 'Stamen tiles',
65e72390dbSMark Prins					'logo' => 'stamen.png',
66e72390dbSMark Prins					'url' => 'http://tile.stamen.com/toner-lite/{Z}/{X}/{Y}.png'
67e72390dbSMark Prins			),
68e72390dbSMark Prins			'terrain' => array (
695c603532SMark Prins					'txt' => 'Stamen tiles',
70e72390dbSMark Prins					'logo' => 'stamen.png',
71e72390dbSMark Prins					'url' => 'http://tile.stamen.com/terrain/{Z}/{X}/{Y}.png'
72*e5840fc5SMark Prins			)
73*e5840fc5SMark Prins			//,
74628e43ccSMark Prins			// 'piste'=>array(
75628e43ccSMark Prins			// 'txt'=>'OpenPisteMap tiles',
76628e43ccSMark Prins			// 'logo'=>'piste_logo.png',
77628e43ccSMark Prins			// 'url'=>''),
78628e43ccSMark Prins			// 'sea'=>array(
79628e43ccSMark Prins			// 'txt'=>'OpenSeaMap tiles',
80628e43ccSMark Prins			// 'logo'=>'sea_logo.png',
81628e43ccSMark Prins			// 'url'=>''),
82e72390dbSMark Prins			// H&B sources
83*e5840fc5SMark Prins//			'hikeandbike' => array (
84*e5840fc5SMark Prins//					'txt' => 'Hike & Bike Map',
85*e5840fc5SMark Prins//					'logo' => 'hnb_logo.png',
86*e5840fc5SMark Prins//					//'url' => 'http://toolserver.org/tiles/hikebike/{Z}/{X}/{Y}.png'
87*e5840fc5SMark Prins//					//moved to: https://www.toolserver.org/tiles/hikebike/12/2105/1388.png
88*e5840fc5SMark Prins//					'url' => 'http://c.tiles.wmflabs.org/hikebike/{Z}/{X}/{Y}.png'
89*e5840fc5SMark Prins//			)
90628e43ccSMark Prins	);
91628e43ccSMark Prins	protected $tileDefaultSrc = 'openstreetmap';
92628e43ccSMark Prins
93628e43ccSMark Prins	// set up markers
94628e43ccSMark Prins	protected $markerPrototypes = array (
95628e43ccSMark Prins			// found at http://www.mapito.net/map-marker-icons.html
96628e43ccSMark Prins			// these are 17x19 px with a pointer at the bottom left
97ab8cbd2bSMark Prins			'lightblue' => array (
98ab8cbd2bSMark Prins					'regex' => '/^lightblue([0-9]+)$/',
99628e43ccSMark Prins					'extension' => '.png',
100628e43ccSMark Prins					'shadow' => false,
101628e43ccSMark Prins					'offsetImage' => '0,-19',
102628e43ccSMark Prins					'offsetShadow' => false
103628e43ccSMark Prins			),
104628e43ccSMark Prins			// openlayers std markers are 21x25px with shadow
105ab8cbd2bSMark Prins			'ol-marker' => array (
106ab8cbd2bSMark Prins					'regex' => '/^marker(|-blue|-gold|-green|-red)+$/',
107628e43ccSMark Prins					'extension' => '.png',
108628e43ccSMark Prins					'shadow' => 'marker_shadow.png',
109628e43ccSMark Prins					'offsetImage' => '-10,-25',
110628e43ccSMark Prins					'offsetShadow' => '-1,-13'
111628e43ccSMark Prins			),
112628e43ccSMark Prins			// these are 16x16 px
113ab8cbd2bSMark Prins			'ww_icon' => array (
114ab8cbd2bSMark Prins					'regex' => '/ww_\S+$/',
115628e43ccSMark Prins					'extension' => '.png',
116628e43ccSMark Prins					'shadow' => false,
117628e43ccSMark Prins					'offsetImage' => '-8,-8',
118628e43ccSMark Prins					'offsetShadow' => false
119628e43ccSMark Prins			),
120628e43ccSMark Prins			// assume these are 16x16 px
121ab8cbd2bSMark Prins			'rest' => array (
122ab8cbd2bSMark Prins					'regex' => '/^(?!lightblue([0-9]+)$)(?!(ww_\S+$))(?!marker(|-blue|-gold|-green|-red)+$)(.*)/',
123628e43ccSMark Prins					'extension' => '.png',
124628e43ccSMark Prins					'shadow' => 'marker_shadow.png',
125628e43ccSMark Prins					'offsetImage' => '-8,-8',
126628e43ccSMark Prins					'offsetShadow' => '-1,-1'
127628e43ccSMark Prins			)
128628e43ccSMark Prins	);
129628e43ccSMark Prins	protected $centerX, $centerY, $offsetX, $offsetY, $image;
1305c603532SMark Prins	protected $zoom, $lat, $lon, $width, $height, $markers, $maptype, $kmlFileName, $gpxFileName, $geojsonFileName, $autoZoomExtent, $apikey;
131628e43ccSMark Prins	protected $tileCacheBaseDir, $mapCacheBaseDir, $mediaBaseDir;
132628e43ccSMark Prins	protected $useTileCache = true;
133628e43ccSMark Prins	protected $mapCacheID = '';
134628e43ccSMark Prins	protected $mapCacheFile = '';
135628e43ccSMark Prins	protected $mapCacheExtension = 'png';
136628e43ccSMark Prins
137628e43ccSMark Prins	/**
138f4b9bdacSMark Prins	 * Constructor.
139ab8cbd2bSMark Prins	 *
140ab8cbd2bSMark Prins	 * @param float $lat
141ab8cbd2bSMark Prins	 *        	Latitude (x) of center of map
142ab8cbd2bSMark Prins	 * @param float $lon
143ab8cbd2bSMark Prins	 *        	Longitude (y) of center of map
144ab8cbd2bSMark Prins	 * @param int $zoom
145ab8cbd2bSMark Prins	 *        	Zoomlevel
146ab8cbd2bSMark Prins	 * @param int $width
147ab8cbd2bSMark Prins	 *        	Width in pixels
148ab8cbd2bSMark Prins	 * @param int $height
149ab8cbd2bSMark Prins	 *        	Height in pixels
150ab8cbd2bSMark Prins	 * @param string $maptype
151ab8cbd2bSMark Prins	 *        	Name of the map
152ab8cbd2bSMark Prins	 * @param mixed $markers
153ab8cbd2bSMark Prins	 *        	array of markers
154ab8cbd2bSMark Prins	 * @param string $gpx
155ab8cbd2bSMark Prins	 *        	GPX filename
156ab8cbd2bSMark Prins	 * @param string $kml
157ab8cbd2bSMark Prins	 *        	KML filename
158ab8cbd2bSMark Prins	 * @param string $mediaDir
159ab8cbd2bSMark Prins	 *        	Directory to store/cache maps
160ab8cbd2bSMark Prins	 * @param string $tileCacheBaseDir
161ab8cbd2bSMark Prins	 *        	Directory to cache map tiles
162ab8cbd2bSMark Prins	 * @param boolean $autoZoomExtent
163ab8cbd2bSMark Prins	 *        	Wheter or not to override zoom/lat/lon and zoom to the extent of gpx/kml and markers
1645c603532SMark Prins	 * @param apikey
1655c603532SMark Prins	 *          Some service require a key to access
166628e43ccSMark Prins	 */
1675c603532SMark Prins	public function __construct($lat, $lon, $zoom, $width, $height, $maptype, $markers, $gpx, $kml, $geojson, $mediaDir, $tileCacheBaseDir, $autoZoomExtent = TRUE, $apikey = '') {
168628e43ccSMark Prins		$this->zoom = $zoom;
169628e43ccSMark Prins		$this->lat = $lat;
170628e43ccSMark Prins		$this->lon = $lon;
171628e43ccSMark Prins		$this->width = $width;
172628e43ccSMark Prins		$this->height = $height;
173628e43ccSMark Prins		// validate + set maptype
174628e43ccSMark Prins		$this->maptype = $this->tileDefaultSrc;
175628e43ccSMark Prins		if (array_key_exists ( $maptype, $this->tileInfo )) {
176628e43ccSMark Prins			$this->maptype = $maptype;
177628e43ccSMark Prins		}
1782d11d700SMark Prins		$this->markers = $markers;
1792d11d700SMark Prins		$this->kmlFileName = $kml;
1802d11d700SMark Prins		$this->gpxFileName = $gpx;
1816914b920SMark Prins		$this->geojsonFileName = $geojson;
1822d11d700SMark Prins		$this->mediaBaseDir = $mediaDir;
183628e43ccSMark Prins		$this->tileCacheBaseDir = $tileCacheBaseDir . '/olmaptiles';
184628e43ccSMark Prins		$this->useTileCache = $this->tileCacheBaseDir !== '';
185628e43ccSMark Prins		$this->mapCacheBaseDir = $mediaDir . '/olmapmaps';
1862d11d700SMark Prins		$this->autoZoomExtent = $autoZoomExtent;
1875c603532SMark Prins		$this->apikey = $apikey;
188628e43ccSMark Prins	}
189628e43ccSMark Prins
190628e43ccSMark Prins	/**
191628e43ccSMark Prins	 *
192628e43ccSMark Prins	 * @param number $long
193628e43ccSMark Prins	 * @param number $zoom
194f4b9bdacSMark Prins	 * @return number
195628e43ccSMark Prins	 */
196628e43ccSMark Prins	public function lonToTile($long, $zoom) {
197628e43ccSMark Prins		return (($long + 180) / 360) * pow ( 2, $zoom );
198628e43ccSMark Prins	}
199628e43ccSMark Prins	/**
200628e43ccSMark Prins	 *
201628e43ccSMark Prins	 * @param number $lat
202628e43ccSMark Prins	 * @param number $zoom
203628e43ccSMark Prins	 * @return number
204628e43ccSMark Prins	 */
205628e43ccSMark Prins	public function latToTile($lat, $zoom) {
2062d11d700SMark Prins		return (1 - log ( tan ( $lat * pi () / 180 ) + 1 / cos ( $lat * M_PI / 180 ) ) / M_PI) / 2 * pow ( 2, $zoom );
207628e43ccSMark Prins	}
208f4b9bdacSMark Prins
209628e43ccSMark Prins	/**
210628e43ccSMark Prins	 */
211628e43ccSMark Prins	public function initCoords() {
212628e43ccSMark Prins		$this->centerX = $this->lonToTile ( $this->lon, $this->zoom );
213628e43ccSMark Prins		$this->centerY = $this->latToTile ( $this->lat, $this->zoom );
214628e43ccSMark Prins		$this->offsetX = floor ( (floor ( $this->centerX ) - $this->centerX) * $this->tileSize );
215628e43ccSMark Prins		$this->offsetY = floor ( (floor ( $this->centerY ) - $this->centerY) * $this->tileSize );
216628e43ccSMark Prins	}
217628e43ccSMark Prins
218628e43ccSMark Prins	/**
219628e43ccSMark Prins	 * make basemap image.
220628e43ccSMark Prins	 */
221628e43ccSMark Prins	public function createBaseMap() {
222628e43ccSMark Prins		$this->image = imagecreatetruecolor ( $this->width, $this->height );
223628e43ccSMark Prins		$startX = floor ( $this->centerX - ($this->width / $this->tileSize) / 2 );
224628e43ccSMark Prins		$startY = floor ( $this->centerY - ($this->height / $this->tileSize) / 2 );
225628e43ccSMark Prins		$endX = ceil ( $this->centerX + ($this->width / $this->tileSize) / 2 );
226628e43ccSMark Prins		$endY = ceil ( $this->centerY + ($this->height / $this->tileSize) / 2 );
227628e43ccSMark Prins		$this->offsetX = - floor ( ($this->centerX - floor ( $this->centerX )) * $this->tileSize );
228628e43ccSMark Prins		$this->offsetY = - floor ( ($this->centerY - floor ( $this->centerY )) * $this->tileSize );
229628e43ccSMark Prins		$this->offsetX += floor ( $this->width / 2 );
230628e43ccSMark Prins		$this->offsetY += floor ( $this->height / 2 );
231628e43ccSMark Prins		$this->offsetX += floor ( $startX - floor ( $this->centerX ) ) * $this->tileSize;
232628e43ccSMark Prins		$this->offsetY += floor ( $startY - floor ( $this->centerY ) ) * $this->tileSize;
233628e43ccSMark Prins
234628e43ccSMark Prins		for($x = $startX; $x <= $endX; $x ++) {
235628e43ccSMark Prins			for($y = $startY; $y <= $endY; $y ++) {
236ab8cbd2bSMark Prins				$url = str_replace ( array (
237ab8cbd2bSMark Prins						'{Z}',
238ab8cbd2bSMark Prins						'{X}',
239ab8cbd2bSMark Prins						'{Y}'
240ab8cbd2bSMark Prins				), array (
241ab8cbd2bSMark Prins						$this->zoom,
242ab8cbd2bSMark Prins						$x,
243ab8cbd2bSMark Prins						$y
244ab8cbd2bSMark Prins				), $this->tileInfo [$this->maptype] ['url'] );
245c8eb1362SMark Prins				$url .= $this->apikey;
246c8eb1362SMark Prins
247628e43ccSMark Prins				$tileData = $this->fetchTile ( $url );
248628e43ccSMark Prins				if ($tileData) {
249628e43ccSMark Prins					$tileImage = imagecreatefromstring ( $tileData );
250628e43ccSMark Prins				} else {
251628e43ccSMark Prins					$tileImage = imagecreate ( $this->tileSize, $this->tileSize );
252628e43ccSMark Prins					$color = imagecolorallocate ( $tileImage, 255, 255, 255 );
253628e43ccSMark Prins					@imagestring ( $tileImage, 1, 127, 127, 'err', $color );
254628e43ccSMark Prins				}
255628e43ccSMark Prins				$destX = ($x - $startX) * $this->tileSize + $this->offsetX;
256628e43ccSMark Prins				$destY = ($y - $startY) * $this->tileSize + $this->offsetY;
257c8eb1362SMark Prins				dbglog($this->tileSize,"imagecopy tile into image: $destX, $destY");
258628e43ccSMark Prins				imagecopy ( $this->image, $tileImage, $destX, $destY, 0, 0, $this->tileSize, $this->tileSize );
259628e43ccSMark Prins			}
260628e43ccSMark Prins		}
261628e43ccSMark Prins	}
262628e43ccSMark Prins
263628e43ccSMark Prins	/**
264628e43ccSMark Prins	 * Place markers on the map and number them in the same order as they are listed in the html.
265628e43ccSMark Prins	 */
266628e43ccSMark Prins	public function placeMarkers() {
267628e43ccSMark Prins		$count = 0;
268628e43ccSMark Prins		$color = imagecolorallocate ( $this->image, 0, 0, 0 );
269628e43ccSMark Prins		$bgcolor = imagecolorallocate ( $this->image, 200, 200, 200 );
270628e43ccSMark Prins		$markerBaseDir = dirname ( __FILE__ ) . '/icons';
271628e43ccSMark Prins		// loop thru marker array
272628e43ccSMark Prins		foreach ( $this->markers as $marker ) {
273628e43ccSMark Prins			// set some local variables
274628e43ccSMark Prins			$markerLat = $marker ['lat'];
275628e43ccSMark Prins			$markerLon = $marker ['lon'];
276628e43ccSMark Prins			$markerType = $marker ['type'];
277628e43ccSMark Prins			// clear variables from previous loops
278628e43ccSMark Prins			$markerFilename = '';
279628e43ccSMark Prins			$markerShadow = '';
280628e43ccSMark Prins			$matches = false;
281628e43ccSMark Prins			// check for marker type, get settings from markerPrototypes
282628e43ccSMark Prins			if ($markerType) {
283628e43ccSMark Prins				foreach ( $this->markerPrototypes as $markerPrototype ) {
284628e43ccSMark Prins					if (preg_match ( $markerPrototype ['regex'], $markerType, $matches )) {
285628e43ccSMark Prins						$markerFilename = $matches [0] . $markerPrototype ['extension'];
286628e43ccSMark Prins						if ($markerPrototype ['offsetImage']) {
28782c0f6baSMark Prins							list ( $markerImageOffsetX, $markerImageOffsetY ) = explode ( ",", $markerPrototype ['offsetImage'] );
288628e43ccSMark Prins						}
289628e43ccSMark Prins						$markerShadow = $markerPrototype ['shadow'];
290628e43ccSMark Prins						if ($markerShadow) {
29182c0f6baSMark Prins							list ( $markerShadowOffsetX, $markerShadowOffsetY ) = explode ( ",", $markerPrototype ['offsetShadow'] );
292628e43ccSMark Prins						}
293628e43ccSMark Prins					}
294628e43ccSMark Prins				}
295628e43ccSMark Prins			}
296628e43ccSMark Prins			// create img resource
297628e43ccSMark Prins			if (file_exists ( $markerBaseDir . '/' . $markerFilename )) {
298628e43ccSMark Prins				$markerImg = imagecreatefrompng ( $markerBaseDir . '/' . $markerFilename );
299628e43ccSMark Prins			} else {
300628e43ccSMark Prins				$markerImg = imagecreatefrompng ( $markerBaseDir . '/marker.png' );
301628e43ccSMark Prins			}
302628e43ccSMark Prins			// check for shadow + create shadow recource
303628e43ccSMark Prins			if ($markerShadow && file_exists ( $markerBaseDir . '/' . $markerShadow )) {
304628e43ccSMark Prins				$markerShadowImg = imagecreatefrompng ( $markerBaseDir . '/' . $markerShadow );
305628e43ccSMark Prins			}
306628e43ccSMark Prins			// calc position
307628e43ccSMark Prins			$destX = floor ( ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile ( $markerLon, $this->zoom )) );
308628e43ccSMark Prins			$destY = floor ( ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile ( $markerLat, $this->zoom )) );
309628e43ccSMark Prins			// copy shadow on basemap
310628e43ccSMark Prins			if ($markerShadow && $markerShadowImg) {
311ab8cbd2bSMark Prins				imagecopy ( $this->image, $markerShadowImg, $destX + intval ( $markerShadowOffsetX ), $destY + intval ( $markerShadowOffsetY ), 0, 0, imagesx ( $markerShadowImg ), imagesy ( $markerShadowImg ) );
312628e43ccSMark Prins			}
313628e43ccSMark Prins			// copy marker on basemap above shadow
314ab8cbd2bSMark Prins			imagecopy ( $this->image, $markerImg, $destX + intval ( $markerImageOffsetX ), $destY + intval ( $markerImageOffsetY ), 0, 0, imagesx ( $markerImg ), imagesy ( $markerImg ) );
315628e43ccSMark Prins			// add label
316628e43ccSMark Prins			imagestring ( $this->image, 3, $destX - imagesx ( $markerImg ) + 1, $destY + intval ( $markerImageOffsetY ) + 1, ++ $count, $bgcolor );
317628e43ccSMark Prins			imagestring ( $this->image, 3, $destX - imagesx ( $markerImg ), $destY + intval ( $markerImageOffsetY ), $count, $color );
318ab8cbd2bSMark Prins		}
319ab8cbd2bSMark Prins		;
320628e43ccSMark Prins	}
32157e65445SMark Prins
322628e43ccSMark Prins	/**
323628e43ccSMark Prins	 *
324628e43ccSMark Prins	 * @param string $url
325628e43ccSMark Prins	 * @return string
326628e43ccSMark Prins	 */
327628e43ccSMark Prins	public function tileUrlToFilename($url) {
328ab8cbd2bSMark Prins		return $this->tileCacheBaseDir . "/" . str_replace ( array (
329ab8cbd2bSMark Prins				'http://'
330ab8cbd2bSMark Prins		), '', $url );
331628e43ccSMark Prins	}
33257e65445SMark Prins
333628e43ccSMark Prins	/**
334628e43ccSMark Prins	 *
335628e43ccSMark Prins	 * @param string $url
336628e43ccSMark Prins	 */
337628e43ccSMark Prins	public function checkTileCache($url) {
338628e43ccSMark Prins		$filename = $this->tileUrlToFilename ( $url );
339628e43ccSMark Prins		if (file_exists ( $filename )) {
340628e43ccSMark Prins			return file_get_contents ( $filename );
341628e43ccSMark Prins		}
342628e43ccSMark Prins	}
343628e43ccSMark Prins	public function checkMapCache() {
344628e43ccSMark Prins		$this->mapCacheID = md5 ( $this->serializeParams () );
345628e43ccSMark Prins		$filename = $this->mapCacheIDToFilename ();
346ab8cbd2bSMark Prins		if (file_exists ( $filename ))
347ab8cbd2bSMark Prins			return true;
348628e43ccSMark Prins	}
349628e43ccSMark Prins	public function serializeParams() {
350ab8cbd2bSMark Prins		return join ( "&", array (
351ab8cbd2bSMark Prins				$this->zoom,
352ab8cbd2bSMark Prins				$this->lat,
353ab8cbd2bSMark Prins				$this->lon,
354ab8cbd2bSMark Prins				$this->width,
355ab8cbd2bSMark Prins				$this->height,
356ab8cbd2bSMark Prins				serialize ( $this->markers ),
357ab8cbd2bSMark Prins				$this->maptype,
358ab8cbd2bSMark Prins				$this->kmlFileName,
359ab8cbd2bSMark Prins				$this->gpxFileName,
360ab8cbd2bSMark Prins				$this->geojsonFileName
361ab8cbd2bSMark Prins		) );
362628e43ccSMark Prins	}
363628e43ccSMark Prins	public function mapCacheIDToFilename() {
364628e43ccSMark Prins		if (! $this->mapCacheFile) {
365628e43ccSMark Prins			$this->mapCacheFile = $this->mapCacheBaseDir . "/" . $this->maptype . "/" . $this->zoom . "/cache_" . substr ( $this->mapCacheID, 0, 2 ) . "/" . substr ( $this->mapCacheID, 2, 2 ) . "/" . substr ( $this->mapCacheID, 4 );
366628e43ccSMark Prins		}
367628e43ccSMark Prins		return $this->mapCacheFile . "." . $this->mapCacheExtension;
368628e43ccSMark Prins	}
36957e65445SMark Prins
3702d11d700SMark Prins	/**
3712d11d700SMark Prins	 * Recursively create the directory.
372ab8cbd2bSMark Prins	 *
373ab8cbd2bSMark Prins	 * @param string $pathname
374ab8cbd2bSMark Prins	 *        	The directory path.
375ab8cbd2bSMark Prins	 * @param int $mode
376ab8cbd2bSMark Prins	 *        	File access mode. For more information on modes, read the details on the chmod manpage.
3772d11d700SMark Prins	 */
378628e43ccSMark Prins	public function mkdir_recursive($pathname, $mode) {
379628e43ccSMark Prins		is_dir ( dirname ( $pathname ) ) || $this->mkdir_recursive ( dirname ( $pathname ), $mode );
380628e43ccSMark Prins		return is_dir ( $pathname ) || @mkdir ( $pathname, $mode );
381628e43ccSMark Prins	}
382628e43ccSMark Prins
3832d11d700SMark Prins	/**
3842d11d700SMark Prins	 * Write a tile into the cache.
385ab8cbd2bSMark Prins	 *
3862d11d700SMark Prins	 * @param string $url
3872d11d700SMark Prins	 * @param mixed $data
3882d11d700SMark Prins	 */
389628e43ccSMark Prins	public function writeTileToCache($url, $data) {
390628e43ccSMark Prins		$filename = $this->tileUrlToFilename ( $url );
391628e43ccSMark Prins		$this->mkdir_recursive ( dirname ( $filename ), 0777 );
392628e43ccSMark Prins		file_put_contents ( $filename, $data );
393628e43ccSMark Prins	}
39457e65445SMark Prins
3952d11d700SMark Prins	/**
3962d11d700SMark Prins	 * Fetch a tile and (if configured) store it in the cache.
397ab8cbd2bSMark Prins	 *
3982d11d700SMark Prins	 * @param string $url
3992d11d700SMark Prins	 */
400628e43ccSMark Prins	public function fetchTile($url) {
401ab8cbd2bSMark Prins		if ($this->useTileCache && ($cached = $this->checkTileCache ( $url )))
402ab8cbd2bSMark Prins			return $cached;
403e4f115f4SMark Prins
404e4f115f4SMark Prins		$_UA = 'Mozilla/4.0 (compatible; DokuWikiSpatial HTTP Client; ' . PHP_OS . ')';
405e4f115f4SMark Prins		if (function_exists ( "curl_init" )) {
406e4f115f4SMark Prins			// use cUrl
407628e43ccSMark Prins			$ch = curl_init ();
408628e43ccSMark Prins			curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
409e4f115f4SMark Prins			curl_setopt ( $ch, CURLOPT_USERAGENT, $_UA );
410628e43ccSMark Prins			curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 10 );
411628e43ccSMark Prins			curl_setopt ( $ch, CURLOPT_URL, $url );
412628e43ccSMark Prins			$tile = curl_exec ( $ch );
413628e43ccSMark Prins			curl_close ( $ch );
414e4f115f4SMark Prins		} else {
415e4f115f4SMark Prins			// use file_get_contents
416e4f115f4SMark Prins			global $conf;
417e4f115f4SMark Prins			$opts = array (
418e4f115f4SMark Prins					'http' => array (
419e4f115f4SMark Prins							'method' => "GET",
420ab8cbd2bSMark Prins							'header' => "Accept-language: en\r\n" . "User-Agent: $_UA\r\n" . "accept: image/png\r\n",
421e4f115f4SMark Prins							'proxy' => "tcp://" . $conf ['proxy'] ['host'] . ":" . $conf ['proxy'] ['port'],
422ab8cbd2bSMark Prins							'request_fulluri' => true
423e4f115f4SMark Prins					)
424e4f115f4SMark Prins			);
425e4f115f4SMark Prins			$context = stream_context_create ( $opts );
426e4f115f4SMark Prins			$tile = file_get_contents ( $url, false, $context );
427e4f115f4SMark Prins		}
428628e43ccSMark Prins		if ($tile && $this->useTileCache) {
429628e43ccSMark Prins			$this->writeTileToCache ( $url, $tile );
430628e43ccSMark Prins		}
431628e43ccSMark Prins		return $tile;
432628e43ccSMark Prins	}
433628e43ccSMark Prins
434628e43ccSMark Prins	/**
435628e43ccSMark Prins	 * Draw gpx trace on the map.
436628e43ccSMark Prins	 */
437628e43ccSMark Prins	public function drawGPX() {
438c977deacSMark Prins		$col = imagecolorallocatealpha ( $this->image, 0, 0, 255, .4 * 127 );
4396c6bb022SMark Prins		$gpxgeom = geoPHP::load ( file_get_contents ( $this->gpxFileName ), 'gpx' );
440c977deacSMark Prins		$this->drawGeometry ( $gpxgeom, $col );
441628e43ccSMark Prins	}
442628e43ccSMark Prins
4436914b920SMark Prins	/**
4446914b920SMark Prins	 * Draw geojson on the map.
4456914b920SMark Prins	 */
4466914b920SMark Prins	public function drawGeojson() {
4476914b920SMark Prins		$col = imagecolorallocatealpha ( $this->image, 255, 0, 255, .4 * 127 );
4486914b920SMark Prins		$gpxgeom = geoPHP::load ( file_get_contents ( $this->geojsonFileName ), 'json' );
4496914b920SMark Prins		$this->drawGeometry ( $gpxgeom, $col );
4506914b920SMark Prins	}
45157e65445SMark Prins
452628e43ccSMark Prins	/**
453628e43ccSMark Prins	 * Draw kml trace on the map.
454628e43ccSMark Prins	 */
455628e43ccSMark Prins	public function drawKML() {
4562d11d700SMark Prins		// TODO get colour from kml node (not currently supported in geoPHP)
457c977deacSMark Prins		$col = imagecolorallocatealpha ( $this->image, 255, 0, 0, .4 * 127 );
458c977deacSMark Prins		$kmlgeom = geoPHP::load ( file_get_contents ( $this->kmlFileName ), 'kml' );
459c977deacSMark Prins		$this->drawGeometry ( $kmlgeom, $col );
460c977deacSMark Prins	}
46157e65445SMark Prins
462c977deacSMark Prins	/**
463c977deacSMark Prins	 * Draw geometry or geometry collection on the map.
464ab8cbd2bSMark Prins	 *
465c977deacSMark Prins	 * @param Geometry $geom
466ab8cbd2bSMark Prins	 * @param int $colour
467ab8cbd2bSMark Prins	 *        	drawing colour
468c977deacSMark Prins	 */
469c977deacSMark Prins	private function drawGeometry($geom, $colour) {
470*e5840fc5SMark Prins		if (empty($geom)) return;
471*e5840fc5SMark Prins
4726c6bb022SMark Prins		switch ($geom->geometryType ()) {
473c977deacSMark Prins			case 'GeometryCollection' :
474c977deacSMark Prins				// recursively draw part of the collection
475c977deacSMark Prins				for($i = 1; $i < $geom->numGeometries () + 1; $i ++) {
476c977deacSMark Prins					$_geom = $geom->geometryN ( $i );
477c977deacSMark Prins					$this->drawGeometry ( $_geom, $colour );
478c977deacSMark Prins				}
4796c6bb022SMark Prins				break;
480c977deacSMark Prins			case 'MultiPolygon' :
481c977deacSMark Prins				// TODO implement / do nothing
482c977deacSMark Prins				break;
483c977deacSMark Prins			case 'MultiLineString' :
484c977deacSMark Prins				// TODO implement / do nothing
485c977deacSMark Prins				break;
486c977deacSMark Prins			case 'MultiPoint' :
487c977deacSMark Prins				// TODO implement / do nothing
4886c6bb022SMark Prins				break;
4896c6bb022SMark Prins			case 'Polygon' :
490c977deacSMark Prins				$this->drawPolygon ( $geom, $colour );
491c977deacSMark Prins				break;
492c977deacSMark Prins			case 'LineString' :
493c977deacSMark Prins				$this->drawLineString ( $geom, $colour );
494c977deacSMark Prins				break;
495c977deacSMark Prins			case 'Point' :
496c977deacSMark Prins				$this->drawPoint ( $geom, $colour );
4976c6bb022SMark Prins				break;
4986c6bb022SMark Prins			default :
4992d11d700SMark Prins				// draw nothing
5006c6bb022SMark Prins				break;
5016c6bb022SMark Prins		}
5026c6bb022SMark Prins	}
503c977deacSMark Prins
504e61425c7SMark Prins	/**
505e61425c7SMark Prins	 * Draw a line on the map.
506ab8cbd2bSMark Prins	 *
507e61425c7SMark Prins	 * @param LineString $line
508ab8cbd2bSMark Prins	 * @param int $colour
509ab8cbd2bSMark Prins	 *        	drawing colour
510e61425c7SMark Prins	 */
511da6f229fSMark Prins	private function drawLineString($line, $colour) {
512cc74a83cSMark Prins		imagesetthickness ( $this->image, 2 );
513da6f229fSMark Prins		for($p = 1; $p < $line->numGeometries (); $p ++) {
514da6f229fSMark Prins			// get first pair of points
515da6f229fSMark Prins			$p1 = $line->geometryN ( $p );
516da6f229fSMark Prins			$p2 = $line->geometryN ( $p + 1 );
517da6f229fSMark Prins			// translate to paper space
518da6f229fSMark Prins			$x1 = floor ( ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile ( $p1->x (), $this->zoom )) );
519da6f229fSMark Prins			$y1 = floor ( ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile ( $p1->y (), $this->zoom )) );
520da6f229fSMark Prins			$x2 = floor ( ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile ( $p2->x (), $this->zoom )) );
521da6f229fSMark Prins			$y2 = floor ( ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile ( $p2->y (), $this->zoom )) );
522da6f229fSMark Prins			// draw to image
523da6f229fSMark Prins			imageline ( $this->image, $x1, $y1, $x2, $y2, $colour );
524da6f229fSMark Prins		}
525e61425c7SMark Prins		imagesetthickness ( $this->image, 1 );
526da6f229fSMark Prins	}
527c977deacSMark Prins
528e61425c7SMark Prins	/**
529e61425c7SMark Prins	 * Draw a point on the map.
530ab8cbd2bSMark Prins	 *
531e61425c7SMark Prins	 * @param Point $point
532ab8cbd2bSMark Prins	 * @param int $colour
533ab8cbd2bSMark Prins	 *        	drawing colour
534e61425c7SMark Prins	 */
535da6f229fSMark Prins	private function drawPoint($point, $colour) {
536c977deacSMark Prins		imagesetthickness ( $this->image, 2 );
537da6f229fSMark Prins		// translate to paper space
538da6f229fSMark Prins		$cx = floor ( ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile ( $point->x (), $this->zoom )) );
539da6f229fSMark Prins		$cy = floor ( ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile ( $point->y (), $this->zoom )) );
540cc74a83cSMark Prins		$r = 5;
541da6f229fSMark Prins		// draw to image
542cc74a83cSMark Prins		// imageellipse($this->image, $cx, $cy,$r, $r, $colour);
543cc74a83cSMark Prins		imagefilledellipse ( $this->image, $cx, $cy, $r, $r, $colour );
544cc74a83cSMark Prins		// don't use imageellipse because the imagesetthickness function has
545c977deacSMark Prins		// no effect. So the better workaround is to use imagearc.
546cc74a83cSMark Prins		imagearc ( $this->image, $cx, $cy, $r, $r, 0, 359, $colour );
547e61425c7SMark Prins		imagesetthickness ( $this->image, 1 );
548da6f229fSMark Prins	}
549c977deacSMark Prins
550e61425c7SMark Prins	/**
551e61425c7SMark Prins	 * Draw a polygon on the map.
552ab8cbd2bSMark Prins	 *
553e61425c7SMark Prins	 * @param Polygon $polygon
554ab8cbd2bSMark Prins	 * @param int $colour
555ab8cbd2bSMark Prins	 *        	drawing colour
556e61425c7SMark Prins	 */
557e61425c7SMark Prins	private function drawPolygon($polygon, $colour) {
558c977deacSMark Prins		// TODO implementation of drawing holes,
559c977deacSMark Prins		// maybe draw the polygon to an in-memory image and use imagecopy, draw polygon in col., draw holes in bgcol?
560c977deacSMark Prins
561c977deacSMark Prins		// print_r('Polygon:<br />');
562c977deacSMark Prins		// print_r($polygon);
563c977deacSMark Prins		$extPoints = array ();
564c977deacSMark Prins		// extring is a linestring actually..
565c977deacSMark Prins		$extRing = $polygon->exteriorRing ();
566c977deacSMark Prins
567c977deacSMark Prins		for($i = 1; $i < $extRing->numGeometries (); $i ++) {
568c977deacSMark Prins			$p1 = $extRing->geometryN ( $i );
569c977deacSMark Prins			$x = floor ( ($this->width / 2) - $this->tileSize * ($this->centerX - $this->lonToTile ( $p1->x (), $this->zoom )) );
570c977deacSMark Prins			$y = floor ( ($this->height / 2) - $this->tileSize * ($this->centerY - $this->latToTile ( $p1->y (), $this->zoom )) );
571c977deacSMark Prins			$extPoints [] = $x;
572c977deacSMark Prins			$extPoints [] = $y;
573e61425c7SMark Prins		}
574c977deacSMark Prins		// print_r('points:('.($i-1).')<br />');
575c977deacSMark Prins		// print_r($extPoints);
576c977deacSMark Prins		// imagepolygon ($this->image, $extPoints, $i-1, $colour );
577c977deacSMark Prins		imagefilledpolygon ( $this->image, $extPoints, $i - 1, $colour );
578c977deacSMark Prins	}
579c977deacSMark Prins
580628e43ccSMark Prins	/**
581628e43ccSMark Prins	 * add copyright and origin notice and icons to the map.
582628e43ccSMark Prins	 */
583628e43ccSMark Prins	public function drawCopyright() {
584628e43ccSMark Prins		$logoBaseDir = dirname ( __FILE__ ) . '/' . 'logo/';
585628e43ccSMark Prins		$logoImg = imagecreatefrompng ( $logoBaseDir . $this->tileInfo ['openstreetmap'] ['logo'] );
586628e43ccSMark Prins		$textcolor = imagecolorallocate ( $this->image, 0, 0, 0 );
587628e43ccSMark Prins		$bgcolor = imagecolorallocate ( $this->image, 200, 200, 200 );
588628e43ccSMark Prins
5892d11d700SMark Prins		imagecopy ( $this->image, $logoImg, 0, imagesy ( $this->image ) - imagesy ( $logoImg ), 0, 0, imagesx ( $logoImg ), imagesy ( $logoImg ) );
590628e43ccSMark Prins		imagestring ( $this->image, 1, imagesx ( $logoImg ) + 2, imagesy ( $this->image ) - imagesy ( $logoImg ) + 1, $this->tileInfo ['openstreetmap'] ['txt'], $bgcolor );
591628e43ccSMark Prins		imagestring ( $this->image, 1, imagesx ( $logoImg ) + 1, imagesy ( $this->image ) - imagesy ( $logoImg ), $this->tileInfo ['openstreetmap'] ['txt'], $textcolor );
592628e43ccSMark Prins
593628e43ccSMark Prins		// additional tile source info, ie. who created/hosted the tiles
594628e43ccSMark Prins		if ($this->maptype != 'openstreetmap') {
595628e43ccSMark Prins			$iconImg = imagecreatefrompng ( $logoBaseDir . $this->tileInfo [$this->maptype] ['logo'] );
5962d11d700SMark Prins			imagecopy ( $this->image, $iconImg, imagesx ( $logoImg ) + 1, imagesy ( $this->image ) - imagesy ( $iconImg ), 0, 0, imagesx ( $iconImg ), imagesy ( $iconImg ) );
597628e43ccSMark Prins			imagestring ( $this->image, 1, imagesx ( $logoImg ) + imagesx ( $iconImg ) + 4, imagesy ( $this->image ) - ceil ( imagesy ( $logoImg ) / 2 ) + 1, $this->tileInfo [$this->maptype] ['txt'], $bgcolor );
598628e43ccSMark Prins			imagestring ( $this->image, 1, imagesx ( $logoImg ) + imagesx ( $iconImg ) + 3, imagesy ( $this->image ) - ceil ( imagesy ( $logoImg ) / 2 ), $this->tileInfo [$this->maptype] ['txt'], $textcolor );
599628e43ccSMark Prins		}
600628e43ccSMark Prins	}
601cc74a83cSMark Prins
602628e43ccSMark Prins	/**
603628e43ccSMark Prins	 * make the map.
604628e43ccSMark Prins	 */
605628e43ccSMark Prins	public function makeMap() {
606628e43ccSMark Prins		$this->initCoords ();
607628e43ccSMark Prins		$this->createBaseMap ();
608ab8cbd2bSMark Prins		if (! empty ( $this->markers ))
609ab8cbd2bSMark Prins			$this->placeMarkers ();
610ab8cbd2bSMark Prins		if (file_exists ( $this->kmlFileName ))
611ab8cbd2bSMark Prins			$this->drawKML ();
612ab8cbd2bSMark Prins		if (file_exists ( $this->gpxFileName ))
613ab8cbd2bSMark Prins			$this->drawGPX ();
614ab8cbd2bSMark Prins		if (file_exists ( $this->geojsonFileName ))
615ab8cbd2bSMark Prins			$this->drawGeojson ();
6166914b920SMark Prins
617628e43ccSMark Prins		$this->drawCopyright ();
618628e43ccSMark Prins	}
619cc74a83cSMark Prins
620628e43ccSMark Prins	/**
621e4f115f4SMark Prins	 * Calculate the lat/lon/zoom values to make sure that all of the markers and gpx/kml are on the map.
622a2fdf7cdSMark Prins	 * can throw an error like
623a2fdf7cdSMark Prins	 * "Fatal error: Uncaught Exception: Cannot create a collection with non-geometries in
624a2fdf7cdSMark Prins	 * D:\www\wild-water.nl\www\dokuwiki\lib\plugins\geophp\geoPHP\lib\geometry\Collection.class.php:29"
625ab8cbd2bSMark Prins	 *
626ab8cbd2bSMark Prins	 * @param float $paddingFactor
627ab8cbd2bSMark Prins	 *        	buffer constant to enlarge (>1.0) the zoom level
6282d11d700SMark Prins	 */
6292d11d700SMark Prins	private function autoZoom($paddingFactor = 1.0) {
6302d11d700SMark Prins		$geoms = array ();
631e4f115f4SMark Prins		$geoms [] = new Point ( $this->lon, $this->lat );
632e4f115f4SMark Prins		if (! empty ( $this->markers )) {
6332d11d700SMark Prins			foreach ( $this->markers as $marker ) {
6342d11d700SMark Prins				$geoms [] = new Point ( $marker ['lon'], $marker ['lat'] );
6352d11d700SMark Prins			}
6362d11d700SMark Prins		}
637a2fdf7cdSMark Prins		$g = FALSE;
6382d11d700SMark Prins		if (file_exists ( $this->kmlFileName )) {
639a2fdf7cdSMark Prins			$g = geoPHP::load ( file_get_contents ( $this->kmlFileName ), 'kml' );
640a2fdf7cdSMark Prins			if($g !== FALSE) {
641a2fdf7cdSMark Prins				$geoms [] = $g;
642a2fdf7cdSMark Prins			}
6432d11d700SMark Prins		}
6442d11d700SMark Prins		if (file_exists ( $this->gpxFileName )) {
645a2fdf7cdSMark Prins			$g = geoPHP::load ( file_get_contents ( $this->gpxFileName ), 'gpx' );
646a2fdf7cdSMark Prins			if($g !== FALSE) {
647a2fdf7cdSMark Prins				$geoms [] = $g;
648a2fdf7cdSMark Prins			}
6492d11d700SMark Prins		}
6506914b920SMark Prins		if (file_exists ( $this->geojsonFileName )) {
651a2fdf7cdSMark Prins			$g = geoPHP::load ( file_get_contents ( $this->geojsonFileName ), 'geojson' );
652a2fdf7cdSMark Prins			if($g !== FALSE) {
653a2fdf7cdSMark Prins				$geoms [] = $g;
654a2fdf7cdSMark Prins			}
6556914b920SMark Prins		}
6566914b920SMark Prins
657a2fdf7cdSMark Prins		if (count ( $geoms ) <= 1) {
658a2fdf7cdSMark Prins			dbglog($geoms,"StaticMap::autoZoom: Skip setting autozoom options");
659ab8cbd2bSMark Prins			return;
660a2fdf7cdSMark Prins		}
66153bfe4a3SMark Prins
6622d11d700SMark Prins		$geom = new GeometryCollection ( $geoms );
6632d11d700SMark Prins		$centroid = $geom->centroid ();
6642d11d700SMark Prins		$bbox = $geom->getBBox ();
6652d11d700SMark Prins
6662d11d700SMark Prins		// determine vertical resolution, this depends on the distance from the equator
6672d11d700SMark Prins		// $vy00 = log(tan(M_PI*(0.25 + $centroid->getY()/360)));
6682d11d700SMark Prins		$vy0 = log ( tan ( M_PI * (0.25 + $bbox ['miny'] / 360) ) );
6692d11d700SMark Prins		$vy1 = log ( tan ( M_PI * (0.25 + $bbox ['maxy'] / 360) ) );
670c8eb1362SMark Prins		dbglog("StaticMap::autoZoom: vertical resolution: $vy0, $vy1");
67153bfe4a3SMark Prins		$zoomFactorPowered = ($this->height / 2) / (40.7436654315252 * ($vy1 - $vy0));
6722d11d700SMark Prins		$resolutionVertical = 360 / ($zoomFactorPowered * $this->tileSize);
6732d11d700SMark Prins		// determine horizontal resolution
6742d11d700SMark Prins		$resolutionHorizontal = ($bbox ['maxx'] - $bbox ['minx']) / $this->width;
6752d11d700SMark Prins		$resolution = max ( $resolutionHorizontal, $resolutionVertical ) * $paddingFactor;
6762d11d700SMark Prins		$zoom = log ( 360 / ($resolution * $this->tileSize), 2 );
6772d11d700SMark Prins
678c8eb1362SMark Prins		if (is_finite($zoom) && $zoom < 15 && $zoom > 2) {
6792d11d700SMark Prins			$this->zoom = floor ( $zoom );
680c8eb1362SMark Prins		}
6812d11d700SMark Prins		$this->lon = $centroid->getX ();
6822d11d700SMark Prins		$this->lat = $centroid->getY ();
683a2fdf7cdSMark Prins		dbglog("StaticMap::autoZoom: Set autozoom options to: z: $this->zoom, lon: $this->lon, lat: $this->lat");
6842d11d700SMark Prins	}
6852d11d700SMark Prins
6862d11d700SMark Prins	/**
687628e43ccSMark Prins	 * get the map, this may return a reference to a cached copy.
688ab8cbd2bSMark Prins	 *
689628e43ccSMark Prins	 * @return string url relative to media dir
690628e43ccSMark Prins	 */
691628e43ccSMark Prins	public function getMap() {
692a2fdf7cdSMark Prins		try {
693a2fdf7cdSMark Prins			if ($this->autoZoomExtent) {
694ab8cbd2bSMark Prins				$this->autoZoom ();
695a2fdf7cdSMark Prins			}
696a2fdf7cdSMark Prins		} catch (Exception $e) {
697a2fdf7cdSMark Prins			dbglog($e);
698a2fdf7cdSMark Prins		}
6992d11d700SMark Prins
700628e43ccSMark Prins			// use map cache, so check cache for map
701628e43ccSMark Prins		if (! $this->checkMapCache ()) {
702628e43ccSMark Prins			// map is not in cache, needs to be build
703628e43ccSMark Prins			$this->makeMap ();
704628e43ccSMark Prins			$this->mkdir_recursive ( dirname ( $this->mapCacheIDToFilename () ), 0777 );
705628e43ccSMark Prins			imagepng ( $this->image, $this->mapCacheIDToFilename (), 9 );
706628e43ccSMark Prins		}
707628e43ccSMark Prins		$this->doc = $this->mapCacheIDToFilename ();
708628e43ccSMark Prins		// make url relative to media dir
709628e43ccSMark Prins		return str_replace ( $this->mediaBaseDir, '', $this->doc );
710628e43ccSMark Prins	}
711628e43ccSMark Prins}
712