jablonka.czprosek.czf

weathermap

Subversion Repositories:
[/] [Weathermap.class.php] - Diff between revs 11 and 13

Show entire file Ignore whitespace

Rev 11 Rev 13
Line 1... Line 1...
<?php <?php
// PHP Weathermap 0.91 // PHP Weathermap 0.92
// Copyright Howard Jones, 2005-2007 howie@thingy.com // Copyright Howard Jones, 2005-2007 howie@thingy.com
// http://www.network-weathermap.com/ // http://www.network-weathermap.com/
// Released under the GNU Public License // Released under the GNU Public License
   
require_once "HTML_ImageMap.class.php"; require_once "HTML_ImageMap.class.php";
   
$WEATHERMAP_VERSION="0.91"; $WEATHERMAP_VERSION="0.92";
$weathermap_debugging=FALSE; $weathermap_debugging=FALSE;
   
// Turn on ALL error reporting for now. // Turn on ALL error reporting for now.
error_reporting (E_ALL); error_reporting (E_ALL);
   
  // parameterise the in/out stuff a bit
  define("IN",0);
  define("OUT",1);
  define("WMCHANNELS",2);
   
// Utility functions // Utility functions
// Check for GD & PNG support This is just in here so that both the editor and CLI can use it without the need for another file // Check for GD & PNG support This is just in here so that both the editor and CLI can use it without the need for another file
function module_checks() function module_checks()
{ {
if (!extension_loaded('gd')) if (!extension_loaded('gd'))
{ {
warn ("\n\nNo image (gd) extension is loaded. This is required by weathermap.\n\n"); warn ("\n\nNo image (gd) extension is loaded. This is required by weathermap.\n\n");
warn ("\nIMPORTANT: Just because mod_php and php_info() shows gd in a webpage, it doesn't mean it's available in your command-line php program. Please check the output from 'php -i' and your 'php.ini' to be sure!\n\n"); warn ("\nrun check.php to check PHP requirements.\n\n");
   
return (FALSE); return (FALSE);
} }
   
if (!function_exists('imagecreatefrompng')) if (!function_exists('imagecreatefrompng'))
{ {
warn ("Your GD php module doesn't support PNG format.\n"); warn ("Your GD php module doesn't support PNG format.\n");
  warn ("\nrun check.php to check PHP requirements.\n\n");
return (FALSE); return (FALSE);
} }
   
if (!function_exists('imagecreatetruecolor')) if (!function_exists('imagecreatetruecolor'))
{ {
warn ("Your GD php module doesn't support truecolor.\n"); warn ("Your GD php module doesn't support truecolor.\n");
  warn ("\nrun check.php to check PHP requirements.\n\n");
return (FALSE); return (FALSE);
} }
   
if (!function_exists('imagecopyresampled')) if (!function_exists('imagecopyresampled'))
{ {
Line 189... Line 196...
else else
{ {
warn("Image file $filename is unreadable. Check permissions.\n"); warn("Image file $filename is unreadable. Check permissions.\n");
} }
return $bgimage; return $bgimage;
  }
   
  // rotate a list of points around cx,cy by an angle in radians, IN PLACE
  function RotateAboutPoint(&$points, $cx,$cy, $angle=0)
  {
  $npoints = count($points)/2;
   
  for($i=0;$i<$npoints;$i++)
  {
  $ox = $points[$i*2] - $cx;
  $oy = $points[$i*2+1] - $cy;
  $rx = $ox * cos($angle) - $oy*sin($angle);
  $ry = $oy * cos($angle) + $ox*sin($angle);
   
  $points[$i*2] = $rx + $cx;
  $points[$i*2+1] = $ry + $cy;
  }
} }
   
// calculate the points for a span of the curve. We pass in the distance so far, and the array index, so that // calculate the points for a span of the curve. We pass in the distance so far, and the array index, so that
// the chunk of array generated by this function can be array_merged with existing points from before. // the chunk of array generated by this function can be array_merged with existing points from before.
// Considering how many array functions there are, PHP has horrible list support // Considering how many array functions there are, PHP has horrible list support
Line 213... Line 237...
$n=$startn; $n=$startn;
$distance=$startdistance; $distance=$startdistance;
   
$lx=$x0; $lx=$x0;
$ly=$y0; $ly=$y0;
   
$allpoints[]=array $allpoints[]=array
( (
$x0, $x0,
$y0, $y0,
$distance $distance
Line 248... Line 272...
$lx=$x; $lx=$x;
$ly=$y; $ly=$y;
} }
   
return array($allpoints, $distance, $n); return array($allpoints, $distance, $n);
  }
   
  function find_distance_coords(&$pointarray,$distance)
  {
  // We find the nearest lower point for each distance,
  // then linearly interpolate to get a more accurate point
  // this saves having quite so many points-per-curve
   
  $index=find_distance($pointarray, $distance);
   
  $ratio=($distance - $pointarray[$index][2]) / ($pointarray[$index + 1][2] - $pointarray[$index][2]);
  $x = $pointarray[$index][0] + $ratio * ($pointarray[$index + 1][0] - $pointarray[$index][0]);
  $y = $pointarray[$index][1] + $ratio * ($pointarray[$index + 1][1] - $pointarray[$index][1]);
   
  return(array($x,$y,$index));
  }
   
  function find_distance_coords_angle(&$pointarray,$distance)
  {
  // This is the point we need
  list($x,$y,$index) = find_distance_coords($pointarray,$distance);
   
  // now to find one either side of it, to get a line to find the angle of
  $left = $index;
  $right = $left+1;
  $max = count($pointarray)-1;
  // if we're right up against the last point, then step backwards one
  if($right>=$max)
  {
  $left--;
  $right--;
  }
  # if($left<=0) { $left = 0; }
   
  $x1 = $pointarray[$left][0];
  $y1 = $pointarray[$left][1];
   
  $x2 = $pointarray[$right][0];
  $y2 = $pointarray[$right][1];
   
  $dx = $x2 - $x1;
  $dy = $y2 - $y1;
   
  $angle = rad2deg(atan2(-$dy,$dx));
   
  return(array($x,$y,$index,$angle));
} }
   
// return the index of the point either at (unlikely) or just before the target distance // return the index of the point either at (unlikely) or just before the target distance
// we will linearly interpolate afterwards to get a true point - pointarray is an array of 3-tuples produced by the function above // we will linearly interpolate afterwards to get a true point - pointarray is an array of 3-tuples produced by the function above
function find_distance($pointarray, $distance) function find_distance(&$pointarray, $distance)
{ {
$left=0; $left=0;
$right=count($pointarray) - 1; $right=count($pointarray) - 1;
   
if ($left == $right) if ($left == $right)
Line 282... Line 352...
   
print "FELL THROUGH\n"; print "FELL THROUGH\n";
die ("Howie's crappy binary search is wrong after all.\n"); die ("Howie's crappy binary search is wrong after all.\n");
} }
   
// top-level function that takes a two lists to define some points, and draws a weathermap link // Give a list of key points, calculate a curve through them
// - this takes care of all the extras, like arrowheads, and where to put the bandwidth labels // return value is an array of triples (x,y,distance)
// xarray and yarray are the points the curve passes through function calc_curve(&$in_xarray, &$in_yarray,$pointsperspan = 12)
// width is the link width (the actual width is twice this)  
// outlinecolour is a GD colour reference  
// fillcolours is an array of two more colour references, one for the out, and one for the in spans  
// pointsperspan is optional, and intended to allow fine-tuning of the smoothness of curves. 15 seems about right for most cases  
// -- returns an array of arrays for the two quarter-points - this is where the  
// bandwidth labels go, if they were required  
function draw_curve($image, $in_xarray, $in_yarray, $width, $outlinecolour, $comment_colour, $fillcolours, $linkname, &$map,  
$q1_percent=25, $q3_percent=75, $pointsperspan = 12)  
{ {
global $marker2, $marker3;  
   
// search through the point list, for consecutive duplicate points // search through the point list, for consecutive duplicate points
// (most common case will be a straight link with both NODEs at the same place, I think) // (most common case will be a straight link with both NODEs at the same place, I think)
// strip those out, because they'll break the binary search/centre-point stuff // strip those out, because they'll break the binary search/centre-point stuff
   
$last_x=NULL; $last_x=NULL;
Line 318... Line 378...
$last_x=$in_xarray[$i]; $last_x=$in_xarray[$i];
$last_y=$in_yarray[$i]; $last_y=$in_yarray[$i];
} }
   
// only proceed if we still have at least two points! // only proceed if we still have at least two points!
if (count($xarray) > 1) if(count($xarray) <= 1)
{ {
  warn ("Arrow not drawn, as it's 1-dimensional.\n");
  return (array(NULL, NULL, NULL, NULL));
  }
   
// duplicate the first and last points, so that all points are drawn // duplicate the first and last points, so that all points are drawn
// (C-R normally would draw from x[1] to x[n-1] // (C-R normally would draw from x[1] to x[n-1]
array_unshift($xarray, $xarray[0]); array_unshift($xarray, $xarray[0]);
array_unshift($yarray, $yarray[0]); array_unshift($yarray, $yarray[0]);
   
$x=array_pop($xarray); $x=array_pop($xarray);
$y=array_pop($yarray); $y=array_pop($yarray);
array_push($xarray, $x); array_push($xarray, $x);
array_push($xarray, $x); array_push($xarray, $x);
array_push($yarray, $y); array_push($yarray, $y);
array_push($yarray, $y); array_push($yarray, $y);
   
$npoints=count($xarray); $npoints=count($xarray);
   
$curvepoints=array $curvepoints=array
( (
);  
   
// add in the very first point manually (the calc function skips this one to avoid duplicates, which mess up the distance stuff)  
$curvepoints[]=array  
(  
$xarray[0],  
$yarray[0],  
0  
); );
   
$startindex=0; // add in the very first point manually (the calc function skips this one to avoid duplicates, which mess up the distance stuff)
$startdistance=0; $curvepoints[]=array
  (
  $xarray[0],
  $yarray[0],
  0
  );
   
for ($i=0; $i < ($npoints - 3); $i++) $np=0;
{ $distance=0;
list($newpoints,  
$distance,  
$np)=calculate_catmull_rom_span($startindex, $startdistance, $pointsperspan, $xarray[$i],  
$yarray[$i], $xarray[$i + 1], $yarray[$i + 1], $xarray[$i + 2],  
$yarray[$i + 2], $xarray[$i + 3], $yarray[$i + 3]);  
$curvepoints=$curvepoints + $newpoints;  
   
$startindex=$np; for ($i=0; $i < ($npoints - 3); $i++)
$startdistance=$distance; {
} list($newpoints,
  $distance,
  $np)=calculate_catmull_rom_span($np, $distance, $pointsperspan, $xarray[$i],
  $yarray[$i], $xarray[$i + 1], $yarray[$i + 1], $xarray[$i + 2],
  $yarray[$i + 2], $xarray[$i + 3], $yarray[$i + 3]);
  $curvepoints=$curvepoints + $newpoints;
  }
   
// now we have a 'spine' - all the central points for this curve. return ($curvepoints);
// time to flesh it out to the right width, and figure out where to draw arrows and bandwidth boxes... }
   
$totaldistance = $startdistance; function calc_arrowsize($width,&$map,$linkname)
$halfway = $totaldistance / 2; {
$q1 = $totaldistance * ($q1_percent/100); $arrowlengthfactor=4;
$q3 = $totaldistance * ($q3_percent/100); $arrowwidthfactor=2;
// $q3=$halfway + $q1;  
   
// We find the nearest lower point for each distance, then linearly interpolate to get a more acccurate point if ($map->links[$linkname]->arrowstyle == 'compact')
// this saves having quite so many points-per-curve {
  $arrowlengthfactor=1;
  $arrowwidthfactor=1;
  }
   
$halfwayindex=find_distance($curvepoints, $halfway); if (preg_match('/(\d+) (\d+)/', $map->links[$linkname]->arrowstyle, $matches))
  {
  $arrowlengthfactor=$matches[1];
  $arrowwidthfactor=$matches[2];
  }
   
$ratio=($halfway - $curvepoints[$halfwayindex][2]) $arrowsize = $width * $arrowlengthfactor;
/ ($curvepoints[$halfwayindex + 1][2] - $curvepoints[$halfwayindex][2]); $arrowwidth = $width * $arrowwidthfactor;
$halfway_x=$curvepoints[$halfwayindex][0] + $ratio  
* ($curvepoints[$halfwayindex + 1][0] - $curvepoints[$halfwayindex][0]); return( array($arrowsize,$arrowwidth) );
$halfway_y=$curvepoints[$halfwayindex][1] + $ratio }
* ($curvepoints[$halfwayindex + 1][1] - $curvepoints[$halfwayindex][1]);  
   
// we calculate the arrow size up here, so that we can decide on the // top-level function that takes a two lists to define some points, and draws a weathermap link
// minimum length for a link. The arrowheads are the limiting factor. // - this takes care of all the extras, like arrowheads, and where to put the bandwidth labels
$arrowlengthfactor=4; // curvepoints is an array of the points the curve passes through
$arrowwidthfactor=2; // width is the link width (the actual width is twice this)
  // outlinecolour is a GD colour reference
  // fillcolours is an array of two more colour references, one for the out, and one for the in spans
  function draw_curve($image, &$curvepoints, $width, $outlinecolour, $comment_colour, $fillcolours, $linkname, &$map,
  $q2_percent=50)
  {
  // now we have a 'spine' - all the central points for this curve.
  // time to flesh it out to the right width, and figure out where to draw arrows and bandwidth boxes...
  $unidirectional = FALSE;
   
  // get the full length of the curve from the last point
  $totaldistance = $curvepoints[count($curvepoints)-1][2];
  // find where the in and out arrows will join (normally halfway point)
  $halfway = $totaldistance * ($q2_percent/100);
   
  $dirs = array(OUT,IN);
   
if ($map->links[$linkname]->arrowstyle == 'compact') // for a unidirectional map, we just ignore the second half (direction = -1)
{ if($unidirectional)
$arrowlengthfactor=1; {
$arrowwidthfactor=1; $halfway = $totaldistance;
} $dirs = array(OUT);
  }
   
  // loop increment, start point, width, labelpos, fillcolour, outlinecolour, commentpos
  $arrowsettings[OUT] = array(+1, 0, $width, 0, $fillcolours[OUT], $outlinecolour, 5);
  $arrowsettings[IN] = array(-1, count($curvepoints) - 1, $width, 0, $fillcolours[IN], $outlinecolour, 95);
   
if (preg_match('/(\d+) (\d+)/', $map->links[$linkname]->arrowstyle, $matches)) // we calculate the arrow size up here, so that we can decide on the
{ // minimum length for a link. The arrowheads are the limiting factor.
$arrowlengthfactor=$matches[1]; list($arrowsize,$arrowwidth) = calc_arrowsize($width,$map,$linkname);
$arrowwidthfactor=$matches[2];  
} // the 2.7 here is empirical. It ought to be 2 in theory.
  // in practice, a link this short is useless anyway, especially with bwlabels.
  $minimumlength = 2.7*$arrowsize;
   
$arrowsize = $width * $arrowlengthfactor; # warn("$linkname: Total: $totaldistance $arrowsize $arrowwidth $minimumlength\n");
$arrowwidth = $width * $arrowwidthfactor; if($totaldistance <= $minimumlength)
// the 2.7 here is empirical. It ought to be 2 in theory. {
// in practice, a link this short is useless anyway, especially with bwlabels. warn("Skipping drawing very short link ($linkname). Impossible to draw! Try changing WIDTH or ARROWSTYLE?\n");
$minimumlength = 2.7*$arrowsize; return;
  }
   
# warn("$linkname: Total: $totaldistance $arrowsize $arrowwidth $minimumlength\n");  
if($totaldistance <= $minimumlength) list($halfway_x,$halfway_y,$halfwayindex) = find_distance_coords($curvepoints,$halfway);
{  
warn("Skipping drawing very short link ($linkname). Impossible to draw! Try changing WIDTH or ARROWSTYLE?\n");  
return;  
}  
   
// loop over direction here // loop over direction here
// direction is 1.0 for the first half (forwards through the pointlist), and -1.0 for the second half (backwards from the end) // direction is 1.0 for the first half (forwards through the pointlist), and -1.0 for the second half (backwards from the end)
// - used as a multiplier on anything that looks forwards or backwards through the list // - used as a multiplier on anything that looks forwards or backwards through the list
   
foreach (array(1.0, -1.0) as $direction) foreach ($dirs as $dir)
{ {
// this is the last index before the arrowhead starts $direction = $arrowsettings[$dir][0];
$pre_midindex=find_distance($curvepoints, $halfway - $direction * $arrowsize); // this is the last index before the arrowhead starts
  list($pre_mid_x,$pre_mid_y,$pre_midindex) = find_distance_coords($curvepoints,$halfway - $direction * $arrowsize);
   
  $there_points=array();
  $back_points=array();
  $arrowpoints=array();
   
$ratio=(($halfway - $direction * $arrowsize) - $curvepoints[$pre_midindex][2]) # if ($direction < 0) { $start=count($curvepoints) - 1; }
/ ($curvepoints[$pre_midindex + $direction][2] - $curvepoints[$pre_midindex][2]); # else { $start=0; }
$pre_mid_x=$curvepoints[$pre_midindex][0] + $ratio $start = $arrowsettings[$dir][1];
* ($curvepoints[$pre_midindex + $direction][0] - $curvepoints[$pre_midindex][0]);  
$pre_mid_y=$curvepoints[$pre_midindex][1] + $ratio  
* ($curvepoints[$pre_midindex + $direction][1] - $curvepoints[$pre_midindex][1]);  
   
$there_points=array for ($i=$start; $i != $pre_midindex; $i+=$direction)
( {
); // for each point on the spine, produce two points normal to it's direction,
  // each is $width away from the spine, but we build up the two lists in the opposite order,
  // so that when they are joined together, we get one continuous line
   
$back_points=array $dx=$curvepoints[$i + $direction][0] - $curvepoints[$i][0];
( $dy=$curvepoints[$i + $direction][1] - $curvepoints[$i][1];
); $l=sqrt(($dx * $dx) + ($dy * $dy));
  $nx=$dy / $l;
  $ny=-$dx / $l;
   
$arrowpoints=array $there_points[]=$curvepoints[$i][0] + $direction * $width * $nx;
( $there_points[]=$curvepoints[$i][1] + $direction * $width * $ny;
);  
   
if ($direction < 0) { $start=count($curvepoints) - 1; } $back_points[]=$curvepoints[$i][0] - $direction * $width * $nx;
else { $start=0; } $back_points[]=$curvepoints[$i][1] - $direction * $width * $ny;
  }
   
for ($i=$start; $i != $pre_midindex; $i+=$direction) // all the normal line is done, now lets add an arrowhead on
{  
// for each point on the spine, produce two points normal to it's direction,  
// each is $width away from the spine, but we build up the two lists in the opposite order,  
// so that when they are joined together, we get one continuous line  
   
$dx=$curvepoints[$i + $direction][0] - $curvepoints[$i][0]; $adx=($halfway_x - $pre_mid_x);
$dy=$curvepoints[$i + $direction][1] - $curvepoints[$i][1]; $ady=($halfway_y - $pre_mid_y);
$l=sqrt(($dx * $dx) + ($dy * $dy)); $l=sqrt(($adx * $adx) + ($ady * $ady));
$nx=$dy / $l;  
$ny=-$dx / $l;  
   
$there_points[]=$curvepoints[$i][0] + $direction * $width * $nx; $anx=$ady / $l;
$there_points[]=$curvepoints[$i][1] + $direction * $width * $ny; $any=-$adx / $l;
   
$back_points[]=$curvepoints[$i][0] - $direction * $width * $nx; $there_points[]=$pre_mid_x + $direction * $width * $anx;
$back_points[]=$curvepoints[$i][1] - $direction * $width * $ny; $there_points[]=$pre_mid_y + $direction * $width * $any;
}  
   
// all the normal line is done, now lets add an arrowhead on $there_points[]=$pre_mid_x + $direction * $arrowwidth * $anx;
  $there_points[]=$pre_mid_y + $direction * $arrowwidth * $any;
   
$adx=($halfway_x - $pre_mid_x); $there_points[]=$halfway_x;
$ady=($halfway_y - $pre_mid_y); $there_points[]=$halfway_y;
$l=sqrt(($adx * $adx) + ($ady * $ady));  
   
$anx=$ady / $l; $there_points[]=$pre_mid_x - $direction * $arrowwidth * $anx;
$any=-$adx / $l; $there_points[]=$pre_mid_y - $direction * $arrowwidth * $any;
   
$there_points[]=$pre_mid_x + $direction * $width * $anx; $there_points[]=$pre_mid_x - $direction * $width * $anx;
$there_points[]=$pre_mid_y + $direction * $width * $any; $there_points[]=$pre_mid_y - $direction * $width * $any;
   
$there_points[]=$pre_mid_x + $direction * $arrowwidth * $anx; // all points done, now combine the lists, and produce the final result.
$there_points[]=$pre_mid_y + $direction * $arrowwidth * $any;  
   
$there_points[]=$halfway_x;  
$there_points[]=$halfway_y;  
   
$there_points[]=$pre_mid_x - $direction * $arrowwidth * $anx;  
$there_points[]=$pre_mid_y - $direction * $arrowwidth * $any;  
   
$there_points[]=$pre_mid_x - $direction * $width * $anx;  
$there_points[]=$pre_mid_y - $direction * $width * $any;  
   
// all points done, now combine the lists, and produce the final result.  
   
  $y=array_pop($back_points);
  $x=array_pop($back_points);
  do
  {
  $there_points[]=$x;
  $there_points[]=$y;
$y=array_pop($back_points); $y=array_pop($back_points);
$x=array_pop($back_points); $x=array_pop($back_points);
  } while (!is_null($y));
   
do $arrayindex=0;
{  
$there_points[]=$x;  
$there_points[]=$y;  
$y=array_pop($back_points);  
$x=array_pop($back_points);  
} while (!is_null($y));  
   
$arrayindex=0; if ($direction < 0) $arrayindex=1;
   
if ($direction < 0) if (!is_null($fillcolours[$arrayindex]))
$arrayindex=1; { imagefilledpolygon($image, $there_points, count($there_points) / 2, $arrowsettings[$dir][4]); }
   
  $map->imap->addArea("Polygon", "LINK:" . $linkname, '', $there_points);
  debug ("Adding Poly imagemap for $linkname\n");
   
if (!is_null($fillcolours[$arrayindex])) if (!is_null($outlinecolour))
{ imagefilledpolygon($image, $there_points, count($there_points) / 2, $fillcolours[$arrayindex]); } imagepolygon($image, $there_points, count($there_points) / 2, $arrowsettings[$dir][5]);
   
$map->imap->addArea("Polygon", "LINK:" . $linkname, '', $there_points);  
debug ("Adding Poly imagemap for $linkname\n");  
   
if (!is_null($outlinecolour))  
imagepolygon($image, $there_points, count($there_points) / 2, $outlinecolour);  
   
// Time to deal with Link Comments, if any  
if($direction > 0)  
{  
$extra_percent = 5;  
$startindex=0;  
# $comment = "OUTCOMMENT";  
$comment = $map->links[$linkname]->outcomment;  
}  
else  
{  
$extra_percent = 95;  
$startindex = count($curvepoints)-1;  
# $comment = "INCOMMENT";  
$comment = $map->links[$linkname]->incomment;  
}  
   
$comment = $map->ProcessString($comment,$map->links[$linkname]);  
   
if($comment != '')  
{  
$font = $map->links[$linkname]->commentfont;  
// nudge pushes the comment out along the link arrow a little bit  
// (otherwise there are more problems with text disappearing underneath links)  
$nudge = 15;  
   
$extra = ($totaldistance * ($extra_percent/100));  
$comment_index = find_distance($curvepoints,$extra);  
   
$ratio = ($extra - $curvepoints[$comment_index][2]) / ($curvepoints[$comment_index + 1][2] - $curvepoints[$comment_index][2]);  
$dx = -$curvepoints[$startindex][0] + ($curvepoints[$comment_index][0] + $ratio * ($curvepoints[$comment_index + 1][0] - $curvepoints[$comment_index][0]));  
$dy = -$curvepoints[$startindex][1] + ($curvepoints[$comment_index][1] + $ratio * ($curvepoints[$comment_index + 1][1] - $curvepoints[$comment_index][1]));  
// we need the angle to draw the text  
$angle = rad2deg(atan2(-$dy,$dx));  
// find the normal to our link, so we can get outside the arrow  
$l=sqrt(($dx * $dx) + ($dy * $dy));  
$dx = $dx/$l; $dy = $dy/$l;  
$nx = $dy; $ny = -$dx;  
$col = $comment_colour;  
   
// if the text will be upside-down, rotate it, flip it, and right-justify it  
// not quite as catchy as Missy's version  
if(abs($angle)>90)  
{  
# $col = $map->selected;  
$angle -= 180;  
if($angle < -180) $angle +=360;  
// other side of the link  
$edge_x = $curvepoints[$startindex][0] + $nudge*$dx - $nx * ($width + 4);  
$edge_y = $curvepoints[$startindex][1] + $nudge*$dy - $ny * ($width + 4);  
   
# $textlength = 80;  
list($textlength, $textheight) = $map->myimagestringsize($font, $comment);  
# $bbox = imageftbbox($fontsize,0,$font,$comment);  
#$textlength = abs($bbox[0]) + abs($bbox[2]);  
   
$edge_x += $dx * $textlength;  
$edge_y += $dy * $textlength;  
}  
else  
{  
$edge_x = $curvepoints[$startindex][0] + $nudge*$dx + $nx * ($width + 4);  
$edge_y = $curvepoints[$startindex][1] + $nudge*$dy + $ny * ($width + 4);  
}  
// FINALLY, draw the text!  
# imagefttext($image, $fontsize, $angle, $edge_x, $edge_y, $col, $font,$comment);  
$map->myimagestring($image, $font, $edge_x, $edge_y, $comment, $col, $angle);  
}  
   
}  
   
// now figure out where the labels should go, so we can pass those  
// coordinates back  
   
$q1index=find_distance($curvepoints, $q1);  
$ratio=($q1 - $curvepoints[$q1index][2]) / ($curvepoints[$q1index + 1][2] - $curvepoints[$q1index][2]);  
$q1_x=$curvepoints[$q1index][0] + $ratio * ($curvepoints[$q1index + 1][0] - $curvepoints[$q1index][0]);  
$q1_y=$curvepoints[$q1index][1] + $ratio * ($curvepoints[$q1index + 1][1] - $curvepoints[$q1index][1]);  
   
$q3index=find_distance($curvepoints, $q3);  
$ratio=($q3 - $curvepoints[$q3index][2]) / ($curvepoints[$q3index + 1][2] - $curvepoints[$q3index][2]);  
$q3_x=$curvepoints[$q3index][0] + $ratio * ($curvepoints[$q3index + 1][0] - $curvepoints[$q3index][0]);  
$q3_y=$curvepoints[$q3index][1] + $ratio * ($curvepoints[$q3index + 1][1] - $curvepoints[$q3index][1]);  
   
return (array($q1_x, $q1_y, $q3_x, $q3_y));  
}  
else  
{  
warn ("Arrow not drawn, as it's 1-dimensional.\n");  
return (array(NULL, NULL, NULL, NULL));  
} }
} }
   
function unformat_number($instring, $kilo = 1000) function unformat_number($instring, $kilo = 1000)
{ {
$matches=0; $matches=0;
$number=0; $number=0;
   
if (preg_match("/([0-9\.]+)(M|G|K|T)/", $instring, $matches)) if (preg_match("/([0-9\.]+)(M|G|K|T|m|u)/", $instring, $matches))
{ {
$number=floatval($matches[1]); $number=floatval($matches[1]);
   
if ($matches[2] == 'K') { $number=$number * $kilo; } if ($matches[2] == 'K') { $number=$number * $kilo; }
   
if ($matches[2] == 'M') { $number=$number * $kilo * $kilo; } if ($matches[2] == 'M') { $number=$number * $kilo * $kilo; }
   
if ($matches[2] == 'G') { $number=$number * $kilo * $kilo * $kilo; } if ($matches[2] == 'G') { $number=$number * $kilo * $kilo * $kilo; }
   
if ($matches[2] == 'T') { $number=$number * $kilo * $kilo * $kilo * $kilo; } if ($matches[2] == 'T') { $number=$number * $kilo * $kilo * $kilo * $kilo; }
   
// new, for absolute datastyle. Think seconds. // new, for absolute datastyle. Think seconds.
if ($matches[2] == 'm') { $number=$number / $kilo; } if ($matches[2] == 'm') { $number=$number / $kilo; }
   
if ($matches[2] == 'u') { $number=$number / ($kilo * $kilo); } if ($matches[2] == 'u') { $number=$number / ($kilo * $kilo); }
} }
else { $number=floatval($instring); } else { $number=floatval($instring); }
   
return ($number); return ($number);
} }
   
// given a compass-point, and a width & height, return a tuple of the x,y offsets // given a compass-point, and a width & height, return a tuple of the x,y offsets
function calc_offset($offsetstring, $width, $height) function calc_offset($offsetstring, $width, $height)
{ {
if(preg_match("/^([-+]*\d+):([-+]*\d+)$/",$offsetstring,$matches)) if(preg_match("/^([-+]?\d+):([-+]?\d+)$/",$offsetstring,$matches))
{ {
debug("Numeric Offset found\n"); debug("Numeric Offset found\n");
return(array($matches[1],$matches[2])); return(array($matches[1],$matches[2]));
} }
else else
Line 802... Line 776...
   
$result=format_number($number, $decimals) . $suffix; $result=format_number($number, $decimals) . $suffix;
return ($result); return ($result);
} }
   
   
  // ***********************************************
   
  // we use enough points in various places to make it worth a small class to save some variable-pairs.
  class Point
  {
  var $x, $y;
  function Point($x=0,$y=0)
  {
  $this->x = $x;
  $this->y = $y;
  }
  }
   
  // similarly for 2D vectors
  class Vector
  {
  var $dx, $dy;
   
  function Vector($dx=0,$dy=0)
  {
  $this->dx = $dx;
  $this->dy = $dy;
  }
   
  function normalise()
  {
  $len = $this->length();
  $this->dx = $this->dx/$len;
  $this->dy = $this->dy/$len;
  }
   
  function length()
  {
  return( sqrt(($this->dx)*($this->dx) + ($this->dy)*($this->dy)) );
  }
  }
   
// *********************************************** // ***********************************************
   
// template class for data sources. All data sources extend this class. // template class for data sources. All data sources extend this class.
// I really wish PHP4 would just die overnight // I really wish PHP4 would just die overnight
Line 868... Line 879...
} }
   
function add_hint($name,$value) function add_hint($name,$value)
{ {
$this->hints[$name] = $value; $this->hints[$name] = $value;
  # warn("Adding hint $name to ".$this->my_type()."/".$this->name."\n");
} }
   
   
function get_hint($name) function get_hint($name)
{ {
Line 927... Line 939...
var $bandwidth_in, $bandwidth_out; var $bandwidth_in, $bandwidth_out;
var $inpercent, $outpercent; var $inpercent, $outpercent;
var $max_bandwidth_in, $max_bandwidth_out; var $max_bandwidth_in, $max_bandwidth_out;
var $max_bandwidth_in_cfg, $max_bandwidth_out_cfg; var $max_bandwidth_in_cfg, $max_bandwidth_out_cfg;
var $labeloffset, $labeloffsetx, $labeloffsety; var $labeloffset, $labeloffsetx, $labeloffsety;
   
var $inherit_fieldlist; var $inherit_fieldlist;
   
var $labelbgcolour; var $labelbgcolour;
var $labeloutlinecolour; var $labeloutlinecolour;
var $labelfontcolour; var $labelfontcolour;
var $labelfontshadowcolour; var $labelfontshadowcolour;
var $cachefile; var $cachefile;
var $usescale; var $usescale;
var $inscalekey,$outscalekey; var $inscalekey,$outscalekey;
var $incolour,$outcolour; # var $incolour,$outcolour;
var $scalevar; var $scalevar;
var $notestext; var $notestext;
var $image; var $image;
var $centre_x, $centre_y; var $centre_x, $centre_y;
var $relative_to; var $relative_to;
Line 959... Line 971...
'relative_to' => '', 'relative_to' => '',
'relative_resolved' => FALSE, 'relative_resolved' => FALSE,
'x' => 0, 'x' => 0,
'y' => 0, 'y' => 0,
'inscalekey'=>'', 'outscalekey'=>'', 'inscalekey'=>'', 'outscalekey'=>'',
'incolour'=>-1,'outcolour'=>-1, #'incolour'=>-1,'outcolour'=>-1,
'original_x' => 0, 'original_x' => 0,
'original_y' => 0, 'original_y' => 0,
'inpercent'=>0, 'inpercent'=>0,
'outpercent'=>0, 'outpercent'=>0,
'iconfile' => '', 'iconfile' => '',
Line 971... Line 983...
'iconscaleh' => 0, 'iconscaleh' => 0,
'targets' => array(), 'targets' => array(),
'infourl' => '', 'infourl' => '',
'notestext' => '', 'notestext' => '',
'notes' => array(), 'notes' => array(),
  'hints' => array(),
'overliburl' => '', 'overliburl' => '',
'overlibwidth' => 0, 'overlibwidth' => 0,
'overlibheight' => 0, 'overlibheight' => 0,
'overlibcaption' => '', 'overlibcaption' => '',
'labeloutlinecolour' => array(0, 0, 0), 'labeloutlinecolour' => array(0, 0, 0),
Line 998... Line 1011...
$this->image = NULL; $this->image = NULL;
} }
   
function my_type() { return "NODE"; } function my_type() { return "NODE"; }
   
   
// make a mini-image, containing this node and nothing else // make a mini-image, containing this node and nothing else
// figure out where the real NODE centre is, relative to the top-left corner. // figure out where the real NODE centre is, relative to the top-left corner.
function pre_render($im, &$map) function pre_render($im, &$map)
{ {
// apparently, some versions of the gd extension will crash // apparently, some versions of the gd extension will crash
Line 1133... Line 1145...
   
$label_x1 += $this->labeloffsetx; $label_x1 += $this->labeloffsetx;
$label_x2 += $this->labeloffsetx; $label_x2 += $this->labeloffsetx;
$label_y1 += $this->labeloffsety; $label_y1 += $this->labeloffsety;
$label_y2 += $this->labeloffsety; $label_y2 += $this->labeloffsety;
   
   
if($this->label != '') if($this->label != '')
{ {
$map->imap->addArea("Rectangle", "NODE:" . $this->name, '', array($label_x1, $label_y1, $label_x2, $label_y2)); $map->imap->addArea("Rectangle", "NODE:" . $this->name, '', array($label_x1, $label_y1, $label_x2, $label_y2));
} }
Line 1218... Line 1229...
   
} }
   
// debug("Choosing NODE BGCOLOR for ".$this->name." based on $pc %\n"); // debug("Choosing NODE BGCOLOR for ".$this->name." based on $pc %\n");
   
list($col,$node_scalekey) = $map->ColourFromPercent($pc, $this->usescale, $this->name); list($col,$node_scalekey) = $map->ColourFromPercent($pc, $this->usescale,$this->name);
// $map->nodes[$this->name]->scalekey = $node_scalekey; // $map->nodes[$this->name]->scalekey = $node_scalekey;
} }
elseif($this->labelbgcolour != array(-1,-1,-1)) elseif($this->labelbgcolour != array(-1,-1,-1))
{ {
$col=myimagecolorallocate($node_im, $this->labelbgcolour[0], $this->labelbgcolour[1], $this->labelbgcolour[2]); $col=myimagecolorallocate($node_im, $this->labelbgcolour[0], $this->labelbgcolour[1], $this->labelbgcolour[2]);
Line 1393... Line 1404...
$this->my_default = $this->owner->defaultnode; $this->my_default = $this->owner->defaultnode;
} }
else else
{ {
// use the default defaults // use the default defaults
foreach (array_keys($this->inherit_fieldlist)as foreach (array_keys($this->inherit_fieldlist)as $fld)
$fld) { $this->$fld=$this->inherit_fieldlist[$fld]; } { $this->$fld = $this->inherit_fieldlist[$fld]; }
} }
  # warn($this->name.": ".var_dump($this->hints)."\n");
  # warn("DEF: ".var_dump($this->owner->defaultnode->hints)."\n");
  #if($this->name == 'North')
  #{
  # warn("In Reset, North says: ".$this->nodes['North']->hints['sigdigits']."\n");
  # }
} }
   
function CopyFrom($source) function CopyFrom(&$source)
{ {
foreach (array_keys($this->inherit_fieldlist)as $fld) { $this->$fld=$source->$fld; } foreach (array_keys($this->inherit_fieldlist)as $fld) { $this->$fld=$source->$fld; }
} }
   
function WriteConfig($fd) function WriteConfig($fd)
Line 1752... Line 1769...
{ {
var $owner, $name; var $owner, $name;
var $maphtml; var $maphtml;
var $a, $b; // the ends - references to nodes var $a, $b; // the ends - references to nodes
var $width, $arrowstyle; var $width, $arrowstyle;
var $bwfont, $labelstyle; var $bwfont, $labelstyle, $labelboxstyle;
var $overliburl, $infourl; var $overliburl, $infourl;
var $notes; var $notes;
var $overlibcaption; var $overlibcaption;
var $overlibwidth, $overlibheight; var $overlibwidth, $overlibheight;
var $bandwidth_in, $bandwidth_out; var $bandwidth_in, $bandwidth_out;
Line 1773... Line 1790...
var $outlinecolour; var $outlinecolour;
var $bwoutlinecolour; var $bwoutlinecolour;
var $bwboxcolour; var $bwboxcolour;
var $commentfont,$notestext; var $commentfont,$notestext;
var $inscalekey,$outscalekey; var $inscalekey,$outscalekey;
var $incolour,$outcolour; # var $incolour,$outcolour;
var $commentfontcolour; var $commentfontcolour;
var $bwfontcolour; var $bwfontcolour;
var $incomment, $outcomment; # var $incomment, $outcomment;
  var $comments = array();
  var $curvepoints;
var $labeloffset_in, $labeloffset_out; var $labeloffset_in, $labeloffset_out;
  var $commentoffset_in, $commentoffset_out;
   
function WeatherMapLink() { $this->inherit_fieldlist=array function WeatherMapLink() { $this->inherit_fieldlist=array
( (
'my_default' => NULL, 'my_default' => NULL,
'width' => 7, 'width' => 7,
'commentfont' => 1, 'commentfont' => 1,
'bwfont' => 2, 'bwfont' => 2,
'labeloffset_out' => 25, 'labeloffset_out' => 25,
'labeloffset_in' => 75, 'labeloffset_in' => 75,
  'commentoffset_out' => 5,
  'commentoffset_in' => 95,
'arrowstyle' => 'classic', 'arrowstyle' => 'classic',
'usescale' => 'DEFAULT', 'usescale' => 'DEFAULT',
'targets' => array(), 'targets' => array(),
'infourl' => '', 'infourl' => '',
'notestext' => '', 'notestext' => '',
'notes' => array(), 'notes' => array(),
  'hints' => array(),
  'comments' => array('',''),
'overliburl' => '', 'overliburl' => '',
'labelstyle' => 'percent', 'labelstyle' => 'percent',
  'labelboxstyle' => 'classic',
'overlibwidth' => 0, 'overlibwidth' => 0,
'overlibheight' => 0, 'overlibheight' => 0,
'outlinecolour' => array(0, 0, 0), 'outlinecolour' => array(0, 0, 0),
'bwoutlinecolour' => array(0, 0, 0), 'bwoutlinecolour' => array(0, 0, 0),
'bwfontcolour' => array(0, 0, 0), 'bwfontcolour' => array(0, 0, 0),
'bwboxcolour' => array(255, 255, 255), 'bwboxcolour' => array(255, 255, 255),
'commentfontcolour' => array(192,192,192), 'commentfontcolour' => array(192,192,192),
'inpercent'=>0, 'outpercent'=>0, 'inpercent'=>0, 'outpercent'=>0,
'inscalekey'=>'', 'outscalekey'=>'', 'inscalekey'=>'', 'outscalekey'=>'',
'incolour'=>-1,'outcolour'=>-1, # 'incolour'=>-1,'outcolour'=>-1,
'a_offset' => 'C', 'a_offset' => 'C',
'b_offset' => 'C', 'b_offset' => 'C',
'incomment' => '', #'incomment' => '',
'outcomment' => '', #'outcomment' => '',
'overlibcaption' => '', 'overlibcaption' => '',
'max_bandwidth_in' => 100000000, 'max_bandwidth_in' => 100000000,
'max_bandwidth_out' => 100000000, 'max_bandwidth_out' => 100000000,
'max_bandwidth_in_cfg' => '100M', 'max_bandwidth_in_cfg' => '100M',
'max_bandwidth_out_cfg' => '100M' 'max_bandwidth_out_cfg' => '100M'
Line 1841... Line 1865...
   
function my_type() { return "LINK"; } function my_type() { return "LINK"; }
   
function CopyFrom($source) function CopyFrom($source)
{ {
foreach (array_keys($this->inherit_fieldlist)as $fld) { $this->$fld=$source->$fld; } foreach (array_keys($this->inherit_fieldlist)as $fld) { $this->$fld = $source->$fld; }
} }
   
// Set the bandwidth for this link. Convert from KMGT as necessary // Set the bandwidth for this link. Convert from KMGT as necessary
function SetBandwidth($inbw, $outbw) function SetBandwidth($inbw, $outbw)
{ {
Line 1856... Line 1880...
$this->max_bandwidth_out_cfg=$outbw; $this->max_bandwidth_out_cfg=$outbw;
debug (sprintf("Setting bandwidth (%s -> %d bps, %s -> %d bps, KILO = %d)\n", $inbw, $this->max_bandwidth_in, $outbw, debug (sprintf("Setting bandwidth (%s -> %d bps, %s -> %d bps, KILO = %d)\n", $inbw, $this->max_bandwidth_in, $outbw,
$this->max_bandwidth_out, $kilo)); $this->max_bandwidth_out, $kilo));
} }
   
function Draw($im, &$map) function DrawComments($image,$col,$width)
{ {
# $max_bw_in = $this->max_bandwidth_in; $curvepoints =& $this->curvepoints;
# $max_bw_out = $this->max_bandwidth_out; $last = count($curvepoints)-1;
  $totaldistance = $curvepoints[$last][2];
   
  $start[OUT] = 0;
  $commentpos[OUT] = $this->commentoffset_out;
  $commentpos[IN] = $this->commentoffset_in;
  $start[IN] = $last;
   
  foreach (array(OUT,IN) as $dir)
  {
  // Time to deal with Link Comments, if any
  $comment = $this->owner->ProcessString($this->comments[$dir], $this);
   
  if($comment != '')
  {
  // XXX - redundant extra variable
  $startindex = $start[$dir];
  $extra_percent = $commentpos[$dir];
   
  $font = $this->commentfont;
  // nudge pushes the comment out along the link arrow a little bit
  // (otherwise there are more problems with text disappearing underneath links)
  # $nudgealong = 0; $nudgeout=0;
  $nudgealong = intval($this->get_hint("comment_nudgealong"));
  $nudgeout = intval($this->get_hint("comment_nudgeout"));
   
  $extra = ($totaldistance * ($extra_percent/100));
  # $comment_index = find_distance($curvepoints,$extra);
   
  list($x,$y,$comment_index,$angle) = find_distance_coords_angle($curvepoints,$extra);
  $dx = $x - $curvepoints[$comment_index][0];
  $dy = $y - $curvepoints[$comment_index][1];
   
  #$ratio = ($extra - $curvepoints[$comment_index][2]) / ($curvepoints[$comment_index + 1][2] - $curvepoints[$comment_index][2]);
  #$dx = -$curvepoints[$startindex][0] + ($curvepoints[$comment_index][0] + $ratio * ($curvepoints[$comment_index + 1][0] - $curvepoints[$comment_index][0]));
  #$dy = -$curvepoints[$startindex][1] + ($curvepoints[$comment_index][1] + $ratio * ($curvepoints[$comment_index + 1][1] - $curvepoints[$comment_index][1]));
  // we need the angle to draw the text
  #$angle = rad2deg(atan2(-$dy,$dx));
  // find the normal to our link, so we can get outside the arrow
   
  $l=sqrt(($dx * $dx) + ($dy * $dy));
  $dx = $dx/$l; $dy = $dy/$l;
  $nx = $dy; $ny = -$dx;
   
  # warn($commentpos[$dir]." $extra/$totaldistance ".$comment_index."\n");
  # warn("$dx/$dy $nx/$ny\n");
  #$edge_x = $x + $nudge*$dx + $nx * ($width + 4);
  #$edge_y = $y + $nudge*$dy + $ny * ($width + 4);
  $flipped = FALSE;
  // if the text will be upside-down, rotate it, flip it, and right-justify it
  // not quite as catchy as Missy's version
  if(abs($angle)>90)
  {
  # $col = $map->selected;
  $angle -= 180;
  if($angle < -180) $angle +=360;
  $edge_x = $x + $nudgealong*$dx - $nx * ($width + 4 + $nudgeout);
  $edge_y = $y + $nudgealong*$dy - $ny * ($width + 4 + $nudgeout);
  # $comment .= "@";
  $flipped = TRUE;
  }
  else
  {
  $edge_x = $x + $nudgealong*$dx + $nx * ($width + 4 + $nudgeout);
  $edge_y = $y + $nudgealong*$dy + $ny * ($width + 4 + $nudgeout);
  }
   
  list($textlength, $textheight) = $this->owner->myimagestringsize($font, $comment);
   
  if( !$flipped && ($extra + $textlength) > $totaldistance)
  {
  $edge_x -= $dx * $textlength;
  $edge_y -= $dy * $textlength;
  # $comment .= "#";
  }
   
  if( $flipped && ($extra - $textlength) < 0)
  {
  $edge_x += $dx * $textlength;
  $edge_y += $dy * $textlength;
  # $comment .= "%";
  }
   
  // FINALLY, draw the text!
  # imagefttext($image, $fontsize, $angle, $edge_x, $edge_y, $col, $font,$comment);
  $this->owner->myimagestring($image, $font, $edge_x, $edge_y, $comment, $col, $angle);
  #imagearc($image,$x,$y,10,10,0, 360,$this->owner->selected);
  #imagearc($image,$edge_x,$edge_y,10,10,0, 360,$this->owner->selected);
  }
  }
  }
   
#$pc=(($this->bandwidth_out) / ($this->max_bandwidth_out)) * 100; function Draw($im, &$map)
#$this->outpercent=$pc; {
  // Get the positions of the end-points
#$pc=(($this->bandwidth_in) / ($this->max_bandwidth_in)) * 100;  
#$this->inpercent=$pc;  
   
#$x1=$this->a->x;  
#$y1=$this->a->y;  
   
#$x2=$this->b->x;  
#$y2=$this->b->y;  
$x1=$map->nodes[$this->a->name]->x; $x1=$map->nodes[$this->a->name]->x;
$y1=$map->nodes[$this->a->name]->y; $y1=$map->nodes[$this->a->name]->y;
   
$x2=$map->nodes[$this->b->name]->x; $x2=$map->nodes[$this->b->name]->x;
$y2=$map->nodes[$this->b->name]->y; $y2=$map->nodes[$this->b->name]->y;
# print "$x1,$y1 -> $x2,$y2 via ";  
  // Adjust them if there's an offset requested
$a_height=$map->nodes[$this->a->name]->height; #$a_height=$map->nodes[$this->a->name]->height;
$a_width=$map->nodes[$this->a->name]->width; #$a_width=$map->nodes[$this->a->name]->width;
   
$b_height=$map->nodes[$this->b->name]->height;  
$b_width=$map->nodes[$this->b->name]->width;  
   
# print "[".$this->a_offset." ".$this->b_offset."] and ($a_width x $a_height and $b_width x $b_height)"; # $b_height=$map->nodes[$this->b->name]->height;
  # $b_width=$map->nodes[$this->b->name]->width;
   
list($dx, $dy)=calc_offset($this->a_offset, $a_width, $a_height); list($dx, $dy)=calc_offset($this->a_offset, $map->nodes[$this->a->name]->width, $map->nodes[$this->a->name]->height);
$x1+=$dx; $x1+=$dx;
$y1+=$dy; $y1+=$dy;
   
list($dx, $dy)=calc_offset($this->b_offset, $b_width, $b_height); list($dx, $dy)=calc_offset($this->b_offset, $map->nodes[$this->b->name]->width, $map->nodes[$this->b->name]->height);
$x2+=$dx; $x2+=$dx;
$y2+=$dy; $y2+=$dy;
   
# print " becomes $x1,$y1 -> $x2,$y2";  
# print "\n";  
   
$outline_colour=NULL; $outline_colour=NULL;
$comment_colour=NULL; $comment_colour=NULL;
   
if ($this->outlinecolour != array if ($this->outlinecolour != array(-1,-1,-1))
( {
-1, $outline_colour=myimagecolorallocate(
-1, $im, $this->outlinecolour[0], $this->outlinecolour[1],
-1 $this->outlinecolour[2]);
)) { $outline_colour=myimagecolorallocate( }
$im, $this->outlinecolour[0], $this->outlinecolour[1],  
$this->outlinecolour[2]); }  
   
if ($this->commentfontcolour != array if ($this->commentfontcolour != array(-1,-1,-1))
( {
-1, $comment_colour=myimagecolorallocate(
-1, $im, $this->commentfontcolour[0], $this->commentfontcolour[1],
-1 $this->commentfontcolour[2]);
)) { $comment_colour=myimagecolorallocate( }
$im, $this->commentfontcolour[0], $this->commentfontcolour[1],  
$this->commentfontcolour[2]); }  
   
$xpoints = array ( ); $xpoints = array ( );
   
$ypoints = array ( ); $ypoints = array ( );
   
$xpoints[]=$x1; $xpoints[]=$x1;
$ypoints[]=$y1; $ypoints[]=$y1;
   
Line 1937... Line 2033...
} }
   
$xpoints[]=$x2; $xpoints[]=$x2;
$ypoints[]=$y2; $ypoints[]=$y2;
   
list($link_in_colour,$link_in_scalekey) = $map->ColourFromPercent($this->inpercent,$this->usescale, $this->name); list($link_in_colour,$link_in_scalekey) = $map->ColourFromPercent($this->inpercent,$this->usescale,$this->name);
list($link_out_colour,$link_out_scalekey) = $map->ColourFromPercent($this->outpercent,$this->usescale, $this->name); list($link_out_colour,$link_out_scalekey) = $map->ColourFromPercent($this->outpercent,$this->usescale,$this->name);
   
// $map->links[$this->name]->inscalekey = $link_in_scalekey; // $map->links[$this->name]->inscalekey = $link_in_scalekey;
// $map->links[$this->name]->outscalekey = $link_out_scalekey; // $map->links[$this->name]->outscalekey = $link_out_scalekey;
   
$link_width=$this->width; $link_width=$this->width;
Line 1951... Line 2047...
$link_out_width=$this->width; $link_out_width=$this->width;
   
// for bulging animations // for bulging animations
if ( ($map->widthmod) || ($map->get_hint('link_bulge') == 1)) if ( ($map->widthmod) || ($map->get_hint('link_bulge') == 1))
{ {
// a few 0.1s and 1s to fix div-by-zero, and invisible links // a few 0.1s and +1s to fix div-by-zero, and invisible links
$link_width = (($link_width * $this->inpercent * 1.5 + 0.1) / 100) + 1; $link_width = (($link_width * $this->inpercent * 1.5 + 0.1) / 100) + 1;
// these too // these too
$link_in_width = (($link_in_width * $this->inpercent * 1.5 + 0.1) / 100) + 1; $link_in_width = (($link_in_width * $this->inpercent * 1.5 + 0.1) / 100) + 1;
$link_out_width = (($link_out_width * $this->outpercent * 1.5 + 0.1) / 100) + 1; $link_out_width = (($link_out_width * $this->outpercent * 1.5 + 0.1) / 100) + 1;
} }
   
list($q1_x,  
$q1_y, // Calculate the spine points - the actual curve
$q3_x, $this->curvepoints = calc_curve($xpoints, $ypoints);
$q3_y)=draw_curve($im, $xpoints, $ypoints,  
$link_width, $outline_colour, $comment_colour, array($link_out_colour, $link_in_colour), draw_curve($im, $this->curvepoints,
$this->name, $map, $this->labeloffset_out, $this->labeloffset_in); $link_width, $outline_colour, $comment_colour, array($link_in_colour, $link_out_colour),
  $this->name, $map);
   
  $this->DrawComments($im,$comment_colour,$link_width*1.1);
   
  $curvelength = $this->curvepoints[count($this->curvepoints)-1][2];
  // figure out where the labels should be, and what the angle of the curve is at that point
  list($q1_x,$q1_y,$junk,$q1_angle) = find_distance_coords_angle($this->curvepoints,($this->labeloffset_out/100)*$curvelength);
  list($q3_x,$q3_y,$junk,$q3_angle) = find_distance_coords_angle($this->curvepoints,($this->labeloffset_in/100)*$curvelength);
   
  # imageline($im, $q1_x+20*cos(deg2rad($q1_angle)),$q1_y-20*sin(deg2rad($q1_angle)), $q1_x-20*cos(deg2rad($q1_angle)), $q1_y+20*sin(deg2rad($q1_angle)), $this->owner->selected );
  # imageline($im, $q3_x+20*cos(deg2rad($q3_angle)),$q3_y-20*sin(deg2rad($q3_angle)), $q3_x-20*cos(deg2rad($q3_angle)), $q3_y+20*sin(deg2rad($q3_angle)), $this->owner->selected );
   
  # warn("$q1_angle $q3_angle\n");
   
if (!is_null($q1_x)) if (!is_null($q1_x))
{ {
$outbound=array $outbound=array
( (
Line 1975... Line 2084...
$q1_y, $q1_y,
0, 0,
0, 0,
$this->outpercent, $this->outpercent,
$this->bandwidth_out, $this->bandwidth_out,
  $q1_angle
); );
   
$inbound=array $inbound=array
( (
$q3_x, $q3_x,
$q3_y, $q3_y,
0, 0,
0, 0,
$this->inpercent, $this->inpercent,
$this->bandwidth_in $this->bandwidth_in,
  $q3_angle
); );
   
if ($map->sizedebug) if ($map->sizedebug)
{ {
$outbound[5]=$this->max_bandwidth_out; $outbound[5]=$this->max_bandwidth_out;
Line 2005... Line 2115...
debug("Bandwidth is ".$task[5]."\n"); debug("Bandwidth is ".$task[5]."\n");
if ($this->labelstyle == 'bits') { $thelabel=nice_bandwidth($task[5], $this->owner->kilo); } if ($this->labelstyle == 'bits') { $thelabel=nice_bandwidth($task[5], $this->owner->kilo); }
elseif ($this->labelstyle == 'unformatted') { $thelabel=$task[5]; } elseif ($this->labelstyle == 'unformatted') { $thelabel=$task[5]; }
elseif ($this->labelstyle == 'percent') { $thelabel=format_number($task[4]) . "%"; } elseif ($this->labelstyle == 'percent') { $thelabel=format_number($task[4]) . "%"; }
   
$map->DrawLabel($im, $task[0], $task[1], $thelabel, $this->bwfont, 0, $padding = intval($this->get_hint('bwlabel_padding'));
$this->name, $this->bwfontcolour, $this->bwboxcolour, $this->bwoutlinecolour,$map);  
  if($this->labelboxstyle == 'angled')
  {
  $map->DrawLabelRotated($im, $task[0], $task[1],$task[6], $thelabel, $this->bwfont, $padding,
  $this->name, $this->bwfontcolour, $this->bwboxcolour, $this->bwoutlinecolour,$map);
  }
  else
  {
  $map->DrawLabel($im, $task[0], $task[1], $thelabel, $this->bwfont, $padding,
  $this->name, $this->bwfontcolour, $this->bwboxcolour, $this->bwoutlinecolour,$map);
  }
   
} }
} }
} }
} }
   
Line 2052... Line 2173...
? $this->inherit_fieldlist['arrowstyle'] : $this->owner->defaultlink->arrowstyle); ? $this->inherit_fieldlist['arrowstyle'] : $this->owner->defaultlink->arrowstyle);
   
if ($this->arrowstyle != $comparison) { $output.="\tARROWSTYLE " . $this->arrowstyle . "\n"; } if ($this->arrowstyle != $comparison) { $output.="\tARROWSTYLE " . $this->arrowstyle . "\n"; }
   
$comparison=($this->name == 'DEFAULT' $comparison=($this->name == 'DEFAULT'
? $this->inherit_fieldlist['labelstyle'] : $this->owner->defaultlink->labelstyle); ? ($this->inherit_fieldlist['labelstyle']) : ($this->owner->defaultlink->labelstyle));
   
if ($this->labelstyle != $comparison) { $output.="\tBWLABEL " . $this->labelstyle . "\n"; } if ($this->labelstyle != $comparison) { $output.="\tBWLABEL " . $this->labelstyle . "\n"; }
   
  $comparison=($this->name == 'DEFAULT'
  ? ($this->inherit_fieldlist['labelboxstyle']) : ($this->owner->defaultlink->labelboxstyle));
  if ($this->labelboxstyle != $comparison) { $output.="\tBWSTYLE " . $this->labelboxstyle . "\n"; }
   
$comparison = ($this->name == 'DEFAULT' $comparison = ($this->name == 'DEFAULT'
? $this->inherit_fieldlist['labeloffset_in'] : $this->owner->defaultlink->labeloffset_in); ? $this->inherit_fieldlist['labeloffset_in'] : $this->owner->defaultlink->labeloffset_in);
$comparison2 = ($this->name == 'DEFAULT' $comparison2 = ($this->name == 'DEFAULT'
? $this->inherit_fieldlist['labeloffset_out'] : $this->owner->defaultlink->labeloffset_out); ? $this->inherit_fieldlist['labeloffset_out'] : $this->owner->defaultlink->labeloffset_out);
   
if ( ($this->labeloffset_in != $comparison) || ($this->labeloffset_out != $comparison2) ) if ( ($this->labeloffset_in != $comparison) || ($this->labeloffset_out != $comparison2) )
{ $output.="\tBWLABELPOS " . $this->labeloffset_in . " " . $this->labeloffset_out . "\n"; } { $output.="\tBWLABELPOS " . $this->labeloffset_in . " " . $this->labeloffset_out . "\n"; }
   
  $comparison=($this->name == 'DEFAULT'
  ? ($this->inherit_fieldlist['commentoffset_in'].":".$this->inherit_fieldlist['commentoffset_out']) : ($this->owner->defaultlink->commentoffset_in.":".$this->owner->defaultlink->commentoffset_out));
  $mine = $this->commentoffset_in.":".$this->commentoffset_out;
  if ($mine != $comparison) { $output.="\tCOMMENTPOS " . $this->commentoffset_in." ".$this->commentoffset_out. "\n"; }
   
   
$comparison=($this->name == 'DEFAULT' $comparison=($this->name == 'DEFAULT'
? $this->inherit_fieldlist['targets'] : $this->owner->defaultlink->targets); ? $this->inherit_fieldlist['targets'] : $this->owner->defaultlink->targets);
   
Line 2086... Line 2213...
if ($this->usescale != $comparison) { $output.="\tUSESCALE " . $this->usescale . "\n"; } if ($this->usescale != $comparison) { $output.="\tUSESCALE " . $this->usescale . "\n"; }
   
   
   
$comparison=($this->name == 'DEFAULT' $comparison=($this->name == 'DEFAULT'
? $this->inherit_fieldlist['incomment'] : $this->owner->defaultlink->incomment); ? $this->inherit_fieldlist['comments'][IN] : $this->owner->defaultlink->comments[IN]);
if ($this->incomment != $comparison) { $output.="\tINCOMMENT " . $this->incomment . "\n"; } if ($this->comments[IN] != $comparison) { $output.="\tINCOMMENT " . $this->comments[IN] . "\n"; }
   
   
$comparison=($this->name == 'DEFAULT' $comparison=($this->name == 'DEFAULT'
? $this->inherit_fieldlist['outcomment'] : $this->owner->defaultlink->outcomment); ? $this->inherit_fieldlist['comments'][OUT] : $this->owner->defaultlink->comments[OUT]);
if ($this->outcomment != $comparison) { $output.="\tOUTCOMMENT " . $this->outcomment . "\n"; } if ($this->comments[OUT] != $comparison) { $output.="\tOUTCOMMENT " . $this->comments[OUT] . "\n"; }
   
   
   
$comparison=($this->name == 'DEFAULT' $comparison=($this->name == 'DEFAULT'
? $this->inherit_fieldlist['usescale'] : $this->owner->defaultlink->usescale); ? $this->inherit_fieldlist['usescale'] : $this->owner->defaultlink->usescale);
Line 2316... Line 2443...
var $keyx, var $keyx,
$keyy; $keyy;
var $titlex, var $titlex,
$titley; $titley;
var $keytext, var $keytext,
$stamptext; $stamptext, $datestamp;
var $htmloutputfile, var $htmloutputfile,
$imageoutputfile; $imageoutputfile;
var $defaultlink, var $defaultlink,
$defaultnode; $defaultnode;
var $need_size_precalc; var $need_size_precalc;
Line 2430... Line 2557...
   
// $this->bg_r = 255; // $this->bg_r = 255;
// $this->bg_g = 255; // $this->bg_g = 255;
// $this->bg_b = 255; // $this->bg_b = 255;
   
$this->fonts=array $this->fonts=array();
(  
); // Adding these makes the editor's job a little easier, mainly
  for($i=1; $i<=5; $i++)
  {
  $this->fonts[$i]->type="GD builtin";
  $this->fonts[$i]->file='';
  $this->fonts[$i]->size=0;
  }
   
$this->LoadPlugins('data', 'lib' . DIRECTORY_SEPARATOR . 'datasources'); $this->LoadPlugins('data', 'lib' . DIRECTORY_SEPARATOR . 'datasources');
$this->LoadPlugins('pre', 'lib' . DIRECTORY_SEPARATOR . 'pre'); $this->LoadPlugins('pre', 'lib' . DIRECTORY_SEPARATOR . 'pre');
$this->LoadPlugins('post', 'lib' . DIRECTORY_SEPARATOR . 'post'); $this->LoadPlugins('post', 'lib' . DIRECTORY_SEPARATOR . 'post');
   
Line 2573... Line 2706...
{ {
warn("ProcessString: $key refers to unknown item\n"); warn("ProcessString: $key refers to unknown item\n");
} }
else else
{ {
# debug("ProcessString: Found appropriate item: ".get_class($the_item)." ".$the_item->name."\n"); # warn($the_item->name.": ".var_dump($the_item->hints)."\n");
  debug("ProcessString: Found appropriate item: ".get_class($the_item)." ".$the_item->name."\n");
   
  # warn($the_item->name."/hints: ".var_dump($the_item->hints)."\n");
  # warn($the_item->name."/notes: ".var_dump($the_item->notes)."\n");
   
// SET and notes have precedent over internal properties // SET and notes have precedent over internal properties
// this is my laziness - it saves me having a list of reserved words // this is my laziness - it saves me having a list of reserved words
// which are currently used for internal props. You can just 'overwrite' any of them. // which are currently used for internal props. You can just 'overwrite' any of them.
if(isset($the_item->hints[$args])) if(isset($the_item->hints[$args]))
{ {
$value = $the_item->hints[$args]; $value = $the_item->hints[$args];
# debug("ProcessString: used hint\n"); debug("ProcessString: used hint\n");
} }
// for some things, we don't want to allow notes to be considered. // for some things, we don't want to allow notes to be considered.
// mainly - TARGET (which can define command-lines), shouldn't be // mainly - TARGET (which can define command-lines), shouldn't be
// able to get data from uncontrolled sources (i.e. data sources rather than SET in config files). // able to get data from uncontrolled sources (i.e. data sources rather than SET in config files).
elseif($include_notes && isset($the_item->notes[$args])) elseif($include_notes && isset($the_item->notes[$args]))
{ {
$value = $the_item->notes[$args]; $value = $the_item->notes[$args];
# debug("ProcessString: used note\n"); debug("ProcessString: used note\n");
   
} }
elseif(isset($the_item->$args)) elseif(isset($the_item->$args))
{ {
$value = $the_item->$args; $value = $the_item->$args;
# debug("ProcessString: used internal property\n"); debug("ProcessString: used internal property\n");
} }
} }
} }
   
// format, and sanitise the value string here, before returning it // format, and sanitise the value string here, before returning it
   
# debug("ProcessString: replacing ".$key." with $value\n"); debug("ProcessString: replacing ".$key." with $value\n");
   
# if($format != '') $value = sprintf($format,$value); # if($format != '') $value = sprintf($format,$value);
if($format != '') if($format != '')
{ {
   
Line 2633... Line 2770...
   
function LoadPlugins( $type="data", $dir="lib/datasources" ) function LoadPlugins( $type="data", $dir="lib/datasources" )
{ {
debug("Beginning to load $type plugins from $dir\n"); debug("Beginning to load $type plugins from $dir\n");
# $this->datasourceclasses = array(); # $this->datasourceclasses = array();
$dh=opendir($dir); $dh=@opendir($dir);
   
  if(!$dh) { // try to find it with the script, if the relative path fails
  $srcdir = substr($_SERVER['argv'][0], 0, strrpos($_SERVER['argv'][0], DIRECTORY_SEPARATOR));
  $dh = opendir($srcdir.DIRECTORY_SEPARATOR.$dir);
  if ($dh) $dir = $srcdir.DIRECTORY_SEPARATOR.$dir;
  }
   
if ($dh) if ($dh)
{ {
while ($file=readdir($dh)) while ($file=readdir($dh))
{ {
Line 2679... Line 2822...
{ {
debug("Running $ds_class"."->Init()\n"); debug("Running $ds_class"."->Init()\n");
$ret = call_user_func(array($ds_class, 'Init'), $this); $ret = call_user_func(array($ds_class, 'Init'), $this);
if(! $ret) if(! $ret)
{ {
debug("Removing $ds_class from Data Source roster\n"); debug("Removing $ds_class from Data Source list, since Init() failed\n");
$this->activedatasourceclasses[$ds_class]=0; $this->activedatasourceclasses[$ds_class]=0;
# unset($this->datasourceclasses[$ds_class]); # unset($this->datasourceclasses[$ds_class]);
} }
} }
debug("Finished Initialising Plugins...\n"); debug("Finished Initialising Plugins...\n");
Line 2798... Line 2941...
$myobj->bandwidth_out = $total_out; $myobj->bandwidth_out = $total_out;
   
$myobj->outpercent = (($total_out) / ($myobj->max_bandwidth_out)) * 100; $myobj->outpercent = (($total_out) / ($myobj->max_bandwidth_out)) * 100;
$myobj->inpercent = (($total_in) / ($myobj->max_bandwidth_in)) * 100; $myobj->inpercent = (($total_in) / ($myobj->max_bandwidth_in)) * 100;
   
list($incol,$inscalekey) = $this->ColourFromPercent($myobj->inpercent,$myobj->usescale); list($incol,$inscalekey) = $this->ColourFromPercent($myobj->inpercent,$myobj->usescale,$myobj->name);
list($outcol,$outscalekey) = $this->ColourFromPercent($myobj->outpercent,$myobj->usescale); list($outcol,$outscalekey) = $this->ColourFromPercent($myobj->outpercent,$myobj->usescale,$myobj->name);
   
// $myobj->incolour = $incol; // $myobj->incolour = $incol;
$myobj->inscalekey = $inscalekey; $myobj->inscalekey = $inscalekey;
// $myobj->outcolour = $outcol; // $myobj->outcolour = $outcol;
$myobj->outscalekey = $outscalekey; $myobj->outscalekey = $outscalekey;
Line 2850... Line 2993...
imagerectangle($im, $x1, $y1, $x2, $y2, $outlinecol); imagerectangle($im, $x1, $y1, $x2, $y2, $outlinecol);
} }
   
$textcol=myimagecolorallocate($im, $textcolour[0], $textcolour[1], $textcolour[2]); $textcol=myimagecolorallocate($im, $textcolour[0], $textcolour[1], $textcolour[2]);
$this->myimagestring($im, $font, $x - $strwidth / 2, $y + $strheight / 2 + 1, $text, $textcol); $this->myimagestring($im, $font, $x - $strwidth / 2, $y + $strheight / 2 + 1, $text, $textcol);
   
  $this->imap->addArea("Rectangle", "LINK:".$linkname, '', array($x1, $y1, $x2, $y2));
   
  }
   
  // nodename is a vestigal parameter, from the days when nodes where just big labels
  function DrawLabelRotated($im, $x, $y, $angle, $text, $font, $padding, $linkname, $textcolour, $bgcolour, $outlinecolour, &$map)
  {
  list($strwidth, $strheight)=$this->myimagestringsize($font, $text);
   
  if(abs($angle)>90)
  {
  $angle -= 180;
  if($angle < -180) $angle +=360;
  }
   
  $rangle = -deg2rad($angle);
   
  $extra=3;
   
  $x1= $x - ($strwidth / 2) - $padding - $extra;
  $x2= $x + ($strwidth / 2) + $padding + $extra;
  $y1= $y - ($strheight / 2) - $padding - $extra;
  $y2= $y + ($strheight / 2) + $padding + $extra;
   
  // a box. the last point is the start point for the text.
  $points = array($x1,$y1, $x1,$y2, $x2,$y2, $x2,$y1, $x-$strwidth/2, $y+$strheight/2 + 1);
  $npoints = count($points)/2;
   
  RotateAboutPoint($points, $x,$y, $rangle);
   
  if ($bgcolour != array
  (
  -1,
  -1,
  -1
  ))
  {
  $bgcol=myimagecolorallocate($im, $bgcolour[0], $bgcolour[1], $bgcolour[2]);
  # imagefilledrectangle($im, $x1, $y1, $x2, $y2, $bgcol);
  imagefilledpolygon($im,$points,4,$bgcol);
  }
   
  if ($outlinecolour != array
  (
  -1,
  -1,
  -1
  ))
  {
  $outlinecol=myimagecolorallocate($im, $outlinecolour[0], $outlinecolour[1], $outlinecolour[2]);
  # imagerectangle($im, $x1, $y1, $x2, $y2, $outlinecol);
  imagepolygon($im,$points,4,$outlinecol);
  }
   
  $textcol=myimagecolorallocate($im, $textcolour[0], $textcolour[1], $textcolour[2]);
  $this->myimagestring($im, $font, $points[8], $points[9], $text, $textcol,$angle);
   
$this->imap->addArea("Rectangle", "LINK:".$linkname, '', array($x1, $y1, $x2, $y2)); $this->imap->addArea("Rectangle", "LINK:".$linkname, '', array($x1, $y1, $x2, $y2));
   
} }
   
Line 2878... Line 3078...
// we get called early now, so might not need to actually allocate a colour // we get called early now, so might not need to actually allocate a colour
if(isset($this->image)) if(isset($this->image))
{ {
if (isset($colour['red2'])) if (isset($colour['red2']))
{ {
$ratio=($percent - $colour["bottom"]) / ($colour["top"] - $colour["bottom"]); if($colour["bottom"] == $colour["top"])
# print "GRADIENT SCALE ($ratio between ".$colour["bottom"]." and ".$colour["top"].")\n"; {
  $ratio = 0;
  }
  else
  {
  $ratio=($percent - $colour["bottom"]) / ($colour["top"] - $colour["bottom"]);
  }
   
$r=$colour["red1"] + ($colour["red2"] - $colour["red1"]) * $ratio; $r=$colour["red1"] + ($colour["red2"] - $colour["red1"]) * $ratio;
$g=$colour["green1"] + ($colour["green2"] - $colour["green1"]) * $ratio; $g=$colour["green1"] + ($colour["green2"] - $colour["green1"]) * $ratio;
$b=$colour["blue1"] + ($colour["blue2"] - $colour["blue1"]) * $ratio; $b=$colour["blue1"] + ($colour["blue2"] - $colour["blue1"]) * $ratio;
   
Line 2898... Line 3104...
} }
} }
} }
else else
{ {
warn("ColourFromPercent: Attempted to use non-existent scale: $scalename\n"); warn("ColourFromPercent: Attempted to use non-existent scale: $scalename for $name\n");
} }
   
// you'll only get grey for a COMPLETELY quiet link if there's no 0 in the SCALE lines // you'll only get grey for a COMPLETELY quiet link if there's no 0 in the SCALE lines
if ($percent == 0) { return array($this->grey,''); } if ($percent == 0) { return array($this->grey,''); }
   
Line 3060... Line 3266...
   
$colours=$this->colours[$scalename]; $colours=$this->colours[$scalename];
$nscales=$this->numscales[$scalename]; $nscales=$this->numscales[$scalename];
   
debug("Drawing $nscales colours into SCALE\n"); debug("Drawing $nscales colours into SCALE\n");
   
  $hide_zero = intval($this->get_hint("key_hidezero_".$scalename));
  $hide_percent = intval($this->get_hint("key_hidepercent_".$scalename));
   
  if( ($hide_zero == 1) && isset($colours['0_0']) )
  {
  $nscales--;
  }
   
$font=$this->keyfont; $font=$this->keyfont;
   
$x=$this->keyx[$scalename]; $x=$this->keyx[$scalename];
$y=$this->keyy[$scalename]; $y=$this->keyy[$scalename];
Line 3106... Line 3320...
   
$i=1; $i=1;
   
foreach ($colours as $colour) foreach ($colours as $colour)
{ {
# debug("$i: drawing\n"); if ($colour['bottom'] >= 0)
if ($colour['bottom'] >= 0) {
{ # debug("$i: drawing\n");
$y=$boxy + $tilespacing * $i + 8; if( ($hide_zero == 0) || $colour['key'] != '0_0')
$x=$boxx + 6;  
   
if (isset($colour['red2']))  
{ {
for ($n=0; $n < $tilewidth; $n++) $y=$boxy + $tilespacing * $i + 8;
  $x=$boxx + 6;
   
  if (isset($colour['red2']))
  {
  for ($n=0; $n <= $tilewidth; $n++)
  {
  $percent
  =$colour['bottom'] + ($n / $tilewidth) * ($colour['top'] - $colour['bottom']);
  list($col,$junk) = $this->ColourFromPercent($percent,$scalename);
  imagefilledrectangle($im, $x + $n, $y, $x + $n, $y + $tileheight,
  $col);
  }
  }
  else
{ {
$percent // pick a percentage in the middle...
=$colour['bottom'] + ($n / $tilewidth) * ($colour['top'] - $colour['bottom']); $percent=($colour['bottom'] + $colour['top']) / 2;
list($col,$junk) = $this->ColourFromPercent($percent,$scalename); list($col,$junk) = $this->ColourFromPercent($percent,$scalename);
imagefilledrectangle($im, $x + $n, $y, $x + $n, $y + $tileheight, imagefilledrectangle($im, $x, $y, $x + $tilewidth, $y + $tileheight,
$col); $col);
} }
   
  $labelstring=sprintf("%s-%s", $colour['bottom'], $colour['top']);
  if($hide_percent==0) { $labelstring.="%"; }
  $this->myimagestring($im, $font, $x + 4 + $tilewidth, $y + $tileheight, $labelstring,
  $this->colours['DEFAULT']['KEYTEXT']['gdref1']);
  $i++;
} }
else  
{  
// pick a percentage in the middle...  
$percent=($colour['bottom'] + $colour['top']) / 2;  
list($col,$junk) = $this->ColourFromPercent($percent,$scalename);  
imagefilledrectangle($im, $x, $y, $x + $tilewidth, $y + $tileheight,  
$col);  
}  
   
$labelstring=sprintf("%s-%s%%", $colour['bottom'], $colour['top']);  
$this->myimagestring($im, $font, $x + 4 + $tilewidth, $y + $tileheight, $labelstring,  
$this->colours['DEFAULT']['KEYTEXT']['gdref1']);  
$i++;  
} }
} }
   
$this->imap->addArea("Rectangle", "LEGEND:$scalename", '', $this->imap->addArea("Rectangle", "LEGEND:$scalename", '',
array($boxx, $boxy, $boxx + $boxwidth, $boxy + $boxheight)); array($boxx, $boxy, $boxx + $boxwidth, $boxy + $boxheight));
Line 3151... Line 3369...
   
function DrawTimestamp($im, $font, $colour) function DrawTimestamp($im, $font, $colour)
{ {
// add a timestamp to the corner, so we can tell if it's all being updated // add a timestamp to the corner, so we can tell if it's all being updated
# $datestring = "Created: ".date("M d Y H:i:s",time()); # $datestring = "Created: ".date("M d Y H:i:s",time());
$datestring=strftime($this->stamptext, time()); # $this->datestamp=strftime($this->stamptext, time());
   
list($boxwidth, $boxheight)=$this->myimagestringsize($font, $datestring); list($boxwidth, $boxheight)=$this->myimagestringsize($font, $this->datestamp);
   
$x=$this->width - $boxwidth; $x=$this->width - $boxwidth;
$y=$boxheight; $y=$boxheight;
   
if (($this->timex > 0) && ($this->timey > 0)) if (($this->timex > 0) && ($this->timey > 0))
{ {
$x=$this->timex; $x=$this->timex;
$y=$this->timey; $y=$this->timey;
} }
   
$this->myimagestring($im, $font, $x, $y, $datestring, $colour); $this->myimagestring($im, $font, $x, $y, $this->datestamp, $colour);
   
$this->imap->addArea("Rectangle", "TIMESTAMP", '', array($x, $y, $x + $boxwidth, $y - $boxheight)); $this->imap->addArea("Rectangle", "TIMESTAMP", '', array($x, $y, $x + $boxwidth, $y - $boxheight));
} }
   
function DrawTitle($im, $font, $colour) function DrawTitle($im, $font, $colour)
Line 3231... Line 3449...
// first, save the previous item, before starting work on the new one // first, save the previous item, before starting work on the new one
if ($last_seen == "NODE") if ($last_seen == "NODE")
{ {
if ($curnode->name == 'DEFAULT') if ($curnode->name == 'DEFAULT')
{ {
$this->defaultnode=$curnode; $this->defaultnode = $curnode;
debug ("Saving Default Node: " . $curnode->name . "\n"); debug ("Saving Default Node: " . $curnode->name . "\n");
} }
else else
{ {
$this->nodes[$curnode->name]=$curnode; $this->nodes[$curnode->name]=$curnode;
Line 3267... Line 3485...
if ($matches[2] == 'DEFAULT') if ($matches[2] == 'DEFAULT')
{ {
if ($linksseen > 0) { warn if ($linksseen > 0) { warn
("LINK DEFAULT is not the first LINK. Defaults will not apply to earlier LINKs.\n"); ("LINK DEFAULT is not the first LINK. Defaults will not apply to earlier LINKs.\n");
} }
  unset($curlink);
$curlink=$this->defaultlink; $curlink = $this->defaultlink;
} }
else else
{ {
  unset($curlink);
$curlink=new WeatherMapLink; $curlink=new WeatherMapLink;
$curlink->name=$matches[2]; $curlink->name=$matches[2];
$curlink->Reset($this); $curlink->Reset($this);
$linksseen++; $linksseen++;
} }
Line 3291... Line 3510...
{ {
if ($nodesseen > 0) { warn if ($nodesseen > 0) { warn
("NODE DEFAULT is not the first NODE. Defaults will not apply to earlier NODEs.\n"); ("NODE DEFAULT is not the first NODE. Defaults will not apply to earlier NODEs.\n");
} }
   
$curnode=$this->defaultnode; unset($curnode);
  $curnode = $this->defaultnode;
} }
else else
{ {
  unset($curnode);
$curnode=new WeatherMapNode; $curnode=new WeatherMapNode;
$curnode->name=$matches[2]; $curnode->name=$matches[2];
$curnode->Reset($this); $curnode->Reset($this);
$nodesseen++; $nodesseen++;
} }
Line 3433... Line 3654...
$linematched++; $linematched++;
} }
   
if ( ($last_seen == 'LINK') && (preg_match("/^\s*INCOMMENT\s+(.*)\s*$/i", $buffer, $matches))) if ( ($last_seen == 'LINK') && (preg_match("/^\s*INCOMMENT\s+(.*)\s*$/i", $buffer, $matches)))
{ {
$curlink->incomment = $matches[1]; # $curlink->incomment = $matches[1];
  $curlink->comments[IN] = $matches[1];
$linematched++; $linematched++;
} }
   
if ( ($last_seen == 'LINK') && (preg_match("/^\s*OUTCOMMENT\s+(.*)\s*$/i", $buffer, $matches))) if ( ($last_seen == 'LINK') && (preg_match("/^\s*OUTCOMMENT\s+(.*)\s*$/i", $buffer, $matches)))
{ {
$curlink->outcomment = $matches[1]; # $curlink->outcomment = $matches[1];
  $curlink->comments[OUT] = $matches[1];
$linematched++; $linematched++;
} }
   
   
if ( ($last_seen == 'LINK') && (preg_match("/^\s*(BANDWIDTH|MAXVALUE)\s+(\d+\.?\d*[KMGT]?)\s*$/i", $buffer, $matches))) if ( ($last_seen == 'LINK') && (preg_match("/^\s*(BANDWIDTH|MAXVALUE)\s+(\d+\.?\d*[KMGT]?)\s*$/i", $buffer, $matches)))
Line 3504... Line 3727...
   
if (preg_match("/^\s*SET\s+(\S+)\s+(.*)\s*$/i", $buffer, $matches)) if (preg_match("/^\s*SET\s+(\S+)\s+(.*)\s*$/i", $buffer, $matches))
{ {
if($curobj) if($curobj)
{ {
  // THIS IS NOT UPDATING THE 'REAL' DEFAULT NODE
$curobj->add_hint($matches[1],$matches[2]); $curobj->add_hint($matches[1],$matches[2]);
$linematched++; $linematched++;
  # warn("POST-SET ".$curobj->name."::".var_dump($curobj->hints)."::\n");
  # warn("DEFAULT FIRST SAYS ".$this->defaultnode->hints['sigdigits']."\n");
} }
else else
{ {
  // it's a global thing, for the map
$this->add_hint($matches[1],$matches[2]); $this->add_hint($matches[1],$matches[2]);
$linematched++; $linematched++;
} }
} }
   
Line 3620... Line 3847...
if ($last_seen == 'LINK' && preg_match( if ($last_seen == 'LINK' && preg_match(
"/^\s*BWLABEL\s+(bits|percent|unformatted|none)\s*$/i", $buffer, "/^\s*BWLABEL\s+(bits|percent|unformatted|none)\s*$/i", $buffer,
$matches)) $matches))
{ {
$curlink->labelstyle=strtolower($matches[1]); $curlink->labelstyle=strtolower($matches[1]);
  $linematched++;
  }
   
  if ($last_seen == 'LINK' && preg_match(
  "/^\s*BWSTYLE\s+(classic|angled)\s*$/i", $buffer,
  $matches))
  {
  $curlink->labelboxstyle=$matches[1];
$linematched++; $linematched++;
} }
   
if ($last_seen == 'LINK' && preg_match( if ($last_seen == 'LINK' && preg_match(
"/^\s*BWLABELPOS\s+(\d+)\s(\d+)\s*$/i", $buffer, "/^\s*BWLABELPOS\s+(\d+)\s(\d+)\s*$/i", $buffer,
$matches)) $matches))
{ {
$curlink->labeloffset_in = $matches[1]; $curlink->labeloffset_in = $matches[1];
$curlink->labeloffset_out = $matches[2]; $curlink->labeloffset_out = $matches[2];
  $linematched++;
  }
   
  if ($last_seen == 'LINK' && preg_match(
  "/^\s*COMMENTPOS\s+(\d+)\s(\d+)\s*$/i", $buffer,
  $matches))
  {
  $curlink->commentoffset_in = $matches[1];
  $curlink->commentoffset_out = $matches[2];
$linematched++; $linematched++;
} }
   
if( ($last_seen == 'NODE') && preg_match("/^\s*USESCALE\s+([A-Za-z][A-Za-z0-9_]*)(\s+(in|out))?\s*$/i",$buffer,$matches)) if( ($last_seen == 'NODE') && preg_match("/^\s*USESCALE\s+([A-Za-z][A-Za-z0-9_]*)(\s+(in|out))?\s*$/i",$buffer,$matches))
{ {
Line 3676... Line 3920...
if($matches[1]=='') $matches[1] = 'DEFAULT'; if($matches[1]=='') $matches[1] = 'DEFAULT';
else $matches[1] = trim($matches[1]); else $matches[1] = trim($matches[1]);
   
$key=$matches[2] . '_' . $matches[3]; $key=$matches[2] . '_' . $matches[3];
   
  $this->colours[$matches[1]][$key]['key']=$key;
$this->colours[$matches[1]][$key]['bottom'] = (float)($matches[2]); $this->colours[$matches[1]][$key]['bottom'] = (float)($matches[2]);
$this->colours[$matches[1]][$key]['top'] = (float)($matches[3]); $this->colours[$matches[1]][$key]['top'] = (float)($matches[3]);
   
$this->colours[$matches[1]][$key]['red1'] = (int)($matches[4]); $this->colours[$matches[1]][$key]['red1'] = (int)($matches[4]);
$this->colours[$matches[1]][$key]['green1'] = (int)($matches[5]); $this->colours[$matches[1]][$key]['green1'] = (int)($matches[5]);
Line 3691... Line 3936...
$this->colours[$matches[1]][$key]['red2'] = (int) ($matches[7]); $this->colours[$matches[1]][$key]['red2'] = (int) ($matches[7]);
$this->colours[$matches[1]][$key]['green2'] = (int) ($matches[8]); $this->colours[$matches[1]][$key]['green2'] = (int) ($matches[8]);
$this->colours[$matches[1]][$key]['blue2'] = (int) ($matches[9]); $this->colours[$matches[1]][$key]['blue2'] = (int) ($matches[9]);
} }
   
$this->colours[$matches[1]][$key]['key']=$key;  
if(! isset($this->numscales[$matches[1]])) if(! isset($this->numscales[$matches[1]]))
{ {
$this->numscales[$matches[1]]=1; $this->numscales[$matches[1]]=1;
} }
else else
Line 4132... Line 4377...
   
if($skipped>0) if($skipped>0)
{ {
warn("There are Circular dependencies in relative POSITION lines for $skipped nodes.\n"); warn("There are Circular dependencies in relative POSITION lines for $skipped nodes.\n");
} }
   
  # warn("---\n\nDEFAULT NODE AGAIN::".var_dump($this->defaultnode->hints)."::\n");
  #warn("DEFAULT NOW SAYS ".$this->defaultnode->hints['sigdigits']."\n");
  #warn("North NOW SAYS ".$this->nodes['North']->hints['sigdigits']."\n");
   
   
debug("Running Pre-Processing Plugins...\n"); debug("Running Pre-Processing Plugins...\n");
foreach ($this->preprocessclasses as $pre_class) foreach ($this->preprocessclasses as $pre_class)
{ {
Line 4326... Line 4575...
debug("Running $post_class"."->run()\n"); debug("Running $post_class"."->run()\n");
call_user_func_array(array($post_class, 'run'), array(&$this)); call_user_func_array(array($post_class, 'run'), array(&$this));
   
} }
debug("Finished Post-Processing Plugins...\n"); debug("Finished Post-Processing Plugins...\n");
   
  $this->datestamp = strftime($this->stamptext, time());
   
// do the basic prep work // do the basic prep work
if ($this->background != '') if ($this->background != '')
{ {
if (is_readable($this->background)) if (is_readable($this->background))
Line 4388... Line 4639...
foreach ($this->nodes as $node) { $node->pre_render($image, $this); } foreach ($this->nodes as $node) { $node->pre_render($image, $this); }
foreach ($this->links as $link) { $link->Draw($image, $this); } foreach ($this->links as $link) { $link->Draw($image, $this); }
   
if($withnodes) if($withnodes)
{ {
foreach ($this->nodes as $node) { $node->NewDraw($image, $this); } foreach ($this->nodes as $node) {
  $node->NewDraw($image, $this);
  # debug($node->name.": ".var_dump($node->notes)."\n");
  }
  # debug("DEFAULT: ".var_dump($this->defaultnode->notes)."\n");
} }
   
foreach ($this->colours as $scalename=>$colours) foreach ($this->colours as $scalename=>$colours)
{ {
debug("Drawing KEY for $scalename if necessary.\n"); debug("Drawing KEY for $scalename if necessary.\n");
Line 4479... Line 4734...
   
$imagethumb=imagecreatetruecolor($twidth, $theight); $imagethumb=imagecreatetruecolor($twidth, $theight);
imagecopyresampled($imagethumb, $image, 0, 0, 0, 0, $twidth, $theight, imagecopyresampled($imagethumb, $image, 0, 0, 0, 0, $twidth, $theight,
$this->width, $this->height); $this->width, $this->height);
$result = imagepng($imagethumb, $thumbnailfile); $result = imagepng($imagethumb, $thumbnailfile);
  imagedestroy($imagethumb);
   
if(($result==FALSE)) if(($result==FALSE))
{ {
if(file_exists($filename)) if(file_exists($filename))
{ {
Line 4505... Line 4761...
   
function CleanUp() function CleanUp()
{ {
// destroy all the images we created, to prevent memory leaks // destroy all the images we created, to prevent memory leaks
foreach ($this->nodes as $node) { if(isset($node->image)) imagedestroy($node->image); } foreach ($this->nodes as $node) { if(isset($node->image)) imagedestroy($node->image); }
  #foreach ($this->nodes as $node) { unset($node); }
  #foreach ($this->links as $link) { unset($link); }
   
} }
   
function PreloadMapHTML() function PreloadMapHTML()
{ {
Line 4521... Line 4779...
   
foreach ($this->links as $link) foreach ($this->links as $link)
{ {
if ( ($link->overliburl != '') || ($link->notestext != '') ) if ( ($link->overliburl != '') || ($link->notestext != '') )
{ {
# $overlibhtml = "onmouseover=\"return overlib('&lt;img src=".$link->overliburl."&gt;',HAUTO,VAUTO,DELAY,250,CAPTION,'".$link->name."');\" onmouseout=\"return nd();\""; # $overlibhtml = "onmouseover=\"return overlib('&lt;img src=".$link->overliburl."&gt;',DELAY,250,CAPTION,'".$link->name."');\" onmouseout=\"return nd();\"";
$a_x=$link->a->x; $a_x=$link->a->x;
$b_x=$link->b->x; $b_x=$link->b->x;
$mid_x=($a_x + $b_x) / 2; $mid_x=($a_x + $b_x) / 2;
$a_y=$link->a->y; $a_y=$link->a->y;
$b_y=$link->b->y; $b_y=$link->b->y;
Line 4568... Line 4826...
$note = htmlspecialchars($note, ENT_NOQUOTES); $note = htmlspecialchars($note, ENT_NOQUOTES);
$note=str_replace("'", "\\&apos;", $note); $note=str_replace("'", "\\&apos;", $note);
$note=str_replace('"', "&quot;", $note); $note=str_replace('"', "&quot;", $note);
$overlibhtml .= $note; $overlibhtml .= $note;
} }
$overlibhtml .= "',HAUTO,VAUTO,DELAY,250,${left}${above}CAPTION,'" . $caption $overlibhtml .= "',DELAY,250,${left}${above}CAPTION,'" . $caption
. "');\" onmouseout=\"return nd();\""; . "');\" onmouseout=\"return nd();\"";
   
$this->imap->setProp("extrahtml", $overlibhtml, "LINK:" . $link->name); $this->imap->setProp("extrahtml", $overlibhtml, "LINK:" . $link->name);
} }
} }
   
foreach ($this->nodes as $node) foreach ($this->nodes as $node)
{ {
if ( ($node->overliburl != '') || ($node->notestext != '') ) if ( ($node->overliburl != '') || ($node->notestext != '') )
{ {
# $overlibhtml = "onmouseover=\"return overlib('&lt;img src=".$node->overliburl."&gt;',HAUTO,VAUTO,DELAY,250,CAPTION,'".$node->name."');\" onmouseout=\"return nd();\""; # $overlibhtml = "onmouseover=\"return overlib('&lt;img src=".$node->overliburl."&gt;',DELAY,250,CAPTION,'".$node->name."');\" onmouseout=\"return nd();\"";
   
debug ($node->overlibwidth . "---" . $node->overlibheight . "---\n"); debug ($node->overlibwidth . "---" . $node->overlibheight . "---\n");
   
$left=""; $left="";
$above=""; $above="";
Line 4620... Line 4878...
$note = htmlspecialchars($note, ENT_NOQUOTES); $note = htmlspecialchars($note, ENT_NOQUOTES);
$note=str_replace("'", "\\&apos;", $note); $note=str_replace("'", "\\&apos;", $note);
$note=str_replace('"', "&quot;", $note); $note=str_replace('"', "&quot;", $note);
$overlibhtml .= $note; $overlibhtml .= $note;
} }
$overlibhtml .= "',HAUTO,VAUTO,DELAY,250,${left}${above}CAPTION,'" . $caption $overlibhtml .= "',DELAY,250,${left}${above}CAPTION,'" . $caption
. "');\" onmouseout=\"return nd();\""; . "');\" onmouseout=\"return nd();\"";
   
# $overlibhtml .= " onclick=\"return overlib('Some Test or other',CAPTION,'MENU',)\""; # $overlibhtml .= " onclick=\"return overlib('Some Test or other',CAPTION,'MENU',)\"";
   
$this->imap->setProp("extrahtml", $overlibhtml, "NODE:" . $node->name); $this->imap->setProp("extrahtml", $overlibhtml, "NODE:" . $node->name);

Powered by WebSVN 2.2.1