Source for file Form.php
Documentation is available at Form.php
* The form is the user interface, it handles the settings that the map uses to
* draw itself. User interface code is always a pain, so I've tried to add
* useful bits as protected functions.
* 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
* This is partially user interface, but mostly a form controller
* It controls all interaction between the user. Nothing here should throw
* exceptions unless passed an incorrect object. We can't trust the user, so
* incomplete vars are just set to default.
* Set so the mapping vars don't collide with anything else. Altering this
* will theoretically allow people to place more than one map on a page
* without them interfering with eachother.
* Note that there are static variables in the layout engine that may
* collide, so exercise caution.
* Options for the screen size selection
* Here are some suggestions for common opt groups, option labels, and
* option values. Values are automatically parsed via regex in
'800x600 (small)' => '800x600',
'1024x768 (medium)' => '1024x768',
'1280x1024 (large)' => '1280x1024',
'1600x1200 (x-large)' => '1600x1200' ),
'1024x640 (small)' => '1024x640',
'1280x800 (medium)' => '1280x800',
'1600x1000 (large)' => '1600x1000',
'1920x1200 (x-large)' => '1920x1200' ),
'US Letter' => '1075x1395p',
'US Legal' => '1075x1775p',
* Store the language package
* Use a SForm to handle all user transactions
* http://www.phpclasses.org/browse/package/3465.html
* All values set here are permanently set. For example, if you want a view
* to always be shown, set its ID in here. Same thing for layer(s).
protected $perm = array('views'=> array(),'layers'=> array());
* Currently set variables
* Once the form variables are deciphered, they are set here. After
* {@link __construct() object construction}, the final value of the form's
* values should be stored here. When in doubt, use these values.
protected $curr = array();
* The incoming request variables
* Use whatever method you wish to place the appropriate request in this
* Any user preferences should be stored here.
* Variables in this array will take priority over the
* {@link $defs defaults}, but will be slave to the {@link $request}
* When a visitor first visits the page, the settings should be these.
protected $defs = array();
* Is the environment a tile image?
* Set when we will be drawing the image for a single tile. The process is
* normally that a script pretends to be
* The construction of the SMap_Form should handle all of the input, and
* from here on out the values in {@link $curr} should be constant.
* @param object Language used
* @param object Geographic def
* @param boolean Are we drawing a single tile?
* @uses SMap_Util::normalizeBounds()
* @uses SMap_Util::wrapBounds()
function __construct(SMap_Lang $lang, SMap_Geo $geo, $isTile){
//Handle the user form if needed
if($this->sform->wasSubmitted()){
if( !isset ($this->curr['lang']) ||
!isset ($this->curr['bounds']) ||
!isset ($this->curr['viewId']) ||
!isset ($this->curr['zoom'])){
throw new SMap_Ex('Missing a required form setting! Check the defaults.');
//Set the language that we will be using
$lang->setLanguage($map['lang']);
//Adjust bounds to make sure we are good
$scale = $geo->zoomFctr($map['zoom']);
$B = & $this->curr['bounds'];
list ($tilesX, $tilesY) = $this->getViewDim($B, $scale);
$muPerTileX, $muPerTileY,
* SForm is another of my packages. I've kept it loosly coupled with SMap.
* If you wish to use some other method than SForm, you'll have to override
* this method, and possible any other method which uses the SForm. It is,
* @return object SForm with appropriate elements
$f->addElement(new SForm_Elm_Hidden('lrs')); // Layers
$f->addElement(new SForm_Elm_Hidden('l')); // Language
$f->addElement(new SForm_Elm_Hidden('v')); // Views
$f->addElement(new SForm_Elm_Hidden('vId')); // View ID
$f->addElement(new SForm_Elm_Hidden('z')); // Zoom
$f->addElement(new SForm_Elm_Hidden('bds')); // Bounds
$f->addElement(new SForm_Elm_Hidden('grd')); // Tile Grid
//Assume that defaults are hardcoded
//Do nothing; override if needed
* Init the prefernce array
* Handle things here like reading a users preferences from a database,
//Do nothing; override if needed
* Uses the SForm to construct an appropriate request array from the user's
* input. If you want to use something other than the SForm, you can always
* take care of that urge here. Just construct the {@link $request} array
* correctly and you're good to go.
$val = $this->sform->getElement('lrs')->getValue();
foreach(explode(',', $val) as $layer){
$newLrs[] = (int) $layer;
$this->request['layers'] = $newLrs;
$val = $this->sform->getElement('v')->getValue();
foreach(explode(',', $val) as $view){
$newViews[] = (int) $view;
$this->request['views'] = $newViews;
$val = $this->sform->getElement('z')->getValue();
$this->request['zoom'] = (int) $val;
$val = $this->sform->getElement('vId')->getValue();
$this->request['viewId'] = (int) $val;
$val = $this->sform->getElement('l')->getValue();
$val = $this->sform->getElement('bds')->getValue();
$val = $this->sform->getElement('grd')->getValue();
* Handles a submitted user form
* Sets up the correct structure of the SForm with the correct defaults,
if(!isset ($this->curr['bounds']) || !isset ($this->curr['zoom'])){
$B = & $this->curr['bounds'];
$z = $this->curr['zoom'];
//Initialize hidden values
$sf->getElement('bds')->setDefault(
$sf->getElement('z')->setDefault($z);
$sf->getElement('lrs')->setDefault(implode(',', $this->curr['layers']));
$sf->getElement('l')->setDefault($this->curr['lang']);
$sf->getElement('v')->setDefault(implode(',', $this->curr['views']));
//These aren't useful in the user submitted form
$sf->removeElement('vId');
$sf->removeElement('grd');
//Add the screen size element
//Handle the new screen size
$ssize = $ssizeElm->getValue();
//Was it a valid request?
if(empty($scrPxDim[$ssize])){
trigger_error('The screen size was not valid: '. $ssize, E_USER_NOTICE);
$scale = $this->geo->zoomFctr($z);
* Keep the map centered at the current location, but change the number
* of tiles by the amount specified in $scrPxDim.
floor($scrPxDim[$ssize][0]/ $widthPx),
floor($scrPxDim[$ssize][1]/ $heightPx));
* Returns an array of the current map's info.
* The returned array is the set of variables that describe the current map
* view. These include an array of all currently enabled views ['views'],
* layers ['layers'], the zoom level ['zoom'], and the language ['lang'].
* The language variable is a three letter ISO 639-2 language code.
return array( 'views' => $this->curr['views'],
'layers' => $this->curr['layers'],
'zoom' => $this->curr['zoom'],
'lang' => $this->curr['lang']);
* Returns an array of the current bounding information
* The bounding array. All bounding indicies used in SMap are defined in
* SMap. Specifically: {@link SMap::MAXX}, {@link SMap::MAXY},
* {@link SMap::MINX}, and {@link SMap::MINY}.
* @return array Current bounds
return $this->curr['bounds'];
* Returns an array of the current tile's info.
* This returns the positioning information array that should represent
* either. The positioning information includes positioning info
* ['tileGrid'] and view ID ['viewId']. Also included is ['isTile'], which
* defines if the map is being drawn as a single tile (as opposed to a set
* The tile grid is an array of integers with keys at SMap_Tile::POSX,
* VIEWX, POSY, VIEWY. The array describes the position of the tile that
* we are viewing in relation to the other tiles. It contains enough
* information to determine which edge a tile is on.
* The position 1,1 is the tile in the upper left. If the view is 7 tiles
* wide and 4 tiles high then the numbers in VIEWX and VIEWY will be 7 and
* 4 respectively. The tile in the upper right corner will be at position
|