Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/*
3
 *  $Id$
4
 *
5
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16
 *
17
 * This software consists of voluntary contributions made by many individuals
18
 * and is licensed under the LGPL. For more information, see
19
 * <http://www.doctrine-project.org>.
20
 */
21
 
22
/**
23
 * Easily add longitude and latitude columns to your records and use inherited functionality for
24
 * calculating distances
25
 *
26
 * @package     Doctrine
27
 * @subpackage  Template
28
 * @license     http://www.opensource.org/licenses/lgpl-license.php LGPL
29
 * @link        www.doctrine-project.org
30
 * @since       1.0
31
 * @version     $Revision$
32
 * @author      Konsta Vesterinen <kvesteri@cc.hut.fi>
33
 * @author      Jonathan H. Wage <jonwage@gmail.com>
34
 */
35
class Doctrine_Template_Geographical extends Doctrine_Template
36
{
37
    /**
38
     * Array of geographical options
39
     *
40
     * @var string
41
     */
42
    protected $_options = array('latitude' =>  array('name'     =>  'latitude',
43
                                                     'type'     =>  'double',
44
                                                     'size'     =>  null,
45
                                                     'options'  =>  array()),
46
                                'longitude' => array('name'     =>  'longitude',
47
                                                     'type'     =>  'double',
48
                                                     'size'     =>  null,
49
                                                     'options'  =>  array()));
50
 
51
    /**
52
     * Set table definition for Geographical behavior
53
     *
54
     * @return void
55
     */
56
    public function setTableDefinition()
57
    {
58
        $this->hasColumn($this->_options['latitude']['name'], $this->_options['latitude']['type'], $this->_options['latitude']['size'], $this->_options['latitude']['options']);
59
        $this->hasColumn($this->_options['longitude']['name'], $this->_options['longitude']['type'], $this->_options['longitude']['size'], $this->_options['longitude']['options']);
60
    }
61
 
62
    /**
63
     * Initiate and get a distance query with the select parts for the number of kilometers and miles
64
     * between this record and other zipcode records in the database
65
     *
66
     * @return Doctrine_Query $query
67
     */
68
    public function getDistanceQuery()
69
    {
70
        $invoker = $this->getInvoker();
71
        $query = $invoker->getTable()->createQuery();
72
 
73
        $rootAlias = $query->getRootAlias();
74
        $latName = $this->_options['latitude']['name'];
75
        $longName = $this->_options['longitude']['name'];
76
 
77
        $query->addSelect($rootAlias . '.*');
78
 
79
        $sql = "((ACOS(SIN(%s * PI() / 180) * SIN(" . $rootAlias . "." . $latName . " * PI() / 180) + COS(%s * PI() / 180) * COS(" . $rootAlias . "." . $latName . " * PI() / 180) * COS((%s - " . $rootAlias . "." . $longName . ") * PI() / 180)) * 180 / PI()) * 60 * %s) as %s";
80
 
81
        $milesSql = sprintf($sql, $invoker->get($latName), $invoker->get($latName), $invoker->get($longName), '1.1515', 'miles');
82
        $query->addSelect($milesSql);
83
 
84
        $kilometersSql = sprintf($sql, $invoker->get($latName), $invoker->get($latName), $invoker->get($longName), '1.1515 * 1.609344', 'kilometers');
85
        $query->addSelect($kilometersSql);
86
 
87
        return $query;
88
    }
89
 
90
    /**
91
     * Get distance between this record and another
92
     *
93
     * @param string $Doctrine_Record
94
     * @param string $kilometers
95
     * @return integer
96
     */
97
    public function getDistance(Doctrine_Record $record, $kilometers = false)
98
    {
99
        $query = $this->getDistanceQuery($kilometers);
100
 
101
        $conditions = array();
102
        $values = array();
103
        foreach ((array) $record->getTable()->getIdentifier() as $id) {
104
            $conditions[] = $query->getRootAlias() . '.' . $id . ' = ?';
105
            $values[] = $record->get($id);
106
        }
107
 
108
        $where = implode(' AND ', $conditions);
109
 
110
        $query->addWhere($where, $values);
111
 
112
        $query->limit(1);
113
 
114
        $result = $query->execute()->getFirst();
115
 
116
        if (isset($result['kilometers']) && $result['miles']) {
117
            return $kilometers ? $result->get('kilometers'):$result->get('miles');
118
        } else {
119
            return 0;
120
        }
121
    }
122
}