X-Git-Url: https://git.rapsys.eu/packbundle/blobdiff_plain/29d552c341c632e185c043037923319a0527be39..3bc9a721a4d6aaa777029a064fb48eb6f568e4e6:/Util/MapUtil.php?ds=inline diff --git a/Util/MapUtil.php b/Util/MapUtil.php index 9bd8acd..b281555 100644 --- a/Util/MapUtil.php +++ b/Util/MapUtil.php @@ -11,435 +11,37 @@ namespace Rapsys\PackBundle\Util; +use Psr\Container\ContainerInterface; + +use Rapsys\PackBundle\RapsysPackBundle; + +use Symfony\Component\Filesystem\Exception\IOExceptionInterface; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Routing\RouterInterface; /** - * Helps manage map + * Manages map */ class MapUtil { /** - * The cycle tile server - * - * @see https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_servers - */ - const cycle = 'http://a.tile.thunderforest.com/cycle/{Z}/{X}/{Y}.png'; - - /** - * The fill color - */ - const fill = '#cff'; - - /** - * The font size - */ - const fontSize = 20; - - /** - * The high fill color - */ - const highFill = '#c3c3f9'; - - /** - * The high font size - */ - const highFontSize = 30; - - /** - * The high radius size - */ - const highRadius = 6; - - /** - * The high stroke color - */ - const highStroke = '#3333c3'; - - /** - * The high stroke size - */ - const highStrokeWidth = 4; - - /** - * The map width - */ - const width = 640; - - /** - * The map height - */ - const height = 640; - - /** - * The osm tile server - * - * @see https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_servers - */ - const osm = 'https://tile.openstreetmap.org/{Z}/{X}/{Y}.png'; - - /** - * The radius size - */ - const radius = 5; - - /** - * The stroke color - */ - const stroke = '#00c3f9'; - - /** - * The stroke size - */ - const strokeWidth = 2; - - /** - * The transport tile server - * - * @see https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_servers - */ - const transport = 'http://a.tile.thunderforest.com/transport/{Z}/{X}/{Y}.png'; - - /** - * The tile size - */ - const tz = 256; - - /** - * The map zoom - */ - const zoom = 17; - - /** - * The RouterInterface instance - */ - protected RouterInterface $router; - - /** - * The SluggerUtil instance - */ - protected SluggerUtil $slugger; - - /** - * The fill color - */ - public string $fill; - - /** - * The font size - */ - public int $fontSize; - - /** - * The high fill color - */ - public string $highFill; - - /** - * The font size - */ - public int $highFontSize; - - /** - * The radius size - */ - public int $highRadius; - - /** - * The high stroke color - */ - public string $highStroke; - - /** - * The stroke size - */ - public int $highStrokeWidth; - - /** - * The stroke color + * Alias string */ - public string $stroke; + protected string $alias; /** - * The stroke size + * Config array */ - public int $strokeWidth; + protected array $config; /** - * The radius size - */ - public int $radius; - - /** - * Creates a new map util + * Creates a new image util * + * @param ContainerInterface $container The container instance * @param RouterInterface $router The RouterInterface instance * @param SluggerUtil $slugger The SluggerUtil instance */ - function __construct(RouterInterface $router, SluggerUtil $slugger, string $fill = self::fill, int $fontSize = self::fontSize, string $highFill = self::highFill, int $highFontSize = self::highFontSize, int $highRadius = self::highRadius, string $highStroke = self::highStroke, int $highStrokeWidth = self::highStrokeWidth, int $radius = self::radius, string $stroke = self::stroke, int $strokeWidth = self::strokeWidth) { - //Set router - $this->router = $router; - - //Set slugger - $this->slugger = $slugger; - - //Set fill - $this->fill = $fill; - - //Set font size - $this->fontSize = $fontSize; - - //Set highFill - $this->highFill = $highFill; - - //Set high font size - $this->highFontSize = $highFontSize; - - //Set high radius size - $this->highRadius = $highRadius; - - //Set highStroke - $this->highStroke = $highStroke; - - //Set high stroke size - $this->highStrokeWidth = $highStrokeWidth; - - //Set radius size - $this->radius = $radius; - - //Set stroke - $this->stroke = $stroke; - - //Set stroke size - $this->strokeWidth = $strokeWidth; - } - - /** - * Get map data - * - * @param string $caption The caption - * @param int $updated The updated timestamp - * @param float $latitude The latitude - * @param float $longitude The longitude - * @param int $zoom The zoom - * @param int $width The width - * @param int $height The height - * @return array The map data - */ - public function getMap(string $caption, int $updated, float $latitude, float $longitude, int $zoom = self::zoom, int $width = self::width, int $height = self::height): array { - //Set link hash - $link = $this->slugger->hash([$updated, $latitude, $longitude, $zoom + 1, $width * 2, $height * 2]); - - //Set src hash - $src = $this->slugger->hash([$updated, $latitude, $longitude, $zoom, $width, $height]); - - //Return array - return [ - 'caption' => $caption, - 'link' => $this->router->generate('rapsys_pack_map', ['hash' => $link, 'updated' => $updated, 'latitude' => $latitude, 'longitude' => $longitude, 'zoom' => $zoom + 1, 'width' => $width * 2, 'height' => $height * 2]), - 'src' => $this->router->generate('rapsys_pack_map', ['hash' => $src, 'updated' => $updated, 'latitude' => $latitude, 'longitude' => $longitude, 'zoom' => $zoom, 'width' => $width, 'height' => $height]), - 'width' => $width, - 'height' => $height - ]; - } - - /** - * Get multi map data - * - * @param string $caption The caption - * @param int $updated The updated timestamp - * @param array $coordinates The coordinates array - * @param int $width The width - * @param int $height The height - * @return array The multi map data - */ - public function getMultiMap(string $caption, int $updated, array $coordinates, int $width = self::width, int $height = self::height): array { - //Set latitudes - $latitudes = array_map(function ($v) { return $v['latitude']; }, $coordinates); - - //Set longitudes - $longitudes = array_map(function ($v) { return $v['longitude']; }, $coordinates); - - //Set latitude - $latitude = round((min($latitudes)+max($latitudes))/2, 6); - - //Set longitude - $longitude = round((min($longitudes)+max($longitudes))/2, 6); - - //Set zoom - $zoom = $this->getMultiZoom($latitude, $longitude, $coordinates, $width, $height); - - //Set coordinate - $coordinate = implode('-', array_map(function ($v) { return $v['latitude'].','.$v['longitude']; }, $coordinates)); - - //Set coordinate hash - $hash = $this->slugger->hash($coordinate); - - //Set link hash - $link = $this->slugger->hash([$updated, $latitude, $longitude, $hash, $zoom + 1, $width * 2, $height * 2]); - - //Set src hash - $src = $this->slugger->hash([$updated, $latitude, $longitude, $hash, $zoom, $width, $height]); - - //Return array - return [ - 'caption' => $caption, - 'link' => $this->router->generate('rapsys_pack_multimap', ['hash' => $link, 'updated' => $updated, 'latitude' => $latitude, 'longitude' => $longitude, 'coordinates' => $coordinate, 'zoom' => $zoom + 1, 'width' => $width * 2, 'height' => $height * 2]), - 'src' => $this->router->generate('rapsys_pack_multimap', ['hash' => $src, 'updated' => $updated, 'latitude' => $latitude, 'longitude' => $longitude, 'coordinates' => $coordinate, 'zoom' => $zoom, 'width' => $width, 'height' => $height]), - 'width' => $width, - 'height' => $height - ]; - } - - /** - * Get multi zoom - * - * Compute a zoom to have all coordinates on multi map - * Multi map visible only from -($width / 2) until ($width / 2) and from -($height / 2) until ($height / 2) - * - * @see Wether we need to take in consideration circle radius in coordinates comparisons, likely +/-(radius / self::tz) - * - * @param float $latitude The latitude - * @param float $longitude The longitude - * @param array $coordinates The coordinates array - * @param int $width The width - * @param int $height The height - * @param int $zoom The zoom - * @return int The zoom - */ - public function getMultiZoom(float $latitude, float $longitude, array $coordinates, int $width, int $height, int $zoom = self::zoom): int { - //Iterate on each zoom - for ($i = $zoom; $i >= 1; $i--) { - //Get tile xy - $centerX = self::longitudeToX($longitude, $i); - $centerY = self::latitudeToY($latitude, $i); - - //Calculate start xy - $startX = floor($centerX - $width / 2 / self::tz); - $startY = floor($centerY - $height / 2 / self::tz); - - //Calculate end xy - $endX = ceil($centerX + $width / 2 / self::tz); - $endY = ceil($centerY + $height / 2 / self::tz); - - //Iterate on each coordinates - foreach($coordinates as $k => $coordinate) { - //Set dest x - $destX = self::longitudeToX($coordinate['longitude'], $i); - - //With outside point - if ($startX >= $destX || $endX <= $destX) { - //Skip zoom - continue(2); - } - - //Set dest y - $destY = self::latitudeToY($coordinate['latitude'], $i); - - //With outside point - if ($startY >= $destY || $endY <= $destY) { - //Skip zoom - continue(2); - } - } - - //Found zoom - break; - } - - //Return zoom - return $i; - } - - /** - * 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 static 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 static 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 static 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 static 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 static function latitudeToSexagesimal(float $latitude): string { - //Set degree - $degree = $latitude % 60; - - //Set minute - $minute = ($latitude - $degree) * 60 % 60; - - //Set second - $second = ($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 static function longitudeToSexagesimal(float $longitude): string { - //Set degree - $degree = $longitude % 60; - - //Set minute - $minute = ($longitude - $degree) * 60 % 60; - - //Set second - $second = ($longitude - $degree - $minute / 60) * 3600 % 3600; - - //Return sexagesimal longitude - return $degree.'°'.$minute.'\''.$second.'"'.($longitude >= 0 ? 'E' : 'W'); + public function __construct(protected ContainerInterface $container, protected RouterInterface $router, protected SluggerUtil $slugger) { + //Retrieve config + $this->config = $container->getParameter($this->alias = RapsysPackBundle::getAlias()); } }