root/g-map/files/lib/data/gmap/GmapCluster.class.php @ 1226

Revision 1226, 2.6 kB (checked in by d0nut, 3 years ago)

finished gmap release candidate, version 1

Line 
1<?php
2
3/**
4 * gets several positions and returns a clustered array
5 *
6 * @author      Torben Brodt
7 * @license     GNU General Public License <http://opensource.org/licenses/gpl-3.0.html>
8 */
9class GmapCluster {
10
11        const OFFSET = 268435456;
12        const RADIUS = 85445659.4471; /* $self::OFFSET / pi() */
13       
14        protected $distance;
15        protected $zoom;
16       
17        /**
18         *
19         * @param       $distance       Distance in pixel inside which markers will be clustered.
20         * @param       $zoom           Current map zoom level.
21         */
22        public function __construct($distance, $zoom) {
23                $this->distance = $distance;
24                $this->zoom = $zoom;
25        }
26       
27        protected function lonToX($lon) {
28                return round(self::OFFSET + self::RADIUS * $lon * pi() / 180);         
29        }
30
31        protected function latToY($lat) {
32                return round(self::OFFSET - self::RADIUS * log((1 + sin($lat * pi() / 180)) / (1 - sin($lat * pi() / 180))) / 2);
33        }
34
35        protected function pixelDistance($lat1, $lon1, $lat2, $lon2, $zoom) {
36                $x1 = $this->lonToX($lon1);
37                $y1 = $this->latToY($lat1);
38
39                $x2 = $this->lonToX($lon2);
40                $y2 = $this->latToY($lat2);
41               
42                return sqrt(pow(($x1-$x2),2) + pow(($y1-$y2),2)) >> (21 - $zoom);
43        }
44       
45        /**
46         * Return average center of markers
47         *
48         * @return   object Google_Maps_Coordinate
49         */
50        protected function getCluster(array $markers) {
51                $count = count($markers);
52
53                /* Calculate average lat and lon of markers. */
54                $lat_sum = $lon_sum = 0;
55                foreach ($markers as $marker) {
56                   $lat_sum += $marker['lat'];
57                   $lon_sum += $marker['lon'];
58                }
59                $lat_avg = $lat_sum / $count;
60                $lon_avg = $lon_sum / $count;
61               
62                return array(
63                        'count' => $count,
64                        'lat' => $lat_avg,
65                        'lon' => $lon_avg
66                );
67        }
68
69        /**
70         *
71         * @param       $markers        Array of lat and lon locations.
72         */
73        public function getMarkers(array $markers) {
74                $clustered = array();
75
76                /* Loop until all markers have been compared. */
77                while (count($markers)) {
78                        $marker  = array_pop($markers);
79                        $cluster = array();
80
81                        /* Compare against all markers which are left. */
82                        foreach ($markers as $key => $target) {
83                                $pixels = $this->pixelDistance($marker['lat'], $marker['lon'], $target['lat'], $target['lon'], $this->zoom);
84
85                                /* If two markers are closer than given distance remove */
86                                /* target marker from array and add it to cluster.        */
87                                if ($this->distance > $pixels) {
88                                        unset($markers[$key]);
89                                        $cluster[] = $target;
90                                }
91                        }
92
93                        /* If a marker has been added to cluster, add also the one  */
94                        /* we were comparing to and remove the original from array. */
95                        if (count($cluster) > 0) {
96                                $cluster[] = $marker;
97                                $clustered[] = $this->getCluster($cluster);
98                        } else {
99                                $clustered[] = $marker;
100                        }
101                }
102                return $clustered;
103        }
104}
Note: See TracBrowser for help on using the browser.