Merge branch 'master' of ssh://apples.lambdacomplex.org/git/busui
[busui.git] / lib / GoogleMapUtility.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
/*
*DISCLAIMER
* 
*THIS SOFTWARE IS PROVIDED BY THE AUTHOR '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 AUTHOR 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.
*
*       @author: Olivier G. <olbibigo_AT_gmail_DOT_com>
*       @version: 1.1
*       @history:
*               1.0     creation
                1.1     disclaimer added
*/
class GoogleMapUtility {
        const TILE_SIZE = 256;
        
        //(lat, lng, z) -> parent tile (X,Y)
        public static function getTileXY($lat, $lng, $zoom) {
                $normalised = GoogleMapUtility::_toNormalisedMercatorCoords(GoogleMapUtility::_toMercatorCoords($lat, $lng));
                $scale = 1 << ($zoom);
                return new Point(
                        (int)($normalised->x * $scale), 
                        (int)($normalised->y * $scale)
                );
        }//toTileXY
        
        //(lat, lng, z) -> (x,y) with (0,0) in the upper left corner of the MAP
        public static function getPixelCoords($lat, $lng, $zoom) {
                $normalised = GoogleMapUtility::_toNormalisedMercatorCoords(GoogleMapUtility::_toMercatorCoords($lat, $lng));
                $scale = (1 << ($zoom)) * GoogleMapUtility::TILE_SIZE;
                return new Point(
                        (int)($normalised->x * $scale), 
                        (int)($normalised->y * $scale)
                );
        }//getPixelCoords
 
        //(lat, lng, z) -> (x,y) in the upper left corner of the TILE ($X, $Y)
        public static function getOffsetPixelCoords($lat,$lng,$zoom, $X, $Y) {
                $pixelCoords = GoogleMapUtility::getPixelCoords($lat, $lng, $zoom);
                return new Point(
                        $pixelCoords->x - $X * GoogleMapUtility::TILE_SIZE, 
                        $pixelCoords->y - $Y * GoogleMapUtility::TILE_SIZE
                );
        }//getPixelOffsetInTile
        
        public static function getTileRect($X,$Y,$zoom) {
                $tilesAtThisZoom = 1 << $zoom;
                $lngWidth = 360.0 / $tilesAtThisZoom;
                $lng = -180 + ($X * $lngWidth); 
                $latHeightMerc = 1.0 / $tilesAtThisZoom;
                $topLatMerc = $Y * $latHeightMerc;
                $bottomLatMerc = $topLatMerc + $latHeightMerc;
                $bottomLat = (180 / M_PI) * ((2 * atan(exp(M_PI * (1 - (2 * $bottomLatMerc))))) - (M_PI / 2));
                $topLat = (180 / M_PI) * ((2 * atan(exp(M_PI * (1 - (2 * $topLatMerc))))) - (M_PI / 2));
                $latHeight = $topLat - $bottomLat;
                return new Boundary($lng, $bottomLat, $lngWidth, $latHeight);
        }//getTileRect  
 
        private static function _toMercatorCoords($lat, $lng) {
                if ($lng > 180) {
                        $lng -= 360;
                }
                $lng /= 360;
                $lat = asinh(tan(deg2rad($lat)))/M_PI/2;
                return new Point($lng, $lat);
        }//_toMercatorCoords
 
        private static function _toNormalisedMercatorCoords($point) {
                $point->x += 0.5;
                $point->y = abs($point->y-0.5);
                return $point;
        }//_toNormalisedMercatorCoords
}//GoogleMapUtility
 
class Point {
        public $x,$y;
        function __construct($x,$y) {
                $this->x = $x;
                $this->y = $y;
        }
        function __toString() {
                return "({$this->x},{$this->y})";
        }
}//Point
 
class Boundary {
        public $x,$y,$width,$height;
        function __construct($x,$y,$width,$height) {
                $this->x = $x;
                $this->y = $y;
                $this->width = $width;
                $this->height = $height;
        }
        function __toString() {
                return "({$this->x} x {$this->y},{$this->width},{$this->height})";
        }
}//Boundary
?>