1628e43ccSMark Prins<?php 2628e43ccSMark Prins 3628e43ccSMark Prins/* 4628e43ccSMark Prins * Copyright (c) 2012 Mark C. Prins <mprins@users.sf.net> 5628e43ccSMark Prins* 6628e43ccSMark Prins* Based on staticMapLite 0.03 available at http://staticmaplite.svn.sourceforge.net/viewvc/staticmaplite/ 7628e43ccSMark Prins* 8628e43ccSMark Prins* Copyright (c) 2009 Gerhard Koch <gerhard.koch AT ymail.com> 9628e43ccSMark Prins* 10628e43ccSMark Prins* Licensed under the Apache License, Version 2.0 (the "License"); 11628e43ccSMark Prins* you may not use this file except in compliance with the License. 12628e43ccSMark Prins* You may obtain a copy of the License at 13628e43ccSMark Prins* 14628e43ccSMark Prins* http://www.apache.org/licenses/LICENSE-2.0 15628e43ccSMark Prins* 16628e43ccSMark Prins* Unless required by applicable law or agreed to in writing, software 17628e43ccSMark Prins* distributed under the License is distributed on an "AS IS" BASIS, 18628e43ccSMark Prins* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19628e43ccSMark Prins* See the License for the specific language governing permissions and 20628e43ccSMark Prins* limitations under the License. 21628e43ccSMark Prins*/ 226c6bb022SMark Prinsinclude_once('geoPHP/geoPHP.inc'); 23628e43ccSMark 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 { 29628e43ccSMark Prins // these 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', 40628e43ccSMark Prins 'url'=>'http://tile.openstreetmap.org/{Z}/{X}/{Y}.png'), 41628e43ccSMark Prins // cloudmade 42628e43ccSMark Prins 'cloudmade' =>array( 43628e43ccSMark Prins 'txt'=>'CloudMade tiles', 44628e43ccSMark Prins 'logo'=>'cloudmade_logo.png', 45628e43ccSMark Prins 'url'=> 'http://tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/2/256/{Z}/{X}/{Y}.png'), 46628e43ccSMark Prins 'fresh' =>array( 47628e43ccSMark Prins 'txt'=>'CloudMade tiles', 48628e43ccSMark Prins 'logo'=>'cloudmade_logo.png', 49628e43ccSMark Prins 'url'=> 'http://tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/{Z}/{X}/{Y}.png'), 50628e43ccSMark Prins // OCM sources 51628e43ccSMark Prins 'cycle'=>array( 52628e43ccSMark Prins 'txt'=>'OpenCycleMap tiles', 53628e43ccSMark Prins 'logo'=>'cycle_logo.png', 54628e43ccSMark Prins 'url'=>'http://tile.opencyclemap.org/cycle/{Z}/{X}/{Y}.png'), 55628e43ccSMark Prins 'transport'=>array( 56628e43ccSMark Prins 'txt'=>'OpenCycleMap tiles', 57628e43ccSMark Prins 'logo'=>'cycle_logo.png', 58628e43ccSMark Prins 'url'=>'http://tile2.opencyclemap.org/transport/{Z}/{X}/{Y}.png'), 59628e43ccSMark Prins 'landscape'=>array( 60628e43ccSMark Prins 'txt'=>'OpenCycleMap tiles', 61628e43ccSMark Prins 'logo'=>'cycle_logo.png', 62628e43ccSMark Prins 'url'=>'http://tile3.opencyclemap.org/landscape/{Z}/{X}/{Y}.png'), 63628e43ccSMark Prins // H&B sources 64628e43ccSMark Prins 'hikeandbike'=>array( 65628e43ccSMark Prins 'txt'=>'Hike & Bike Map', 66628e43ccSMark Prins 'logo'=>'hnb_logo.png', 67628e43ccSMark Prins 'url'=>'http://toolserver.org/tiles/hikebike/{Z}/{X}/{Y}.png'), 68628e43ccSMark Prins //'piste'=>array( 69628e43ccSMark Prins // 'txt'=>'OpenPisteMap tiles', 70628e43ccSMark Prins // 'logo'=>'piste_logo.png', 71628e43ccSMark Prins // 'url'=>''), 72628e43ccSMark Prins //'sea'=>array( 73628e43ccSMark Prins // 'txt'=>'OpenSeaMap tiles', 74628e43ccSMark Prins // 'logo'=>'sea_logo.png', 75628e43ccSMark Prins // 'url'=>''), 76628e43ccSMark Prins // MapQuest 77628e43ccSMark Prins 'mapquest'=>array( 78628e43ccSMark Prins 'txt'=>'MapQuest tiles', 79628e43ccSMark Prins 'logo'=>'mq_logo.png', 80628e43ccSMark Prins 'url'=>'http://otile3.mqcdn.com/tiles/1.0.0/osm/{Z}/{X}/{Y}.png') 81628e43ccSMark Prins ); 82628e43ccSMark Prins protected $tileDefaultSrc = 'openstreetmap'; 83628e43ccSMark Prins 84628e43ccSMark Prins // set up markers 85628e43ccSMark Prins protected $markerPrototypes = array( 86628e43ccSMark Prins // found at http://www.mapito.net/map-marker-icons.html 87628e43ccSMark Prins // these are 17x19 px with a pointer at the bottom left 88628e43ccSMark Prins 'lighblue' => array('regex'=>'/^lightblue([0-9]+)$/', 89628e43ccSMark Prins 'extension'=>'.png', 90628e43ccSMark Prins 'shadow'=>false, 91628e43ccSMark Prins 'offsetImage'=>'0,-19', 92628e43ccSMark Prins 'offsetShadow'=>false 93628e43ccSMark Prins ), 94628e43ccSMark Prins // openlayers std markers are 21x25px with shadow 95628e43ccSMark Prins 'ol-marker'=> array('regex'=>'/^marker(|-blue|-gold|-green|-red)+$/', 96628e43ccSMark Prins 'extension'=>'.png', 97628e43ccSMark Prins 'shadow'=>'marker_shadow.png', 98628e43ccSMark Prins 'offsetImage'=>'-10,-25', 99628e43ccSMark Prins 'offsetShadow'=>'-1,-13' 100628e43ccSMark Prins ), 101628e43ccSMark Prins // these are 16x16 px 102628e43ccSMark Prins 'ww_icon'=> array('regex'=>'/ww_\S+$/', 103628e43ccSMark Prins 'extension'=>'.png', 104628e43ccSMark Prins 'shadow'=>false, 105628e43ccSMark Prins 'offsetImage'=>'-8,-8', 106628e43ccSMark Prins 'offsetShadow'=>false 107628e43ccSMark Prins ), 108628e43ccSMark Prins // assume these are 16x16 px 109628e43ccSMark Prins 'rest' => array('regex'=>'/^(?!lightblue([0-9]+)$)(?!(ww_\S+$))(?!marker(|-blue|-gold|-green|-red)+$)(.*)/', 110628e43ccSMark Prins 'extension'=>'.png', 111628e43ccSMark Prins 'shadow'=>'marker_shadow.png', 112628e43ccSMark Prins 'offsetImage'=>'-8,-8', 113628e43ccSMark Prins 'offsetShadow'=>'-1,-1' 114628e43ccSMark Prins ) 115628e43ccSMark Prins ); 116628e43ccSMark Prins protected $centerX, $centerY, $offsetX, $offsetY, $image; 117628e43ccSMark Prins protected $zoom, $lat, $lon, $width, $height, $markers, $maptype, $kmlFileName, $gpxFileName; 118628e43ccSMark Prins protected $tileCacheBaseDir, $mapCacheBaseDir, $mediaBaseDir; 119628e43ccSMark Prins protected $useTileCache = true; 120628e43ccSMark Prins protected $mapCacheID = ''; 121628e43ccSMark Prins protected $mapCacheFile = ''; 122628e43ccSMark Prins protected $mapCacheExtension = 'png'; 123628e43ccSMark Prins 124628e43ccSMark Prins /** 125628e43ccSMark Prins * 126628e43ccSMark Prins * @param number $lat 127628e43ccSMark Prins * @param number $lon 128628e43ccSMark Prins * @param number $zoom 129628e43ccSMark Prins * @param number $width 130628e43ccSMark Prins * @param number $height 131628e43ccSMark Prins * @param string $maptype 132628e43ccSMark Prins * @param mixed $markers 133628e43ccSMark Prins * @param string $gpx 134628e43ccSMark Prins * @param string $kml 135628e43ccSMark Prins * @param string $mediaDir 136628e43ccSMark Prins * @param string $tileCacheBaseDir 137628e43ccSMark Prins */ 138628e43ccSMark Prins public function __construct($lat,$lon,$zoom,$width,$height,$maptype, $markers,$gpx,$kml,$mediaDir,$tileCacheBaseDir){ 139628e43ccSMark Prins $this->zoom = $zoom; 140628e43ccSMark Prins $this->lat = $lat; 141628e43ccSMark Prins $this->lon = $lon; 142628e43ccSMark Prins $this->width = $width; 143628e43ccSMark Prins $this->height = $height; 144628e43ccSMark Prins $this->markers = $markers; 145628e43ccSMark Prins $this->mediaBaseDir = $mediaDir; 146628e43ccSMark Prins // validate + set maptype 147628e43ccSMark Prins $this->maptype = $this->tileDefaultSrc; 148628e43ccSMark Prins if(array_key_exists($maptype,$this->tileInfo)) { 149628e43ccSMark Prins $this->maptype = $maptype; 150628e43ccSMark Prins } 151628e43ccSMark Prins 152628e43ccSMark Prins $this->tileCacheBaseDir= $tileCacheBaseDir.'/olmaptiles'; 153628e43ccSMark Prins $this->useTileCache = $this->tileCacheBaseDir !==''; 154628e43ccSMark Prins $this->mapCacheBaseDir = $mediaDir.'/olmapmaps'; 155628e43ccSMark Prins 156*da6f229fSMark Prins $this->kmlFileName = $kml; 157*da6f229fSMark Prins $this->gpxFileName = $gpx; 158628e43ccSMark Prins } 159628e43ccSMark Prins 160628e43ccSMark Prins /** 161628e43ccSMark Prins * 162628e43ccSMark Prins * @param number $long 163628e43ccSMark Prins * @param number $zoom 164628e43ccSMark Prins */ 165628e43ccSMark Prins public function lonToTile($long, $zoom){ 166628e43ccSMark Prins return (($long + 180) / 360) * pow(2, $zoom); 167628e43ccSMark Prins } 168628e43ccSMark Prins /** 169628e43ccSMark Prins * 170628e43ccSMark Prins * @param number $lat 171628e43ccSMark Prins * @param number $zoom 172628e43ccSMark Prins * @return number 173628e43ccSMark Prins */ 174628e43ccSMark Prins public function latToTile($lat, $zoom){ 175628e43ccSMark Prins return (1 - log(tan($lat * pi()/180) + 1 / cos($lat* pi()/180)) / pi()) /2 * pow(2, $zoom); 176628e43ccSMark Prins } 177628e43ccSMark Prins /** 178628e43ccSMark Prins * 179628e43ccSMark Prins */ 180628e43ccSMark Prins public function initCoords(){ 181628e43ccSMark Prins $this->centerX = $this->lonToTile($this->lon, $this->zoom); 182628e43ccSMark Prins $this->centerY = $this->latToTile($this->lat, $this->zoom); 183628e43ccSMark Prins $this->offsetX = floor((floor($this->centerX)-$this->centerX)*$this->tileSize); 184628e43ccSMark Prins $this->offsetY = floor((floor($this->centerY)-$this->centerY)*$this->tileSize); 185628e43ccSMark Prins } 186628e43ccSMark Prins 187628e43ccSMark Prins /** 188628e43ccSMark Prins * make basemap image. 189628e43ccSMark Prins */ 190628e43ccSMark Prins public function createBaseMap(){ 191628e43ccSMark Prins $this->image = imagecreatetruecolor($this->width, $this->height); 192628e43ccSMark Prins $startX = floor($this->centerX-($this->width/$this->tileSize)/2); 193628e43ccSMark Prins $startY = floor($this->centerY-($this->height/$this->tileSize)/2); 194628e43ccSMark Prins $endX = ceil($this->centerX+($this->width/$this->tileSize)/2); 195628e43ccSMark Prins $endY = ceil($this->centerY+($this->height/$this->tileSize)/2); 196628e43ccSMark Prins $this->offsetX = -floor(($this->centerX-floor($this->centerX))*$this->tileSize); 197628e43ccSMark Prins $this->offsetY = -floor(($this->centerY-floor($this->centerY))*$this->tileSize); 198628e43ccSMark Prins $this->offsetX += floor($this->width/2); 199628e43ccSMark Prins $this->offsetY += floor($this->height/2); 200628e43ccSMark Prins $this->offsetX += floor($startX-floor($this->centerX))*$this->tileSize; 201628e43ccSMark Prins $this->offsetY += floor($startY-floor($this->centerY))*$this->tileSize; 202628e43ccSMark Prins 203628e43ccSMark Prins for($x=$startX; $x<=$endX; $x++){ 204628e43ccSMark Prins for($y=$startY; $y<=$endY; $y++){ 205628e43ccSMark Prins $url = str_replace(array('{Z}','{X}','{Y}'),array($this->zoom, $x, $y), $this->tileInfo[$this->maptype]['url']); 206628e43ccSMark Prins $tileData = $this->fetchTile($url); 207628e43ccSMark Prins if($tileData){ 208628e43ccSMark Prins $tileImage = imagecreatefromstring($tileData); 209628e43ccSMark Prins } else { 210628e43ccSMark Prins $tileImage = imagecreate($this->tileSize,$this->tileSize); 211628e43ccSMark Prins $color = imagecolorallocate($tileImage, 255, 255, 255); 212628e43ccSMark Prins @imagestring($tileImage,1,127,127,'err',$color); 213628e43ccSMark Prins } 214628e43ccSMark Prins $destX = ($x-$startX)*$this->tileSize+$this->offsetX; 215628e43ccSMark Prins $destY = ($y-$startY)*$this->tileSize+$this->offsetY; 216628e43ccSMark Prins imagecopy($this->image, $tileImage, $destX, $destY, 0, 0, $this->tileSize, $this->tileSize); 217628e43ccSMark Prins } 218628e43ccSMark Prins } 219628e43ccSMark Prins } 220628e43ccSMark Prins 221628e43ccSMark Prins /** 222628e43ccSMark Prins * Place markers on the map and number them in the same order as they are listed in the html. 223628e43ccSMark Prins */ 224628e43ccSMark Prins public function placeMarkers(){ 225628e43ccSMark Prins $count=0; 226628e43ccSMark Prins $color=imagecolorallocate ($this->image,0,0,0 ); 227628e43ccSMark Prins $bgcolor=imagecolorallocate ($this->image,200,200,200 ); 228628e43ccSMark Prins $markerBaseDir = dirname(__FILE__).'/icons'; 229628e43ccSMark Prins // loop thru marker array 230628e43ccSMark Prins foreach($this->markers as $marker){ 231628e43ccSMark Prins // set some local variables 232628e43ccSMark Prins $markerLat = $marker['lat']; 233628e43ccSMark Prins $markerLon = $marker['lon']; 234628e43ccSMark Prins $markerType = $marker['type']; 235628e43ccSMark Prins // clear variables from previous loops 236628e43ccSMark Prins $markerFilename = ''; 237628e43ccSMark Prins $markerShadow = ''; 238628e43ccSMark Prins $matches = false; 239628e43ccSMark Prins // check for marker type, get settings from markerPrototypes 240628e43ccSMark Prins if($markerType){ 241628e43ccSMark Prins foreach($this->markerPrototypes as $markerPrototype){ 242628e43ccSMark Prins if(preg_match($markerPrototype['regex'],$markerType,$matches)){ 243628e43ccSMark Prins $markerFilename = $matches[0].$markerPrototype['extension']; 244628e43ccSMark Prins if($markerPrototype['offsetImage']){ 245628e43ccSMark Prins list($markerImageOffsetX, $markerImageOffsetY) = split(",",$markerPrototype['offsetImage']); 246628e43ccSMark Prins } 247628e43ccSMark Prins $markerShadow = $markerPrototype['shadow']; 248628e43ccSMark Prins if($markerShadow){ 249628e43ccSMark Prins list($markerShadowOffsetX, $markerShadowOffsetY) = split(",",$markerPrototype['offsetShadow']); 250628e43ccSMark Prins } 251628e43ccSMark Prins } 252628e43ccSMark Prins } 253628e43ccSMark Prins } 254628e43ccSMark Prins // create img resource 255628e43ccSMark Prins if(file_exists($markerBaseDir.'/'.$markerFilename)){ 256628e43ccSMark Prins $markerImg = imagecreatefrompng($markerBaseDir.'/'.$markerFilename); 257628e43ccSMark Prins } else { 258628e43ccSMark Prins $markerImg = imagecreatefrompng($markerBaseDir.'/marker.png'); 259628e43ccSMark Prins } 260628e43ccSMark Prins // check for shadow + create shadow recource 261628e43ccSMark Prins if($markerShadow && file_exists($markerBaseDir.'/'.$markerShadow)){ 262628e43ccSMark Prins $markerShadowImg = imagecreatefrompng($markerBaseDir.'/'.$markerShadow); 263628e43ccSMark Prins } 264628e43ccSMark Prins // calc position 265628e43ccSMark Prins $destX = floor(($this->width/2)-$this->tileSize*($this->centerX-$this->lonToTile($markerLon, $this->zoom))); 266628e43ccSMark Prins $destY = floor(($this->height/2)-$this->tileSize*($this->centerY-$this->latToTile($markerLat, $this->zoom))); 267628e43ccSMark Prins // copy shadow on basemap 268628e43ccSMark Prins if($markerShadow && $markerShadowImg){ 269628e43ccSMark Prins imagecopy($this->image, $markerShadowImg, $destX+intval($markerShadowOffsetX), $destY+intval($markerShadowOffsetY), 270628e43ccSMark Prins 0, 0, imagesx($markerShadowImg), imagesy($markerShadowImg)); 271628e43ccSMark Prins } 272628e43ccSMark Prins // copy marker on basemap above shadow 273628e43ccSMark Prins imagecopy($this->image, $markerImg, $destX+intval($markerImageOffsetX), $destY+intval($markerImageOffsetY), 274628e43ccSMark Prins 0, 0, imagesx($markerImg), imagesy($markerImg)); 275628e43ccSMark Prins // add label 276628e43ccSMark Prins imagestring ($this->image , 3 , $destX-imagesx($markerImg)+1 , $destY+intval($markerImageOffsetY)+1 , ++$count , $bgcolor ); 277628e43ccSMark Prins imagestring ($this->image , 3 , $destX-imagesx($markerImg) , $destY+intval($markerImageOffsetY) , $count , $color ); 278628e43ccSMark Prins }; 279628e43ccSMark Prins } 280628e43ccSMark Prins /** 281628e43ccSMark Prins * 282628e43ccSMark Prins * @param string $url 283628e43ccSMark Prins * @return string 284628e43ccSMark Prins */ 285628e43ccSMark Prins public function tileUrlToFilename($url){ 286628e43ccSMark Prins return $this->tileCacheBaseDir."/".str_replace(array('http://'),'',$url); 287628e43ccSMark Prins } 288628e43ccSMark Prins /** 289628e43ccSMark Prins * 290628e43ccSMark Prins * @param string $url 291628e43ccSMark Prins */ 292628e43ccSMark Prins public function checkTileCache($url){ 293628e43ccSMark Prins $filename = $this->tileUrlToFilename($url); 294628e43ccSMark Prins if(file_exists($filename)){ 295628e43ccSMark Prins return file_get_contents($filename); 296628e43ccSMark Prins } 297628e43ccSMark Prins } 298628e43ccSMark Prins 299628e43ccSMark Prins public function checkMapCache(){ 300628e43ccSMark Prins $this->mapCacheID = md5($this->serializeParams()); 301628e43ccSMark Prins $filename = $this->mapCacheIDToFilename(); 302628e43ccSMark Prins if(file_exists($filename)) return true; 303628e43ccSMark Prins } 304628e43ccSMark Prins 305628e43ccSMark Prins public function serializeParams(){ 306628e43ccSMark Prins return join("&",array($this->zoom,$this->lat,$this->lon,$this->width,$this->height, serialize($this->markers),$this->maptype)); 307628e43ccSMark Prins } 308628e43ccSMark Prins 309628e43ccSMark Prins public function mapCacheIDToFilename(){ 310628e43ccSMark Prins if(!$this->mapCacheFile){ 311628e43ccSMark Prins $this->mapCacheFile = $this->mapCacheBaseDir."/".$this->maptype."/".$this->zoom."/cache_".substr($this->mapCacheID,0,2)."/".substr($this->mapCacheID,2,2)."/".substr($this->mapCacheID,4); 312628e43ccSMark Prins } 313628e43ccSMark Prins return $this->mapCacheFile.".".$this->mapCacheExtension; 314628e43ccSMark Prins } 315628e43ccSMark Prins 316628e43ccSMark Prins public function mkdir_recursive($pathname, $mode){ 317628e43ccSMark Prins is_dir(dirname($pathname)) || $this->mkdir_recursive(dirname($pathname), $mode); 318628e43ccSMark Prins return is_dir($pathname) || @mkdir($pathname, $mode); 319628e43ccSMark Prins } 320628e43ccSMark Prins 321628e43ccSMark Prins public function writeTileToCache($url, $data){ 322628e43ccSMark Prins $filename = $this->tileUrlToFilename($url); 323628e43ccSMark Prins $this->mkdir_recursive(dirname($filename),0777); 324628e43ccSMark Prins file_put_contents($filename, $data); 325628e43ccSMark Prins } 326628e43ccSMark Prins 327628e43ccSMark Prins public function fetchTile($url){ 328628e43ccSMark Prins if($this->useTileCache && ($cached = $this->checkTileCache($url))) return $cached; 329628e43ccSMark Prins $ch = curl_init(); 330628e43ccSMark Prins curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 331628e43ccSMark Prins curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; DokuWikiSpatial HTTP Client; '.PHP_OS.')'); 332628e43ccSMark Prins curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); 333628e43ccSMark Prins curl_setopt($ch, CURLOPT_URL, $url); 334628e43ccSMark Prins $tile = curl_exec($ch); 335628e43ccSMark Prins curl_close($ch); 336628e43ccSMark Prins if($tile && $this->useTileCache){ 337628e43ccSMark Prins $this->writeTileToCache($url,$tile); 338628e43ccSMark Prins } 339628e43ccSMark Prins return $tile; 340628e43ccSMark Prins } 341628e43ccSMark Prins 342628e43ccSMark Prins /** 343628e43ccSMark Prins * Draw gpx trace on the map. 344628e43ccSMark Prins */ 345628e43ccSMark Prins public function drawGPX(){ 3466c6bb022SMark Prins $gpxgeom = geoPHP::load(file_get_contents($this->gpxFileName),'gpx'); 3476c6bb022SMark Prins $col = imagecolorallocate($this->image, 0, 0, 255); 3486c6bb022SMark Prins 3496c6bb022SMark Prins for ($i = 1; $i < $gpxgeom->numGeometries()+1; $i++) { 3506c6bb022SMark Prins $geom = $gpxgeom->geometryN($i); 3516c6bb022SMark Prins // can be Point or LineString 3526c6bb022SMark Prins switch ($geom->geometryType()) { 3536c6bb022SMark Prins case 'LineString': 354*da6f229fSMark Prins $this->drawLineString($geom, $col); 3556c6bb022SMark Prins break; 3566c6bb022SMark Prins case 'Point': 357*da6f229fSMark Prins $this->drawPoint($geom, $col); 3586c6bb022SMark Prins break; 3596c6bb022SMark Prins default: 3606c6bb022SMark Prins //do nothing 3616c6bb022SMark Prins break; 3626c6bb022SMark Prins } 3636c6bb022SMark Prins } 364628e43ccSMark Prins } 365628e43ccSMark Prins 366628e43ccSMark Prins /** 367628e43ccSMark Prins * Draw kml trace on the map. 368628e43ccSMark Prins */ 369628e43ccSMark Prins public function drawKML(){ 370628e43ccSMark Prins //TODO implementation 3716c6bb022SMark Prins $kmlgeom = geoPHP::load(file_get_contents($this->kmlFileName),'kml'); 3726c6bb022SMark Prins // TODO get colour from kml node 373*da6f229fSMark Prins $col = imagecolorallocate($this->image, 255, 0, 0); 3746c6bb022SMark Prins 375*da6f229fSMark Prins for ($i = 1; $i < $kmlgeom->numGeometries()+1; $i++) { 376*da6f229fSMark Prins $geom = $kmlgeom->geometryN($i); 3776c6bb022SMark Prins switch ($geom->geometryType()) { 3786c6bb022SMark Prins case 'LineString': 379*da6f229fSMark Prins $this->drawLineString($geom, $col); 3806c6bb022SMark Prins break; 3816c6bb022SMark Prins case 'Point': 382*da6f229fSMark Prins $this->drawPoint($geom, $col); 3836c6bb022SMark Prins break; 3846c6bb022SMark Prins case 'Polygon': 3856c6bb022SMark Prins break; 3866c6bb022SMark Prins default: 3876c6bb022SMark Prins //do nothing 3886c6bb022SMark Prins break; 3896c6bb022SMark Prins } 3906c6bb022SMark Prins } 391628e43ccSMark Prins } 392628e43ccSMark Prins 393*da6f229fSMark Prins private function drawLineString($line, $colour){ 394*da6f229fSMark Prins for ($p = 1; $p < $line->numGeometries(); $p++) { 395*da6f229fSMark Prins // get first pair of points 396*da6f229fSMark Prins $p1 = $line->geometryN($p); 397*da6f229fSMark Prins $p2 = $line->geometryN($p+1); 398*da6f229fSMark Prins // translate to paper space 399*da6f229fSMark Prins $x1 = floor(($this->width/2)-$this->tileSize*($this->centerX-$this->lonToTile($p1->x(), $this->zoom))); 400*da6f229fSMark Prins $y1 = floor(($this->height/2)-$this->tileSize*($this->centerY-$this->latToTile($p1->y(), $this->zoom))); 401*da6f229fSMark Prins $x2 = floor(($this->width/2)-$this->tileSize*($this->centerX-$this->lonToTile($p2->x(), $this->zoom))); 402*da6f229fSMark Prins $y2 = floor(($this->height/2)-$this->tileSize*($this->centerY-$this->latToTile($p2->y(), $this->zoom))); 403*da6f229fSMark Prins // draw to image 404*da6f229fSMark Prins imageline ( $this->image , $x1 , $y1 , $x2 , $y2 , $colour ); 405*da6f229fSMark Prins } 406*da6f229fSMark Prins } 407*da6f229fSMark Prins 408*da6f229fSMark Prins private function drawPoint($point, $colour){ 409*da6f229fSMark Prins // translate to paper space 410*da6f229fSMark Prins $cx = floor(($this->width/2)-$this->tileSize*($this->centerX-$this->lonToTile($point->x(), $this->zoom))); 411*da6f229fSMark Prins $cy = floor(($this->height/2)-$this->tileSize*($this->centerY-$this->latToTile($point->y(), $this->zoom))); 412*da6f229fSMark Prins // draw to image 413*da6f229fSMark Prins imageellipse ( $this->image , $cx , $cy , 14 /*width*/ , 14 /*height*/ , $colour ); 414*da6f229fSMark Prins } 415*da6f229fSMark Prins 416628e43ccSMark Prins /** 417628e43ccSMark Prins * add copyright and origin notice and icons to the map. 418628e43ccSMark Prins */ 419628e43ccSMark Prins public function drawCopyright(){ 420628e43ccSMark Prins $logoBaseDir = dirname(__FILE__).'/'.'logo/'; 421628e43ccSMark Prins $logoImg = imagecreatefrompng($logoBaseDir.$this->tileInfo['openstreetmap']['logo']); 422628e43ccSMark Prins $textcolor = imagecolorallocate($this->image, 0, 0, 0); 423628e43ccSMark Prins $bgcolor = imagecolorallocate($this->image, 200, 200, 200); 424628e43ccSMark Prins 425628e43ccSMark Prins imagecopy($this->image, 426628e43ccSMark Prins $logoImg, 427628e43ccSMark Prins 0, 428628e43ccSMark Prins imagesy($this->image)-imagesy($logoImg), 429628e43ccSMark Prins 0, 430628e43ccSMark Prins 0, 431628e43ccSMark Prins imagesx($logoImg), 432628e43ccSMark Prins imagesy($logoImg) 433628e43ccSMark Prins ); 434628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+2 , imagesy($this->image)-imagesy($logoImg)+1 , $this->tileInfo['openstreetmap']['txt'],$bgcolor ); 435628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+1 , imagesy($this->image)-imagesy($logoImg) , $this->tileInfo['openstreetmap']['txt'] ,$textcolor ); 436628e43ccSMark Prins 437628e43ccSMark Prins // additional tile source info, ie. who created/hosted the tiles 438628e43ccSMark Prins if ($this->maptype!='openstreetmap') { 439628e43ccSMark Prins $iconImg = imagecreatefrompng($logoBaseDir.$this->tileInfo[$this->maptype]['logo']); 440628e43ccSMark Prins imagecopy($this->image, 441628e43ccSMark Prins $iconImg, 442628e43ccSMark Prins imagesx($logoImg)+1, 443628e43ccSMark Prins imagesy($this->image)-imagesy($iconImg), 444628e43ccSMark Prins 0, 445628e43ccSMark Prins 0, 446628e43ccSMark Prins imagesx($iconImg), 447628e43ccSMark Prins imagesy($iconImg) 448628e43ccSMark Prins ); 449628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+imagesx($iconImg)+4 , imagesy($this->image)-ceil(imagesy($logoImg)/2)+1 , $this->tileInfo[$this->maptype]['txt'],$bgcolor ); 450628e43ccSMark Prins imagestring ($this->image , 1 , imagesx($logoImg)+imagesx($iconImg)+3 , imagesy($this->image)-ceil(imagesy($logoImg)/2) , $this->tileInfo[$this->maptype]['txt'] ,$textcolor ); 451628e43ccSMark Prins } 452628e43ccSMark Prins } 453628e43ccSMark Prins /** 454628e43ccSMark Prins * make the map. 455628e43ccSMark Prins */ 456628e43ccSMark Prins public function makeMap(){ 457628e43ccSMark Prins $this->initCoords(); 458628e43ccSMark Prins $this->createBaseMap(); 459628e43ccSMark Prins if(count($this->markers))$this->placeMarkers(); 460628e43ccSMark Prins if(file_exists($this->kmlFileName)) $this->drawKML(); 461628e43ccSMark Prins if(file_exists($this->gpxFileName)) $this->drawGPX(); 462628e43ccSMark Prins $this->drawCopyright(); 463628e43ccSMark Prins } 464628e43ccSMark Prins /** 465628e43ccSMark Prins * get the map, this may return a reference to a cached copy. 466628e43ccSMark Prins * @return string url relative to media dir 467628e43ccSMark Prins */ 468628e43ccSMark Prins public function getMap(){ 469628e43ccSMark Prins // use map cache, so check cache for map 470628e43ccSMark Prins if(!$this->checkMapCache()){ 471628e43ccSMark Prins // map is not in cache, needs to be build 472628e43ccSMark Prins $this->makeMap(); 473628e43ccSMark Prins $this->mkdir_recursive(dirname($this->mapCacheIDToFilename()),0777); 474628e43ccSMark Prins imagepng($this->image,$this->mapCacheIDToFilename(),9); 475628e43ccSMark Prins } 476628e43ccSMark Prins $this->doc =$this->mapCacheIDToFilename(); 477628e43ccSMark Prins // make url relative to media dir 478628e43ccSMark Prins return str_replace($this->mediaBaseDir, '', $this->doc); 479628e43ccSMark Prins } 480628e43ccSMark Prins} 481