Location: PHPKode > scripts > GPX Mapper & CMS > gpx-mapper-cms/cls.gpxDrawer.php
<?

/*		
	GPX Drawer Class
	Version: 1.0 
	Author: David Boardman
	URL: http://www.netzfunk.org/?usr=d
	Licenced under Creative Commons Attribution-NonCommercial-ShareAlike 2.5

	If redistributed in any form, please include credits and a link to http://www.netzfunk.org/?usr=d
*/

class gpxDrawer{
	
	var $mapname;
	var $path;
	var $metadata;
	var $wpt;
	var $rte;
	var $trk;
	var $trkpt;
	var $pixelfact;
	var $mapscale;
	var $xml;
	var $colors;
	var $mapwidth;
	var $mapheight;
	var $area;
	var $distance=0;
	var $legenda;
	var $context;
	
	function gpxDrawer($mapwidth,$mapheight,$mapname,$path,$xml,$scale,$legenda,$context){ //  FUNZIONE MAIN
		if (!is_numeric($scale) || $scale==0) $scale = 20000;
		$this->pixelfact=2817.947378;
		$this->mapscale=$scale;
		$this->mapname=$mapname;
		$this->mapwidth=$mapwidth;
		$this->mapheight=$mapheight;
		$this->path=$path;
		$this->xml=$xml;
		$this->legenda=$legenda;
		$this->context=$context;
	}
	
	function collectMETA(){  // COLLEZIONA METADATA
		$meta=$this->xml['gpx']['metadata'];
		$this->metadata['filename']=$meta['name']['value'];
		$this->metadata['filedesc']=$meta['desc']['value'];
		$this->metadata['fileauth']=$meta['author']['name']['value'];
		$this->metadata['filelink']=$meta['author']['link']['text']['value'];
		$this->metadata['filehref']=$meta['author']['link']['href'];
		$this->metadata['copy_year']=$meta['copyright']['year']['value'];
		$this->metadata['link_text']=$meta['link']['text']['value'];
		$this->metadata['link_href']=$meta['link']['href'];
		$this->metadata['time']=$meta['time']['value'];
		$this->metadata['keywords']=$meta['keywords']['value'];
		$this->metadata['bounds_minlat']=$meta['bounds']['minlat'];
		$this->metadata['bounds_maxlat']=$meta['bounds']['maxlat'];
		$this->metadata['bounds_minlon']=$meta['bounds']['minlon'];
		$this->metadata['bounds_maxlon']=$meta['bounds']['maxlon'];
		return $this->metadata;
	}
	
	function collectWPT(){ // COLLEZIONA WPT
		$i=0;
		foreach($this->xml['gpx']['wpt'] as $wpts){
			$this->wpt[$i]['ele']=$wpts['ele']['value'];
			$this->wpt[$i]['time']=$wpts['time']['value'];
			$this->wpt[$i]['magvar']=$wpts['magvar']['value'];
			$this->wpt[$i]['geoidheight']=$wpts['geoidheight']['value'];
			$this->wpt[$i]['src']=$wpts['src']['value'];
			$this->wpt[$i]['link']=$wpts['link']['value'];
			$this->wpt[$i]['name']=$wpts['name']['value'];
			$this->wpt[$i]['cmt']=$wpts['cmt']['value'];
			$this->wpt[$i]['desc']=$wpts['desc']['value'];
			$this->wpt[$i]['sym']=$wpts['sym']['value'];
			$this->wpt[$i]['lat']=$wpts['lat'];
			$this->wpt[$i]['lon']=$wpts['lon'];
			$i++;
		}
		return $this->wpt;
	}
	
	function collectRTE(){  // COLLEZIONA RTE
		$data=$this->xml['gpx']['rte'];
		$this->rte['name']=$data['name']['value'];
		$this->rte['desc']=$data['desc']['value'];
		$this->rte['gpxcolor']=$data['extensions']['gpx_style:color']['value'];
		return $this->rte;
	}
	
	function collectTRK(){ // COLLEZIONA TRK
		$trklist=$this->xml['gpx']['trk'];
		$this->trk['name']=$trklist['name']['value'];
		$this->trk['cmt']=$trklist['name']['value'];
		$this->trk['desc']=$trklist['desc']['value'];
		$this->trk['number']=$trklist['number']['value'];
		$this->trk['gpxcolor']=$trklist['extensions']['gpx_style:color']['value'];
		return $this->trk;
	}	

	function collectTRKPT(){  // COLLEZIONA TRKPT
		$i=0;
		foreach($this->xml['gpx']['trk']['trkseg']['trkpt'] as $trkptlist){
			//$this->trkpt[$i]['ele']=$trkptlist['ele']['value'];
			//$this->trkpt[$i]['time']=$trkptlist['time']['value'];
			//$this->trkpt[$i]['magvar']=$trkptlist['magvar']['value'];
			//$this->trkpt[$i]['geoidheight']=$trkptlist['geoidheight']['value'];
			//$this->trkpt[$i]['name']=$trkptlist['name']['value'];
			//$this->trkpt[$i]['cmt']=$trkptlist['cmt']['value'];
			//$this->trkpt[$i]['desc']=$trkptlist['desc']['value'];
			//$this->trkpt[$i]['sym']=$trkptlist['sym']['value'];
			//$this->trkpt[$i]['fix']=$trkptlist['fix']['value'];
			//$this->trkpt[$i]['sat']=$trkptlist['sat']['value'];
			//$this->trkpt[$i]['hdop']=$trkptlist['hdop']['value'];
			//$this->trkpt[$i]['vdop']=$trkptlist['vdop']['value'];
			//$this->trkpt[$i]['pdop']=$trkptlist['pdop']['value'];
			//$this->trkpt[$i]['dpgpsid']=$trkptlist['dpgpsid']['value'];
			$this->trkpt[$i]['lat']=doubleval($trkptlist['lat']);
			$this->trkpt[$i]['lon']=doubleval($trkptlist['lon']);
			$i++;
		}
		return $this->trkpt;
	}

	function getMapCenter(){  // CALCOLA IL CENTRO DELLA MAPPA
		$centerlat=$centerlon=$totlat=$totlon=$j=0;
		for ($i=0;$i<count($this->trkpt);$i++){
			if ($this->trkpt[$i]['lat'] != 0 && $this->trkpt[$i]['lon'] != 0){
				$j++;
				$totlat+=$this->trkpt[$i]['lat'];
				$totlon+=$this->trkpt[$i]['lon'];
			}
		}
		$centerlat=round( $totlat/$j, 6);
		$centerlon=round( $totlon/$j, 6);
		return array('lat' => $centerlat, 'lon' => $centerlon );
	}

	function dist($type,$lon1,$lat1,$lon2,$lat2){
		$lon1=$lon1*M_PI/180;
		$lon2=$lon2*M_PI/180;
		$lat1=$lat1*M_PI/180;
		$lat2=$lat2*M_PI/180;
		$dlon=$lon2-$lon1;
		$dlat=$lat2-$lat1;
		$a=(sin($dlat/2) * sin($dlat/2)) + cos($lat1) * cos($lat2) * (sin($dlon/2) * sin($dlon/2));
		$c=2*atan2(sqrt($a),sqrt(1-$a));
		$dlon=$lon2-$lon1;
		$dlat=$lat2-$lat1;
		$mi=round(3956*$c,4);
		$km=round(6367*$c,4);
		if($type=="m") return $mi; // return miglia
		else return $km; // return chilometri
	}


	function calcxy($lat, $lon, $pixelfact, $zero_lat, $zero_long){  // CONVERTI LAT/LON IN X/Y
		$dif=0;
		$px = $py = 0;
		
		$px = ($this->calcRay($lat) * M_PI / 180.0) * cos (M_PI * $lat / 180.0) * ($lon - $zero_long);
		
		$px = ($this->mapwidth/2) + $px / $pixelfact;
		$py = ($this->calcRay($lat) * M_PI / 180.0) * ($lat - $zero_lat);
		$dif = $this->calcRay($lat) * (1 - (cos ((M_PI * ($lon - $zero_long)) / 180.0)));

		$py = $py + $dif / 1.85;
		$py = ($this->mapheight/2) - $py / $pixelfact;

		$px += $draw_x_offset;
		$py += $draw_y_offset;
	
		$px = round($px);
		$py = round($py);
				
		$posxy = array('x' => $px, 'y' => $py );
		return $posxy;
	}
	
	function calcRay($lat){ //calcRay($raggio,$lat,$lon);
		$a = 6378.137;
		$e2 = 0.081082 * 0.081082;
		/*
		the radius of curvature of an ellipsoidal Earth in the plane of the
		meridian is given by
		
		R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2)
		
		where a is the equatorial radius,
		b is the polar radius, and
		e is the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2)
		
		a = 6378 km (3963 mi) Equatorial radius (surface to center distance)
		b = 6356.752 km (3950 mi) Polar radius (surface to center distance)
		e = 0.081082 Eccentricity
		*/
		$lat = $lat * M_PI / 180.0;
		$sc = sin ($lat);
		$x = $a * (1.0 - $e2);
		$z = 1.0 - $e2 * $sc * $sc;
		$y = pow ($z, 1.5);
		$r = $x / $y;
		$r = $r * 1000.0;
		return $r;
	}
	
	function drawPath($img,$pos){  // DISEGNO TRACKPOINTS (TRKPT)
		for($i=0;$i<count($pos);$i++){ 
			if(($pos[$i]['x'] <= $this->mapwidth)&&($pos[$i]['y'] <= $this->mapheight)){
				$x1=$pos[$i]['x'];
				$y1=$pos[$i]['y'];
				if((($x2!="")&&($y2!=""))||(($x2!=0)&&($y2!=0))) imageline($img,$x1,$y1,$x2,$y2,$this->colors['white']);
				else imagefilledrectangle($img,$x1-4,$y1-4,$x1+4,$y1+4,$this->colors['green']); //punto iniziale mappa
				$x2=$x1;
				$y2=$y1;
				if($i==count($pos)-1){
					imagefilledrectangle($img,$x1-4,$y1-4,$x1+4,$y1+4,$this->colors['blue']); //punto finale mappa
				}
			}
		}
	}

	function drawPOI($img,$pos,$link,$title,$r){  // (img mappa,x/y,link poi,titolo poi,raggio) DISEGNO WAYPOINTS (WPT)
		for($i=0;$i<count($pos);$i++){
			if(($pos[$i]['x'] <= $this->mapwidth)&&($pos[$i]['y'] <= $this->mapheight)){
				imagefilledellipse($img,$pos[$i]['x'],$pos[$i]['y'],$r[$i],$r[$i],$this->colors['red']);
				$this->area.="<area shape=\"circle\" coords=\"".$pos[$i]['x'].",".$pos[$i]['y'].",".$r[$i]."\" href=\"javascript:showPOI('".$link[$i]."');\" onmouseover=\"doTooltip(event,'".htmlspecialchars(strtoupper($title[$i]))."')\" onmouseout=\"hideTip()\">\n";				
			}
		}
	}
	
	function drawMap(){  // DISEGNO MAPPA
		if(!is_writable($this->path)){
			exit("Check permissions on \"".$this->path."\" directory.");
		}
		
		$lat1=$lon1=$lat2=$lon2=0;
		$map=@imagecreatetruecolor($this->mapwidth,$this->mapheight) or die("Failed to init GD truecolor stream");
		
		//$src_map=@imagecreatefrompng($this->path.$this->mapname.".png") or die("Failed to init GD stream from mapfile");
		//imagecopy($map,$src_map,0,0,0,0,$width,$height);
		//imagedestroy($src_map);
		
		$this->colors['red']=imagecolorallocate($map,255,0,0);
		$this->colors['white']=imagecolorallocate($map, 255, 255, 255);
		$this->colors['blue']=imagecolorallocate($map,10,10,255);
		$this->colors['green']=imagecolorallocate($map,10,255,10);
		$this->colors['black']=imagecolorallocate($map, 0, 0, 0); 

		$center=$this->getMapCenter();
		$mapscalepixfact=$this->mapscale / $this->pixelfact;
		
		for($i=0;$i<count($this->trkpt);$i++){ // TRACKPOINTS
			$p[$i]=$this->calcxy($this->trkpt[$i]['lat'],$this->trkpt[$i]['lon'],$mapscalepixfact,$center['lat'],$center['lon']);
				//calcolo della distanza percorsa
				$lat1=$this->trkpt[$i]['lat'];
				$lon1=$this->trkpt[$i]['lon'];
				if((($lat2!="")&&($lon2!=""))||(($lat2!=0)&&($lon2!=0))){
						$this->distance+=$this->dist("k",$lon1,$lat1,$lon2,$lat2);
				}
				$lat2=$lat1;
				$lon2=$lon1;				
			}
			
		for($i=0;$i<count($this->wpt);$i++){ // WAYPOINTS
			$w[$i]=$this->calcxy($this->wpt[$i]['lat'],$this->wpt[$i]['lon'],$mapscalepixfact,$center['lat'],$center['lon']);
			//$l[$i]=$this->wpt[$i]['link'];
			$l[$i]=$this->wpt[$i]['desc'];
			$t[$i]=$this->wpt[$i]['cmt'];
			$ray=explode("|",$this->wpt[$i]['desc']);
			$r[$i]=8;
			//$r[$i]=$this->calcRay($ray[0],$ray[1],$ray[2]); // calcola raggio WPTS
		}
		
		$this->drawPath($map,$p);
		$this->drawPOI($map,$w,$l,$t,$r);  //(mappa,x/y,link,titolo,raggio)
		//$this->insertLegend($map,$this->legenda);
	 	//$this->showMapToBrowser($map);
		$this->saveMapAs($map);		
	}
	
	function insertLegend($map,$pos){  // inserisce riquadro legenda con elementi principali
		if(!is_writable($this->path)){
			exit("Check permissions on \"".$this->path."\" directory.");
		}
		$leg=imagecreatefrompng($this->path."/legenda.png");
		$legx=imagesx($leg);
		$legy=imagesy($leg);
		switch($pos){
			case "1": // alto-sinistra
				$x=10;
				$y=10;
			break;
			
			case "2": // alto-destra
				$x=$this->mapwidth-$legx;
				$y=10;
			break;
			
			case "3": //basso-sinistra
				$x=10;
				$y=$this->mapheight-$legy;
			break;
			
			case "4": // basso-destra
				$x=$this->mapwidth-$legx;
				$y=$this->mapheight-$legy;
			break;
			
			default:
				return;
			break;
			
			}
		imagecopyresized($map,$leg,$x,$y,0,0,$legx,$legy,$legx,$legy);
	}
		
	function getMapArea(){ // RESTITUISCI AREA CLICCABILE MAPPA
		return $this->area;
	}
	
	function getPathDistance(){ // RESTITUISCI LA DISTANZA PERCORSA
		return $this->distance;
	}
	
	function outMetaData(){  // RESTITUISCI METATAGS GPX
		$m="<pre>".print_r($this->metadata)."</pre>";
		return $m;
	}
	
	function showMapToBrowser($map){  // MOSTRA MAPPA NEL BROWSER
		header("Content-type:image/png");
		return imagepng($map);
	}
	
	function saveMapAs($map){  // SALVA LA MAPPA
		return imagepng($map,$this->path."/map_".$this->mapname.".png");
	}
	
	function deleteMap(){  // CANCELLA MAPPA
		@unlink($this->path."/map_".$this->mapname.".png");
	}

}

?>
Return current item: GPX Mapper & CMS