phpDocumentor SMap
Objects
[ class tree: SMap ] [ index: SMap ] [ all elements ]

Source for file Object.php

Documentation is available at Object.php

  1. <?php
  2. /**
  3.  * Object primitives used to draw the view
  4.  * 
  5.  * SMap requires at least PHP version 5, but there are important bug fixes in
  6.  * more recent versions of PHP. Try to stay current.
  7.  *
  8.  * <b>License</b>:
  9.  * 
  10.  * Copyright (c) 2006-2007, Seth Price <{@link mailto:seth@pricepages.org}
  11.  * seth@pricepages.org}> All rights reserved.
  12.  *
  13.  * Redistribution and use in source and binary forms, with or without
  14.  * modification, are permitted provided that the following conditions
  15.  * are met:
  16.  *
  17.  * - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  18.  * - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  19.  * - The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  22.  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  23.  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  24.  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
  25.  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  26.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  27.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  28.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  29.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  30.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32.  *
  33.  * @access public
  34.  * @author Seth Price <seth@pricepages.org>
  35.  * @copyright Seth Price, 2006-2007
  36.  * @see SMap_Object
  37.  * @package        SMap
  38.  */
  39.  
  40. /**
  41.  * An Object that can appear in a layer
  42.  * 
  43.  * The Object is the basic unit of drawing. {@link SMap_Layer Layers} generate
  44.  * these Objects and pass them back to the {@link SMap_Tile tile} when
  45.  * {@link SMap_Layer::getMapObjs()} or {@link SMap_Layer::getImgObjs()} is
  46.  * called. At this point each tile has an ordered array of Objects.
  47.  * 
  48.  * The Objects are then organized by calling {@link SMap_Object::applyTile()} to
  49.  * pass a {@link SMap_Tile} to each Object. The intent is for each Object crop
  50.  * each and define the bounds which will be clipping the object. At this point,
  51.  * the Object has the option of returning false, and it will not be drawn.
  52.  * 
  53.  * At this point, each Object should have all of the information required to be
  54.  * drawn. So {@link SMap_Object::draw()} is called on each Object, and a
  55.  * {@link SMap_Canvas canvas} is passed. The Canvas should be fairly efficent at
  56.  * rasterizing only when needed.
  57.  * 
  58.  * Keep in mind that some of these steps are skipped when using cached images.
  59.  * For more information on the caching process, see
  60.  * {@link SMap_Tile::flatten()}.
  61.  * 
  62.  * In order to work correctly, {@link SMap_Object_Area_Label} has some hooks in
  63.  * interesting places also. Only developers should need to worry about that,
  64.  * though.
  65.  * 
  66.  * @package        SMap
  67.  * @subpackage    Objects
  68.  */
  69. abstract class SMap_Object {
  70.     
  71.     /**
  72.      * The layer that this object resides in
  73.      * 
  74.      * @var        object 
  75.      */
  76.     protected $layer;
  77.     
  78.     /**
  79.      * The view that this object resides in
  80.      * 
  81.      * @var        object 
  82.      */
  83.     protected $view;
  84.     
  85.     /**
  86.      * The map that this object resides in
  87.      * 
  88.      * @var        object 
  89.      */
  90.     protected $map;
  91.     
  92.     /**
  93.      * Does this object link to anything?
  94.      * 
  95.      * @var        string 
  96.      */
  97.     protected $url = '';
  98.     protected $alt = '';
  99.     
  100.     /**
  101.      * Are we labeling this object?
  102.      * 
  103.      * @var        string 
  104.      */
  105.     protected $label = null;
  106.     
  107.     /**
  108.      * The tile that has been applied to this object
  109.      * 
  110.      * @var        object 
  111.      */
  112.     protected $tile;
  113.     
  114.     /**
  115.      * The color
  116.      * 
  117.      * @var        array 
  118.      * @see        setColor()
  119.      */
  120.     protected $color;
  121.     
  122.     /**
  123.      * Give the object a context
  124.      * 
  125.      * @param    object    The view that contains this object
  126.      * @param    object    The layer that produced this object
  127.      */
  128.     public function __construct(SMap_View $viewSMap_Layer $layer){
  129.         $this->map = $layer->getMap();
  130.         $this->view = $view;
  131.         $this->layer = $layer;
  132.     }
  133.     
  134.     /**
  135.      * Set the color for this object
  136.      * 
  137.      * This is a generic color setting method, and means different things to
  138.      * different subclasses. If the first parameter is false, then the color is
  139.      * default.
  140.      * 
  141.      * @param    mixed    Red channel or false (for no color)
  142.      * @param    integer    Green channel
  143.      * @param    integer    Blue channel
  144.      * @param    integer    Alpha channel (127 == clear)
  145.      */
  146.     function setColor($r$g 0$b 0$a null){
  147.         if($r === false){
  148.             $this->color = false;
  149.         else {
  150.             $this->color = array($r$g$b$a);
  151.         }
  152.     }
  153.     
  154.     /**
  155.      * Set this to link to something
  156.      * 
  157.      * @param    string    The URL
  158.      * @param    string    The URL's description
  159.      */
  160.     public function setLink($url$alt){
  161.         $this->url = $url;
  162.         $this->alt = $alt;
  163.     }
  164.     
  165.     /**
  166.      * Get the rough inner rectangular bounds for this object.
  167.      * 
  168.      * @return    array    A bounding the array
  169.      */
  170.     abstract function getInnerBounds();
  171.  
  172.     /**
  173.      * Are we drawing a label for this object?
  174.      * 
  175.      * @param    object    Apply a label to this object
  176.      */
  177.     abstract function label(SMap_Object_Area_Label $label);
  178.  
  179.     /**
  180.      * Apply a tile to this object
  181.      * 
  182.      * Do whatever precalculation is needed to display this object in a given
  183.      * tile. Return if this object is visible.
  184.      * 
  185.      * @param    object    The tile
  186.      * @return    boolean    Is visible?
  187.      */
  188.     abstract function applyTile(SMap_Tile $tile);
  189.     
  190.     /**
  191.      * Draw this object on a canvas
  192.      * 
  193.      * @param    object 
  194.      */
  195.     abstract function draw(SMap_Canvas $canvas);
  196.     
  197.     /**
  198.      * Return a map of this object
  199.      * 
  200.      * If we are returning a client side image map, returned set of arrays
  201.      * represent the "area" of the image map. They have indexes at ['alt'],
  202.      * ['coords'], ['shape'], and ['href'].
  203.      * 
  204.      * @return    mixed    An array of arrays of coords, or false.
  205.      * @see        SMap_Tile::getImageMap()
  206.      * @see        SMap_Layer::getTileMap()
  207.      */
  208.     abstract function map();
  209. }
  210.  
  211. /**
  212.  * A point on a map
  213.  * 
  214.  * Displays a pixel
  215.  * 
  216.  * @package        SMap
  217.  * @subpackage    Objects
  218.  */
  219. class SMap_Object_Point extends SMap_Object {
  220.     /**
  221.      * Location of the point
  222.      * 
  223.      * In SMap Units.
  224.      * 
  225.      * @var        float 
  226.      */
  227.     protected $x = null;
  228.     protected $y = null;
  229.     
  230.     /**
  231.      * Color of point
  232.      * 
  233.      * Defaults to red
  234.      * 
  235.      * @var        array 
  236.      */
  237.     protected $color = array(255,0,0);
  238.     
  239.     /**
  240.      * Set the location of the point
  241.      * 
  242.      * @param    object    The view that this object is attached to
  243.      */
  244.     function __construct(SMap_View $viewSMap_Layer $layer$x$y){
  245.         parent::__construct($view$layer);
  246.         $this->x = $x;
  247.         $this->y = $y;
  248.     }
  249.  
  250.     /**
  251.      * Return the bounds of the point
  252.      * 
  253.      * Expands the point by a pixel in each direction
  254.      * 
  255.      * @return    array    Bounding array
  256.      */
  257.     public function getInnerBounds(){
  258.         $scale $this->view->scale;
  259.         //Expand by a bit so we don't overlap
  260.         return array(    SMap::MAXX => $this->x + $scale[0],
  261.                         SMap::MAXY => $this->y + $scale[1],
  262.                         SMap::MINX => $this->x - $scale[0],
  263.                         SMap::MINY => $this->y - $scale[1);
  264.     }
  265.     
  266.     /**
  267.      * 
  268.      */
  269.     public function label(SMap_Object_Area_Label $label){
  270.         //FIXME
  271.         trigger_error('FIXME'E_USER_ERROR);
  272.     }
  273.     
  274.     /**
  275.      * Apply a tile to this point
  276.      * 
  277.      * @param    object 
  278.      * @return    boolean 
  279.      */
  280.     public function applyTile(SMap_Tile $tile){
  281.         $this->tile = $tile;
  282.         $B $tile->bounds;
  283.         
  284.         return    ($B[SMap::MAXY>= $this->y &&
  285.                  $B[SMap::MAXX>  $this->x &&
  286.                  $B[SMap::MINY<  $this->y &&
  287.                  $B[SMap::MINX<= $this->x );
  288.     }
  289.     
  290.     /**
  291.      * Set a pixel on the canvas
  292.      * 
  293.      * Alone, it won't be noticable, but if you draw many, you might have
  294.      * something.
  295.      * 
  296.      * @param    object 
  297.      */
  298.     public function draw(SMap_Canvas $canvas){
  299.         $B $this->tile->bounds;
  300.         
  301.         $ix round(($this->x - $B[SMap::MINX])/$this->view->scale[0]);
  302.         $iy round(($B[SMap::MAXY$this->y)/$this->view->scale[1]);
  303.         
  304.         $col $canvas->allocColor($this->color);
  305.         $canvas->setPixel($ix$iy$col);
  306.     }
  307.     
  308.     /**
  309.      * A pixel gives nothing to work with
  310.      * 
  311.      * So, an empty array is returned.
  312.      * 
  313.      * @return    array    Nothing
  314.      */
  315.     public function map(){
  316.         return array();
  317.     }
  318. }
  319.  
  320. /**
  321.  * A line between two points
  322.  * 
  323.  * The line can include a grid line, part of a path, or a boundary line.
  324.  * 
  325.  * @package        SMap
  326.  * @subpackage    Objects
  327.  */
  328. class SMap_Object_Line extends SMap_Object {
  329.     /**
  330.      * Beginning and end of the line
  331.      * 
  332.      * @var        array 
  333.      */
  334.     protected $points = array();
  335.     
  336.     /**
  337.      * Lock this when we start retrieving data from it
  338.      * 
  339.      * @var        boolean 
  340.      */
  341.     protected $locked = false;
  342.     
  343.     /**
  344.      * 
  345.      */
  346.     protected $color = array(0,0,0,null);
  347.     protected $label = null;
  348.     
  349.     /**
  350.      * Construct with the beginning and end of the line
  351.      */
  352.     function __construct(    SMap_View $viewSMap_Layer $layer,
  353.                             $begX$begY$endX$endY){
  354.         
  355.         parent::__construct($view$layer);
  356.         
  357.         $this->points = array($begX$begY$endX$endY);
  358.     }
  359.     
  360.     /**
  361.      * Extends this line
  362.      * 
  363.      * @param    float    Next X coord
  364.      * @param    float    Next Y coord
  365.      */
  366.     public function extend($x$y){
  367.         $this->points[$x;
  368.         $this->points[$y;
  369.     }
  370.     
  371.     /**
  372.      * 
  373.      * 
  374.      * @return    array    A reasonable inner bounds
  375.      */
  376.     public function getInnerBounds(){
  377.         $locked true;
  378.         
  379.         $B array(    SMap::MAXY        => $this->points[1],
  380.                     SMap::MAXX    => $this->points[0],
  381.                     SMap::MINY    => $this->points[1],
  382.                     SMap::MINX        => $this->points[0);
  383.         
  384.         for($i 2isset($this->points[$i+1])$i += 2){
  385.             $B[SMap::MAXYmax($B[SMap::MAXY]$this->points[$i+1]);
  386.             $B[SMap::MAXXmax($B[SMap::MAXX]$this->points[$i]);
  387.             $B[SMap::MINYmin($B[SMap::MINY]$this->points[$i+1]);
  388.             $B[SMap::MINXmin($B[SMap::MINX]$this->points[$i]);
  389.         }
  390.         
  391.         return $B;
  392.     }
  393.     
  394.     /**
  395.      * Place the label on the line
  396.      */
  397.     public function label(SMap_Object_Area_Label $label){
  398.         $this->label = $label;
  399.     }
  400.     
  401.     /**
  402.      * 
  403.      */
  404.     public function applyTile(SMap_Tile $tile){
  405.         //FIXME doesn't test visibilty
  406.         $this->tile = $tile;
  407.         return true;
  408.     }
  409.     
  410.     /**
  411.      * 
  412.      */
  413.     public function draw(SMap_Canvas $canvas){
  414.         //This function has been optimized. Blech.
  415.         $debug SMap::getOption('debug');
  416.         $B $this->tile->bounds;
  417.         $Bminx $B[SMap::MINX];
  418.         $Bmaxy $B[SMap::MAXY];
  419.         
  420.         $invScaleX 1/$this->view->scale[0];
  421.         $invScaleY 1/$this->view->scale[1];
  422.         $pts =$this->points;
  423.         
  424.         $col $canvas->allocColor($this->color);
  425.         
  426.         //Find pt location, +0.5 because we are fake-rounding
  427.         $endX ($pts[0$Bminx)*$invScaleX+0.5;
  428.         $endY ($Bmaxy $pts[1])*$invScaleY+0.5;
  429.         
  430.         $i 1;
  431.         while(isset($pts[++$i])){
  432.             $begX $endX;
  433.             $begY $endY;
  434.             
  435.             $endX ($pts[  $i$Bminx)*$invScaleX+0.5;
  436.             $endY ($Bmaxy $pts[++$i])*$invScaleY+0.5;
  437.     
  438.             if($debug){
  439.                 echo
  440.                     'Drawing '.get_class().
  441.                     "<blockquote>\n".
  442.                     "\tColor: ".$this->color[0].' '.$this->color[1].' '.$this->color[2]."<br />\n".
  443.                     "\tEndpoints: (".$begX.", ".$begY.") (".$endX.", ".$endY.")<br />\n".
  444.                     "\tBounds: ";
  445.                 var_dump($B);
  446.                 echo "\t</blockquote>\n";
  447.                 
  448.                 continue;
  449.             }
  450.             
  451.             $canvas->line($begX,$begY$endX,$endY$col);
  452.         }
  453.     }
  454.     
  455.     /**
  456.      * 
  457.      */
  458.     public function map(){
  459.         return array();
  460.     }
  461. }
  462.  
  463. /**
  464.  * A path that connects a series of points
  465.  * 
  466.  * It would be nice to label this with distance markers.
  467.  * 
  468.  * @package        SMap
  469.  * @subpackage    Objects
  470.  */
  471.     private $leftArea null;
  472.     private $rightAreanull;
  473.     
  474.     /**
  475.      * 
  476.      */
  477.     public function applyTile(SMap_Tile $tile){
  478.         //FIXME
  479.         trigger_error('FIXME'E_USER_ERROR);
  480.     }
  481.     
  482.     /**
  483.      * 
  484.      */
  485.     public function draw(SMap_Canvas $canvas){
  486.         //FIXME
  487.         trigger_error('FIXME'E_USER_ERROR);
  488.     }
  489. }
  490.  
  491. /**
  492.  * A boundary line
  493.  * 
  494.  * @package        SMap
  495.  * @subpackage    Objects
  496.  */
  497.     
  498.     /**
  499.      * A boundary seperates two areas
  500.      */
  501.     private $leftArea null;
  502.     private $rightAreanull;
  503.     
  504.     /**
  505.      * Sets the left and right areas that this boundary seperates
  506.      */
  507.     function setLeft($area){}
  508.     function setRight($area){}
  509.     
  510.     /**
  511.      * Returns the area that is not the passed area
  512.      */
  513.     function getOther($area){}
  514.     
  515.     /**
  516.      * 
  517.      */
  518.     public function label(SMap_Object_Area_Label $label){
  519.         //FIXME
  520.         trigger_error('FIXME'E_USER_ERROR);
  521.     }
  522.     
  523.     /**
  524.      * 
  525.      */
  526.     public function applyTile(SMap_Tile $tile){
  527.         //FIXME
  528.         trigger_error('FIXME'E_USER_ERROR);
  529.     }
  530.     
  531.     /**
  532.      * 
  533.      */
  534.     public function draw(SMap_Canvas $canvas){
  535.         //FIXME
  536.         trigger_error('FIXME'E_USER_ERROR);
  537.     }
  538. }
  539.  
  540. /**
  541.  * An area on the map encompassing one or more pixels
  542.  * 
  543.  * An area is interesting because at this point it is linkable/clickable.
  544.  * 
  545.  * @package        SMap
  546.  * @subpackage    Objects
  547.  */
  548. abstract class SMap_Object_Area extends SMap_Object {
  549.     /**
  550.      * Save the colors for this area
  551.      */
  552.     protected $borderColor = null;
  553.     
  554.     /**
  555.      * Set the border color for this image
  556.      * 
  557.      * If the first parameter is false, then there is no border. (default)
  558.      * 
  559.      * @param    mixed    Red channel or false (for no color)
  560.      * @param    integer    Green channel
  561.      * @param    integer    Blue channel
  562.      * @param    integer    Alpha channel
  563.      */
  564.     function setBrdrColor($r$g 0$b 0$a null){
  565.         if($r === false){
  566.             $this->borderColor = null;
  567.         else {
  568.             $this->borderColor = array($r$g$b$a);
  569.         }
  570.     }
  571. }
  572.  
  573. /**
  574.  * Sets the default click for the tile
  575.  * 
  576.  * @package        SMap
  577.  * @subpackage    Objects
  578.  */
  579.     
  580.     /**
  581.      * Default URL
  582.      * 
  583.      * @var        string 
  584.      */
  585.     protected $url = '';
  586.     
  587.     /**
  588.      * Default label
  589.      * </