From: Raphaël Gertz Date: Sun, 8 Dec 2024 03:10:19 +0000 (+0100) Subject: Move every map features in image util X-Git-Tag: 0.5.4~20 X-Git-Url: https://git.rapsys.eu/packbundle/commitdiff_plain/2a4829218845b2db4b72835e101d27f067f3c5d8?ds=sidebyside Move every map features in image util --- diff --git a/Util/MapUtil.php b/Util/MapUtil.php index b7d2232..b281555 100644 --- a/Util/MapUtil.php +++ b/Util/MapUtil.php @@ -11,6 +11,12 @@ 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; /** @@ -18,411 +24,24 @@ use Symfony\Component\Routing\RouterInterface; */ 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 + * Alias string */ - const highFontSize = 30; + protected string $alias; /** - * The high radius size + * Config array */ - const highRadius = 6; + protected array $config; /** - * The high stroke color - */ - const highStroke = '#3333c3'; - - /** - * The high stroke width - */ - 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 width - */ - 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; - - /** - * 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(protected RouterInterface $router, protected SluggerUtil $slugger, protected string $fill = self::fill, protected int $fontSize = self::fontSize, protected string $highFill = self::highFill, protected int $highFontSize = self::highFontSize, protected int $highRadius = self::highRadius, protected string $highStroke = self::highStroke, protected int $highStrokeWidth = self::highStrokeWidth, protected int $radius = self::radius, protected string $stroke = self::stroke, protected int $strokeWidth = self::strokeWidth) { - } - - /** - * Get fill color - */ - function getFill() { - return $this->fill; - } - - /** - * Get font size - */ - function getFontSize() { - return $this->fontSize; - } - - /** - * Get high fill color - */ - function getHighFill() { - return $this->highFill; - } - - /** - * Get high font size - */ - function getHighFontSize() { - return $this->highFontSize; - } - - /** - * Get high radius size - */ - function getHighRadius() { - return $this->highRadius; - } - - /** - * Get high stroke color - */ - function getHighStroke() { - return $this->highStroke; - } - - /** - * Get high stroke width - */ - function getHighStrokeWidth() { - return $this->highStrokeWidth; - } - - /** - * Get radius size - */ - function getRadius() { - return $this->radius; - } - - /** - * Get stroke color - */ - function getStroke() { - return $this->stroke; - } - - /** - * Get stroke width - */ - function getStrokeWidth() { - return $this->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('rapsyspack_map', ['hash' => $link, 'updated' => $updated, 'latitude' => $latitude, 'longitude' => $longitude, 'zoom' => $zoom + 1, 'width' => $width * 2, 'height' => $height * 2]), - 'src' => $this->router->generate('rapsyspack_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 { - //Without coordinates - if (empty($coordinates)) { - //Return empty array - return []; - } - - //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('rapsyspack_multimap', ['hash' => $link, 'updated' => $updated, 'latitude' => $latitude, 'longitude' => $longitude, 'coordinates' => $coordinate, 'zoom' => $zoom + 1, 'width' => $width * 2, 'height' => $height * 2]), - 'src' => $this->router->generate('rapsyspack_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 - //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 static 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'); + public function __construct(protected ContainerInterface $container, protected RouterInterface $router, protected SluggerUtil $slugger) { + //Retrieve config + $this->config = $container->getParameter($this->alias = RapsysPackBundle::getAlias()); } }