+ /**
+ * Convert longitude to tile x number
+ *
+ * @see https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Lon..2Flat._to_tile_numbers_5
+ *
+ * @param float $longitude The longitude
+ * @param int $zoom The zoom
+ *
+ * @return float The tile x
+ */
+ public function longitudeToX(float $longitude, int $zoom): float {
+ return (($longitude + 180) / 360) * pow(2, $zoom);
+ }
+
+ /**
+ * Convert latitude to tile y number
+ *
+ * @see https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Lon..2Flat._to_tile_numbers_5
+ *
+ * @param $latitude The latitude
+ * @param $zoom The zoom
+ *
+ * @return float The tile y
+ */
+ public function latitudeToY(float $latitude, int $zoom): float {
+ return (1 - log(tan(deg2rad($latitude)) + 1 / cos(deg2rad($latitude))) / pi()) / 2 * pow(2, $zoom);
+ }
+
+ /**
+ * Convert tile x to longitude
+ *
+ * @param float $x The tile x
+ * @param int $zoom The zoom
+ *
+ * @return float The longitude
+ */
+ public function xToLongitude(float $x, int $zoom): float {
+ return $x / pow(2, $zoom) * 360.0 - 180.0;
+ }
+
+ /**
+ * Convert tile y to latitude
+ *
+ * @param float $y The tile y
+ * @param int $zoom The zoom
+ *
+ * @return float The latitude
+ */
+ public function yToLatitude(float $y, int $zoom): float {
+ return rad2deg(atan(sinh(pi() * (1 - 2 * $y / pow(2, $zoom)))));
+ }
+
+ /**
+ * Convert decimal latitude to sexagesimal
+ *
+ * @param float $latitude The decimal latitude
+ *
+ * @return string The sexagesimal longitude
+ */
+ public function latitudeToSexagesimal(float $latitude): string {
+ //Set degree
+ //TODO: see if round or intval is better suited to fix the Deprecated: Implicit conversion from float to int loses precision
+ $degree = round($latitude) % 60;
+
+ //Set minute
+ $minute = round(($latitude - $degree) * 60) % 60;
+
+ //Set second
+ $second = round(($latitude - $degree - $minute / 60) * 3600) % 3600;
+
+ //Return sexagesimal longitude
+ return $degree.'°'.$minute.'\''.$second.'"'.($latitude >= 0 ? 'N' : 'S');
+ }
+
+ /**
+ * Convert decimal longitude to sexagesimal
+ *
+ * @param float $longitude The decimal longitude
+ *
+ * @return string The sexagesimal longitude
+ */
+ public function longitudeToSexagesimal(float $longitude): string {
+ //Set degree
+ //TODO: see if round or intval is better suited to fix the Deprecated: Implicit conversion from float to int loses precision
+ $degree = round($longitude) % 60;
+
+ //Set minute
+ $minute = round(($longitude - $degree) * 60) % 60;
+
+ //Set second
+ $second = round(($longitude - $degree - $minute / 60) * 3600) % 3600;
+
+ //Return sexagesimal longitude
+ return $degree.'°'.$minute.'\''.$second.'"'.($longitude >= 0 ? 'E' : 'W');
+ }
+