@@ -15,25 +15,35 @@ class MapData
1515{
1616
1717 /**
18- * Convert longitude and zoom to horizontal OpenStreetMap tile number.
18+ * Convert longitude and zoom to horizontal OpenStreetMap tile number and pixel position .
1919 * @param float $lon Longitude
2020 * @param int $zoom Zoom
21- * @return int OpenStreetMap tile id of the given longitude and zoom
21+ * @return int[] OpenStreetMap tile id and pixel position of the given longitude and zoom
2222 */
23- public static function lngToXTile (float $ lon , int $ zoom ): int
23+ public static function lngToXTile (float $ lon , int $ zoom ): array
2424 {
25- return \floor (($ lon + 180 ) / 360 * \pow (2 , $ zoom ));
25+ $ x = ($ lon + 180 ) / 360 * \pow (2 , $ zoom );
26+ $ tile = \floor ($ x );
27+ return [
28+ 'id ' => $ tile ,
29+ 'position ' => 256 * ($ x - $ tile )
30+ ];
2631 }
2732
2833 /**
29- * Convert latitude and zoom to vertical OpenStreetMap tile number.
34+ * Convert latitude and zoom to vertical OpenStreetMap tile number and pixel position .
3035 * @param float $lat Latitude
3136 * @param int $zoom Zoom
32- * @return int OpenStreetMap tile id of the given latitude and zoom
37+ * @return int[] OpenStreetMap tile id and pixel position of the given latitude and zoom
3338 */
34- public static function latToYTile (float $ lat , int $ zoom ): int
39+ public static function latToYTile (float $ lat , int $ zoom ): array
3540 {
36- return \floor ((1 - \log (\tan (\deg2rad ($ lat )) + 1 / \cos (\deg2rad ($ lat ))) / M_PI ) / 2 * \pow (2 , $ zoom ));
41+ $ y = (1 - \log (\tan (\deg2rad ($ lat )) + 1 / \cos (\deg2rad ($ lat ))) / M_PI ) / 2 * \pow (2 , $ zoom );
42+ $ tile = \floor ($ y );
43+ return [
44+ 'id ' => $ tile ,
45+ 'position ' => 256 * ($ y - $ tile )
46+ ];
3747 }
3848
3949 /**
@@ -58,32 +68,6 @@ public static function yTileToLat(int $y, int $zoom): float
5868 return \rad2deg (\atan (\sinh (M_PI * (1 - 2 * $ y / \pow (2 , $ zoom )))));
5969 }
6070
61- /**
62- * Convert latitude to pixel position from top of the tile.
63- * @param float $lat latitude
64- * @param int $zoom Zoom
65- * @return float pixel position from top of the tile
66- */
67- public static function latToTilePx (float $ lat , int $ zoom ): float
68- {
69- $ y = static ::latToYTile ($ lat , $ zoom );
70- $ latTile = static ::yTileToLat ($ y , $ zoom );
71- return ($ latTile - $ lat ) * 256 / ($ latTile - static ::yTileToLat ($ y + 1 , $ zoom ));
72- }
73-
74- /**
75- * Convert longitude to pixel position from left of the tile.
76- * @param float $lng longitude
77- * @param int $zoom Zoom
78- * @return float pixel position from left of the tile
79- */
80- public static function lngToTilePx (float $ lng , int $ zoom ): float
81- {
82- $ x = static ::lngToXTile ($ lng , $ zoom );
83- $ lngTile = static ::xTileToLng ($ x , $ zoom );
84- return ($ lngTile - $ lng ) * 256 / ($ lngTile - static ::xTileToLng ($ x + 1 , $ zoom ));
85- }
86-
8771
8872 /**
8973 * Convert pixel position from top of the tile to latitude.
@@ -157,12 +141,13 @@ public function __construct(LatLng $centerMap, int $zoom, XY $outputSize)
157141 $ this ->zoom = $ zoom ;
158142 $ this ->outputSize = $ outputSize ;
159143
160- $ startX = \floor ($ outputSize ->getX () / 2 - static ::lngToTilePx ($ centerMap ->getLng (), $ zoom ));
161- $ startY = \floor ($ outputSize ->getY () / 2 - static ::latToTilePx ($ centerMap ->getLat (), $ zoom ));
162-
163144 $ x = static ::lngToXTile ($ centerMap ->getLng (), $ zoom );
164145 $ y = static ::latToYTile ($ centerMap ->getLat (), $ zoom );
165146
147+ $ startX = \floor ($ outputSize ->getX () / 2 - $ x ['position ' ]);
148+ $ startY = \floor ($ outputSize ->getY () / 2 - $ y ['position ' ]);
149+
150+
166151 $ rightSize = $ outputSize ->getX () - $ startX ;
167152 $ bottomSize = $ outputSize ->getY () - $ startY ;
168153
@@ -175,12 +160,12 @@ public function __construct(LatLng $centerMap, int $zoom, XY $outputSize)
175160 ($ bottomSize % 256 == 0 ? 0 : 256 - $ bottomSize % 256 )
176161 );
177162 $ this ->tileTopLeft = new XY (
178- $ x - \ceil ($ startX / 256 ),
179- $ y - \ceil ($ startY / 256 )
163+ $ x[ ' id ' ] - \ceil ($ startX / 256 ),
164+ $ y[ ' id ' ] - \ceil ($ startY / 256 )
180165 );
181166 $ this ->tileBottomRight = new XY (
182- $ x - 1 + \ceil ($ rightSize / 256 ),
183- $ y - 1 + \ceil ($ bottomSize / 256 )
167+ $ x[ ' id ' ] - 1 + \ceil ($ rightSize / 256 ),
168+ $ y[ ' id ' ] - 1 + \ceil ($ bottomSize / 256 )
184169 );
185170
186171 $ this ->latLngTopLeft = new LatLng (
@@ -306,8 +291,8 @@ public function convertLatLngToPxPosition(LatLng $latLng): XY
306291 $ y = static ::latToYTile ($ latLng ->getLat (), $ this ->zoom );
307292
308293 return new XY (
309- ($ x - $ this ->tileTopLeft ->getX ()) * 256 - $ this ->mapCropTopLeft ->getX () + static :: lngToTilePx ( $ latLng -> getLng (), $ this -> zoom ) ,
310- ($ y - $ this ->tileTopLeft ->getY ()) * 256 - $ this ->mapCropTopLeft ->getY () + static :: latToTilePx ( $ latLng -> getLat (), $ this -> zoom )
294+ ($ x[ ' id ' ] - $ this ->tileTopLeft ->getX ()) * 256 - $ this ->mapCropTopLeft ->getX () + $ x [ ' position ' ] ,
295+ ($ y[ ' id ' ] - $ this ->tileTopLeft ->getY ()) * 256 - $ this ->mapCropTopLeft ->getY () + $ y [ ' position ' ]
311296 );
312297 }
313298}
0 commit comments