<?php
    
// +----------------------------------------------------------------------+
    // | PHP version 4                                                        |
    // +----------------------------------------------------------------------+
    // | Copyright (c) 2003-2004 Michal Migurski                              |
    // +----------------------------------------------------------------------+
    // | This source file is subject to version 3.0 of the PHP license,       |
    // | that is bundled with this package in the file LICENSE, and is        |
    // | available through the world-wide-web at the following url:           |
    // | http://www.php.net/license/3_0.txt.                                  |
    // | If you did not receive a copy of the PHP license and are unable to   |
    // | obtain it through the world-wide-web, please send a note to          |
    // | license@php.net so we can mail you a copy immediately.               |
    // +----------------------------------------------------------------------+
    // | Author: Michal Migurski <mike@teczno.com>                            |
    // +----------------------------------------------------------------------+
    //
    // $Id: Albers_Conical_EqualArea.php,v 1.3 2004/11/24 19:18:44 migurski Exp $
    /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

    // : latitude (N/S)
    // lambda: longitude (E/W)
    // DON'T FORGET: deg2rad()
    
    
require_once('Linear.php');
    
   
/** Albers_Conical_EqualArea_Projection
    * calculates Albers Conical Equal-Area Projection
    * http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html
    */
    
class Albers_Conical_EqualArea_Projection extends Linear_Projection
    
{
        var 
$transform;
        var 
$inverse;
    
        var 
$lat0;
        var 
$lon0;
        var 
$lat1;
        var 
$lat2;
        var 
$n;
        var 
$C;
        
        function 
Albers_Conical_EqualArea_Projection($lat0=0$lon0=0$lat1=0$lat2=0)
        {
            
$this->initializeTransform();

            
$this->lat0 $lat0;
            
$this->lon0 $lon0;
            
$this->lat1 $lat1;
            
$this->lat2 $lat2;

            
$this->0.5 * (sin($lat1) + sin($lat2));
            
$this->pow(cos($lat1), 2) + ($this->sin($lat1));
        }
        
       
/** _GPSToMap
        * calculates map x,y coordinate from gps lat/long coordinates
        *
        * @param    lat     float       latitude, in radians
        * @param    lon     float       longitude, in radians
        *
        * @return   array   'x', 'y' elements, map coordinates
        */
        
function _GPSToMap($lat$lon)
        {
            if (
$this->== 0) {
                
$p0 0;
                
$p 0;
            } else {
                
$p0 sqrt($this->- ($this->sin($this->lat0))) / $this->n;
                
$p sqrt($this->- ($this->sin($lat))) / $this->n;
            }
    
            
$th $this->* ($lon $this->lon0);
            
            
$x $p sin($th);
            
$y $p0 - ($p cos($th));
    
            
$vector = new Math_Matrix(array(array($x$y1)));
            
$vector->multiply($this->transform);

            return array(
'x' => $vector->getElement(00),
                         
'y' => $vector->getElement(01));
        }
    
       
/** _mapToGPS
        * calculates gps lat/long coordinate from map coordinates.
        *
        * @param    x       float       horizontal map position
        * @param    y       float       vertical map position
        *
        * @return   array   'lat', 'lon' elements, gps coordinates in radians
        */
        
function _mapToGPS($x$y)
        {
            
$vector = new Math_Matrix(array(array($x$y1)));
            
$vector->multiply($this->inverse);
            
            
$x $vector->getElement(00);
            
$y $vector->getElement(01);

            if (
$this->== 0) {
                
$p0 0;
                
$p sqrt(pow($x2) + pow(($p0 $y), 2));
            } else {
                
$p0 sqrt($this->- ($this->sin($this->lat0))) / $this->n;
                
$p sqrt(pow($x2) + pow(($p0 $y), 2));
            }
    
            
$th atan($x / ($p0 $y));
        
            
$lat asin(($this->- (pow($p2) * pow($this->n2))) / ($this->n));
            
$lon $this->lon0 + ($th $this->n);
    
            return array(
'lat' => $lat'lon' => $lon);
        }

    }

?>