1*628e43ccSMark Prins<?php 2*628e43ccSMark Prins 3*628e43ccSMark Prins/* 4*628e43ccSMark Prins * Copyright (c) 2012 Mark C. Prins <mprins@users.sf.net> 5*628e43ccSMark Prins* 6*628e43ccSMark Prins* Based on staticMapLite 0.03 available at http://staticmaplite.svn.sourceforge.net/viewvc/staticmaplite/ 7*628e43ccSMark Prins* 8*628e43ccSMark Prins* Copyright (c) 2009 Gerhard Koch <gerhard.koch AT ymail.com> 9*628e43ccSMark Prins* 10*628e43ccSMark Prins* Licensed under the Apache License, Version 2.0 (the "License"); 11*628e43ccSMark Prins* you may not use this file except in compliance with the License. 12*628e43ccSMark Prins* You may obtain a copy of the License at 13*628e43ccSMark Prins* 14*628e43ccSMark Prins* http://www.apache.org/licenses/LICENSE-2.0 15*628e43ccSMark Prins* 16*628e43ccSMark Prins* Unless required by applicable law or agreed to in writing, software 17*628e43ccSMark Prins* distributed under the License is distributed on an "AS IS" BASIS, 18*628e43ccSMark Prins* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19*628e43ccSMark Prins* See the License for the specific language governing permissions and 20*628e43ccSMark Prins* limitations under the License. 21*628e43ccSMark Prins*/ 22*628e43ccSMark Prins 23*628e43ccSMark Prins/** 24*628e43ccSMark Prins * @author Mark C. Prins <mprins@users.sf.net> 25*628e43ccSMark Prins * @author Gerhard Koch <gerhard.koch AT ymail.com> 26*628e43ccSMark Prins * 27*628e43ccSMark Prins * USAGE: 28*628e43ccSMark Prins * 29*628e43ccSMark Prins * map.php?center=40.714728,-73.998672&zoom=14&size=512x512&maptype=cycle&markers=40.702147,-74.015794,lightblue1|40.711614,-74.012318,lightblue2|40.718217,-73.998284,lightblue3&gpx=&kml= 30*628e43ccSMark Prins*/ 31*628e43ccSMark Prinsclass StaticMap { 32*628e43ccSMark Prins // these should probably not be changed 33*628e43ccSMark Prins protected $tileSize = 256; 34*628e43ccSMark Prins 35*628e43ccSMark Prins // the final output 36*628e43ccSMark Prins var $doc = ''; 37*628e43ccSMark Prins 38*628e43ccSMark Prins protected $tileInfo = array( 39*628e43ccSMark Prins // OSM sources 40*628e43ccSMark Prins 'openstreetmap'=>array( 41*628e43ccSMark Prins 'txt'=>'(c) OpenStreetMap CC-BY-SA', 42*628e43ccSMark Prins 'logo'=>'osm_logo.png', 43*628e43ccSMark Prins 'url'=>'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png'), 44*628e43ccSMark Prins // cloudmade 45*628e43ccSMark Prins 'cloudmade' =>array( 46*628e43ccSMark Prins 'txt'=>'CloudMade tiles', 47*628e43ccSMark Prins 'logo'=>'cloudmade_logo.png', 48*628e43ccSMark Prins 'url'=> 'http://tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/2/256/{Z}/{X}/{Y}.png'), 49*628e43ccSMark Prins 'fresh' =>array( 50*628e43ccSMark Prins 'txt'=>'CloudMade tiles', 51*628e43ccSMark Prins 'logo'=>'cloudmade_logo.png', 52*628e43ccSMark Prins 'url'=> 'http://tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{Z}/{X}/{Y}.png'), 53*628e43ccSMark Prins // OCM sources 54*628e43ccSMark Prins 'cycle'=>array( 55*628e43ccSMark Prins 'txt'=>'OpenCycleMap tiles', 56*628e43ccSMark Prins 'logo'=>'cycle_logo.png', 57*628e43ccSMark Prins 'url'=>'http://tile.opencyclemap.org/cycle/{Z}/{X}/{Y}.png'), 58*628e43ccSMark Prins 'transport'=>array( 59*628e43ccSMark Prins 'txt'=>'OpenCycleMap tiles', 60*628e43ccSMark Prins 'logo'=>'cycle_logo.png', 61*628e43ccSMark Prins 'url'=>'http://tile2.opencyclemap.org/transport/{Z}/{X}/{Y}.png'), 62*628e43ccSMark Prins 'landscape'=>array( 63*628e43ccSMark Prins 'txt'=>'OpenCycleMap tiles', 64*628e43ccSMark Prins 'logo'=>'cycle_logo.png', 65*628e43ccSMark Prins 'url'=>'http://tile3.opencyclemap.org/landscape/{Z}/{X}/{Y}.png'), 66*628e43ccSMark Prins // H&B sources 67*628e43ccSMark Prins 'hikeandbike'=>array( 68*628e43ccSMark Prins 'txt'=>'Hike & Bike Map', 69*628e43ccSMark Prins 'logo'=>'hnb_logo.png', 70*628e43ccSMark Prins 'url'=>'http://toolserver.org/tiles/hikebike/{Z}/{X}/{Y}.png'), 71*628e43ccSMark Prins //'piste'=>array( 72*628e43ccSMark Prins // 'txt'=>'OpenPisteMap tiles', 73*628e43ccSMark Prins // 'logo'=>'piste_logo.png', 74*628e43ccSMark Prins // 'url'=>''), 75*628e43ccSMark Prins //'sea'=>array( 76*628e43ccSMark Prins // 'txt'=>'OpenSeaMap tiles', 77*628e43ccSMark Prins // 'logo'=>'sea_logo.png', 78*628e43ccSMark Prins // 'url'=>''), 79*628e43ccSMark Prins // MapQuest 80*628e43ccSMark Prins 'mapquest'=>array( 81*628e43ccSMark Prins 'txt'=>'MapQuest tiles', 82*628e43ccSMark Prins 'logo'=>'mq_logo.png', 83*628e43ccSMark Prins 'url'=>'http://otile3.mqcdn.com/tiles/1.0.0/osm/{Z}/{X}/{Y}.png') 84*628e43ccSMark Prins ); 85*628e43ccSMark Prins protected $tileDefaultSrc = 'openstreetmap'; 86*628e43ccSMark Prins 87*628e43ccSMark Prins // set up markers 88*628e43ccSMark Prins protected $markerPrototypes = array( 89*628e43ccSMark Prins // found at http://www.mapito.net/map-marker-icons.html 90*628e43ccSMark Prins // these are 17x19 px with a pointer at the bottom left 91*628e43ccSMark Prins 'lighblue' => array('regex'=>'/^lightblue([0-9]+)$/', 92*628e43ccSMark Prins 'extension'=>'.png', 93*628e43ccSMark Prins 'shadow'=>false, 94*628e43ccSMark Prins 'offsetImage'=>'0,-19', 95*628e43ccSMark Prins 'offsetShadow'=>false 96*628e43ccSMark Prins ), 97*628e43ccSMark Prins // openlayers std markers are 21x25px with shadow 98*628e43ccSMark Prins 'ol-marker'=> array('regex'=>'/^marker(|-blue|-gold|-green|-red)+$/', 99*628e43ccSMark Prins 'extension'=>'.png', 100*628e43ccSMark Prins 'shadow'=>'marker_shadow.png', 101*628e43ccSMark Prins 'offsetImage'=>'-10,-25', 102*628e43ccSMark Prins 'offsetShadow'=>'-1,-13' 103*628e43ccSMark Prins ), 104*628e43ccSMark Prins // these are 16x16 px 105*628e43ccSMark Prins 'ww_icon'=> array('regex'=>'/ww_\S+$/', 106*628e43ccSMark Prins 'extension'=>'.png', 107*628e43ccSMark Prins 'shadow'=>false, 108*628e43ccSMark Prins 'offsetImage'=>'-8,-8', 109*628e43ccSMark Prins 'offsetShadow'=>false 110*628e43ccSMark Prins ), 111*628e43ccSMark Prins // assume these are 16x16 px 112*628e43ccSMark Prins 'rest' => array('regex'=>'/^(?!lightblue([0-9]+)$)(?!(ww_\S+$))(?!marker(|-blue|-gold|-green|-red)+$)(.*)/', 113*628e43ccSMark Prins 'extension'=>'.png', 114*628e43ccSMark Prins 'shadow'=>'marker_shadow.png', 115*628e43ccSMark Prins 'offsetImage'=>'-8,-8', 116*628e43ccSMark Prins 'offsetShadow'=>'-1,-1' 117*628e43ccSMark Prins ) 118*628e43ccSMark Prins ); 119*628e43ccSMark Prins protected $centerX, $centerY, $offsetX, $offsetY, $image; 120*628e43ccSMark Prins protected $zoom, $lat, $lon, $width, $height, $markers, $maptype, $kmlFileName, $gpxFileName; 121*628e43ccSMark Prins protected $tileCacheBaseDir, $mapCacheBaseDir, $mediaBaseDir; 122*628e43ccSMark Prins protected $useTileCache = true; 123*628e43ccSMark Prins protected $mapCacheID = ''; 124*628e43ccSMark Prins protected $mapCacheFile = ''; 125*628e43ccSMark Prins protected $mapCacheExtension = 'png'; 126*628e43ccSMark Prins 127*628e43ccSMark Prins /** 128*628e43ccSMark Prins * 129*628e43ccSMark Prins * @param number $lat 130*628e43ccSMark Prins * @param number $lon 131*628e43ccSMark Prins * @param number $zoom 132*628e43ccSMark Prins * @param number $width 133*628e43ccSMark Prins * @param number $height 134*628e43ccSMark Prins * @param string $maptype 135*628e43ccSMark Prins * @param mixed $markers 136*628e43ccSMark Prins * @param string $gpx 137*628e43ccSMark Prins * @param string $kml 138*628e43ccSMark Prins * @param string $mediaDir 139*628e43ccSMark Prins * @param string $tileCacheBaseDir 140*628e43ccSMark Prins */ 141*628e43ccSMark Prins public function __construct($lat,$lon,$zoom,$width,$height,$maptype, $markers,$gpx,$kml,$mediaDir,$tileCacheBaseDir){ 142*628e43ccSMark Prins $this->zoom = $zoom; 143*628e43ccSMark Prins $this->lat = $lat; 144*628e43ccSMark Prins $this->lon = $lon; 145*628e43ccSMark Prins $this->width = $width; 146*628e43ccSMark Prins $this->height = $height; 147*628e43ccSMark Prins $this->markers = $markers; 148*628e43ccSMark Prins $this->mediaBaseDir = $mediaDir; 149*628e43ccSMark Prins // validate + set maptype 150*628e43ccSMark Prins $this->maptype = $this->tileDefaultSrc; 151*628e43ccSMark Prins if(array_key_exists($maptype,$this->tileInfo)) { 152*628e43ccSMark Prins $this->maptype = $maptype; 153*628e43ccSMark Prins } 154*628e43ccSMark Prins 155*628e43ccSMark Prins $this->tileCacheBaseDir= $tileCacheBaseDir.'/olmaptiles'; 156*628e43ccSMark Prins $this->useTileCache = $this->tileCacheBaseDir !==''; 157*628e43ccSMark Prins $this->mapCacheBaseDir = $mediaDir.'/olmapmaps'; 158*628e43ccSMark Prins 159*628e43ccSMark Prins $this->kmlFileName = $this->mediaBaseDir.str_replace(":","/",$kml); 160*628e43ccSMark Prins $this->gpxFileName = $this->mediaBaseDir.str_replace(":","/",$gpx); 161*628e43ccSMark Prins } 162*628e43ccSMark Prins 163*628e43ccSMark Prins /** 164*628e43ccSMark Prins * 165*628e43ccSMark Prins * @param number $long 166*628e43ccSMark Prins * @param number $zoom 167*628e43ccSMark Prins */ 168*628e43ccSMark Prins public function lonToTile($long, $zoom){ 169*628e43ccSMark Prins return (($long + 180) / 360) * pow(2, $zoom); 170*628e43ccSMark Prins } 171*628e43ccSMark Prins /** 172*628e43ccSMark Prins * 173*628e43ccSMark Prins * @param number $lat 174*628e43ccSMark Prins * @param number $zoom 175*628e43ccSMark Prins * @return number 176*628e43ccSMark Prins */ 177*628e43ccSMark Prins public function latToTile($lat, $zoom){ 178*628e43ccSMark Prins return (1 - log(tan($lat * pi()/180) + 1 / cos($lat* pi()/180)) / pi()) /2 * pow(2, $zoom); 179*628e43ccSMark Prins } 180*628e43ccSMark Prins /** 181*628e43ccSMark Prins * 182*628e43ccSMark Prins */ 183*628e43ccSMark Prins public function initCoords(){ 184*628e43ccSMark Prins $this->centerX = $this->lonToTile($this->lon, $this->zoom); 185*628e43ccSMark Prins $this->centerY = $this->latToTile($this->lat, $this->zoom); 186*628e43ccSMark Prins $this->offsetX = floor((floor($this->centerX)-$this->centerX)*$this->tileSize); 187*628e43ccSMark Prins $this->offsetY = floor((floor($this->centerY)-$this->centerY)*$this->tileSize); 188*628e43ccSMark Prins } 189*628e43ccSMark Prins 190*628e43ccSMark Prins /** 191*628e43ccSMark Prins * make basemap image. 192*628e43ccSMark Prins */ 193*628e43ccSMark Prins public function createBaseMap(){ 194*628e43ccSMark Prins $this->image = imagecreatetruecolor($this->width, $this->height); 195*628e43ccSMark Prins $startX = floor($this->centerX-($this->width/$this->tileSize)/2); 196*628e43ccSMark Prins $startY = floor($this->centerY-($this->height/$this->tileSize)/2); 197*628e43ccSMark Prins $endX = ceil($this->centerX+($this->width/$this->tileSize)/2); 198*628e43ccSMark Prins $endY = ceil($this->centerY+($this->height/$this->tileSize)/2); 199*628e43ccSMark Prins $this->offsetX = -floor(($this->centerX-floor($this->centerX))*$this->tileSize); 200*628e43ccSMark Prins $this->offsetY = -floor(($this->centerY-floor($this->centerY))*$this->tileSize); 201*628e43ccSMark Prins $this->offsetX += floor($this->width/2); 202*628e43ccSMark Prins $this->offsetY += floor($this->height/2); 203*628e43ccSMark Prins $this->offsetX += floor($startX-floor($this->centerX))*$this->tileSize; 204*628e43ccSMark Prins $this->offsetY += floor($startY-floor($this->centerY))*$this->tileSize; 205*628e43ccSMark Prins 206*628e43ccSMark Prins for($x=$startX; $x<=$endX; $x++){ 207*628e43ccSMark Prins for($y=$startY; $y<=$endY; $y++){ 208*628e43ccSMark Prins $url = str_replace(array('{Z}','{X}','{Y}'),array($this->zoom, $x, $y), $this->tileInfo[$this->maptype]['url']); 209*628e43ccSMark Prins $tileData = $this->fetchTile($url); 210*628e43ccSMark Prins if($tileData){ 211*628e43ccSMark Prins $tileImage = imagecreatefromstring($tileData); 212*628e43ccSMark Prins } else { 213*628e43ccSMark Prins $tileImage = imagecreate($this->tileSize,$this->tileSize); 214*628e43ccSMark Prins $color = imagecolorallocate($tileImage, 255, 255, 255); 215*628e43ccSMark Prins @imagestring($tileImage,1,127,127,'err',$color); 216*628e43ccSMark Prins } 217*628e43ccSMark Prins $destX = ($x-$startX)*$this->tileSize+$this->offsetX; 218*628e43ccSMark Prins $destY = ($y-$startY)*$this->tileSize+$this->offsetY; 219*628e43ccSMark Prins imagecopy($this->image, $tileImage, $destX, $destY, 0, 0, $this->tileSize, $this->tileSize); 220*628e43ccSMark Prins } 221*628e43ccSMark Prins } 222*628e43ccSMark Prins } 223*628e43ccSMark Prins 224*628e43ccSMark Prins /** 225*628e43ccSMark Prins * Place markers on the map and number them in the same order as they are listed in the html. 226*628e43ccSMark Prins */ 227*628e43ccSMark Prins public function placeMarkers(){ 228*628e43ccSMark Prins $count=0; 229*628e43ccSMark Prins $color=imagecolorallocate ($this->image,0,0,0 ); 230*628e43ccSMark Prins $bgcolor=imagecolorallocate ($this->image,200,200,200 ); 231*628e43ccSMark Prins $markerBaseDir = dirname(__FILE__).'/icons'; 232*628e43ccSMark Prins // loop thru marker array 233*628e43ccSMark Prins foreach($this->markers as $marker){ 234*628e43ccSMark Prins // set some local variables 235*628e43ccSMark Prins $markerLat = $marker['lat']; 236*628e43ccSMark Prins $markerLon = $marker['lon']; 237*628e43ccSMark Prins $markerType = $marker['type']; 238*628e43ccSMark Prins // clear variables from previous loops 239*628e43ccSMark Prins $markerFilename = ''; 240*628e43ccSMark Prins $markerShadow = ''; 241*628e43ccSMark Prins $matches = false; 242*628e43ccSMark Prins // check for marker type, get settings from markerPrototypes 243*628e43ccSMark Prins if($markerType){ 244*628e43ccSMark Prins foreach($this->markerPrototypes as $markerPrototype){ 245*628e43ccSMark Prins if(preg_match($markerPrototype['regex'],$markerType,$matches)){ 246*628e43ccSMark Prins $markerFilename = $matches[0].$markerPrototype['extension']; 247*628e43ccSMark Prins if($markerPrototype['offsetImage']){ 248*628e43ccSMark Prins list($markerImageOffsetX, $markerImageOffsetY) = split(",",$markerPrototype['offsetImage']); 249*628e43ccSMark Prins } 250*628e43ccSMark Prins $markerShadow = $markerPrototype['shadow']; 251*628e43ccSMark Prins if($markerShadow){ 252*628e43ccSMark Prins list($markerShadowOffsetX, $markerShadowOffsetY) = split(",",$markerPrototype['offsetShadow']); 253*628e43ccSMark Prins } 254*628e43ccSMark Prins } 255*628e43ccSMark Prins } 256*628e43ccSMark Prins } 257*628e43ccSMark Prins // create img resource 258*628e43ccSMark Prins if(file_exists($markerBaseDir.'/'.$markerFilename)){ 259*628e43ccSMark Prins $markerImg = imagecreatefrompng($markerBaseDir.'/'.$markerFilename); 260*628e43ccSMark Prins } else { 261*628e43ccSMark Prins $markerImg = imagecreatefrompng($markerBaseDir.'/marker.png'); 262*628e43ccSMark Prins } 263*628e43ccSMark Prins // check for shadow + create shadow recource 264*628e43ccSMark Prins if($markerShadow && file_exists($markerBaseDir.'/'.$markerShadow)){ 265*628e43ccSMark Prins $markerShadowImg = imagecreatefrompng($markerBaseDir.'/'.$markerShadow); 266*628e43ccSMark Prins } 267*628e43ccSMark Prins // calc position 268*628e43ccSMark Prins $destX = floor(($this->width/2)-$this->tileSize*($this->centerX-$this->lonToTile($markerLon, $this->zoom))); 269*628e43ccSMark Prins $destY = floor(($this->height/2)-$this->tileSize*($this->centerY-$this->latToTile($markerLat, $this->zoom))); 270*628e43ccSMark Prins // copy shadow on basemap 271*628e43ccSMark Prins if($markerShadow && $markerShadowImg){ 272*628e43ccSMark Prins imagecopy($this->image, $markerShadowImg, $destX+intval($markerShadowOffsetX), $destY+intval($markerShadowOffsetY), 273*628e43ccSMark Prins 0, 0, imagesx($markerShadowImg), imagesy($markerShadowImg)); 274*628e43ccSMark Prins } 275*628e43ccSMark Prins // copy marker on basemap above shadow 276*628e43ccSMark Prins imagecopy($this->image, $markerImg, $destX+intval($markerImageOffsetX), $destY+intval($markerImageOffsetY), 277*628e43ccSMark Prins 0, 0, imagesx($markerImg), imagesy($markerImg)); 278*628e43ccSMark Prins // add label 279*628e43ccSMark Prins imagestring ($this->image , 3 , $destX-imagesx($markerImg)+1 , $destY+intval($markerImageOffsetY)+1 , ++$count , $bgcolor ); 280*628e43ccSMark Prins imagestring ($this->image , 3 , $destX-imagesx($markerImg) , $destY+intval($markerImageOffsetY) , $count , $color ); 281*628e43ccSMark Prins }; 282*628e43ccSMark Prins } 283*628e43ccSMark Prins /** 284*628e43ccSMark Prins * 285*628e43ccSMark Prins * @param string $url 286*628e43ccSMark Prins * @return string 287*628e43ccSMark Prins */ 288*628e43ccSMark Prins public function tileUrlToFilename($url){ 289*628e43ccSMark Prins return $this->tileCacheBaseDir."/".str_replace(array('http://'),'',$url); 290*628e43ccSMark Prins } 291*628e43ccSMark Prins /** 292*628e43ccSMark Prins * 293*628e43ccSMark Prins * @param string $url 294*628e43ccSMark Prins */ 295*628e43ccSMark Prins public function checkTileCache($url){ 296*628e43ccSMark Prins $filename = $this->tileUrlToFilename($url); 297*628e43ccSMark Prins if(file_exists($filename)){ 298*628e43ccSMark Prins return file_get_contents($filename); 299*628e43ccSMark Prins } 300*628e43ccSMark Prins } 301*628e43ccSMark Prins 302*628e43ccSMark Prins public function checkMapCache(){ 303*628e43ccSMark Prins $this->mapCacheID = md5($this->serializeParams()); 304*628e43ccSMark Prins $filename = $this->mapCacheIDToFilename(); 305*628e43ccSMark Prins if(file_exists($filename)) return true; 306*628e43ccSMark Prins } 307*628e43ccSMark Prins 308*628e43ccSMark Prins public function serializeParams(){ 309*628e43ccSMark Prins return join("&",array($this->zoom,$this->lat,$this->lon,$this->width,$this->height, serialize($this->markers),$this->maptype)); 310*628e43ccSMark Prins } 311*628e43ccSMark Prins 312*628e43ccSMark Prins public function mapCacheIDToFilename(){ 313*628e43ccSMark Prins if(!$this->mapCacheFile){ 314*628e43ccSMark Prins $this->mapCacheFile = $this->mapCacheBaseDir."/".$this->maptype."/".$this->zoom."/cache_".substr($this->mapCacheID,0,2)."/".substr($this->mapCacheID,2,2)."/".substr($this->mapCacheID,4); 315*628e43ccSMark Prins } 316*628e43ccSMark Prins return $this->mapCacheFile.".".$this->mapCacheExtension; 317*628e43ccSMark Prins } 318*628e43ccSMark Prins 319*628e43ccSMark Prins public function mkdir_recursive($pathname, $mode){ 320*628e43ccSMark Prins is_dir(dirname($pathname)) || $this->mkdir_recursive(dirname($pathname), $mode); 321*628e43ccSMark Prins return is_dir($pathname) || @mkdir($pathname, $mode); 322*628e43ccSMark Prins } 323*628e43ccSMark Prins 324*628e43ccSMark Prins public function writeTileToCache($url, $data){ 325*628e43ccSMark Prins $filename = $this->tileUrlToFilename($url); 326*628e43ccSMark Prins $this->mkdir_recursive(dirname($filename),0777); 327*628e43ccSMark Prins file_put_contents($filename, $data); 328*628e43ccSMark Prins } 329*628e43ccSMark Prins 330*628e43ccSMark Prins public function fetchTile($url){ 331*628e43ccSMark Prins if($this->useTileCache && ($cached = $this->checkTileCache($url))) return $cached; 332*628e43ccSMark Prins $ch = curl_init(); 333*628e43ccSMark Prins curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 334*628e43ccSMark Prins curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; DokuWikiSpatial HTTP Client; '.PHP_OS.')'); 335*628e43ccSMark Prins curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 336*628e43ccSMark Prins curl_setopt($ch, CURLOPT_URL, $url); 337*628e43ccSMark Prins $tile = curl_exec($ch); 338*628e43ccSMark Prins curl_close($ch); 339*628e43ccSMark Prins if($tile && $this->useTileCache){ 340*628e43ccSMark Prins $this->writeTileToCache($url,$tile); 341*628e43ccSMark Prins } 342*628e43ccSMark Prins return $tile; 343*628e43ccSMark Prins } 344*628e43ccSMark Prins 345*628e43ccSMark Prins /** 346*628e43ccSMark Prins * Draw gpx trace on the map. 347*628e43ccSMark Prins */ 348*628e43ccSMark Prins public function drawGPX(){ 349*628e43ccSMark Prins //TODO implementation 350*628e43ccSMark Prins //determine bbox gpx 351*628e43ccSMark Prins } 352*628e43ccSMark Prins 353*628e43ccSMark Prins /** 354*628e43ccSMark Prins * Draw kml trace on the map. 355*628e43ccSMark Prins */ 356*628e43ccSMark Prins public function drawKML(){ 357*628e43ccSMark Prins //TODO implementation 358*628e43ccSMark Prins } 359*628e43ccSMark Prins 360*628e43ccSMark Prins /** 361*628e43ccSMark Prins * add copyright and origin notice and icons to the map. 362*628e43ccSMark Prins */ 363*628e43ccSMark Prins public function drawCopyright(){ 364*628e43ccSMark Prins $logoBaseDir = dirname(__FILE__).'/'.'logo/'; 365*628e43ccSMark Prins $logoImg = imagecreatefrompng($logoBaseDir.$this->tileInfo['openstreetmap']['logo']); 366*628e43ccSMark Prins $textcolor = imagecolorallocate($this->image, 0, 0, 0); 367*628e43ccSMark Prins $bgcolor = imagecolorallocate($this->image, 200, 200, 200); 368*628e43ccSMark Prins 369*628e43ccSMark Prins imagecopy($this->image, 370*628e43ccSMark Prins $logoImg, 371*628e43ccSMark Prins 0, 372*628e43ccSMark Prins imagesy($this->image)-imagesy($logoImg), 373*628e43ccSMark Prins 0, 374*628e43ccSMark Prins 0, 375*628e43ccSMark Prins imagesx($logoImg), 376*628e43ccSMark Prins imagesy($logoImg) 377*628e43ccSMark Prins ); 378*628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+2 , imagesy($this->image)-imagesy($logoImg)+1 , $this->tileInfo['openstreetmap']['txt'],$bgcolor ); 379*628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+1 , imagesy($this->image)-imagesy($logoImg) , $this->tileInfo['openstreetmap']['txt'] ,$textcolor ); 380*628e43ccSMark Prins 381*628e43ccSMark Prins // additional tile source info, ie. who created/hosted the tiles 382*628e43ccSMark Prins if ($this->maptype!='openstreetmap') { 383*628e43ccSMark Prins $iconImg = imagecreatefrompng($logoBaseDir.$this->tileInfo[$this->maptype]['logo']); 384*628e43ccSMark Prins imagecopy($this->image, 385*628e43ccSMark Prins $iconImg, 386*628e43ccSMark Prins imagesx($logoImg)+1, 387*628e43ccSMark Prins imagesy($this->image)-imagesy($iconImg), 388*628e43ccSMark Prins 0, 389*628e43ccSMark Prins 0, 390*628e43ccSMark Prins imagesx($iconImg), 391*628e43ccSMark Prins imagesy($iconImg) 392*628e43ccSMark Prins ); 393*628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+imagesx($iconImg)+4 , imagesy($this->image)-ceil(imagesy($logoImg)/2)+1 , $this->tileInfo[$this->maptype]['txt'],$bgcolor ); 394*628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+imagesx($iconImg)+3 , imagesy($this->image)-ceil(imagesy($logoImg)/2) , $this->tileInfo[$this->maptype]['txt'] ,$textcolor ); 395*628e43ccSMark Prins } 396*628e43ccSMark Prins } 397*628e43ccSMark Prins /** 398*628e43ccSMark Prins * make the map. 399*628e43ccSMark Prins */ 400*628e43ccSMark Prins public function makeMap(){ 401*628e43ccSMark Prins $this->initCoords(); 402*628e43ccSMark Prins $this->createBaseMap(); 403*628e43ccSMark Prins if(count($this->markers))$this->placeMarkers(); 404*628e43ccSMark Prins if(file_exists($this->kmlFileName)) $this->drawKML(); 405*628e43ccSMark Prins if(file_exists($this->gpxFileName)) $this->drawGPX(); 406*628e43ccSMark Prins $this->drawCopyright(); 407*628e43ccSMark Prins } 408*628e43ccSMark Prins /** 409*628e43ccSMark Prins * get the map, this may return a reference to a cached copy. 410*628e43ccSMark Prins * @return string url relative to media dir 411*628e43ccSMark Prins */ 412*628e43ccSMark Prins public function getMap(){ 413*628e43ccSMark Prins // use map cache, so check cache for map 414*628e43ccSMark Prins if(!$this->checkMapCache()){ 415*628e43ccSMark Prins // map is not in cache, needs to be build 416*628e43ccSMark Prins $this->makeMap(); 417*628e43ccSMark Prins $this->mkdir_recursive(dirname($this->mapCacheIDToFilename()),0777); 418*628e43ccSMark Prins imagepng($this->image,$this->mapCacheIDToFilename(),9); 419*628e43ccSMark Prins } 420*628e43ccSMark Prins $this->doc =$this->mapCacheIDToFilename(); 421*628e43ccSMark Prins // make url relative to media dir 422*628e43ccSMark Prins return str_replace($this->mediaBaseDir, '', $this->doc); 423*628e43ccSMark Prins } 424*628e43ccSMark Prins} 425