<?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);
?>