Заливка сложной области
Для заливки сложной замкнутой области удобно использовать функциюimagefilledpolygon:
int imagefilledpolygon ( resource image, array points, int num_points, int color )
где,
- image- идентификатор изображения;
- points- массив точек;
- num_points- количество точек в полигоне;
- color- цвет заливки.
Массив точек содержит X и Y координату каждой точки. Таким образом, для трех точек, массив содержит шесть элементов: Array( X1, Y1, X2, Y2, X3, Y3)
Пример 29.Вывод самого простого полигона (треугольник):
<?php header ("Content-type: image/png"); $im = imagecreatetruecolor(320, 240); $ink = imagecolorallocate($im, 255, 255, 255); imagefilledpolygon($im, Array( 100,100, 120,180, 210,160, ), 3, $ink); imagepng($im); imagedestroy($im); ?>
Результат работы этой программы выглядит следующим образом:
Эта функция удобна тем, что линии полигона могут пересекаться, и заливка при этом работает корректно:
Карта России
Рассмотрим следующую задачу: необходимо нарисовать карту России и выделить определенные регионы цветами, в зависимости от какого-то параметра (плотности населения, числа жителей, количества продаж и т.п.)
Задача на первый взгляд сложная, так как контуры некоторых регионов России имеют неправильную форму и использовать функциюimagefillнельзя. По этому, я использовал функциюimagepolygonдля прорисовки контуров, и функциюimagefilledpolygonдля закрашивания регионов.
Метод, которым я нарисовал карту рассматривался в уроке 6.
Пример 30.Рисование карты России:
<?php // Ширина и высота изображения $W=500; $H=375; // Функция выводит контуры региона и закрашивает его внутреннюю часть // $im - идентификатор изображения // $filename - имя файла содержащего контур региона (в формате // Adobe Illustrator // $maxw - максимальное значение координаты X в файле с контурами // России (необходимо для того, чтобы все регионы // рисовались с одним масштабом) // $maxh - максимальное значение координаты Y в файле с контурами // России // $color - цвет, в который будет закрашиваться регион function DrawIllustratorFile($im,$filename,$maxw,$maxh,$color) { GLOBAL $W,$H; // Чтения файла $d=file($filename); // Если массив $d содержит только один элемент, // то в качестве переноса строк используется символ // возврата каретки, и нам необходимо разбить текст // на строку вручную if (count($d)==1) $d=explode("\r",$d[0]); // С помощью регулярного выражение выберем координаты // всех точек. $poly=Array(); for ($i=0;$i<count($d);$i++) if (preg_match("/([0-9.]+) ([0-9.]+) [lm]/",$d[$i],$r)) { $poly[]=$r[1]; $poly[]=$r[2]; } for ($i=0;$i<count($poly);$i+=2) { // Нормализуем координаты $poly[$i]/=$maxw; $poly[$i+1]/=$maxh; // Отмасштабируем координаты $poly[$i]*=($W-10); $poly[$i+1]*=($H-10); // Перевернем изображение по вертикали $poly[$i+1]=$H-$poly[$i+1]; } // Вывод полигона imagefilledpolygon($im, $poly, count($poly)/2, $color); imagepolygon($im, $poly, count($poly)/2, $color["black"]); } // Чтения файла $d=file("russia.ai"); // Если массив $d содержит только один элемент, // то в качестве переноса строк используется символ // возврата каретки, и нам необходимо разбить текст // на строку вручную if (count($d)==1) $d=explode("\r",$d[0]); // С помощью регулярного выражение выберем координаты // всех точек и найдем точки с самыми большими координатами. // Эти значения нам понадобятся для нормализации. $maxw=$maxh=0; for ($i=0;$i<count($d);$i++) if (preg_match("/([0-9.]+) ([0-9.]+) [lm]/",$d[$i],$r)) { if ($maxw<$r[1]) $maxw=$r[1]; if ($maxh<$r[2]) $maxh=$r[2]; } // В отличи от урока 6, в одном файле может быть несколько // полигонов. Для хранения координат их вершин, будем использовать // двухмерный массив // С помощью регулярного выражение выберем координаты // всех полигонов. Формат Adobe Illustrator, прост, // при условии использования прямых линий $points=Array(); $num=-1; for ($i=0;$i<count($d);$i++) { // Первая точка в полигоне if (preg_match("/([0-9.]+) ([0-9.]+) [m]/",$d[$i],$r)) { $num++; $points[$num][]=$r[1]; $points[$num][]=$r[2]; } // Не первая точка в полигоне if (preg_match("/([0-9.]+) ([0-9.]+) [l]/",$d[$i],$r)) { $points[$num][]=$r[1]; $points[$num][]=$r[2]; } } // Создадим изображение и выделим цвета header ("Content-type: image/png"); $im = imagecreatetruecolor($W, $H); $bg = imagecolorallocate($im, 255, 255, 255); imagefilledrectangle($im,0,0,imagesx($im),imagesy($im),$bg); $ink=imagecolorallocate($im,0,0,0); // Вывод полигонов for ($j=0;$j<count($points);$j++) { // Перерассчитанные координаты полигона // будем хранить в массиве $poly $poly=Array(); for ($i=0;$i<count($points[$j]);$i+=2) { $x=$points[$j][$i]; $y=$points[$j][$i+1]; // Нормализуем координаты $x=$x/$maxw; $y=$y/$maxh; // Отмасштабируем координаты $x=$x*($W-10); $y=$y*($H-10); // Перевернем изображение по вертикали $y=$H-$y; // Заносим координаты в массив, по которому // будет построен полигон $poly[]=$x; $poly[]=$y; } // Вывод полигона imagepolygon($im, $poly, count($poly)/2, $ink); } // Выделим цвета для заливки регионов $color=Array(); for ($i=196;$i<256;$i+=6) $color[]=imagecolorallocate($im,$i,$i,$i); $color["black"]=$ink; // Прорисовка и закрашивание регионов DrawIllustratorFile($im,"arhangelsk.ai",$maxw,$maxh,$color[7]); DrawIllustratorFile($im,"murmansk.ai",$maxw,$maxh,$color[5]); DrawIllustratorFile($im,"novgorod.ai",$maxw,$maxh,$color[0]); DrawIllustratorFile($im,"pertrozavodsk.ai",$maxw,$maxh,$color[3]); DrawIllustratorFile($im,"pskov.ai",$maxw,$maxh,$color[8]); DrawIllustratorFile($im,"s-petersburg.ai",$maxw,$maxh,$color[9]); DrawIllustratorFile($im,"syktyvkar.ai",$maxw,$maxh,$color[3]); DrawIllustratorFile($im,"vologda.ai",$maxw,$maxh,$color[4]); imagepng($im); imagedestroy($im); ?>
Так выглядит карта России до закрашивания регионов:
А окончательный результат работы этой программы выглядит следующим образом: (Терпения мне хватило только на обводку областей северо-западного федерального округа)
Скачать PHP скрипт рисующий карту России можно здесь.
На самом деле, обводить контур страны не обязательно, так как его построят сложенные вместе регионы. Я сделал это лишь из-за того что не нашел времени обвести все регионы.
Этот метод, в сочетании со сглаживанием изображения, я использовал для рисования карты мира на сайте http://top.novgorod.ru/. Вот как она выглядит:
Ссылки по теме
- PHP Manual - функция imagefill;
- PHP Manual - функция imagepolygon.
- PHP Manual - функция imagefilledpolygon.
Назад | Оглавление | Далее