<?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: Lambert_Conformal_Conic.php,v 1.3 2004/11/24 19:18:44 migurski Exp $
    /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

    // theta: latitude (N/S)
    // lambda: longitude (E/W)
    // DON'T FORGET: deg2rad()
    
    
require_once('Linear.php');
    
   
/** Lambert_Conformal_Conic_Projection
    * calculates Lambert Conformal Conic Projection
    * http://mathworld.wolfram.com/LambertConformalConicProjection.html
    */
    
class Lambert_Conformal_Conic_Projection extends Linear_Projection
    
{
        var 
$transform;
        var 
$inverse;
    
        var 
$lat0;
        var 
$lon0;
        var 
$lat1;
        var 
$lat2;
        var 
$n;
        var 
$F;
        var 
$p0;
        
        function 
Lambert_Conformal_Conic_Projection($lat0=0$lon0=0$lat1=0$lat2=0)
        {
            
$this->initializeTransform();

            
$this->lat0 $lat0;
            
$this->lon0 $lon0;
            
$this->lat1 $lat1;
            
$this->lat2 $lat2;
            
            
$n log(cos($lat1) / cos($lat2)) / log(tan((pi() / 4) + ($lat2 2)) / tan((pi() / 4) + ($lat1 2)));
            
$F = (cos($lat1) * pow(tan((pi() / 4) + ($lat1 2)), $n)) / $n;
            
$p0 $F pow((tan((pi() / 4) + ($lat0 2))), $n);
            
            
$this->$n;
            
$this->$F;
            
$this->p0 $p0;
        }
        
       
/** _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)
        {
            
$p $this->pow((tan((pi() / 4) + ($lat 2))), $this->n);
            
//printf("p: ${p}\n");
            
            
$x $p sin($this->* ($lon $this->lon0));
            
$y $this->p0 - ($p cos($this->* ($lon $this->lon0)));
    
            
$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);

            
$p $this->_sign($this->n) * sqrt(pow($x2) + pow(($this->p0 $y), 2));
            
$theta atan($x / ($this->p0 $y));
            
            
$lat = (atan(pow(($this->$p), ($this->n)))) - (pi() / 2);
            
$lon $this->lon0 + ($theta $this->n);
            
            return array(
'lat' => $lat'lon' => $lon);
        }
        
       
/** _sign
        * returns sign of input: -1, 0, or +1, depending on whether input is negative, zero, or positive.
        *
        * @param    x   number  some number, float or integer
        *
        * @return   number  sign of x
        */
        
function _sign($x)
        {
            return ((
$x == 0) ? : ($x abs($x)));
        }

    }

?>