Skip to content

Instantly share code, notes, and snippets.

@jaketoolson
Created November 20, 2012 17:12
Show Gist options
  • Save jaketoolson/4119324 to your computer and use it in GitHub Desktop.
Save jaketoolson/4119324 to your computer and use it in GitHub Desktop.
Plotter
The above code is used to generate a dynamic image similar to below:
https://dl.dropbox.com/u/15302156/flows.png
<?php
/**
* for constructing GIS type images driven by latitude/longitude coordinates
* with some specialize power industry functions
*
* Image($x,$y) - constructs the image x width, y height
* show() - displays the image
* save($f_name) - save image as a png with file name $f_name
* destroy() - destroys the image and frees memory
* SetBackground($r,$g,$b) - set rgb overall background
* SetCenterColor($rcenter,$gcenter,$bcenter) - center color for a gradient circle
* AddGradientCircle($width,$xcenter,$ycenter) - adds a single gradient circle
* SetLineColor($r,$g,$b) - sets rgb color for lines
* SetTextColor($r,$g,$b) - sets rgb color for text
* SetFillColor($r,$g,$b) - fill color for fill operations
* AddCircle($lat,$lon,$diameter,$label,$fill="unfilled") - circle with optional text and optional fill
* AddFilledCircle($lat,$lon,$diameter) - adds a filled circle, no text, no outline
* AddLine($x1,$y1,$x2,$y2,$thick=1)
* AddRectangle($x1,$y1,$x2,$y2,$thick=1) - rectangle outline of given widht
* AddFilledRectangle($x1,$y1,$x2,$y2,$label) - filled rectange, no outline, optional text
* AddText($text,$fontsize,$angle,$x,$y,$alignment) - centered vertically on y, alignment at x (relative to text)
* AddArrowLine($lat1,$lon1,$lat2,$lon2,$flow) - for displaying power flows, negative flows allowed
* SetScale($zerolat,$zerolon,$maxlat,$maxlon) - scale for transforming lat/lon to x,y scale of image
* AddPolygonFile($file,$fill) - file of lat/lon points, $fill = "outline", "fill", or "both"
* AddLineFile($file,$thick=1) - file of lat/lon points defining a multisement line, SetLineColor to set color
* DMStoDEC($deg,$min,$sec) - convert to decimal form of lat or lon
* SetColorScale($min,$low,$high,$max) - color break points
* GetColor($p) - sets internal color variables for price/flow (coverted to a price)
* AddPriceCircle($lat,$lon,$name,$price) - adds a gradient circle and label at lat/lon
* AddLegend($x1,$y1,$fontsize,$alignment,$labels) - add legend block, upper left x1,y1, "right" or "left", array of labels
* AddImgMap($mname,) - sets up and adds the image map name also used for php file name
* FinishImgMap() - completes the image map string into GLOBALS ["$mapname"]
*
*/
class Image{
var $file_name;
var $info;
var $width;
var $height;
var $image;
var $org_image;
var $lata; // a & b scale factor for lat / long to point location
var $latb;
var $lona;
var $lonb;
var $linecolor;
var $textcolor;
var $fillcolor; // for filing polygons
var $backred;
var $backgreen;
var $backblue;
var $scale; // array with prices and colors
var $pricer; // for price being plotted the r value
var $priceg;
var $priceb;
var $font_file;
var $mapname; // name for image map variable and calls
var $mapstring; // the image map string
/**
* Constructor -
* Arguments : Image Filepath
*/
function Image($x,$y) {
$this->image = @imagecreatetruecolor($x, $y);
$this->info['mime']="image/png";
$this->width = $x;
$this->height = $y;
$this->org_image = $this->image;
$this->backred = 255; // white default
$this->backgreen = 255;
$this->backblue = 255;
$this->textcolor = imagecolorallocate($this->image,0,0,0); // black default
$this->linecolor = imagecolorallocate($this->image,0,0,0);
$this->fillcolor = imagecolorallocate($this->image,255,255,255);
$this->font_file="plot/NCS.ttf";
} // end function
/**
* Display the image and then destroy it.
* Example: $img->show();
*/
function show() {
header("Content-type: ".$this->info['mime']);
imagepng($this->image);
}
/*************************************************************
* save the image
* use .png for now
*/
function save($f_name) {
$this->file_name = $f_name;
return imagepng($this->image, $f_name);
}
/**
* Destroy the image to save the memory. Do this after all operations are complete.
*/
function destroy() {
imagedestroy($this->image);
imagedestroy($this->org_image);
}
/**
* set up the image map
*/
function AddImgMap($mname) {
$this->mapname = $mname;
$this->mapstring = "<div><map name=\"$this->mapname\" id=\"$this->mapname\">";
}
/**
* finish the image map
*/
function FinishImgMap() {
$this->mapstring .= "</map></div>";
}
/**
* set background color of entire image
*/
function SetBackground($r,$g,$b) {
$back_color = imagecolorallocate($this->image, $r,$g,$b);
imagefill($this->image, 0, 0, $back_color);
$this->backred = $r;
$this->backgreen = $g;
$this->backblue = $b;
} // end function
/**
* set color of gradient at the center of the circle
*/
function SetCenterColor($rcenter,$gcenter,$bcenter) {
$this->rcenter = $rcenter; // scale factor applied to red (0 = no red)
$this->gcenter = $gcenter; // scale factor applied to green
$this->bcenter = $bcenter;// scale factor applied to blue
} // end function
/**
* plots a gradient fill circle
* blends from background color to center color
*/
function AddGradientCircle($width, $xcenter, $ycenter) {
$kr= ($this->backred-$this->rcenter)*(2/$width);
$kg= ($this->backgreen-$this->gcenter)*(2/$width);
$kb= ($this->backblue-$this->bcenter)*(2/$width);
for ($i = 0.5; $i <= $width/2; $i++){
$diameter = $width - 2 * $i;
$r = $this->backred - $i * $kr;
$g = $this->backgreen - $i * $kg;
$b = $this->backblue - $i * $kb;
$color = imagecolorallocate($this->image, $r, $g, $b);
imagearc($this->image, $xcenter, $ycenter, $diameter, $diameter, 0, 360, $color);
imagefilltoborder($this->image, $xcenter, $ycenter, $color, $color);
}
} // end function
/**
* set color for lines
*/
function SetLineColor($r,$g,$b) {
$this->linecolor = imagecolorallocate($this->image, $r,$g,$b);
} // end function
/**
* set color for text
*/
function SetTextColor($r,$g,$b) {
$this->textcolor = imagecolorallocate($this->image, $r,$g,$b);
} // end function
/**
* set polygon/circle/rectangle fill color
*/
function SetFillColor($r,$g,$b) {
$this->fillcolor = imagecolorallocate($this->image, $r,$g,$b);
} // end function
/**
* add a filled/unfilled circle with optional text
*/
function AddCircle($lat,$lon,$diameter,$label,$fill,$mapit,$id,$title) {
// *** convert lat, lon into xy coordinates
if(stripos($lat,'+')) { // deg, min, sec format
list($d,$m,$s) = explode("+",$lat);
$ycenter = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon);
$xcenter = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
} else { // decimal format
$ycenter = round($lat*$this->lata +$this->latb);
$xcenter = round(abs($lon)*$this->lona +$this->lonb);
}
imagearc($this->image, $xcenter, $ycenter, $diameter, $diameter, 0, 360, $this->linecolor);
if ($fill=="filled") {
imagefilltoborder($this->image, $xcenter, $ycenter, $this->linecolor, $this->fillcolor);
}
// *** now the text labels if non-null string passed in
if ($label<>"filled") {
$t = $label;
$bbox= imageftbbox ( 8, 0, $this->font_file, $t);
$bwidth = abs($bbox[4] - $bbox[0]);
$bheight = abs($bbox[1] - $bbox[5]);
$txc=$xcenter-$bwidth/2;
$tyc=$ycenter+$bheight/2; // seems better without correction -$bheight/2;
imagefttext($this->image, 8, 0, $txc, $tyc, $this->textcolor, $this->font_file,$t);
}
if ($mapit>0){
$this->mapstring .= " <area shape=\"circle\" coords = \"$xcenter, $ycenter, $mapit\" href=\"$this->mapname.php?wxcode=$id\" title=\"$title\" target = \"_self\" /> ";
}
} // end function
/**
* add a filled circle - no text no outline
*/
function AddFilledCircle($lat,$lon,$diameter) {
// *** convert lat, lon into xy coordinates
if(stripos($lat,'+')) { // deg, min, sec format
list($d,$m,$s) = explode("+",$lat);
$ycenter = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon);
$xcenter = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
} else { // decimal format
$ycenter = round($lat*$this->lata +$this->latb);
$xcenter = round(abs($lon)*$this->lona +$this->lonb);
}
imagefilledellipse($this->image, $xcenter, $ycenter, $diameter, $diameter,$this->fillcolor);
} // end function
/**
* add a line
*/
function AddLine($x1,$y1,$x2,$y2,$thick=1) {
$x1 = round($x1);
$y1 = round($y1);
$x2 = round($x2);
$y2 = round($y2);
imagesetthickness($this->image, $thick);
imageline($this->image,$x1,$y1,$x2,$y2,$this->linecolor);
imagesetthickness($this->image, 1);
} // end function
/**
* add a rectangle
*/
function AddRectangle($x1,$y1,$x2,$y2,$thick=1) {
imagesetthickness($this->image, $thick);
imagerectangle($this->image,$x1,$y1,$x2,$y2,$this->linecolor);
imagesetthickness($this->image, 1);
} // end function
/**
* add a filled rectangle with optional text
*/
function AddFilledRectangle($x1,$y1,$x2,$y2,$label) {
imagefilledrectangle($this->image, $x1, $y1, $x2,$y2,$this->fillcolor);
if ($label<>"") {
$xcenter = ($x1+$x2)/2;
$ycenter = ($y1+$y2)/2;
$t = $label;
$bbox= imageftbbox ( 8, 0, $this->font_file, $t);
$bwidth = abs($bbox[4] - $bbox[0]);
$bheight = abs($bbox[1] - $bbox[5]);
$txc=$xcenter-$bwidth/2;
$tyc=$ycenter+$bheight/2; // seems better without correction -$bheight/2;
imagefttext($this->image, 8, 0, $txc, $tyc, $this->textcolor, $this->font_file,$t);
}
} // end function
/**
* add text with params for size, angle (0 or 90), location, and alignment
*/
function AddText($text,$fontsize,$angle,$x,$y,$alignment) {
$bbox= imageftbbox ( $fontsize, $angle, $this->font_file, $text);
$bwidth = abs($bbox[4] - $bbox[0]);
$bheight = abs($bbox[1] - $bbox[5]);
if($angle==0) {
if ($alignment == "center"){
$xt=$x-$bwidth/2;
$yt=$y+$bheight/2;
}
if ($alignment == "left"){
$xt=$x;
$yt=$y+bheight/2;
}
if ($alignment == "right"){
$xt=$x-$bwidth;
$yt=$y+bheight/2;
}
} else {
// 90 degrees
if ($alignment == "center"){
$xt=$x-$bwidth/2;
$yt=$y+$bheight/2;
}
if ($alignment == "left"){
$xt=$x-$bwidth/2;
$yt=$y;
}
if ($alignment == "right"){
$xt=$x-$bwidth/2;
$yt=$y+$bheight;
}
}
imagefttext($this->image, $fontsize, $angle, $xt, $yt, $this->textcolor, $this->font_file,$text);
} // end function
/**
* add a legend to the image image
*/
function AddLegend($x1,$y1,$fontsize,$alignment,$label) {
$legend_count=count($label);
$bwidth=0;
for ($i=0;$i<$legend_count;$i++) {
$bbox= imageftbbox ( $fontsize, 0, $this->font_file, $label[$i]);
$bwidth = max($bwidth,abs($bbox[4] - $bbox[0]));
}
// *** alignment
if($alignment=="left") {
$x2 = $x1 + $bwidth + 4*$fontsize;
$y2 = $y1 + (2*($legend_count)+1)*$fontsize;
} else { // right
$x2 = $x1;
$x1 = $x2 -($bwidth + 4*$fontsize);
$y2 = $y1 + (2*($legend_count)+1)*$fontsize;
}
$text = "";
$this->AddFilledRectangle($x1,$y1,$x2,$y2,$text);
$this->AddRectangle($x1,$y1,$x2,$y2,$thick=1);
for ($i=0;$i<$legend_count;$i++) {
$this->AddText($label[$i],$fontsize,0,$x1+2*$fontsize,$y1+2*($i+1)*$fontsize,"left");
}
} // end function
/**
* add a line with sized arrow
* file data looks like -> 41+59+07,124+12+28 (lat, lon)
*/
function AddArrowLine($lat1,$lon1,$lat2,$lon2,$flow,$flow_scale=10000) {
$size = ($this->height+$this->width)/2;
// $arrowmax = .1;
$arrowmax = .07;
$arrow_size = min($arrowmax*$size,6+abs(($flow/$flow_scale)*$size*$arrowmax));
$arrow_color = abs(250*($flow/$flow_scale));
// *** convert lat, lon into xy coordinates
if(stripos($lat1,'+')) { // deg, min, sec format
list($d,$m,$s) = explode("+",$lat1);
$y1 = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon1);
$x1 = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
} else { // decimal format
$y1 = round($lat1*$this->lata +$this->latb);
$x1 = round(abs($lon1)*$this->lona +$this->lonb);
}
if(stripos($lat2,'+')) { // deg, min, sec format
list($d,$m,$s) = explode("+",$lat2);
$y2 = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon2);
$x2 = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
} else { // decimal format
$y2 = round($lat2*$this->lata +$this->latb);
$x2 = round(abs($lon2)*$this->lona +$this->lonb);
}
// *** add the line
$this->AddLine($x1,$y1,$x2,$y2,1);
// *** adjust line angle for flow direction
if ($flow > 0) {
$angle = atan2($y2-$y1,$x2-$x1);
} else if ($flow <0) {
$angle = atan2($y2-$y1,$x2-$x1)+deg2rad(180);
} else {
return $flow;
}
// *** compute the arrow points
$aminus90 = $angle - deg2rad(90);
$aplus90 = $angle + deg2rad(90);
$sqrt3 = sqrt(3);
// ** arrow mid point
$mpx = round(($x1 + $x2)/2);
$mpy = round(($y1 + $y2)/2);
// ** middle of base
$bx = $mpx - cos($angle)*$arrow_size/2;
$by = $mpy - sin($angle)*$arrow_size/2;
// ** point of arrow
$px = $mpx + cos($angle)*$arrow_size/2;
$py = $mpy + sin($angle)*$arrow_size/2;
// ** left point
$lpx = $bx + cos($aminus90)*$arrow_size/$sqrt3;
$lpy = $by + sin($aminus90)*$arrow_size/$sqrt3;
// ** right point
$rpx = $bx + cos($aplus90)*$arrow_size/$sqrt3;
$rpy = $by + sin($aplus90)*$arrow_size/$sqrt3;
$points = array ($px,$py,$lpx,$lpy,$rpx,$rpy);
$num_points = 3;
// *** get a fill color for the arrow
$this->GetColor($arrow_color);
$frac = .8; // sets background at a washed out version of the price color
$r = 255-$frac*(255-$this->pricer);
$g = 255-$frac*(255-$this->priceg);
$b = 255-$frac*(255-$this->priceb);
$this->SetFillColor($r,$g,$b);
// *** add the arrow
imagefilledpolygon ( $this->image,$points,$num_points,$this->fillcolor );
// *** now the label at upper rightmost point
if ($size >600 ) {
$font = 8;
} else {
$font = 7;
}
$font = 7;
if (($py>$lpy) and ($py>$rpy)) {
// must be either lp or rp
if ($lpx > $rpx) {
// lp is the one
$tx = $lpx;
$ty = $lpy;
}
if ($rpx > $lpx) {
// rp is the one
$tx = $rpx;
$ty = $rpy;
}
}
if (($lpy>$py) and ($lpy>$rpy)) {
// must be p or rp
if ($px > $rpx) {
// p is the one
$tx = $px;
$ty = $py;
}
if ($rpx > $px) {
// rp is the one
$tx = $rpx;
$ty = $rpy;
}
}
if (($rpy>$py) and ($rpy>$lpy)) {
// must be p or lp
if ($px > $lpx) {
// p is the one
$tx = $px;
$ty = $py;
}
if ($lpx > $px) {
// lp is the one
$tx = $lpx;
$ty = $lpy;
}
}
$text = abs($flow);
imagefttext($this->image, $font, 0, $tx, $ty, $this->textcolor, $this->font_file,$text);
} // end function
/**
* compute longitude scale factors
*
* $zerolat - latitude at top left corner of image
* $zerolon - longitude at top left corner of image
* $maxlat - latitude at bottom right corner of image
* $maxlon - longitude at bottom right corner of image
*/
function SetScale($zerolat,$zerolon,$maxlat,$maxlon) {
$this->lata = $this->height/($maxlat-$zerolat);
$this->latb = - $this->lata *$zerolat;
$this->lona = $this->width/($maxlon-$zerolon);
$this->lonb = - $this->lona *$zerolon;
} // end function
/**
* add a polygon from a file
* file data looks like -> 41+59+07,124+12+28 (lat, lon)
*/
function AddPolygonFile($file,$fill) {
($fp = fopen("$file","r")) or die ("could not open $target, bummer");
flock ($fp, LOCK_EX);
$p=0;
while (!feof($fp)) {
$line = fgets($fp);
list($lat,$lon)=explode(",",$line);
list($d,$m,$s) = explode("+",$lat);
$points[2*$p+1] = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon);
$points[2*$p] = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
$p = $p+1;
}
$num_points=$p;
flock ($fp, LOCK_UN);
fclose($fp);
if ($fill=="outline") {
imagepolygon($this->image,$points,$num_points,$this->linecolor);
}
if ($fill=="filled") {
imagefilledpolygon ( $this->image,$points,$num_points,$this->fillcolor );
}
if ($fill=="both") {
imagefilledpolygon ( $this->image,$points,$num_points,$this->fillcolor );
imagepolygon($this->image,$points,$num_points,$this->linecolor);
}
} // end function
/**
* add a multisegment line from a file
* file data looks like -> 41+59+07,124+12+28 (lat, lon) or decimal format
*/
function AddLineFile($file,$thick=1) {
($fp = fopen("$file","r")) or die ("could not open $target, bummer");
flock ($fp, LOCK_EX);
$p=0;
while (!feof($fp)) {
$line = fgets($fp);
list($lat,$lon)=explode(",",$line);
if(stripos($lat,'+')) { // deg, min, sec format
list($d,$m,$s) = explode("+",$lat);
$y[$p] = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon);
$x[$p] = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
} else { // decimal format
$y[$p] = round($lat*$this->lata +$this->latb);
$x[$p] = round(abs($lon)*$this->lona +$this->lonb);
}
// list($d,$m,$s) = explode("+",$lat);
// $y[$p] = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
// list($d,$m,$s) = explode("+",$lon);
// $x[$p] = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
if($p>=1){
$x1 = $x[$p-1];
$y1 = $y[$p-1];
$x2 = $x[$p];
$y2 = $y[$p];
// echo "$x1,$y1,$x2,$y2,$thick <br>";
$this->Addline($x1,$y1,$x2,$y2,$thick);
}
$p = $p+1;
}
$num_points=$p;
flock ($fp, LOCK_UN);
fclose($fp);
} // end function
/**
* adds text to map based on lat/lon point
* file data looks like -> 41+59+07,124+12+28 (lat, lon)
* using AddText($text,$fontsize,$angle,$x,$y,$alignment)
*/
function AddTextFile($file,$fontsize,$angle,$alignment) {
($fp = fopen("$file","r")) or die ("could not open $target, bummer");
flock ($fp, LOCK_EX);
$p=0;
while (!feof($fp)) {
$line = fgets($fp);
list($lat,$lon,$text)=explode(",",$line);
list($d,$m,$s) = explode("+",$lat);
$y = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon);
$x = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
// echo "$file,$text,$fontsize,$angle,$x,$y,$alignment<br>";
$this->AddText($text,$fontsize,$angle,$x,$y,$alignment);
$p = $p+1;
}
$num_points=$p;
flock ($fp, LOCK_UN);
fclose($fp);
} // end function
/**
* Converts DMS ( Degrees / minutes / seconds )
* to decimal format longitude / latitude
*/
function DMStoDEC($deg,$min,$sec) {
return $deg+((($min*60)+($sec))/3600);
}
/**
*
* fills array for scaling prices
*
*/
function SetColorScale($min,$low,$high,$max) {
$this->scale = array("max" => array ( "p" => $max,
"r" => 255,
"g" => 0,
"b" => 0
),
"high"=> array ( "p" => $high,
"r" => 255,
"g" => 0,
"b" => 255
),
"low"=> array ( "p" => $low,
"r" => 0,
"g" => 255,
"b" => 255
),
"min"=> array ( "p" => $min,
"r" => 0,
"g" => 255,
"b" => 0
)
);
} // end function
/**
*
* gets colors for a price
*
*/
function GetColor($p) {
if($p <= $this->scale["min"]["p"]) {
$this->pricer = $this->scale["min"]["r"];
$this->priceg = $this->scale["min"]["g"];
$this->priceb = $this->scale["min"]["b"];
} else
if ($p <= $this->scale["low"]["p"] ){
$f = ($p -$this->scale["min"]["p"])/
($this->scale["low"]["p"]-$this->scale["min"]["p"]);
$this->pricer = $this->scale["min"]["r"] +
($this->scale["low"]["r"]-$this->scale["min"]["r"]) * $f;
$this->priceg = $this->scale["min"]["g"] +
($this->scale["low"]["g"]-$this->scale["min"]["g"]) * $f;
$this->priceb = $this->scale["min"]["b"] +
($this->scale["low"]["b"]-$this->scale["min"]["b"]) * $f;
} else
if ($p <= $this->scale["high"]["p"] ){
$f = ($p -$this->scale["low"]["p"])/
($this->scale["high"]["p"]-$this->scale["low"]["p"]);
$this->pricer = $this->scale["low"]["r"] +
($this->scale["high"]["r"]-$this->scale["low"]["r"]) * $f;
$this->priceg = $this->scale["low"]["g"] +
($this->scale["high"]["g"]-$this->scale["low"]["g"]) * $f;
$this->priceb = $this->scale["low"]["b"] +
($this->scale["high"]["b"]-$this->scale["low"]["b"]) * $f;
} else
if ($p <= $this->scale["max"]["p"] ){
$f = ($p -$this->scale["high"]["p"])/
($this->scale["max"]["p"]-$this->scale["high"]["p"]);
$this->pricer = $this->scale["high"]["r"] +
($this->scale["max"]["r"]-$this->scale["high"]["r"]) * $f;
$this->priceg = $this->scale["high"]["g"] +
($this->scale["max"]["g"]-$this->scale["high"]["g"]) * $f;
$this->priceb = $this->scale["high"]["b"] +
($this->scale["max"]["b"]-$this->scale["high"]["b"]) * $f;
} else {
$this->pricer = $this->scale["max"]["r"];
$this->priceg = $this->scale["max"]["g"];
$this->priceb = $this->scale["max"]["b"];
}
} // end function
/**
* adds a gradient circle from a lat,lon,name, and price
* the lat/lon look like ->41+59+07,124+12+28
*/
function AddPriceCircle($lat,$lon,$name,$price,$hr) {
$maxfrac = .25;
$size = ($this->height+$this->width)/2;
$width = ($price/$this->scale["max"]["p"])*$maxfrac*$size;
$width = max(20,$width); // keep from being too small
$width = min($maxfrac*$size,$width); // keep from being too large
if(stripos($lat,'+')) { // deg, min, sec format
list($d,$m,$s) = explode("+",$lat);
$ycenter = round($this->DMStoDEC($d,$m,$s)*$this->lata +$this->latb);
list($d,$m,$s) = explode("+",$lon);
$xcenter = round($this->DMStoDEC($d,$m,$s)*$this->lona +$this->lonb);
} else { // decimal format
// echo "decimal<BR>";
$ycenter = round($lat*$this->lata +$this->latb);
$xcenter = round(abs($lon)*$this->lona +$this->lonb); // - lat in west 180, may need to tweak in east 180
}
// print "$xcenter, $ycenter<BR>";
$this->GetColor($price);
$this->SetCenterColor($this->pricer,$this->priceg,$this->priceb);
$this->AddGradientCircle($width, $xcenter, $ycenter);
// *** now the text labels
$t = "$name: \$$price/MWh HR: $hr";
$bbox= imageftbbox ( 8, 0, $this->font_file, $t);
$bwidth = abs($bbox[4] - $bbox[0]);
$bheight = abs($bbox[1] - $bbox[5]);
$txc=$xcenter-$bwidth/2;
$tyc=$ycenter; // seems better without correction -$bheight/2;
imagefttext($this->image, 8, 0, $txc, $tyc, $this->textcolor, $this->font_file,$t);
} // end function
} // end class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment