Пример #1
0
 /**
  * @return float
  */
 public function getTileSize()
 {
     $size = TileStorageInterface::TILE_SIZE;
     if ($this->zoom > $this->maxZoom) {
         $size = $this->proj->scale($this->zoom) / $this->proj->scale($this->maxZoom) * $size;
     }
     return $size;
 }
Пример #2
0
 /**
  * Draw same type to labels (area, region, etc) into tiles
  *
  * @param int $zoom
  * @param Label[] $labels
  * @param array $style
  * @param bool $withIcon
  *
  * @throws \RuntimeException
  */
 protected function processLabels($zoom, $labels, $style, $withIcon)
 {
     $scale = $this->proj->scale($zoom);
     $count = count($labels);
     foreach ($labels as $id => $label) {
         $mem = memory_get_usage();
         if (!isset($label->text[$this->lang])) {
             throw new \RuntimeException("Missing translation ({$this->lang}), abort");
         }
         // center point in grid
         $point = new Point($label->point->x * $scale, $label->point->y * $scale);
         $text = $label->text[$this->lang];
         // center tile
         $txHome = floor($point->x / TileStorageInterface::TILE_SIZE);
         $tyHome = floor($point->y / TileStorageInterface::TILE_SIZE);
         $this->info("[{$mem}] + ({$zoom}) ({$count}) [{$txHome}, {$tyHome}], {$text}, \r");
         --$count;
         // label position relative to tile
         $cx = $point->x - $txHome * TileStorageInterface::TILE_SIZE;
         $cy = $point->y - $tyHome * TileStorageInterface::TILE_SIZE;
         $this->debug("+ ({$id}:{$text}) {$point} ({$txHome}, {$tyHome}) -> cx/cy [{$cx}, {$cy}]\n");
         $bbox = $this->getTextDimensions($style, $text);
         $tileBounds = $this->getTileBounds($point, $bbox);
         // 1x1 tile will give 0/0 as width/height
         $xTiles = $tileBounds->getWidth() + 1;
         $yTiles = $tileBounds->getHeight() + 1;
         $tx1 = $tileBounds->left;
         $ty1 = $tileBounds->top;
         // work image
         $canvas = $this->createTile($xTiles * TileStorageInterface::TILE_SIZE, $yTiles * TileStorageInterface::TILE_SIZE);
         // load tiles that needs to be modified
         $this->loadCanvas($canvas, $zoom, $tx1, $ty1, $xTiles, $yTiles);
         // label position relative to canvas
         $p = new Point($cx + ($txHome - $tx1) * TileStorageInterface::TILE_SIZE, $cy + ($tyHome - $ty1) * TileStorageInterface::TILE_SIZE);
         if ($withIcon) {
             $this->drawIcon($canvas, $p);
         }
         if ($style['fontSize'] > 0) {
             $this->drawText($canvas, $p, $style, $text, $label->color);
         }
         // now save those tiles back
         $this->saveCanvas($canvas, $zoom, $tx1, $ty1, $xTiles, $yTiles);
         imagedestroy($canvas);
     }
 }
Пример #3
0
 /**
  * @return int
  */
 private function getBoundsZoom()
 {
     $zoom = $this->autoMaxZoom;
     // area in pixels that markers/polygons occupy
     $w = $this->bounds->getWidth();
     $h = $this->bounds->getHeight();
     // map image size in pixels
     while ($zoom > 1) {
         $scale = $this->proj->scale($zoom);
         $newW = (int) ($w * $scale + $this->hMargin);
         $newH = (int) ($h * $scale + $this->vMargin);
         if ($newW < $this->width && $newH < $this->height) {
             break;
         }
         $zoom--;
     }
     return $zoom;
 }
Пример #4
0
 /**
  * @param int $zoom
  * @param float $expected
  *
  * @dataProvider zoomScaleProvider
  */
 public function testScale($zoom, $expected)
 {
     $mod = $this->proj->scale($zoom);
     $this->assertEquals($expected, $mod);
 }
Пример #5
0
 /**
  * @param resource $mapImage
  * @param int $zoom
  * @param int $mapImageWidth
  * @param int $mapImageHeight
  * @param Bounds $zoneBounds
  */
 protected function mapCutter($mapImage, $zoom, $mapImageWidth, $mapImageHeight, $zoneBounds)
 {
     // map image coords at base zoom
     $zoneLeft = $zoneBounds->left;
     $zoneBottom = $zoneBounds->bottom;
     $zoneRight = $zoneBounds->right;
     $zoneTop = $zoneBounds->top;
     $this->info("");
     $zoomScale = $this->projWorld->scale($zoom);
     // coords at current zoom level
     $left = $zoneLeft * $zoomScale;
     $bottom = $zoneBottom * $zoomScale;
     $right = $zoneRight * $zoomScale;
     $top = $zoneTop * $zoomScale;
     $width = $right - $left;
     $height = $bottom - $top;
     $scaleWidth = $mapImageWidth / $width;
     $scaleHeight = $mapImageHeight / $height;
     $this->debug("({$zoom}) map size ({$width}, {$height}), scaled (%.3f, %.3f)\n", $scaleWidth, $scaleHeight);
     // tiles this image lands
     $leftTile = floor($left / TileStorageInterface::TILE_SIZE);
     $topTile = floor($top / TileStorageInterface::TILE_SIZE);
     // right/bottom are +1 in value
     // (map on 0,0 tile has 1,1 as right/bottom) as we need top-left coords for that tile
     $rightTile = ceil($right / TileStorageInterface::TILE_SIZE);
     $bottomTile = ceil($bottom / TileStorageInterface::TILE_SIZE);
     $xTiles = $rightTile - $leftTile;
     $yTiles = $bottomTile - $topTile;
     $this->debug("    num tiles ({$xTiles}, {$yTiles}), map at ({$left}, {$top}):({$right}, {$bottom}) on tiles({$leftTile}, {$topTile}, %d, %d)\n", $rightTile - 1, $bottomTile - 1);
     $x1 = 0;
     $cw = 0;
     for ($xTile = 0; $xTile < $xTiles; $xTile++) {
         $y1 = 0;
         $ch = 0;
         for ($yTile = 0; $yTile < $yTiles; $yTile++) {
             $mem = memory_get_usage();
             $this->info("[{$mem}] - zoom % 2d (% 5dx% 5d @ %8d grid, mul=%.5f), tile % 3dx% 3d\r", $zoom, $width, $height, pow(2, $zoom) * TileStorageInterface::TILE_SIZE, $zoomScale, $xTile, $yTile);
             // tile coords within grid
             $tx1 = ($leftTile + $xTile) * TileStorageInterface::TILE_SIZE;
             $ty1 = ($topTile + $yTile) * TileStorageInterface::TILE_SIZE;
             $tx2 = ($leftTile + $xTile) * TileStorageInterface::TILE_SIZE + TileStorageInterface::TILE_SIZE;
             $ty2 = ($topTile + $yTile) * TileStorageInterface::TILE_SIZE + TileStorageInterface::TILE_SIZE;
             // image padding in tile
             $pad_l = 0;
             $pad_t = 0;
             $pad_r = 0;
             $pad_b = 0;
             if ($tx1 < $left) {
                 $pad_l = floor($left - $tx1);
             }
             if ($ty1 < $top) {
                 $pad_t = floor($top - $ty1);
             }
             if ($tx2 > $right) {
                 $pad_r = ceil($tx2 - $right);
             }
             if ($ty2 > $bottom) {
                 $pad_b = ceil($ty2 - $bottom);
             }
             $this->debug(">> (xTile:{$xTile}, yTile:{$yTile}): (tx1:{$tx1},ty1:{$ty1}):(tx2:{$tx2},ty2:{$ty2}), padding ({$pad_l}, {$pad_t}):({$pad_r}, {$pad_b})\n");
             $dstWidth = TileStorageInterface::TILE_SIZE - $pad_r - $pad_l;
             $dstHeight = TileStorageInterface::TILE_SIZE - $pad_b - $pad_t;
             $cw = $dstWidth * $scaleWidth;
             $ch = $dstHeight * $scaleHeight;
             $this->debug(">> copy from (%d, %d):(%d,%d) to tile (%d, %d):(%d,%d)\n", $x1, $y1, $cw, $ch, $pad_l, $pad_t, $dstWidth, $dstHeight);
             $out = $this->loadTileImage($zoom, $leftTile + $xTile, $topTile + $yTile);
             imagecopyresampled($out, $mapImage, $pad_l, $pad_t, $x1, $y1, $dstWidth, $dstHeight, $cw, $ch);
             if ($this->debug) {
                 $c = imagecolorallocatealpha($out, 255, 0, 0, 50);
                 imagerectangle($out, $pad_l, $pad_t, $pad_l + $dstWidth, $pad_t + $dstHeight, $c);
             }
             $this->saveTileImage($zoom, $leftTile + $xTile, $topTile + $yTile, $out);
             $y1 += $ch;
         }
         $x1 += $cw;
     }
 }