diff --git a/src/CanvasTilePainter/CanvasTilePainter.php b/src/CanvasTilePainter/CanvasTilePainter.php index b778862..8794271 100644 --- a/src/CanvasTilePainter/CanvasTilePainter.php +++ b/src/CanvasTilePainter/CanvasTilePainter.php @@ -2,6 +2,9 @@ namespace StaticMapLite\CanvasTilePainter; +use Imagine\Gd\Imagine; +use Imagine\Image\Box; +use Imagine\Image\ImageInterface; use Imagine\Image\Point; use StaticMapLite\Canvas\Canvas; use StaticMapLite\TileResolver\TileResolverInterface; @@ -14,6 +17,9 @@ class CanvasTilePainter /** @var TileResolverInterface $tileResolver */ protected $tileResolver; + /** @var ImageInterface $tmpCanvasImage */ + protected $tmpCanvasImage; + public function __construct() { @@ -33,8 +39,33 @@ class CanvasTilePainter return $this; } + protected function createTmpCanvasImage(): CanvasTilePainter + { + $tileSize = $this->canvas->getTileSize(); + + $size = new Box($this->canvas->getWidth() + 2 * $tileSize, $this->canvas->getHeight() + 2 * $tileSize); + + $imagine = new Imagine(); + $this->tmpCanvasImage = $imagine->create($size); + + return $this; + } + + protected function cropToCanvas(): CanvasTilePainter + { + $tmpTopLeftPoint = new Point(256, 256); + $this->tmpCanvasImage->crop($tmpTopLeftPoint, $this->canvas->getImage()->getSize()); + + $topLeftPoint = new Point(0, 0); + $this->canvas->getImage()->paste($this->tmpCanvasImage, $topLeftPoint); + + return $this; + } + public function paint(): CanvasTilePainter { + $this->createTmpCanvasImage(); + $startX = floor($this->canvas->getCenterX() - ($this->canvas->getWidth() / $this->canvas->getTileSize()) / 2); $startY = floor($this->canvas->getCenterY() - ($this->canvas->getHeight() / $this->canvas->getTileSize()) / 2); $endX = ceil($this->canvas->getCenterX() + ($this->canvas->getWidth() / $this->canvas->getTileSize()) / 2); @@ -47,6 +78,8 @@ class CanvasTilePainter $offsetX += floor($startX - floor($this->canvas->getCenterX())) * $this->canvas->getTileSize(); $offsetY += floor($startY - floor($this->canvas->getCenterY())) * $this->canvas->getTileSize(); + $box = new Box(256, 256); + for ($x = $startX; $x <= $endX; $x++) { for ($y = $startY; $y <= $endY; $y++) { $tileImage = $this->tileResolver->fetch($this->canvas->getZoom(), $x, $y); @@ -54,13 +87,16 @@ class CanvasTilePainter $destX = ($x - $startX) * $this->canvas->getTileSize() + $offsetX; $destY = ($y - $startY) * $this->canvas->getTileSize() + $offsetY; - if ($destX >= 0 && $destY >= 0 && $destX < $this->canvas->getWidth() && $destY < $this->canvas->getHeight()) { - $point = new Point($destX, $destY); - $tileImage->paste($this->canvas->getImage(), $point); + $point = new Point($destX + 256, $destY + 256); + + if ($this->tmpCanvasImage->getSize()->contains($box, $point)) { + $this->tmpCanvasImage->paste($tileImage, $point); } } } + $this->cropToCanvas(); + return $this; } }