Skip to content

Commit 184ba2b

Browse files
authored
Merge pull request #7 from stephan-strate/tileserver-support
Add tile server support
2 parents b65ccea + ca2a29b commit 184ba2b

File tree

4 files changed

+134
-13
lines changed

4 files changed

+134
-13
lines changed

src/OpenStreetMap.php

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
*/
1616
class OpenStreetMap
1717
{
18+
/**
19+
* @var TileServer Tile server settings, defaults to OpenStreetMaps tile server
20+
*/
21+
protected $tileServer;
1822
/**
1923
* @var MapData Data about the generated map (bounding box, size, OSM tile ids...)
2024
*/
@@ -28,17 +32,18 @@ class OpenStreetMap
2832
*/
2933
protected $draws = [];
3034

31-
3235
/**
3336
* OpenStreetMap constructor.
3437
* @param LatLng $centerMap Latitude and longitude of the map center
3538
* @param int $zoom Zoom
3639
* @param int $imageWidth Width of the generated map image
3740
* @param int $imageHeight Height of the generated map image
41+
* @param TileServer $tileServer Tile server configuration, defaults to OpenStreetMaps tile server
3842
*/
39-
public function __construct(LatLng $centerMap, int $zoom, int $imageWidth, int $imageHeight)
43+
public function __construct(LatLng $centerMap, int $zoom, int $imageWidth, int $imageHeight, TileServer $tileServer = null)
4044
{
4145
$this->mapData = new MapData($centerMap, $zoom, new XY($imageWidth, $imageHeight));
46+
$this->tileServer = is_null($tileServer) ? TileServer::defaultTileServer() : $tileServer;
4247
}
4348

4449
/**
@@ -90,7 +95,7 @@ protected function getMapImage(): Image
9095
for ($y = $startY; $y < $imgSize->getY(); $y += 256) {
9196
$xTile = $this->mapData->getTileTopLeft()->getX();
9297
for ($x = $startX; $x < $imgSize->getX(); $x += 256) {
93-
$i = Image::fromCurl('https://tile.openstreetmap.org/' . $this->mapData->getZoom() . '/' . $xTile . '/' . $yTile . '.png');
98+
$i = Image::fromCurl($this->tileServer->getTileUrl($xTile, $yTile, $this->mapData->getZoom()));
9499
$image->pasteOn($i, $x, $y);
95100
++$xTile;
96101
}
@@ -100,15 +105,6 @@ protected function getMapImage(): Image
100105
return $image;
101106
}
102107

103-
/**
104-
* Get attribution text
105-
* @return string Attribution text
106-
*/
107-
protected function getAttributionText(): string
108-
{
109-
return '© OpenStreetMap contributors';
110-
}
111-
112108
/**
113109
* Draw OpenStreetMap attribution at the right bottom of the image
114110
* @param Image $image The image of the map
@@ -119,7 +115,7 @@ protected function drawAttribution(Image $image): Image
119115
$margin = 5;
120116
$attribution = function (Image $image, $margin): array {
121117
return $image->writeTextAndGetBoundingBox(
122-
$this->getAttributionText(),
118+
$this->tileServer->getAttributionText(),
123119
__DIR__ . '/resources/font.ttf',
124120
10,
125121
'0078A8',

src/TileServer.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
namespace DantSu\OpenStreetMapStaticAPI;
4+
5+
/**
6+
* DantSu\OpenStreetMapStaticAPI\TileServer define tile server url and related configuration
7+
*
8+
* @package DantSu\OpenStreetMapStaticAPI
9+
* @author Stephan Strate <hello@stephan.codes>
10+
* @access public
11+
* @see https://github.com/DantSu/php-osm-static-api Github page of this project
12+
*/
13+
class TileServer
14+
{
15+
/**
16+
* @var string Tile server url, defaults to OpenStreetMap tile server
17+
*/
18+
private $url;
19+
20+
/**
21+
* @var string Tile server attribution according to license
22+
*/
23+
private $attributionText;
24+
25+
/**
26+
* @var string[] Tile server subdomains
27+
*/
28+
private $subdomains;
29+
30+
/**
31+
* TileServer constructor
32+
* @param string $url tile server url with placeholders (`x`, `y`, `z`, `r`, `s`)
33+
* @param string $attributionText tile server attribution text
34+
* @param string $subdomains tile server subdomains
35+
*/
36+
public function __construct(string $url, string $attributionText, string $subdomains = 'abc')
37+
{
38+
$this->url = $url;
39+
$this->attributionText = $attributionText;
40+
$this->subdomains = str_split($subdomains);
41+
}
42+
43+
/**
44+
* Get tile url for coordinates and zoom level
45+
* @param int $x x coordinate
46+
* @param int $y y coordinate
47+
* @param int $z zoom level
48+
* @return string tile url
49+
*/
50+
public function getTileUrl(int $x, int $y, int $z): string
51+
{
52+
$patterns = ['r', 's', 'x', 'y', 'z'];
53+
$replacements = ['', $this->getSubdomain($x, $y), $x, $y, $z];
54+
return preg_replace(array_map(function ($character) { return "/\\$?\{$character}/"; }, $patterns), $replacements, $this->url);
55+
}
56+
57+
/**
58+
* Select subdomain of tile server to prevent rate limiting on remote server
59+
* @param int $x x coordinate
60+
* @param int $y y coordinate
61+
* @return string selected subdomain
62+
* @see https://github.com/Leaflet/Leaflet/blob/main/src/layer/tile/TileLayer.js#L233 Leaflet implementation
63+
*/
64+
protected function getSubdomain(int $x, int $y): string
65+
{
66+
$index = abs($x + $y) % sizeof($this->subdomains);
67+
return $this->subdomains[$index];
68+
}
69+
70+
/**
71+
* Get attribution text
72+
* @return string Attribution text
73+
*/
74+
public function getAttributionText(): string
75+
{
76+
return $this->attributionText;
77+
}
78+
79+
/**
80+
* Default tile server. OpenStreetMaps with related attribution text
81+
* @return TileServer default tile server
82+
*/
83+
public static function defaultTileServer(): TileServer
84+
{
85+
return new TileServer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', '© OpenStreetMap contributors');
86+
}
87+
}

src/samples/resources/sample4.png

132 KB
Loading

src/samples/sample4.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
require_once '../../vendor/autoload.php';
3+
4+
require_once '../MapData.php';
5+
require_once '../LatLng.php';
6+
require_once '../Polygon.php';
7+
require_once '../Markers.php';
8+
require_once '../OpenStreetMap.php';
9+
require_once '../XY.php';
10+
11+
use \DantSu\OpenStreetMapStaticAPI\OpenStreetMap;
12+
use \DantSu\OpenStreetMapStaticAPI\LatLng;
13+
use \DantSu\OpenStreetMapStaticAPI\Polygon;
14+
use \DantSu\OpenStreetMapStaticAPI\Markers;
15+
use DantSu\OpenStreetMapStaticAPI\TileServer;
16+
17+
\header('Content-type: image/png');
18+
$tileServer = new TileServer('https://stamen-tiles-{s}.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}{r}.png',
19+
'Map tiles by Stamen Design, CC BY 3.0 - © OpenStreetMap contributors');
20+
(new OpenStreetMap(new LatLng(44.351933, 2.568113), 17, 600, 400, $tileServer))
21+
->addMarkers(
22+
(new Markers(__DIR__ . '/resources/marker.png'))
23+
->setAnchor(Markers::ANCHOR_CENTER, Markers::ANCHOR_BOTTOM)
24+
->addMarker(new LatLng(44.351933, 2.568113))
25+
->addMarker(new LatLng(44.351510, 2.570020))
26+
->addMarker(new LatLng(44.351873, 2.566250))
27+
)
28+
->addDraw(
29+
(new Polygon('FF0000', 2, 'FF0000DD'))
30+
->addPoint(new LatLng(44.351172, 2.571092))
31+
->addPoint(new LatLng(44.352097, 2.570045))
32+
->addPoint(new LatLng(44.352665, 2.568107))
33+
->addPoint(new LatLng(44.352887, 2.566503))
34+
->addPoint(new LatLng(44.352806, 2.565972))
35+
->addPoint(new LatLng(44.351517, 2.565672))
36+
)
37+
->getImage()
38+
->displayPNG();

0 commit comments

Comments
 (0)