Source for file View.php
Documentation is available at View.php
* The window through which the map is viewed
* SMap requires at least PHP version 5, but there are important bug fixes in
* more recent versions of PHP. Try to stay current.
* Copyright (c) 2006-2007, Seth Price <{@link mailto:seth@pricepages.org}
* seth@pricepages.org}> All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* - Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* - 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.
* - The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @copyright Copyright (c) 2006-2007, Seth Price
* @author Seth Price <seth@pricepages.org>
* @license http://opensource.org/licenses/bsd-license.php New BSD License
* Multiple views can be controlled at the same time. A view is like a porthole
* through which you can see the map, but only part of it at a time. The view
* has controls associated with it to pan, zoom, etc.
* A view with id 0 is the main view. All others are negotiable.
* All of the layers in this view
* The map that contains this view
* A cached copy of all of the tiles
* The bounds of this view
* What is the scale in each direction?
* This is SMap Units per one pixel.
* Background color for this view
'group' => array(false, 'SMap_Layer_Group'),
'points' => array(false, 'SMap_Layer_Points'),
'polygon' => array(false, 'SMap_Layer_Polygon'),
'ogr' => array(false, 'SMap_Layer_OGR'),
'images' => array(false, 'SMap_Layer_Images'),
'grid' => array(false, 'SMap_Layer_Grid'),
'zoom' => array(false, 'SMap_Layer_Zoom'),
'pan' => array(false, 'SMap_Layer_Pan'));
* Give this view an identity
* @param object The controlling map
* @param integer This view's ID
* @param array View's background color
public function __construct(SMap $map, $viewId, $bkCol = null){
$this->id = (int) $viewId;
//Calculate/save the view's bounds
$tv = $map->form->getTileVars();
$this->zoom = $map->zoom;
$this->scale = $map->scale;
* Access useful vars read-only
* @param string Name of member
* @return mixed Value of member
public function __get($nm){
throw new SMap_Ex('Attempted to read non-existant member '. $nm);
* Adjust the view coords if we are in an image
* Uses the current bounds and the tile grid to calculate the view bounds of
* the original image. Sometimes it's missing data, so it does the best it
* @param object The map we are in
* @param array The tile grid
* @return array The overall view bounds
$diffX = $B[SMap::MAXX] - $B[SMap::MINX];
$diffY = $B[SMap::MAXY] - $B[SMap::MINY];
$B[SMap::MAXX] = $B[SMap::MAXX] + $diffX *
$B[SMap::MINY] = $B[SMap::MINY] - $diffY *
* If there are no layers, then this layer becomes the bottom most layer.
* If there is a layer, then this layer is composited on top of it.
* @param mixed SMap_Layer subclass or layer to create
* @param integer Normally a Layer ID
* @param mixed Additional arguments passed to layer constructor
* @return object The added layer
public function addLayer( $layer, $arg1 = null, $arg2 = null,
$arg3 = null, $arg4 = null, $arg5 = null,
$arg6 = null, $arg7 = null, $arg8 = null){
//Check if we've already been rendered
throw new SMap_Ex('You can\'t add a layer after the tiles have been ' .
//Do we need to create the layer?
$layer = $this->createLayer($layer, $this->map, $arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8);
//Was the layer passed to us?
throw new SMap_Ex('Passed $layer not an instance of SMap_Layer.');
//Make sure it dosen't exist
if(!empty($this->layers[$lid])){
throw new SMap_Ex( 'SMap_Layer of ID '. $lid. ' already exists',
//Only add enabled layers
* Serves as a view factory. The first argument is the name of a view that
* is registered with, and the rest of the arguments are passed to the view.
* @param string View name
* @param integer Normally the Layer ID
* @param mixed Additional arguments...
* @return object The created view
public static function createLayer( $layer, $arg1, $arg2 = null, $arg3 = null,
$arg4 = null, $arg5 = null, $arg6 = null,
$arg7 = null, $arg8 = null, $arg9 = null){
if(empty(self::$regLayers[$layer])){
throw new Exception('The given layer type "'. $layer. '" is not built in. ' .
'If you have created a custom layer, please simply ' .
'pass the object to addLayer().');
$meta = self::$regLayers[$layer];
if($meta[0] && !class_exists($meta[1])){
$lr = new $meta[1]($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9);
throw new SMap_Ex('Layer not a subclass of SMap_Layer.');
* Send an object to another tile
* Used to create an object in another tile dynamically. This is intended to
* only be used by methods in {@link SMap_Object} during rendering. The
* normal method of adding an object to a tile is to include it in the
* return value of {@link SMap_Layer::getMapObjs()} or {@link }
* SMap_Layer::getImgObjs()}.
* @param object New object
* @param integer X location of tile in tile grid
* @param integer Y location of tile in tile grid
public function sendObj(SMap_Object $newObj, $newX, $newY){
if(!isset ($this->tiles[$newY][$newX])){
$this->tiles[$newY][$newX]->addObject($newObj);
* Return the name of this view
* The name is defined by {@link SMap_Lang}, so this method simply uses that
* @return string View name
$defs = $this->map->lang->genViewDefs();
if(isset ($defs[$this->id])){
* Creates and returns the set of tiles that represent this view
* This constructs a set of tiles that fully represent this view.
* {@link SMap_Object Objects} have been added to each tile, and they have
* been {@link SMap_Tile::flatten() flattened} and {@link }
* SMap_Tile::constrain() constrained}.
* @return array The tiles in this view
//Cache a copy of the cached tiles
//Are we constructed correctly?
throw new SMap_Ex('View not added to a map. ID: '. $this->id);
//PreCalc the offset of each cell
$lrDiff = $widthPx * $this->scale[0];
$tbDiff = $heightPx * $this->scale[1];
//Save these vars locally for speed
$tilesX = $this->map->tilesX;
$tilesY = $this->map->tilesY;
//Count starting at the bottom
for($y = 0; $y < $tilesY; $y++ ){
$bottom = $top - $tbDiff;
//Count starting on the left
for($x = 0; $x < $tilesX; $x++ ){
$right = $left + $lrDiff;
//Create new tile with correct bounds and grid position
$bounds = array( SMap::MAXY => $top,
foreach($this->layers as $layer){
//Set the member so sendObj() can work
//Constrain the object bounds
foreach($this->layers as $lid => $layer){
for($y = 0; $y < $tilesY; $y++ ){
for($x = 0; $x < $tilesX; $x++ ){
$tiles[$y][$x]->constrain($lid);
* Handle getting the XHTML
* @param array The array of tiles
* @return string XHTML of the map
abstract public function getXHTML($tiles);
* A view composed of images
* This is intended to be called from an image script.
* @param object SMap_Tile
foreach($this->layers as $layer){
foreach($this->layers as $lid => $layer){
* Renders and returns the view XHTML
* @param array Tiles to render
* @return string Rendered XHTML
* @uses SMap_Form::getMapXHTML()
return $this->map->form->getMapXHTML($this, $tiles);
* A view intended to be inset in a layer
* The purpose of this view is to appear as an object inside of a layer (which
* is inside another view).
* Tile to draw the view onto
* If the tile is null, then no drawing is done, and no inset is created.
* This is probably because we can't zoom out far enough to create a useful
* Construct & adjust the view bounds
* @param object Tile to draw the inset onto
public function __construct(SMap $map, $viewId, SMap_Tile $tile){
$xSpan = ($vB[SMap::MAXX] - $vB[SMap::MINX])* 3;
$ySpan = ($vB[SMap::MAXY] - $vB[SMap::MINY])* 3;
//Adjust the zoom & scale
for($zoom = $this->zoom - 2; $zoom >= 0; -- $zoom){
$scale = $map->geo->zoomFctr($this->zoom);
|