![]() ![]() |
weathermap |
Subversion Repositories: |
Compare with Previous - Blame - Download
<?php// Copyright Howard Jones, 2005 howie@thingy.com// http://wotsit.thingy.com/haj/cacti/// Released under the GNU Public License// A simple port of the guts of Apache's mod_imap// - if you have an image control in a form, it's not really defined what happens to USEMAP// attributes. They are allowed in HTML 4.0 and XHTML, but some testing shows that they're// basically ignored. So you need to use server-side imagemaps if you want to have a form// where you are choosing a verb from (for example) a <SELECT> and also specifying part of// an image with an IMAGE control.////class HTML_ImageMap_Area{var $href;var $name;var $id;var $alt;var $extrahtml;function common_html(){$h = "";if($this->name != ""){$h .= " alt=\"".$this->name."\" ";$h .= " id=\"".$this->name."\" ";}if($this->href != ""){$h .= " href=\"".$this->href."\" ";}if($this->extrahtml != ""){$h .= " ".$this->extrahtml." ";}return $h;}}class HTML_ImageMap_Area_Polygon extends HTML_ImageMap_Area{var $points = array();var $minx,$maxx,$miny,$maxy; // bounding boxvar $npoints;function asHTML(){foreach ($this->points as $point){$flatpoints[] = $point[0];$flatpoints[] = $point[1];}$coordstring = join(",",$flatpoints);return '<area'.$this->common_html().' shape="poly" coords="'.$coordstring.'" />';}function asJSON(){$json = "{ shape:'poly', npoints:".$this->npoints.", name:'".$this->name."',";$xlist = '';$ylist = '';foreach ($this->points as $point){$xlist .= $point[0].",";$ylist .= $point[1].",";}$xlist = rtrim($xlist,", ");$ylist = rtrim($ylist,", ");$json .= " x: [ $xlist ], y:[ $ylist ], minx: ".$this->minx.", miny: ".$this->miny.", maxx:".$this->maxx.", maxy:".$this->maxy."}";return($json);}function hitTest($x,$y){$c = 0;// do the easy bounding-box test first.if( ($x < $this->minx) || ($x>$this->maxx) || ($y<$this->miny) || ($y>$this->maxy)){return false;}// Algotithm from from// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html#The%20C%20Codefor ($i = 0, $j = $this->npoints-1; $i < $this->npoints; $j = $i++){// print "Checking: $i, $j\n";$x1 = $this->points[$i][0];$y1 = $this->points[$i][1];$x2 = $this->points[$j][0];$y2 = $this->points[$j][1];// print "($x,$y) vs ($x1,$y1)-($x2,$y2)\n";if (((($y1<=$y) && ($y<$y2)) || (($y2<=$y) && ($y<$y1))) &&($x < ($x2 - $x1) * ($y - $y1) / ($y2 - $y1) + $x1)){$c = !$c;}}return ($c);}function HTML_ImageMap_Area_Polygon ( $name="", $href="",$coords){$c = $coords[0];$this->name = $name;$this->href= $href;$this->npoints = count($c)/2;if( intval($this->npoints) != ($this->npoints)){die("Odd number of points!");}for ($i=0; $i<count($c); $i+=2){$x = intval($c[$i]);$y = intval($c[$i+1]);$point = array($x,$y);$xlist[] = $x; // these two are used to get the bounding box in a moment$ylist[] = $y;$this->points[] = $point;}$this->minx = min($xlist);$this->maxx = max($xlist);$this->miny = min($ylist);$this->maxy = max($ylist);// print $this->asHTML()."\n";}}class HTML_ImageMap_Area_Rectangle extends HTML_ImageMap_Area{var $x1,$x2,$y1,$y2;function HTML_ImageMap_Area_Rectangle ( $name="", $href="",$coords){$c = $coords[0];$x1 = $c[0];$y1 = $c[1];$x2 = $c[2];$y2 = $c[3];// sort the points, so that the first is the top-leftif($x1>$x2){$this->x1=$x2;$this->x2=$x1;}else{$this->x1=$x1;$this->x2=$x2;}if($y1>$y2){$this->y1=$y2;$this->y2=$y1;}else{$this->y1=$y1;$this->y2=$y2;}$this->name = $name;$this->href = $href;}function hitTest($x,$y){return ( ($x > $this->x1) && ($x < $this->x2) && ($y > $this->y1) && ($y < $this->y2) );}function asHTML(){$coordstring = join(",",array($this->x1,$this->y1,$this->x2,$this->y2));return '<area'.$this->common_html().' shape="rect" coords="'.$coordstring.'" />';}function asJSON(){$json = "{ shape:'rect', ";$json .= " x1:".$this->x1.", y1:".$this->y1.", x2:".$this->x2.", y2:".$this->y2.",name:'".$this->name."'}";return($json);}}class HTML_ImageMap_Area_Circle extends HTML_ImageMap_Area{var $centx,$centy, $edgex, $edgey;function asHTML(){$coordstring = join(",",array($this->centx,$this->centy,$this->edgex,$this->edgey) );return '<area'.$this->common_html().' shape="circle" coords="'.$coordstring.'" />';}function hitTest($x,$y){$radius1 = ($this->edgey - $this->centy) * ($this->edgey - $this->centy)+ ($this->edgex - $this->centx) * ($this->edgex - $this->centx);$radius2 = ($this->edgey - $y) * ($this->edgey - $y)+ ($this->edgex - $x) * ($this->edgex - $x);return ($radius2 <= $radius1);}function HTML_ImageMap_Area_Circle($name="", $href="",$coords){$c = $coords[0];$this->name = $name;$this->href = $href;$this->centx = $c[0];$this->centy = $c[1];$this->edgex = $c[2];$this->edgey = $c[3];}}class HTML_ImageMap{var $shapes;var $nshapes;var $name;function HTML_ImageMap($name=""){$this->Reset();$this->name = $name;}function Reset(){$this->shapes = array();$this->nshapes = 0;$this->name = "";}// add an element to the map - takes an array with the info, in a similar way to HTML_QuickFormfunction addArea($element){if (is_object($element) && is_subclass_of($element, 'html_imagemap_area')) {$elementObject = &$element;} else {$args = func_get_args();$className = "HTML_ImageMap_Area_".$element;$elementObject =& new $className($args[1],$args[2],array_slice($args, 3));}$this->shapes[] =& $elementObject;$this->nshapes++;// print $this->nshapes." shapes\n";}// do a hit-test based on the current map// - can be limited to only match elements whose names match the filter// (e.g. pick a building, in a campus map)function hitTest($x,$y,$namefilter=""){$preg = '/'.$namefilter.'/';foreach ($this->shapes as $shape){if($shape->hitTest($x,$y)){if( ($namefilter == "") || ( preg_match($preg,$shape->name) ) ){return $shape->name;}}}return false;}// update a property on all elements in the map that match a name// (use it for retro-actively adding in link information to a pre-built geometry before generating HTML)// returns the number of elements that were matched/changedfunction setProp($which, $what, $where){$count = 0;for($i=0; $i<count($this->shapes); $i++){// this USED to be a substring match, but that broke some things// and wasn't actually used as one anywhere.if( ($where == "") || ( $this->shapes[$i]->name==$where) ){switch($which){case 'href':$this->shapes[$i]->href= $what;break;case 'extrahtml':$this->shapes[$i]->extrahtml= $what;break;}$count++;}}return $count;}// Return the imagemap as an HTML client-side imagemap for inclusion in a pagefunction asHTML(){$html = '<map';if($this->name != ""){$html .= ' name="'.$this->name.'"';}$html .=">\n";foreach ($this->shapes as $shape){$html .= $shape->asHTML();$html .= "\n";}$html .= "</map>\n";return $html;}function subJSON($namefilter="",$reverseorder=false){$json = '';$preg = '/'.$namefilter.'/';foreach ($this->shapes as $shape){if( ($namefilter == "") || ( preg_match($preg,$shape->name) )){if($reverseorder){$json = $shape->asJSON().",\n".$json;}else{$json .= $shape->asJSON().",\n";}}}$json = rtrim($json,"\n, ");$json .= "\n";return $json;}// return HTML for a subset of the map, specified by the filter string// (suppose you want some partof your UI to have precedence over another part// - the imagemap is checked from top-to-bottom in the HTML)function subHTML($namefilter="",$reverseorder=false){$html = "";$preg = '/'.$namefilter.'/';foreach ($this->shapes as $shape){if( ($namefilter == "") || ( preg_match($preg,$shape->name) )){if($reverseorder){$html = $shape->asHTML()."\n".$html;}else{$html .= $shape->asHTML()."\n";}}}return $html;}}// vim:ts=4:sw=4:?>