Location: PHPKode > projects > Geo GPS > geoGPS.v1.0/img/profile.php
<?php
if($_GET['jpg'])
header("Content-type: image/jpeg");
else 
header("Content-type: image/png");

include('../overall.php');
include('../core/geodb.class.php');
include('../core/georoute.class.php');

$routeId = $_GET['r'];

// First of all, check if there is a cached image of this route in the cache/ folder
//
if(empty($_GET['jpg']))
$cache_file = '../cache/profile_'.$routeId.'_'.$_GET['s'].'.png';

if(file_exists($cache_file)) {
	die(file_get_contents($cache_file));
}


// Some useful functions
function nearest($lat,$lng,$limit) { //cheks the nearest point from the $points variable, relative to a lat/lng point
	global $points;
	$lastd = $limit;
	$nearest = 0;
	
	$n = count($points);
	if($n < 1) return 0;
	
	for($i = 0; $i < $n; $i++){
		$d = 6371000 * acos(cos(deg2rad($lat))*cos(deg2rad($points[$i]->lat))*cos(deg2rad($points[$i]->lng)-deg2rad($lng))+sin(deg2rad($lat))*sin(deg2rad($points[$i]->lat))); //distance in meters
		if($d < $lastd && $d < $limit){ //must be at less than 1.5km, else its not "near"...
			$nearest = $i; $dg = $d;
		} 
		$lastd = $d;
	}
	return $nearest;
}
function getNearLabels($near,$limit){
	$label = array();
	foreach($near as $n){
		$np = nearest($n->lat,$n->lng,$limit); //nearest point
		if($np!=0) {
			while(!empty($label[$np])) $np += 2;
			$label[$np] = $n->name;
		}
	}
	return $label;
}

$drawnlabels = array();
function drawLabel($x,$y,$txt,$bgcolor){ //draws a label
	global $drawnlabels,$width,$height,$im,$white,$black;
	//mend the messy
	if($y<0) $y=0; if($y>$height) $y=$height; if($x<0) $x=0; if($x>$width) $x=$width;
	
	$pad = 5; //padding in px
	$ba = 6; //size of the triangle of the balloon
	$box = imagettfbbox(12,0,'ROLLOSB.TTF',$txt);
	$w = abs($box[0] - $box[4])+2*$pad;
	$h = abs($box[1] - $box[5])+$ba+2*$pad;
	//choose default position
	$dirx = ($x>$width/2) ? 1 : -1; // 1 = right, -1 = left
	$diry = -1; // 1 = down, -1 = up
	
	if(!fitInBox($x,$y,$x+$w*$dirx,$y+$h*$diry,$width,$height))
		$diry *= -1;
	if(!fitInBox($x,$y,$x+$w*$dirx,$y+$h*$diry,$width,$height))
		{ $diry *= -1; $dirx *= -1; }
	if(!fitInBox($x,$y,$x+$w*$dirx,$y+$h*$diry,$width,$height))
		$diry *= -1;
	
	$polygon = labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba);
	
	$limits = array(min($x,$polygon[4]),max($x,$polygon[4]),min($y,$polygon[5]),max($y,$polygon[5]));
	
	if(count($drawnlabels)>0){ //check if there is overlay with other labels
		foreach($drawnlabels as $l) {
			if(boxOverlay($limits,$l)) { //overlay between boxes
				$diry *= -1; //change the up/down direction
				if(fitInBox($x,$y,$x+$w*$dirx,$y+$h*$diry,$width,$height)) { //if its right for the field
					$polygon = labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba); //new polygon...
					$limits = array(min($x,$polygon[4]),max($x,$polygon[4]),min($y,$polygon[5]),max($y,$polygon[5]));
					if(boxOverlay($limits,$l)) {
						$diry *= -1; $dirx *= -1; //change the left/right direction
						if(fitInBox($x,$y,$x+$w*$dirx,$y+$h*$diry,$width,$height)) { //if its right for the field
							$polygon = labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba); //new polygon...
							$limits = array(min($x,$polygon[4]),max($x,$polygon[4]),min($y,$polygon[5]),max($y,$polygon[5]));
						} else {
							$dirx *= -1; //back to default directions
							$y += $h*$diry; //move it, for the last chance...
							$polygon = labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba); //new polygon...
							$limits = array(min($x,$polygon[4]),max($x,$polygon[4]),min($y,$polygon[5]),max($y,$polygon[5]));
						}
					}
				} else {
					$diry *= -1; $dirx *= -1; //change the left/right direction
					if(fitInBox($x,$y,$x+$w*$dirx,$y+$h*$diry,$width,$height)) { //if its right for the field
						$polygon = labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba); //new polygon...
						$limits = array(min($x,$polygon[4]),max($x,$polygon[4]),min($y,$polygon[5]),max($y,$polygon[5]));
					} else {
						$dirx *= -1; //back to default directions
						$y += $h*$diry; //move it, for the last chance...
						$polygon = labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba); //new polygon...
						$limits = array(min($x,$polygon[4]),max($x,$polygon[4]),min($y,$polygon[5]),max($y,$polygon[5]));
					}
				}
			}
		}
	}
	
	imagefilledpolygon($im, $polygon, count($polygon)/2, $bgcolor); //box
	$drawnlabels[] = $limits;
	
	$txtx = ($dirx > 0) ? $x+$pad : $x-$w+$pad;
	$txty = ($diry > 0) ? $y+$ba+$h-$pad*2 : $y-$ba-$pad;
	imagettftext($im, 12, 0, $txtx+1, $txty+1, $black, 'ROLLOSB.TTF', $txt); //shadow
	imagettftext($im, 12, 0, $txtx, $txty, $white, 'ROLLOSB.TTF', $txt); //text
}
function fitInBox($x1,$y1,$x2,$y2,$w,$h) { //returns true if the box fits in the image
	//x and y (1,2) are oposite  corners of the box
	return ($x1 > 0 && $x2 > 0 && $x1 < $w && $x2 < $w && $y1 > 0 && $y2 > 0 && $y1 < $h && $y2 < $h);	
}
function boxOverlay($b1,$b2){ //returns true if b1 and b2 are overlaying
	return (($b1[0]>$b2[0] && $b1[0]<$b2[1])||($b1[1]>$b2[0] && $b1[1]<$b2[1])) 
	&&(($b1[2]>$b2[2] && $b1[2]<$b2[3])||($b1[3]>$b2[2] && $b1[3]<$b2[3]));
}
function labelPolygon($x,$y,$w,$h,$dirx,$diry,$ba) { //returns the polygon to print the label
	return array(
		$x,$y, //initial
		$x,($y+$h*$diry), //up or down
		($x+$w*$dirx),($y+$h*$diry), //left or right
		($x+$w*$dirx),($y+$ba*$diry), //up or down
		($x+$ba*$dirx),($y+$ba*$diry), //left or right
		$x,$y //back to initial
	);
}

$database = new GeoDB;
$database->connect(GEO_DB_NAME,GEO_DB_USER,GEO_DB_PASS,GEO_DB_HOST);

$data = $database->getRouteById($routeId);
$points = $database->getPointsById($data->id);
$nearps = $database->getNearNamesById($data->id,40);

$route = new Route;
$route->fromPoints($points);

if(is_numeric($_GET['s'])) {
	$width = $_GET['s'];
	$height = $width*0.75;
} else {
	switch($_GET['s']){
		case 'thumbnail': $width = 100; $height = 75; break;
		case 'full': $width = empty($_GET['w'])? 600 : $_GET['w']; $height = 350; break;
		default: $width = 600; $height = 150;
	}
}

//where will the near points be:
if(count($nearps) > 0) {
	$limLab = 1500;
	do {
		$label = getNearLabels($nearps,$limLab);
		$limLab -= 100;
	} while(count($label) > 5 && $limLab > 100);
}

$im = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
$grey = imagecolorallocate($im, 200, 200, 200);
$blue = imagecolorallocate($im, 0, 100, 255); //blue..
$bluealpha = imagecolorallocatealpha($im, 0, 100, 255, 70); //blue, wih alpha channel
$blackalpha = imagecolorallocatealpha($im, 0, 0, 0, 70); //black, wih alpha channel
imagefilledrectangle($im, 0, 0, $width, $height, $white); //fill the background on white

if($_GET['s'] == 'full') { //full
	if(array_sum($route->alts) < 1) { // if there is NO altitude data
		$box = imagettfbbox(20,0,'ROLLOSB.TTF','Altitudes no disponibles');
		imagettftext($im, 20, 0, $width*0.5-abs($box[4] - $box[0])*0.5, $height*0.5-abs($box[1] - $box[5])*0.5, $blue, 'ROLLOSB.TTF', 'Altitudes no disponibles');
	} else {
		// Some calculations...
		$wProp = $width/$route->dist;
		$maxalt = ceil(max($route->alts)/100)*100;
		$hProp = $height/$maxalt;
		
		if($route->dist < 30000) $kmstep = 5000; //step of 5 kms
		elseif($route->dist > 70000) $kmstep = 20000; //step of 20 kms
		else $kmstep = 10000; //step of 10 kms
		
		if($maxalt < 300) $altstep = 50; //step of 50 mts
		elseif($maxalt < 100) $altstep = 20; //step of 200 mts
		elseif($maxalt > 1500) $altstep = 500; //step of 200 mts
		elseif($maxalt > 600) $altstep = 200; //step of 200 mts
		else $altstep = 100; //step of 100 mts
		
		//draw elevation lines
		for($i=$altstep; $i<$maxalt; $i+=$altstep){
			$liney = $height-$i*$hProp;
			imageline($im, 0,$liney, $width,$liney, $grey);
			imagettftext($im, 12, 0, 3, $liney+15, $grey, 'ROLLOSB.TTF', $i.' m'); //text
		}
		//Initialice polygon
		$polygon = array(0,$height);

		$altss = $altsc = $lastx = $amax = $amin = $aalt = $setkm = 0;
		for($i=1; $i<$route->n; $i++){
			$dlat = abs($route->lats[$i]-$route->lats[$i-1]); //latitude difference
			$dlng = abs($route->lngs[$i]-$route->lngs[$i-1]); //longitude difference
	
			$amax += max($dlat,$dlng); //sum of maximum degrees
			$amin += min($dlat,$dlng); //sum of minimum degrees
			$aalt += abs($route->alts[$i]-$route->alts[$i-1]); //sum of elevations
	
			$pdist = $route->distAB(0,0,0,$amax,$amin,$aalt); //distance until this point
			
			$till = floor($pdist*$wProp); //where am i on the image (x pixel)
			if($till > $lastx+GEO_PROFILE_SMOOTH){ 
				$altsc++;
				$altAvg = ($altss+$route->alts[$i])/$altsc; //average of elevations
				$x = $lastx;
				$y = $height-round($altAvg*$hProp);
		
				$polygon[] = $x; $polygon[] = $y; //one more point of the polygon
				
				if($pdist > $setkm){ //reached 10 more kms
					imagettftext($im, 12, 0, $setkm*$wProp+4, $height-4, $blue, 'ROLLOSB.TTF', ($setkm/1000).' Km');
					$setkm += $kmstep; //next indication
				}
				
				$lasty = $y;
				$lastx = $till;
				$altss = $altsc = 0;
			} else {
				$altss += $route->alts[$i]; //average of elevations within GEO_PROFILE_SMOOTH pixels
				$altsc++;
			}
			
			if($label[$i]) { //if there is a label to write in here...
				$labelsdraw[] = array($till,round($height-$route->alts[$i]*$hProp),$label[$i]); 
			}
		}

		$polygon[] = $width; $polygon[] = $lasty;
		$polygon[] = $width; $polygon[] = $height;

		imagefilledpolygon($im, $polygon, count($polygon)/2, $bluealpha);
		// now draw the labels
		if(count($labelsdraw) > 0){
			foreach($labelsdraw as $la)
				drawLabel($la[0],$la[1],$la[2],$blackalpha);
		}
	}
} else {
	if(array_sum($route->alts) < 1) { // if NO altitude data
		imagettftext($im, 40, 0, 40, 55, $bluealpha, 'ROLLOSB.TTF', '?');
	} else {
		//Initialice polygon
		$polygon = array(0,$height);
		// Some calculations...
		$wProp = $width/$route->dist;
		$maxalt = ceil(max($route->alts)/100)*100;
		$hProp = $height/$maxalt;

		$altss = $altsc = $lastx = $amax = $amin = $aalt = 0;
		for($i=1; $i<$route->n; $i++){
			$dlat = abs($route->lats[$i]-$route->lats[$i-1]);
			$dlng = abs($route->lngs[$i]-$route->lngs[$i-1]);
	
			$amax += max($dlat,$dlng);
			$amin += min($dlat,$dlng);
			$aalt += abs($route->alts[$i]-$route->alts[$i-1]);
	
			$pdist = $route->distAB(0,0,0,$amax,$amin,$aalt);
			
			$till = floor($pdist*$wProp);
			if($till > $lastx){
				$altsc++;
				$altAvg = ($altss+$route->alts[$i])/$altsc; //average of elevations
				$x = $lastx;
				$y = $height-round($altAvg*$hProp);
		
				$polygon[] = $x; $polygon[] = $y; //one more point of the polygon
				
				$lasty = $y;
				$lastx = $till;
				$altss = $altsc = 0;
			} else {
				$altss += $route->alts[$i];
				$altsc++;
			}
		}

		$polygon[] = $width; $polygon[] = $lasty;
		$polygon[] = $width; $polygon[] = $height;

		imagefilledpolygon($im, $polygon, count($polygon)/2, $bluealpha);
	}
}

// Save a cached image in the cache folder
if($data->id && GEO_PROFILE_CACHE && !$_GET['jpg']) { //check if it really exists a route with the specified id
	imagepng($im,$cache_file,6); //compression can be set from 0 (no compression) to 9
}
if($_GET['jpg'])
imagejpeg($im,NULL,70);
else
imagepng($im);
imagedestroy($im);
?>
Return current item: Geo GPS