From b783c595859ac1fccf134f9055d69785d3b32d93 Mon Sep 17 00:00:00 2001 From: eyeNsky Date: Thu, 2 Apr 2015 08:19:48 -0400 Subject: [PATCH 01/74] add jpgpng support for ArcGIS Desktop --- tileserver.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 55f7d27..31d762b 100644 --- a/tileserver.php +++ b/tileserver.php @@ -745,7 +745,11 @@ public function getCapabilities() { $profile = $m['profile']; $bounds = $m['bounds']; $format = $m['format']; - $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/png'; + if ($format == 'jpgpng'){ + $mime = 'image/jpgpng'; + } else { + $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/png'; + } if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; } else { From abb40879423deceddc48555005ee90d7f89f2b51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 1 Dec 2015 23:03:54 +0100 Subject: [PATCH 02/74] Cleaning of image format choser for wmts #58 --- tileserver.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54def2b..c8b01f5 100644 --- a/tileserver.php +++ b/tileserver.php @@ -764,11 +764,7 @@ public function getCapabilities() { $profile = $m['profile']; $bounds = $m['bounds']; $format = $m['format']; - if ($format == 'jpgpng'){ - $mime = 'image/jpgpng'; - } else { - $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/png'; - } + $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; } else { From c660ab8f41dd947bbaae58236e87ff4fac3124ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Fri, 4 Dec 2015 14:00:48 +0100 Subject: [PATCH 03/74] Hybrid tile format support #59 --- tileserver.php | 65 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/tileserver.php b/tileserver.php index c8b01f5..cd80cdf 100644 --- a/tileserver.php +++ b/tileserver.php @@ -20,10 +20,10 @@ '/:alpha/:number/:number/:number.:alpha.json' => 'Json:getUTFGrid', '/wmts' => 'Wmts:get', '/wmts/1.0.0/WMTSCapabilities.xml' => 'Wmts:get', - '/wmts/:alpha/:number/:number/:number.:alpha' => 'Wmts:getTile', - '/wmts/:alpha/:alpha/:number/:number/:number.:alpha' => 'Wmts:getTile', - '/wmts/:alpha/:alpha/:alpha/:number/:number/:number.:alpha' => 'Wmts:getTile', - '/:alpha/:number/:number/:number.:alpha' => 'Wmts:getTile', + '/wmts/:alpha/:number/:number/:alpha' => 'Wmts:getTile', + '/wmts/:alpha/:alpha/:number/:number/:alpha' => 'Wmts:getTile', + '/wmts/:alpha/:alpha/:alpha/:number/:number/:alpha' => 'Wmts:getTile', + '/:alpha/:number/:number/:alpha' => 'Wmts:getTile', '/tms' => 'Tms:getCapabilities', '/tms/:alpha' => 'Tms:getLayerCapabilities', )); @@ -92,13 +92,12 @@ public function setParams($params) { $this->layer = $params[1]; } $params = array_reverse($params); - if (isset($params[3])) { - $this->z = $params[3]; - $this->x = $params[2]; - $this->y = $params[1]; - } - if (isset($params[0])) { - $this->ext = $params[0]; + if (isset($params[2])) { + $this->z = $params[2]; + $this->x = $params[1]; + $file = explode('.', $params[0]); + $this->y = $file[0]; + $this->ext = isset($file[1]) ? $file[1] : NULL; } } @@ -331,10 +330,21 @@ public function renderTile($tileset, $z, $y, $x, $ext) { echo $data; } } elseif ($this->isFileLayer($tileset)) { - $name = './' . $tileset . '/' . $z . '/' . $x . '/' . $y . '.' . $ext; + $name = './' . $tileset . '/' . $z . '/' . $x . '/' . $y; + $mime = 'image/'; + if($ext != NULL){ + $name .= '.' . $ext; + } if ($fp = @fopen($name, 'rb')) { + if($ext != NULL){ + $mime .= $ext; + }else{ + //detect image type from file + $mimetypes = ['gif', 'jpeg', 'png']; + $mime .= $mimetypes[exif_imagetype($name) - 1]; + } header('Access-Control-Allow-Origin: *'); - header('Content-Type: image/' . $ext); + header('Content-Type: ' . $mime); header('Content-Length: ' . filesize($name)); fpassthru($fp); die; @@ -350,8 +360,8 @@ public function renderTile($tileset, $z, $y, $x, $ext) { echo '{"message":"Tile does not exist"}'; die; } - $this->getCleanTile($meta->scale); } + $this->getCleanTile($meta->scale); } else { header('HTTP/1.1 404 Not Found'); echo 'Server: Unknown or not specified dataset "'.$tileset.'"'; @@ -552,7 +562,12 @@ public function metadataTileJson($metadata) { $metadata['scheme'] = 'xyz'; $tiles = array(); foreach ($this->config['baseUrls'] as $url) { - $tiles[] = '' . $this->config['protocol'] . '://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}.' . $metadata['format']; + $url = '' . $this->config['protocol'] . '://' . $url . '/' . + $metadata['basename'] . '/{z}/{x}/{y}'; + if(strlen($metadata['format']) <= 4){ + $url .= '.' . $metadata['format']; + } + $tiles[] = $url; } $metadata['tiles'] = $tiles; if ($this->isDBLayer($metadata['basename'])) { @@ -763,7 +778,7 @@ public function getCapabilities() { $title = (array_key_exists('name', $m)) ? $m['name'] : $basename; $profile = $m['profile']; $bounds = $m['bounds']; - $format = $m['format']; + $format = $m['format'] == 'hybrid' ? 'jpgpng' : $m['format']; $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; @@ -773,6 +788,11 @@ public function getCapabilities() { list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); } + $resourceUrlTemplate = $this->config['protocol'] . '://' + . $this->config['baseUrls'][0] . '/wmts/' . $basename . '/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}'; + if(strlen($format) <= 4){ + $resourceUrlTemplate .= '.' . $format; + } echo' ' . $title . ' @@ -788,8 +808,7 @@ public function getCapabilities() { ' . $tileMatrixSet . ' - + '; } echo ' @@ -1160,7 +1179,13 @@ public function getTile() { } else { $format = $this->getGlobal('Format'); } - parent::renderTile($this->getGlobal('Layer'), $this->getGlobal('TileMatrix'), $this->getGlobal('TileRow'), $this->getGlobal('TileCol'), $format); + parent::renderTile( + $this->getGlobal('Layer'), + $this->getGlobal('TileMatrix'), + $this->getGlobal('TileRow'), + $this->getGlobal('TileCol'), + $format + ); } else { parent::renderTile($this->layer, $this->z, $this->y, $this->x, $this->ext); } @@ -1446,7 +1471,7 @@ public static function serve($routes) { $tokens = array( ':string' => '([a-zA-Z]+)', ':number' => '([0-9]+)', - ':alpha' => '([a-zA-Z0-9-_@]+)' + ':alpha' => '([a-zA-Z0-9-_@.]+)' ); //global $config; foreach ($routes as $pattern => $handler_name) { From 3343f80e09d631a6e7064565eeb3833a332de573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 15 Dec 2015 16:27:28 +0100 Subject: [PATCH 04/74] 404 with JSON message for not found tile #56 --- tileserver.php | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/tileserver.php b/tileserver.php index cd80cdf..3fb3ddd 100644 --- a/tileserver.php +++ b/tileserver.php @@ -308,11 +308,12 @@ public function renderTile($tileset, $z, $y, $x, $ext) { $result = $this->db->query('select tile_data as t from tiles where zoom_level=' . $z . ' and tile_column=' . $x . ' and tile_row=' . $y); $data = $result->fetchColumn(); if (!isset($data) || $data === FALSE) { - //scale of tile (for retina tiles) + //if tile doesn't exist + //select scale of tile (for retina tiles) $result = $this->db->query('select value from metadata where name="scale"'); $resultdata = $result->fetchColumn(); $scale = isset($resultdata) && $resultdata !== FALSE ? $resultdata : 1; - $this->getCleanTile($scale); + $this->getCleanTile($scale, $ext); } else { $result = $this->db->query('select value from metadata where name="format"'); $resultdata = $result->fetchColumn(); @@ -354,14 +355,8 @@ public function renderTile($tileset, $z, $y, $x, $ext) { if(!isset($meta->scale)){ $meta->scale = 1; } - if ($ext == 'pbf') { - header('HTTP/1.1 404 Not Found'); - header('Content-Type: application/json; charset=utf-8'); - echo '{"message":"Tile does not exist"}'; - die; - } } - $this->getCleanTile($meta->scale); + $this->getCleanTile($meta->scale, $ext); } else { header('HTTP/1.1 404 Not Found'); echo 'Server: Unknown or not specified dataset "'.$tileset.'"'; @@ -373,16 +368,25 @@ public function renderTile($tileset, $z, $y, $x, $ext) { * Returns clean tile * @param integer $scale Default 1 */ - public function getCleanTile($scale = 1) { - $tileSize = 256 * $scale; - $png = imagecreatetruecolor($tileSize, $tileSize); - imagesavealpha($png, true); - $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127); - imagefill($png, 0, 0, $trans_colour); - header('Access-Control-Allow-Origin: *'); - header('Content-type: image/png'); - imagepng($png); - die; + public function getCleanTile($scale = 1, $format = 'png') { + switch ($format) { + case 'pbf': + header('HTTP/1.1 404 Not Found'); + header('Content-Type: application/json; charset=utf-8'); + echo '{"message":"Tile does not exist"}'; + die; + case 'png': + default: + $tileSize = 256 * $scale; + $png = imagecreatetruecolor($tileSize, $tileSize); + imagesavealpha($png, true); + $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127); + imagefill($png, 0, 0, $trans_colour); + header('Access-Control-Allow-Origin: *'); + header('Content-type: image/png'); + imagepng($png); + die; + } } /** From 79926b92fc003ef5d5282ae444d9c624b81691e6 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Wed, 16 Dec 2015 17:07:04 +0100 Subject: [PATCH 05/74] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 37923f1..0f93cf3 100644 --- a/README.md +++ b/README.md @@ -38,9 +38,9 @@ Requirements: ------------- - Apache webserver (with mod_rewrite / .htaccess supported) -- PHP 5.2+ +- PHP 5.2+ with SQLite module (php5-sqlite) -(or anther webserver implementing mod_rewrite rules and PHP) +(or another webserver implementing mod_rewrite rules and PHP) Installation: ------------- From 8f6a2ced68af2f85a4fb7882d3b9fe78c618fd75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 25 Jan 2016 18:13:15 +0100 Subject: [PATCH 06/74] Fix of utfgid detection --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 3fb3ddd..1fcd49e 100644 --- a/tileserver.php +++ b/tileserver.php @@ -576,7 +576,7 @@ public function metadataTileJson($metadata) { $metadata['tiles'] = $tiles; if ($this->isDBLayer($metadata['basename'])) { $this->DBconnect($metadata['basename'] . '.mbtiles'); - $res = $this->db->query('SELECT name FROM sqlite_master WHERE name="grids";'); + $res = $this->db->query('SELECT * FROM grids LIMIT 1;'); if ($res) { foreach ($this->config['baseUrls'] as $url) { $grids[] = '' . $this->config['protocol'] . '://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}.grid.json'; From 28aba6f9e20188c0e79a6ca3639adc3397cc6d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 25 Jan 2016 18:32:07 +0100 Subject: [PATCH 07/74] Fix of utfgrid serving bug related with changes in #59 --- tileserver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index 1fcd49e..03bdb93 100644 --- a/tileserver.php +++ b/tileserver.php @@ -15,9 +15,9 @@ '/' => 'Server:getHtml', '/test' => 'Server:getInfo', '/html' => 'Server:getHtml', + '/:alpha/:number/:number/:number.:alpha.json' => 'Json:getUTFGrid', '/:alpha.json' => 'Json:getJson', '/:alpha.jsonp' => 'Json:getJsonp', - '/:alpha/:number/:number/:number.:alpha.json' => 'Json:getUTFGrid', '/wmts' => 'Wmts:get', '/wmts/1.0.0/WMTSCapabilities.xml' => 'Wmts:get', '/wmts/:alpha/:number/:number/:alpha' => 'Wmts:getTile', @@ -1475,7 +1475,7 @@ public static function serve($routes) { $tokens = array( ':string' => '([a-zA-Z]+)', ':number' => '([0-9]+)', - ':alpha' => '([a-zA-Z0-9-_@.]+)' + ':alpha' => '([a-zA-Z0-9-_@\.]+)' ); //global $config; foreach ($routes as $pattern => $handler_name) { From dc26c831f1d0a6292e894146518e718a0fcb0370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 26 Jan 2016 13:51:39 +0100 Subject: [PATCH 08/74] Url for viewer switched to cdn. --- tileserver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index 03bdb93..ccff6c9 100644 --- a/tileserver.php +++ b/tileserver.php @@ -484,8 +484,8 @@ public function getHtml() { $maps = array_merge($this->fileLayer, $this->dbLayer); header('Content-Type: text/html;charset=UTF-8'); echo '' . $this->config['serverTitle'] . ''; - echo ' - + echo ' +

Welcome to ' . $this->config['serverTitle'] . '

This server distributes maps to desktop, web, and mobile applications.

From f5408fd10893c2e677c48e7a4af3a47d21a35e4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 26 Jan 2016 22:31:12 +0100 Subject: [PATCH 09/74] Utfgrid routing bug fixed --- tileserver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index ccff6c9..5749bf0 100644 --- a/tileserver.php +++ b/tileserver.php @@ -15,7 +15,7 @@ '/' => 'Server:getHtml', '/test' => 'Server:getInfo', '/html' => 'Server:getHtml', - '/:alpha/:number/:number/:number.:alpha.json' => 'Json:getUTFGrid', + '/:alpha/:number/:number/:number.grid.json' => 'Json:getUTFGrid', '/:alpha.json' => 'Json:getJson', '/:alpha.jsonp' => 'Json:getJsonp', '/wmts' => 'Wmts:get', @@ -433,7 +433,7 @@ public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { header("Content-Type:text/javascript; charset=utf-8"); echo $grid; } - } + } } catch (PDOException $e) { header('Content-type: text/plain'); print 'Error querying the database: ' . $e->getMessage(); From 6b5933e21f0e97d508440f9d9c8a34607af8fd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 26 Jan 2016 22:55:34 +0100 Subject: [PATCH 10/74] Utfgrid empty response bug fixed (related #62) --- tileserver.php | 90 +++++++++++++++++++++++++++----------------------- 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/tileserver.php b/tileserver.php index 5749bf0..fcaada1 100644 --- a/tileserver.php +++ b/tileserver.php @@ -35,25 +35,25 @@ class Server { /** * Configuration of TileServer [baseUrls, serverTitle] - * @var array + * @var array */ public $config; /** * Datasets stored in file structure - * @var array + * @var array */ public $fileLayer = array(); /** * Datasets stored in database - * @var array + * @var array */ public $dbLayer = array(); /** * PDO database connection - * @var object + * @var object */ public $db; @@ -143,7 +143,7 @@ public function isFileLayer($layer) { } /** - * + * * @param string $jsonFileName * @return array */ @@ -166,7 +166,7 @@ public function metadataFromMbtiles($mbt) { $resultdata = $result->fetchAll(); foreach ($resultdata as $r) { - $value = preg_replace('/(\\n)+/','',$r['value']); + $value = preg_replace('/(\\n)+/','',$r['value']); $metadata[$r['name']] = addslashes($value); } if (!array_key_exists('minzoom', $metadata) @@ -203,7 +203,7 @@ public function metadataFromMbtiles($mbt) { $metadata['basename'] = $mbt[0]; return $metadata; } - + /** * Convert row number to latitude of the top of the row * @param integer $r @@ -406,20 +406,22 @@ public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { } try { $this->DBconnect($tileset . '.mbtiles'); - $result = $this->db->query('SELECT grid FROM grids WHERE tile_column = ' . $x . ' AND tile_row = ' . $y . ' AND zoom_level = ' . $z); - if (!isset($result) || $result === FALSE) { - header('Access-Control-Allow-Origin: *'); - echo '{}'; - die; - } else { - $data = $result->fetchColumn(); - $grid = gzuncompress($data); + $query = 'SELECT grid FROM grids WHERE tile_column = ' . $x . ' AND ' + . 'tile_row = ' . $y . ' AND zoom_level = ' . $z; + $result = $this->db->query($query); + $data = $result->fetch(PDO::FETCH_ASSOC); + + if ($data !== FALSE) { + $grid = gzuncompress($data['grid']); $grid = substr(trim($grid), 0, -1); //adds legend (data) to output $grid .= ',"data":{'; - $result = $this->db->query('SELECT key_name as key, key_json as json FROM grid_data WHERE zoom_level=' . $z . ' and tile_column=' . $x . ' and tile_row=' . $y); + $kquery = 'SELECT key_name as key, key_json as json FROM grid_data ' + . 'WHERE zoom_level=' . $z . ' and ' + . 'tile_column=' . $x . ' and tile_row=' . $y; + $result = $this->db->query($kquery); while ($r = $result->fetch(PDO::FETCH_ASSOC)) { $grid .= '"' . $r['key'] . '":' . $r['json'] . ','; } @@ -427,14 +429,18 @@ public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { header('Access-Control-Allow-Origin: *'); if (isset($_GET['callback']) && !empty($_GET['callback'])) { - header("Content-Type:text/javascript charset=utf-8"); + header('Content-Type:text/javascript charset=utf-8'); echo $_GET['callback'] . '(' . $grid . ');'; } else { - header("Content-Type:text/javascript; charset=utf-8"); + header('Content-Type:text/javascript; charset=utf-8'); echo $grid; } - } - } catch (PDOException $e) { + } else { + header('Access-Control-Allow-Origin: *'); + echo '{}'; + die; + } + } catch (Exception $e) { header('Content-type: text/plain'); print 'Error querying the database: ' . $e->getMessage(); } @@ -515,7 +521,7 @@ class Json extends Server { /** * Callback for JSONP default grid - * @var string + * @var string */ private $callback = 'grid'; @@ -525,27 +531,27 @@ class Json extends Server { public $layer = 'index'; /** - * @var integer + * @var integer */ public $z; /** - * @var integer + * @var integer */ public $y; /** - * @var integer + * @var integer */ public $x; /** - * @var string + * @var string */ public $ext; /** - * + * * @param array $params */ public function __construct($params) { @@ -566,7 +572,7 @@ public function metadataTileJson($metadata) { $metadata['scheme'] = 'xyz'; $tiles = array(); foreach ($this->config['baseUrls'] as $url) { - $url = '' . $this->config['protocol'] . '://' . $url . '/' . + $url = '' . $this->config['protocol'] . '://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}'; if(strlen($metadata['format']) <= 4){ $url .= '.' . $metadata['format']; @@ -670,27 +676,27 @@ class Wmts extends Server { public $layer; /** - * @var integer + * @var integer */ public $z; /** - * @var integer + * @var integer */ public $y; /** - * @var integer + * @var integer */ public $x; /** - * @var string + * @var string */ public $ext; /** - * + * * @param array $params */ public function __construct($params) { @@ -714,7 +720,7 @@ public function get() { } /** - * Returns tilesets getCapabilities + * Returns tilesets getCapabilities */ public function getCapabilities() { header("Content-type: application/xml"); @@ -1184,10 +1190,10 @@ public function getTile() { $format = $this->getGlobal('Format'); } parent::renderTile( - $this->getGlobal('Layer'), - $this->getGlobal('TileMatrix'), - $this->getGlobal('TileRow'), - $this->getGlobal('TileCol'), + $this->getGlobal('Layer'), + $this->getGlobal('TileMatrix'), + $this->getGlobal('TileRow'), + $this->getGlobal('TileCol'), $format ); } else { @@ -1208,27 +1214,27 @@ class Tms extends Server { public $layer; /** - * @var integer + * @var integer */ public $z; /** - * @var integer + * @var integer */ public $y; /** - * @var integer + * @var integer */ public $x; /** - * @var string + * @var string */ public $ext; /** - * + * * @param array $params */ public function __construct($params) { From 250512168c178ce3ae1d0e01505119ced80f01b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 1 Feb 2016 20:51:03 +0100 Subject: [PATCH 11/74] Fix of syntax error on PHP 5.2 (closes #63) --- tileserver.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index fcaada1..54103aa 100644 --- a/tileserver.php +++ b/tileserver.php @@ -9,7 +9,7 @@ global $config; $config['serverTitle'] = 'TileServer-php v1'; -//$config['baseUrls'] = ['t0.server.com', 't1.server.com']; +//$config['baseUrls'] = array('t0.server.com', 't1.server.com'); Router::serve(array( '/' => 'Server:getHtml', @@ -341,7 +341,7 @@ public function renderTile($tileset, $z, $y, $x, $ext) { $mime .= $ext; }else{ //detect image type from file - $mimetypes = ['gif', 'jpeg', 'png']; + $mimetypes = array('gif', 'jpeg', 'png'); $mime .= $mimetypes[exif_imagetype($name) - 1]; } header('Access-Control-Allow-Origin: *'); @@ -1307,7 +1307,7 @@ public function getLayerCapabilities() { '; for ($zoom = $m['minzoom']; $zoom < $m['maxzoom'] + 1; $zoom++) { - echo ''; + echo ''; } echo''; } From b7960baaaa9b2d2ed2cd4998976c380fcfde6367 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 2 Feb 2016 10:57:57 +0100 Subject: [PATCH 12/74] Travis status icon --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0f93cf3..672d636 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ TileServer PHP: MapTiler and MBTiles maps via WMTS ================================================== +[![Build Status](https://travis-ci.org/klokantech/tileserver-php.svg?branch=travis)](https://travis-ci.org/klokantech/tileserver-php) + This server distributes maps to desktop, web, and mobile applications from a standard Apache+PHP web hosting. From 5b5f5e7905dcde9c9f9718f75abbf71c7a6bb014 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Tue, 2 Feb 2016 15:21:02 +0100 Subject: [PATCH 13/74] Add .travis.yml to master --- .travis.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..89e1027 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: php +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm +script: + - php tileserver.php From 853ca41ce032a80c765821c6f3ce62c1f761680a Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Tue, 2 Feb 2016 15:26:11 +0100 Subject: [PATCH 14/74] Update travis badge + add docker hub badge --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 672d636..c6a986c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ TileServer PHP: MapTiler and MBTiles maps via WMTS ================================================== -[![Build Status](https://travis-ci.org/klokantech/tileserver-php.svg?branch=travis)](https://travis-ci.org/klokantech/tileserver-php) +[![Build Status](https://travis-ci.org/klokantech/tileserver-php.svg)](https://travis-ci.org/klokantech/tileserver-php) +[![Docker Hub](https://img.shields.io/badge/docker-hub-blue.svg)](https://hub.docker.com/r/klokantech/tileserver-php/) This server distributes maps to desktop, web, and mobile applications from a standard Apache+PHP web hosting. From 0446445248775f24d45db9ef746a35dd26acdaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 3 Feb 2016 15:13:56 +0100 Subject: [PATCH 15/74] Generate tilematrix sets from variables --- tileserver.php | 425 +++++++++---------------------------------------- 1 file changed, 73 insertions(+), 352 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54103aa..323d540 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,6 +718,59 @@ public function get() { $this->getCapabilities(); } } + + /** + * Default TileMetrixSet for Pseudo Mercator projection 3857 + * @return string TileMatrixSet xml + */ + public function getMercatorTileMatrixSet(){ + $name = 'GoogleMapsCompatible'; + $corner = array(-20037508.34278925, 20037508.34278925); + $scalesBase = 559082264.0287178; + $scales = array(); + + for($i = 0; $i <= 18; $i++){ + $scales[] = $scalesBase / pow(2, $i); + } + + return $this->getTileMatrixSet($name, $scales, $corner); + } + + /** + * Prints WMTS tilematrixset + * @param string $name + * @param array $scales Array of scales + * @param array $corner Position of TopLeft corner of matrix + * @param string $crs Code of crs eg: EPSG:3857 + * @param array $matrixRatio Ratio of matrix sides + * @param array $tilesize Size of tile in pixels + * @return string TileMatrixSet xml + */ + public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + $srs = explode(':', $crs); + $TileMatrixSet = ' + ' . $name . ' + ' . $name . ' '. $crs .' + ' . $name . ' + urn:ogc:def:crs:'.$srs[0].'::'.$srs[1].''; + // $TileMatrixSet .= 'urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible'; + for($i = 0; $i <= sizeof($scales); $i++){ + $matrixWidth = pow(2, $i); + $TileMatrixSet .= ' + + ' . $i . ' + ' . $scales[$i] . ' + '. $corner[0] . ' ' . $corner[1] .' + ' . $tilesize[0] . ' + ' . $tilesize[1] . ' + ' . $matrixWidth * $matrixRatio[0] . ' + ' . $matrixWidth * $matrixRatio[1] . ' + '; + } + $TileMatrixSet .= ''; + + return $TileMatrixSet; + } /** * Returns tilesets getCapabilities @@ -821,358 +874,26 @@ public function getCapabilities() { '; } - echo ' - - GoogleMapsCompatible - the wellknown \'GoogleMapsCompatible\' tile matrix set defined by OGC WMTS specification - GoogleMapsCompatible - urn:ogc:def:crs:EPSG:6.18:3:3857 - urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible - - 0 - 559082264.0287178 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1 - 1 - - - 1 - 279541132.0143589 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2 - 2 - - - 2 - 139770566.0071794 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4 - 4 - - - 3 - 69885283.00358972 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8 - 8 - - - 4 - 34942641.50179486 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16 - 16 - - - 5 - 17471320.75089743 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32 - 32 - - - 6 - 8735660.375448715 - -20037508.34278925 20037508.34278925 - 256 - 256 - 64 - 64 - - - 7 - 4367830.187724357 - -20037508.34278925 20037508.34278925 - 256 - 256 - 128 - 128 - - - 8 - 2183915.093862179 - -20037508.34278925 20037508.34278925 - 256 - 256 - 256 - 256 - - - 9 - 1091957.546931089 - -20037508.34278925 20037508.34278925 - 256 - 256 - 512 - 512 - - - 10 - 545978.7734655447 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1024 - 1024 - - - 11 - 272989.3867327723 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2048 - 2048 - - - 12 - 136494.6933663862 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4096 - 4096 - - - 13 - 68247.34668319309 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8192 - 8192 - - - 14 - 34123.67334159654 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16384 - 16384 - - - 15 - 17061.83667079827 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32768 - 32768 - - - 16 - 8530.918335399136 - -20037508.34278925 20037508.34278925 - 256 - 256 - 65536 - 65536 - - - 17 - 4265.459167699568 - -20037508.34278925 20037508.34278925 - 256 - 256 - 131072 - 131072 - - - 18 - 2132.729583849784 - -20037508.34278925 20037508.34278925 - 256 - 256 - 262144 - 262144 - - - - WGS84 - GoogleCRS84Quad - urn:ogc:def:crs:EPSG:6.3:4326 - - -180.000000 -90.000000 - 180.000000 90.000000 - - urn:ogc:def:wkss:OGC:1.0:GoogleCRS84Quad - - 0 - 279541132.01435887813568115234 - 90.000000 -180.000000 - 256 - 256 - 2 - 1 - - - 1 - 139770566.00717943906784057617 - 90.000000 -180.000000 - 256 - 256 - 4 - 2 - - - 2 - 69885283.00358971953392028809 - 90.000000 -180.000000 - 256 - 256 - 8 - 4 - - - 3 - 34942641.50179485976696014404 - 90.000000 -180.000000 - 256 - 256 - 16 - 8 - - - 4 - 17471320.75089742988348007202 - 90.000000 -180.000000 - 256 - 256 - 32 - 16 - - - 5 - 8735660.37544871494174003601 - 90.000000 -180.000000 - 256 - 256 - 64 - 32 - - - 6 - 4367830.18772435747087001801 - 90.000000 -180.000000 - 256 - 256 - 128 - 64 - - - 7 - 2183915.09386217873543500900 - 90.000000 -180.000000 - 256 - 256 - 256 - 128 - - - 8 - 1091957.54693108936771750450 - 90.000000 -180.000000 - 256 - 256 - 512 - 256 - - - 9 - 545978.77346554468385875225 - 90.000000 -180.000000 - 256 - 256 - 1024 - 512 - - - 10 - 272989.38673277234192937613 - 90.000000 -180.000000 - 256 - 256 - 2048 - 1024 - - - 11 - 136494.69336638617096468806 - 90.000000 -180.000000 - 256 - 256 - 4096 - 2048 - - - 12 - 68247.34668319308548234403 - 90.000000 -180.000000 - 256 - 256 - 8192 - 4096 - - - 13 - 34123.67334159654274117202 - 90.000000 -180.000000 - 256 - 256 - 16384 - 8192 - - - 14 - 17061.83667079825318069197 - 90.000000 -180.000000 - 256 - 256 - 32768 - 16384 - - - 15 - 8530.91833539912659034599 - 90.000000 -180.000000 - 256 - 256 - 65536 - 32768 - - - 16 - 4265.45916769956329517299 - 90.000000 -180.000000 - 256 - 256 - 131072 - 65536 - - - 17 - 2132.72958384978574031265 - 90.000000 -180.000000 - 256 - 256 - 262144 - 131072 - - - + + //Print mercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + + //Print wgs84 TileMatrixSet + $name = 'WGS84'; + $corner = array(-180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($name, $scales, $corner, $crs, $matrixRatio); + + echo ' '; } From 3a9e74e3b07bc1341dc0729729ce41305a9e3da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 3 Feb 2016 15:13:56 +0100 Subject: [PATCH 16/74] Generate tilematrix sets from variables --- tileserver.php | 425 +++++++++---------------------------------------- 1 file changed, 73 insertions(+), 352 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54103aa..323d540 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,6 +718,59 @@ public function get() { $this->getCapabilities(); } } + + /** + * Default TileMetrixSet for Pseudo Mercator projection 3857 + * @return string TileMatrixSet xml + */ + public function getMercatorTileMatrixSet(){ + $name = 'GoogleMapsCompatible'; + $corner = array(-20037508.34278925, 20037508.34278925); + $scalesBase = 559082264.0287178; + $scales = array(); + + for($i = 0; $i <= 18; $i++){ + $scales[] = $scalesBase / pow(2, $i); + } + + return $this->getTileMatrixSet($name, $scales, $corner); + } + + /** + * Prints WMTS tilematrixset + * @param string $name + * @param array $scales Array of scales + * @param array $corner Position of TopLeft corner of matrix + * @param string $crs Code of crs eg: EPSG:3857 + * @param array $matrixRatio Ratio of matrix sides + * @param array $tilesize Size of tile in pixels + * @return string TileMatrixSet xml + */ + public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + $srs = explode(':', $crs); + $TileMatrixSet = ' + ' . $name . ' + ' . $name . ' '. $crs .' + ' . $name . ' + urn:ogc:def:crs:'.$srs[0].'::'.$srs[1].''; + // $TileMatrixSet .= 'urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible'; + for($i = 0; $i <= sizeof($scales); $i++){ + $matrixWidth = pow(2, $i); + $TileMatrixSet .= ' + + ' . $i . ' + ' . $scales[$i] . ' + '. $corner[0] . ' ' . $corner[1] .' + ' . $tilesize[0] . ' + ' . $tilesize[1] . ' + ' . $matrixWidth * $matrixRatio[0] . ' + ' . $matrixWidth * $matrixRatio[1] . ' + '; + } + $TileMatrixSet .= ''; + + return $TileMatrixSet; + } /** * Returns tilesets getCapabilities @@ -821,358 +874,26 @@ public function getCapabilities() { '; } - echo ' - - GoogleMapsCompatible - the wellknown \'GoogleMapsCompatible\' tile matrix set defined by OGC WMTS specification - GoogleMapsCompatible - urn:ogc:def:crs:EPSG:6.18:3:3857 - urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible - - 0 - 559082264.0287178 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1 - 1 - - - 1 - 279541132.0143589 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2 - 2 - - - 2 - 139770566.0071794 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4 - 4 - - - 3 - 69885283.00358972 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8 - 8 - - - 4 - 34942641.50179486 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16 - 16 - - - 5 - 17471320.75089743 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32 - 32 - - - 6 - 8735660.375448715 - -20037508.34278925 20037508.34278925 - 256 - 256 - 64 - 64 - - - 7 - 4367830.187724357 - -20037508.34278925 20037508.34278925 - 256 - 256 - 128 - 128 - - - 8 - 2183915.093862179 - -20037508.34278925 20037508.34278925 - 256 - 256 - 256 - 256 - - - 9 - 1091957.546931089 - -20037508.34278925 20037508.34278925 - 256 - 256 - 512 - 512 - - - 10 - 545978.7734655447 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1024 - 1024 - - - 11 - 272989.3867327723 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2048 - 2048 - - - 12 - 136494.6933663862 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4096 - 4096 - - - 13 - 68247.34668319309 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8192 - 8192 - - - 14 - 34123.67334159654 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16384 - 16384 - - - 15 - 17061.83667079827 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32768 - 32768 - - - 16 - 8530.918335399136 - -20037508.34278925 20037508.34278925 - 256 - 256 - 65536 - 65536 - - - 17 - 4265.459167699568 - -20037508.34278925 20037508.34278925 - 256 - 256 - 131072 - 131072 - - - 18 - 2132.729583849784 - -20037508.34278925 20037508.34278925 - 256 - 256 - 262144 - 262144 - - - - WGS84 - GoogleCRS84Quad - urn:ogc:def:crs:EPSG:6.3:4326 - - -180.000000 -90.000000 - 180.000000 90.000000 - - urn:ogc:def:wkss:OGC:1.0:GoogleCRS84Quad - - 0 - 279541132.01435887813568115234 - 90.000000 -180.000000 - 256 - 256 - 2 - 1 - - - 1 - 139770566.00717943906784057617 - 90.000000 -180.000000 - 256 - 256 - 4 - 2 - - - 2 - 69885283.00358971953392028809 - 90.000000 -180.000000 - 256 - 256 - 8 - 4 - - - 3 - 34942641.50179485976696014404 - 90.000000 -180.000000 - 256 - 256 - 16 - 8 - - - 4 - 17471320.75089742988348007202 - 90.000000 -180.000000 - 256 - 256 - 32 - 16 - - - 5 - 8735660.37544871494174003601 - 90.000000 -180.000000 - 256 - 256 - 64 - 32 - - - 6 - 4367830.18772435747087001801 - 90.000000 -180.000000 - 256 - 256 - 128 - 64 - - - 7 - 2183915.09386217873543500900 - 90.000000 -180.000000 - 256 - 256 - 256 - 128 - - - 8 - 1091957.54693108936771750450 - 90.000000 -180.000000 - 256 - 256 - 512 - 256 - - - 9 - 545978.77346554468385875225 - 90.000000 -180.000000 - 256 - 256 - 1024 - 512 - - - 10 - 272989.38673277234192937613 - 90.000000 -180.000000 - 256 - 256 - 2048 - 1024 - - - 11 - 136494.69336638617096468806 - 90.000000 -180.000000 - 256 - 256 - 4096 - 2048 - - - 12 - 68247.34668319308548234403 - 90.000000 -180.000000 - 256 - 256 - 8192 - 4096 - - - 13 - 34123.67334159654274117202 - 90.000000 -180.000000 - 256 - 256 - 16384 - 8192 - - - 14 - 17061.83667079825318069197 - 90.000000 -180.000000 - 256 - 256 - 32768 - 16384 - - - 15 - 8530.91833539912659034599 - 90.000000 -180.000000 - 256 - 256 - 65536 - 32768 - - - 16 - 4265.45916769956329517299 - 90.000000 -180.000000 - 256 - 256 - 131072 - 65536 - - - 17 - 2132.72958384978574031265 - 90.000000 -180.000000 - 256 - 256 - 262144 - 131072 - - - + + //Print mercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + + //Print wgs84 TileMatrixSet + $name = 'WGS84'; + $corner = array(-180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($name, $scales, $corner, $crs, $matrixRatio); + + echo ' '; } From ea100ad8c2f45d7a01eb3799d6e5cb1d801afdb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 3 Feb 2016 16:50:07 +0100 Subject: [PATCH 17/74] Custom profile testing implemetation --- tileserver.php | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/tileserver.php b/tileserver.php index 323d540..98185d4 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,7 +718,7 @@ public function get() { $this->getCapabilities(); } } - + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml @@ -728,14 +728,14 @@ public function getMercatorTileMatrixSet(){ $corner = array(-20037508.34278925, 20037508.34278925); $scalesBase = 559082264.0287178; $scales = array(); - + for($i = 0; $i <= 18; $i++){ $scales[] = $scalesBase / pow(2, $i); } return $this->getTileMatrixSet($name, $scales, $corner); } - + /** * Prints WMTS tilematrixset * @param string $name @@ -768,7 +768,7 @@ public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $m '; } $TileMatrixSet .= ''; - + return $TileMatrixSet; } @@ -830,6 +830,10 @@ public function getCapabilities() { '; + //TileMatrixSets that will be printed: + $tileMatrixSets = array('GoogleMapsCompatible' => FALSE, 'custom' => FALSE, 'geodetic' => FALSE); + + //layers $maps = array_merge($this->fileLayer, $this->dbLayer); $mercator = new GlobalMercator(); foreach ($maps as $m) { @@ -843,10 +847,18 @@ public function getCapabilities() { $bounds = $m['bounds']; $format = $m['format'] == 'hybrid' ? 'jpgpng' : $m['format']; $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; + if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; + $tileMatrixSets['geodetic'] = TRUE; + }elseif ($m['profile'] == 'custom') { + $crs = explode(':', $m['crs']); + $tileMatrixSet = 'custom' . $crs[1]; + $tileMatrixSets['custom'] = TRUE; } else { $tileMatrixSet = "GoogleMapsCompatible"; + $tileMatrixSets['GoogleMapsCompatible'] = TRUE; + list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); @@ -874,24 +886,30 @@ public function getCapabilities() { '; } - - //Print mercator TileMatrixSet - echo $this->getMercatorTileMatrixSet(); - - //Print wgs84 TileMatrixSet - $name = 'WGS84'; - $corner = array(-180.000000, 90.000000); - $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + + if ($tileMatrixSets['geodetic']) { + //Print wgs84 TileMatrixSet + $corner = array(-180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, - 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, 2132.72958384978574031265); - $crs = 'EPSG::4326'; - $matrixRatio = array(2, 1); - - echo $this->getTileMatrixSet($name, $scales, $corner, $crs, $matrixRatio); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($tileMatrixSet, $scales, $corner, $crs, $matrixRatio); + } + if ($tileMatrixSets['custom']) { + // Custom from metadata + echo $this->getTileMatrixSet($tileMatrixSet, $m['scales'], array($m['projected_bounds'][0], $m['projected_bounds'][4]), $m['crs']); + } + if($tileMatrixSets['GoogleMapsCompatible']){ + //Print mercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + } echo ' From 8b49aa2b8c2ed0265a51098e0820db6daa77cdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 9 Feb 2016 14:36:24 +0100 Subject: [PATCH 18/74] Custom matrix sets generation refactring --- tileserver.php | 67 +++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/tileserver.php b/tileserver.php index 98185d4..b55d1d3 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,14 +718,14 @@ public function get() { $this->getCapabilities(); } } - + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml */ public function getMercatorTileMatrixSet(){ $name = 'GoogleMapsCompatible'; - $corner = array(-20037508.34278925, 20037508.34278925); + $extent = array(-20037508.34,-20037508.34,20037508.34,20037508.34); $scalesBase = 559082264.0287178; $scales = array(); @@ -733,20 +733,20 @@ public function getMercatorTileMatrixSet(){ $scales[] = $scalesBase / pow(2, $i); } - return $this->getTileMatrixSet($name, $scales, $corner); + return $this->getTileMatrixSet($name, $scales, $extent); } /** * Prints WMTS tilematrixset * @param string $name * @param array $scales Array of scales - * @param array $corner Position of TopLeft corner of matrix + * @param array $extent Boundingbox of matrix * @param string $crs Code of crs eg: EPSG:3857 * @param array $matrixRatio Ratio of matrix sides * @param array $tilesize Size of tile in pixels * @return string TileMatrixSet xml */ - public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + public function getTileMatrixSet($name, $scales, $extent, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ $srs = explode(':', $crs); $TileMatrixSet = ' ' . $name . ' @@ -760,7 +760,7 @@ public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $m ' . $i . ' ' . $scales[$i] . ' - '. $corner[0] . ' ' . $corner[1] .' + '. $extent[0] . ' ' . $extent[3] .' ' . $tilesize[0] . ' ' . $tilesize[1] . ' ' . $matrixWidth * $matrixRatio[0] . ' @@ -830,8 +830,8 @@ public function getCapabilities() { '; - //TileMatrixSets that will be printed: - $tileMatrixSets = array('GoogleMapsCompatible' => FALSE, 'custom' => FALSE, 'geodetic' => FALSE); + + $customtileMatrixSets = ''; //layers $maps = array_merge($this->fileLayer, $this->dbLayer); @@ -850,14 +850,15 @@ public function getCapabilities() { if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; - $tileMatrixSets['geodetic'] = TRUE; }elseif ($m['profile'] == 'custom') { + //TODO: Each custom neads each tileset BUG!! $crs = explode(':', $m['crs']); $tileMatrixSet = 'custom' . $crs[1]; - $tileMatrixSets['custom'] = TRUE; + + $customtileMatrixSets .= $this->getTileMatrixSet($tileMatrixSet, $m['scales'], $m['bounds'], $m['crs']); + } else { $tileMatrixSet = "GoogleMapsCompatible"; - $tileMatrixSets['GoogleMapsCompatible'] = TRUE; list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); @@ -886,31 +887,29 @@ public function getCapabilities() { '; } - - if ($tileMatrixSets['geodetic']) { - //Print wgs84 TileMatrixSet - $corner = array(-180.000000, 90.000000); - $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, - 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, - 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, - 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, - 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, - 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, - 2132.72958384978574031265); - $crs = 'EPSG::4326'; - $matrixRatio = array(2, 1); - - echo $this->getTileMatrixSet($tileMatrixSet, $scales, $corner, $crs, $matrixRatio); - } - if ($tileMatrixSets['custom']) { - // Custom from metadata - echo $this->getTileMatrixSet($tileMatrixSet, $m['scales'], array($m['projected_bounds'][0], $m['projected_bounds'][4]), $m['crs']); - } - if($tileMatrixSets['GoogleMapsCompatible']){ - //Print mercator TileMatrixSet - echo $this->getMercatorTileMatrixSet(); + // Print PseudoMercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + + //Print wgs84 TileMatrixSet + $matrixExtent = array(-180.000000, -90.000000, 180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($tileMatrixSet, $scales, $matrixExtent, $crs, $matrixRatio); + + //Print custom TileMatrixSet + if (strlen($customtileMatrixSets) > 0) { + echo $customtileMatrixSets; } + echo ' '; From ab7862209a40bb4c9583d2687caeae65f7ada72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 9 Feb 2016 14:37:26 +0100 Subject: [PATCH 19/74] Functions for parsing tilematrixset from json --- tileserver.php | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tileserver.php b/tileserver.php index b55d1d3..3ed04f6 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,6 +718,71 @@ public function get() { $this->getCapabilities(); } } + + /** + * Validates tilematrixset, calculates missing params + * @param Obrject $tileMatrix + * @return Object + */ + public function parseTileMatrix($tileMatrix){ + + for($i = 0; $i <= sizeof($tileMatrix[$i]); $i++){ + if(!isset($tileMatrix[$i]['tile_size'])){ + $tileMatrix[$i]['tile_size'] = array(256, 256); + } + + if (!isset($tileMatrix[$i]['matrix_size'])) { + $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); + } + + //když není nebo když + if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ + $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); + } + + if(!isset($tileMatrix[$i]['scale_denominator'])){ + //constants + $tileMatrix[$i]['scale_denominator'] = null; + } + + if(!isset($tileMatrix[$i]['pixel_size']) && $tileMatrix[$i]['pixel_size'][1] > 0){ + + } + + //kontrola jestli piel size je kladná v obou osách + } + + return $tileMatrix; + } + + /** + * Calculates corners of tilematrix + * @param array $extent + * @param array $origin + * @param array $pixel_size + * @param array $tile_size + * @return array + */ + public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { + //$minx, $miny, $maxx, $maxy = $extent; + + function minsample($x, $f){ + return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } + + function maxsample($x, $f){ + return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } + + $tiles = array(); + $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); + $tiles[] =minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); + + $tiles[] =maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); + $tiles[] =maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); + + return $tiles; + } /** * Default TileMetrixSet for Pseudo Mercator projection 3857 From ce485c67135c607f84170c20ad488689e9e4073c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 11:39:16 +0100 Subject: [PATCH 20/74] Allow to read metadata bounding box also as array --- tileserver.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 3ed04f6..9011f93 100644 --- a/tileserver.php +++ b/tileserver.php @@ -221,10 +221,10 @@ public function row2lat($r, $zoom) { * @return object */ public function metadataValidation($metadata) { - if (array_key_exists('bounds', $metadata)) { + if (!array_key_exists('bounds', $metadata)) { + $metadata['bounds'] = array(-180, -85.06, 180, 85.06); + } elseif (!is_array($metadata['bounds'])) { $metadata['bounds'] = array_map('floatval', explode(',', $metadata['bounds'])); - } else { - $metadata['bounds'] = array(-180, -85.051128779807, 180, 85.051128779807); } if (!array_key_exists('profile', $metadata)) { $metadata['profile'] = 'mercator'; From 0609b25905ab9e0dbed36afda3aaed838d8af5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 20:29:39 +0100 Subject: [PATCH 21/74] Refactoring of tilematrixsets creation --- tileserver.php | 147 +++++++++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 60 deletions(-) diff --git a/tileserver.php b/tileserver.php index 9011f93..912bc8c 100644 --- a/tileserver.php +++ b/tileserver.php @@ -725,36 +725,36 @@ public function get() { * @return Object */ public function parseTileMatrix($tileMatrix){ - + for($i = 0; $i <= sizeof($tileMatrix[$i]); $i++){ if(!isset($tileMatrix[$i]['tile_size'])){ $tileMatrix[$i]['tile_size'] = array(256, 256); } - + if (!isset($tileMatrix[$i]['matrix_size'])) { $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); } - //když není nebo když + //když není nebo když if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); } - + if(!isset($tileMatrix[$i]['scale_denominator'])){ //constants $tileMatrix[$i]['scale_denominator'] = null; } - + if(!isset($tileMatrix[$i]['pixel_size']) && $tileMatrix[$i]['pixel_size'][1] > 0){ - + } - + //kontrola jestli piel size je kladná v obou osách } - + return $tileMatrix; } - + /** * Calculates corners of tilematrix * @param array $extent @@ -765,11 +765,11 @@ public function parseTileMatrix($tileMatrix){ */ public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { //$minx, $miny, $maxx, $maxy = $extent; - + function minsample($x, $f){ return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); } - + function maxsample($x, $f){ return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); } @@ -777,59 +777,94 @@ function maxsample($x, $f){ $tiles = array(); $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); $tiles[] =minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); - + $tiles[] =maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); $tiles[] =maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); - + return $tiles; } - + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml */ public function getMercatorTileMatrixSet(){ - $name = 'GoogleMapsCompatible'; + $denominatorBase = 559082264.0287178; $extent = array(-20037508.34,-20037508.34,20037508.34,20037508.34); - $scalesBase = 559082264.0287178; - $scales = array(); + $tileMatrixSet = array(); for($i = 0; $i <= 18; $i++){ - $scales[] = $scalesBase / pow(2, $i); + $level = new stdClass(); + $level->extent = $extent; + $level->id = (string) $i; + $matrixSize = pow(2, $i); + $level->matrix_size = array($matrixSize, $matrixSize); + $level->origin = array($extent[0], $extent[1]); + $level->scale_denominator = $denominatorBase / pow(2, $i); + $level->tile_size = array(256, 256); + + $tileMatrixSet[] = (array) $level; + } + + return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); + } + + /** + * Default TileMetrixSet for WGS84 projection 4326 + * @return string Xml + */ + public function getWGS84TileMatrixSet(){ + $extent = array(-180.000000, -90.000000, 180.000000, 90.000000); + $scaleDenominators = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $tileMatrixSet = array(); + + for($i = 0; $i <= count($scaleDenominators); $i++){ + $level = new stdClass(); + $level->extent = $extent; + $level->id = (string) $i; + $matrixSize = pow(2, $i); + $level->matrix_size = array($matrixSize * 2, $matrixSize); + $level->origin = array($extent[0], $extent[1]); + $level->scale_denominator = $scaleDenominators[$i]; + $level->tile_size = array(256, 256); + + $tileMatrixSet[] = (array) $level; } - return $this->getTileMatrixSet($name, $scales, $extent); + return $this->getTileMatrixSet('WGS84', $tileMatrixSet, 'EPSG:4326'); } /** - * Prints WMTS tilematrixset + * Prints WMTS TileMatrixSet * @param string $name - * @param array $scales Array of scales - * @param array $extent Boundingbox of matrix + * @param array $tileMatrixSet Array of levels * @param string $crs Code of crs eg: EPSG:3857 - * @param array $matrixRatio Ratio of matrix sides - * @param array $tilesize Size of tile in pixels * @return string TileMatrixSet xml */ - public function getTileMatrixSet($name, $scales, $extent, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + public function getTileMatrixSet($name, $tileMatrixSet, $crs = 'EPSG:3857'){ $srs = explode(':', $crs); $TileMatrixSet = ' ' . $name . ' ' . $name . ' '. $crs .' ' . $name . ' urn:ogc:def:crs:'.$srs[0].'::'.$srs[1].''; - // $TileMatrixSet .= 'urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible'; - for($i = 0; $i <= sizeof($scales); $i++){ - $matrixWidth = pow(2, $i); + // urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible; + foreach($tileMatrixSet as $level){ $TileMatrixSet .= ' - ' . $i . ' - ' . $scales[$i] . ' - '. $extent[0] . ' ' . $extent[3] .' - ' . $tilesize[0] . ' - ' . $tilesize[1] . ' - ' . $matrixWidth * $matrixRatio[0] . ' - ' . $matrixWidth * $matrixRatio[1] . ' + ' . $level['id'] . ' + ' . $level['scale_denominator'] . ' + '. $level['origin'][0] . ' ' . $level['origin'][1] .' + ' . $level['tile_size'][0] . ' + ' . $level['tile_size'][1] . ' + ' . $level['matrix_size'][0] . ' + ' . $level['matrix_size'][1] . ' '; } $TileMatrixSet .= ''; @@ -895,9 +930,9 @@ public function getCapabilities() { '; - + $customtileMatrixSets = ''; - + //layers $maps = array_merge($this->fileLayer, $this->dbLayer); $mercator = new GlobalMercator(); @@ -912,19 +947,22 @@ public function getCapabilities() { $bounds = $m['bounds']; $format = $m['format'] == 'hybrid' ? 'jpgpng' : $m['format']; $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; - + if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; }elseif ($m['profile'] == 'custom') { - //TODO: Each custom neads each tileset BUG!! $crs = explode(':', $m['crs']); $tileMatrixSet = 'custom' . $crs[1]; - - $customtileMatrixSets .= $this->getTileMatrixSet($tileMatrixSet, $m['scales'], $m['bounds'], $m['crs']); - + + $customtileMatrixSets .= $this->getTileMatrixSet( + $tileMatrixSet, + $m['tile_matrix'], + $m['crs'] + ); + } else { $tileMatrixSet = "GoogleMapsCompatible"; - + list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); @@ -952,29 +990,18 @@ public function getCapabilities() { '; } + // Print PseudoMercator TileMatrixSet echo $this->getMercatorTileMatrixSet(); - - //Print wgs84 TileMatrixSet - $matrixExtent = array(-180.000000, -90.000000, 180.000000, 90.000000); - $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, - 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, - 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, - 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, - 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, - 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, - 2132.72958384978574031265); - $crs = 'EPSG::4326'; - $matrixRatio = array(2, 1); - echo $this->getTileMatrixSet($tileMatrixSet, $scales, $matrixExtent, $crs, $matrixRatio); - - //Print custom TileMatrixSet + // Print WGS84 TileMatrixSet + echo $this->getWGS84TileMatrixSet(); + + // Print custom TileMatrixSets if (strlen($customtileMatrixSets) > 0) { - echo $customtileMatrixSets; + echo $customtileMatrixSets; } - echo ' '; From 6da6b13fed41e4e14289ba80f55e989ded354490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 21:19:16 +0100 Subject: [PATCH 22/74] Parse TileMatrixSet --- tileserver.php | 74 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/tileserver.php b/tileserver.php index 912bc8c..5540200 100644 --- a/tileserver.php +++ b/tileserver.php @@ -241,6 +241,11 @@ public function metadataValidation($metadata) { if (!array_key_exists('format', $metadata)) { $metadata['format'] = 'png'; } + + if (!array_key_exists('scale', $metadata)) { + $metadata['scale'] = 1; + } + return $metadata; } @@ -724,32 +729,34 @@ public function get() { * @param Obrject $tileMatrix * @return Object */ - public function parseTileMatrix($tileMatrix){ + public function parseTileMatrix($layer, $tileMatrix){ - for($i = 0; $i <= sizeof($tileMatrix[$i]); $i++){ - if(!isset($tileMatrix[$i]['tile_size'])){ - $tileMatrix[$i]['tile_size'] = array(256, 256); + for($i = 0; $i <= count($tileMatrix); $i++){ + if(!isset($tileMatrix[$i]['id'])){ + $tileMatrix[$i]['id'] = (string) $i; } - + + if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { + $tileMatrix[$i]['extent'] = $layer['extent']; + } + + //TODO: Compute from $ŧhis->tilesOfExtent() if (!isset($tileMatrix[$i]['matrix_size'])) { $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); } - - //když není nebo když + if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); } - + if(!isset($tileMatrix[$i]['scale_denominator'])){ - //constants - $tileMatrix[$i]['scale_denominator'] = null; + $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; + } + + if(!isset($tileMatrix[$i]['tile_size'])){ + $tileSize = 256 * (int) $layer['scale']; + $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); } - - if(!isset($tileMatrix[$i]['pixel_size']) && $tileMatrix[$i]['pixel_size'][1] > 0){ - - } - - //kontrola jestli piel size je kladná v obou osách } return $tileMatrix; @@ -802,13 +809,13 @@ public function getMercatorTileMatrixSet(){ $level->origin = array($extent[0], $extent[1]); $level->scale_denominator = $denominatorBase / pow(2, $i); $level->tile_size = array(256, 256); - + $tileMatrixSet[] = (array) $level; } return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); } - + /** * Default TileMetrixSet for WGS84 projection 4326 * @return string Xml @@ -833,7 +840,7 @@ public function getWGS84TileMatrixSet(){ $level->origin = array($extent[0], $extent[1]); $level->scale_denominator = $scaleDenominators[$i]; $level->tile_size = array(256, 256); - + $tileMatrixSet[] = (array) $level; } @@ -876,6 +883,19 @@ public function getTileMatrixSet($name, $tileMatrixSet, $crs = 'EPSG:3857'){ * Returns tilesets getCapabilities */ public function getCapabilities() { + + $layers = array_merge($this->fileLayer, $this->dbLayer); + + //if TileMatrixSet is provided validate it + for($i = 0; $i >= count($layers); $i++){ + if($layers[$i]['profile'] == 'custom' || isset($layers[$i]['tile_matrix'])){ + $layers[$i]['tile_matrix'] = $this->parseTileMatrix( + $layers[$i], + $layers[$i]['tile_matrix'] + ); + } + } + header("Content-type: application/xml"); echo ' @@ -934,14 +954,10 @@ public function getCapabilities() { $customtileMatrixSets = ''; //layers - $maps = array_merge($this->fileLayer, $this->dbLayer); $mercator = new GlobalMercator(); - foreach ($maps as $m) { - if (strpos($m['basename'], '.') !== false) { - $basename = explode('.', $m['basename']); - } else { - $basename = $m['basename']; - } + foreach ($layers as $m) { + + $basename = $m['basename']; $title = (array_key_exists('name', $m)) ? $m['name'] : $basename; $profile = $m['profile']; $bounds = $m['bounds']; @@ -955,8 +971,8 @@ public function getCapabilities() { $tileMatrixSet = 'custom' . $crs[1]; $customtileMatrixSets .= $this->getTileMatrixSet( - $tileMatrixSet, - $m['tile_matrix'], + $tileMatrixSet, + $m['tile_matrix'], $m['crs'] ); @@ -990,7 +1006,7 @@ public function getCapabilities() { '; } - + // Print PseudoMercator TileMatrixSet echo $this->getMercatorTileMatrixSet(); From 4ff5d95a38af08ad44df53550c4953f2c66bb90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 21:29:53 +0100 Subject: [PATCH 23/74] Code formating --- tileserver.php | 80 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/tileserver.php b/tileserver.php index 5540200..d3fd156 100644 --- a/tileserver.php +++ b/tileserver.php @@ -4,7 +4,7 @@ * TileServer.php project * ====================== * https://github.com/klokantech/tileserver-php/ - * Copyright (C) 2014 - Klokan Technologies GmbH + * Copyright (C) 2016 - Klokan Technologies GmbH */ global $config; @@ -143,7 +143,7 @@ public function isFileLayer($layer) { } /** - * + * Get metadata from metadataJson * @param string $jsonFileName * @return array */ @@ -166,7 +166,7 @@ public function metadataFromMbtiles($mbt) { $resultdata = $result->fetchAll(); foreach ($resultdata as $r) { - $value = preg_replace('/(\\n)+/','',$r['value']); + $value = preg_replace('/(\\n)+/', '', $r['value']); $metadata[$r['name']] = addslashes($value); } if (!array_key_exists('minzoom', $metadata) @@ -175,10 +175,12 @@ public function metadataFromMbtiles($mbt) { // autodetect minzoom and maxzoom $result = $this->db->query('select min(zoom_level) as min, max(zoom_level) as max from tiles'); $resultdata = $result->fetchAll(); - if (!array_key_exists('minzoom', $metadata)) + if (!array_key_exists('minzoom', $metadata)){ $metadata['minzoom'] = $resultdata[0]['min']; - if (!array_key_exists('maxzoom', $metadata)) + } + if (!array_key_exists('maxzoom', $metadata)){ $metadata['maxzoom'] = $resultdata[0]['max']; + } } // autodetect format using JPEG magic number FFD8 if (!array_key_exists('format', $metadata)) { @@ -192,10 +194,10 @@ public function metadataFromMbtiles($mbt) { if (!array_key_exists('bounds', $metadata)) { $result = $this->db->query('select min(tile_column) as w, max(tile_column) as e, min(tile_row) as s, max(tile_row) as n from tiles where zoom_level='.$metadata['maxzoom']); $resultdata = $result->fetchAll(); - $w = -180 + 360 * ($resultdata[0]['w'] / pow(2,$metadata['maxzoom'])); - $e = -180 + 360 * ((1+$resultdata[0]['e']) / pow(2,$metadata['maxzoom'])); + $w = -180 + 360 * ($resultdata[0]['w'] / pow(2, $metadata['maxzoom'])); + $e = -180 + 360 * ((1 + $resultdata[0]['e']) / pow(2, $metadata['maxzoom'])); $n = $this->row2lat($resultdata[0]['n'], $metadata['maxzoom']); - $s = $this->row2lat($resultdata[0]['s']-1, $metadata['maxzoom']); + $s = $this->row2lat($resultdata[0]['s'] - 1, $metadata['maxzoom']); $metadata['bounds'] = implode(',', array($w, $s, $e, $n)); } $metadata = $this->metadataValidation($metadata); @@ -211,8 +213,8 @@ public function metadataFromMbtiles($mbt) { * @return integer */ public function row2lat($r, $zoom) { - $y = $r / pow(2,$zoom-1) - 1; - return rad2deg(2.0 * atan(exp(3.191459196*$y)) - 1.57079632679489661922); + $y = $r / pow(2, $zoom - 1 ) - 1; + return rad2deg(2.0 * atan(exp(3.191459196 * $y)) - 1.57079632679489661922); } /** @@ -229,23 +231,25 @@ public function metadataValidation($metadata) { if (!array_key_exists('profile', $metadata)) { $metadata['profile'] = 'mercator'; } -// TODO: detect thumb / SQL for mbtiles - if (array_key_exists('minzoom', $metadata)) + if (array_key_exists('minzoom', $metadata)){ $metadata['minzoom'] = intval($metadata['minzoom']); - else + }else{ $metadata['minzoom'] = 0; - if (array_key_exists('maxzoom', $metadata)) + } + if (array_key_exists('maxzoom', $metadata)){ $metadata['maxzoom'] = intval($metadata['maxzoom']); - else + }else{ $metadata['maxzoom'] = 18; + } if (!array_key_exists('format', $metadata)) { $metadata['format'] = 'png'; } - if (!array_key_exists('scale', $metadata)) { $metadata['scale'] = 1; } - + + // TODO: detect thumb / SQL for mbtiles + return $metadata; } @@ -277,8 +281,8 @@ public function isModified($filename) { $filename = $filename . '.mbtiles'; $lastModifiedTime = filemtime($filename); $eTag = md5($lastModifiedTime); - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastModifiedTime) . " GMT"); - header("Etag:" . $eTag); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT'); + header('Etag:' . $eTag); if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModifiedTime || @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $eTag) { return TRUE; @@ -356,7 +360,7 @@ public function renderTile($tileset, $z, $y, $x, $ext) { die; } else { //scale of tile (for retina tiles) - $meta = json_decode(file_get_contents($tileset.'/metadata.json')); + $meta = json_decode(file_get_contents($tileset . '/metadata.json')); if(!isset($meta->scale)){ $meta->scale = 1; } @@ -364,7 +368,7 @@ public function renderTile($tileset, $z, $y, $x, $ext) { $this->getCleanTile($meta->scale, $ext); } else { header('HTTP/1.1 404 Not Found'); - echo 'Server: Unknown or not specified dataset "'.$tileset.'"'; + echo 'Server: Unknown or not specified dataset "' . $tileset . '"'; die; } } @@ -483,7 +487,7 @@ public function getInfo() { . $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json
'; echo 'Bounds: ' . $extend . '

'; } - echo '

Copyright (C) 2014 - Klokan Technologies GmbH

'; + echo '

Copyright (C) 2016 - Klokan Technologies GmbH

'; echo ''; } @@ -643,7 +647,7 @@ private function createJson($basename) { public function getJson() { parent::setDatasets(); header('Access-Control-Allow-Origin: *'); - header("Content-Type: application/json; charset=utf-8"); + header('Content-Type: application/json; charset=utf-8'); if ($this->callback !== 'grid') { echo $this->callback . '(' . $this->createJson($this->layer) . ');'; die; } else { @@ -657,7 +661,7 @@ public function getJson() { public function getJsonp() { parent::setDatasets(); header('Access-Control-Allow-Origin: *'); - header("Content-Type: application/javascript; charset=utf-8"); + header('Content-Type: application/javascript; charset=utf-8'); echo $this->callback . '(' . $this->createJson($this->layer) . ');'; } @@ -735,24 +739,24 @@ public function parseTileMatrix($layer, $tileMatrix){ if(!isset($tileMatrix[$i]['id'])){ $tileMatrix[$i]['id'] = (string) $i; } - + if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { $tileMatrix[$i]['extent'] = $layer['extent']; } - + //TODO: Compute from $ŧhis->tilesOfExtent() if (!isset($tileMatrix[$i]['matrix_size'])) { $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); } - + if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); } - + if(!isset($tileMatrix[$i]['scale_denominator'])){ $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; } - + if(!isset($tileMatrix[$i]['tile_size'])){ $tileSize = 256 * (int) $layer['scale']; $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); @@ -896,7 +900,7 @@ public function getCapabilities() { } } - header("Content-type: application/xml"); + header('Content-type: application/xml'); echo ' @@ -965,19 +969,17 @@ public function getCapabilities() { $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; if ($profile == 'geodetic') { - $tileMatrixSet = "WGS84"; + $tileMatrixSet = 'WGS84'; }elseif ($m['profile'] == 'custom') { $crs = explode(':', $m['crs']); $tileMatrixSet = 'custom' . $crs[1]; - $customtileMatrixSets .= $this->getTileMatrixSet( $tileMatrixSet, $m['tile_matrix'], $m['crs'] ); - } else { - $tileMatrixSet = "GoogleMapsCompatible"; + $tileMatrixSet = 'GoogleMapsCompatible'; list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); @@ -1094,16 +1096,16 @@ public function __construct($params) { public function getCapabilities() { parent::setDatasets(); $maps = array_merge($this->fileLayer, $this->dbLayer); - header("Content-type: application/xml"); + header('Content-type: application/xml'); echo''; foreach ($maps as $m) { $basename = $m['basename']; $title = (array_key_exists('name', $m) ) ? $m['name'] : $basename; $profile = $m['profile']; if ($profile == 'geodetic') { - $srs = "EPSG:4326"; + $srs = 'EPSG:4326'; } else { - $srs = "EPSG:3857"; + $srs = 'EPSG:3857'; echo ''; @@ -1128,12 +1130,12 @@ public function getLayerCapabilities() { $description = (array_key_exists('description', $m)) ? $m['description'] : ""; $bounds = $m['bounds']; if ($m['profile'] == 'geodetic') { - $srs = "EPSG:4326"; + $srs = 'EPSG:4326'; $originx = -180.0; $originy = -90.0; $initialResolution = 0.703125; } else { - $srs = "EPSG:3857"; + $srs = 'EPSG:3857'; $originx = -20037508.342789; $originy = -20037508.342789; $mercator = new GlobalMercator(); From 27fc9a73ca87b3a9c02e8d984cca79f35d1a7a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 18 Feb 2016 08:43:49 +0100 Subject: [PATCH 24/74] Minor loop fixes --- tileserver.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tileserver.php b/tileserver.php index d3fd156..545f26d 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,12 +734,13 @@ public function get() { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - - for($i = 0; $i <= count($tileMatrix); $i++){ + + for($i = 0; $i < count($tileMatrix); $i++){ + if(!isset($tileMatrix[$i]['id'])){ $tileMatrix[$i]['id'] = (string) $i; } - + if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { $tileMatrix[$i]['extent'] = $layer['extent']; } @@ -750,7 +751,9 @@ public function parseTileMatrix($layer, $tileMatrix){ } if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ - $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); + $tileMatrix[$i]['origin'] = array( + $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4] + ); } if(!isset($tileMatrix[$i]['scale_denominator'])){ @@ -787,10 +790,10 @@ function maxsample($x, $f){ $tiles = array(); $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] =minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); + $tiles[] = minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); - $tiles[] =maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] =maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); + $tiles[] = maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); + $tiles[] = maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); return $tiles; } @@ -890,8 +893,8 @@ public function getCapabilities() { $layers = array_merge($this->fileLayer, $this->dbLayer); - //if TileMatrixSet is provided validate it - for($i = 0; $i >= count($layers); $i++){ + //if TileMatrixSet is provided validate it + for($i = 0; $i < count($layers); $i++){ if($layers[$i]['profile'] == 'custom' || isset($layers[$i]['tile_matrix'])){ $layers[$i]['tile_matrix'] = $this->parseTileMatrix( $layers[$i], From a2162eeb991ddeb4eee630ddc4446d1254bb4359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 18 Feb 2016 16:49:48 +0100 Subject: [PATCH 25/74] Computation of matrix size --- tileserver.php | 60 +++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/tileserver.php b/tileserver.php index 545f26d..e1f32cf 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,32 +734,35 @@ public function get() { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - + for($i = 0; $i < count($tileMatrix); $i++){ - + if(!isset($tileMatrix[$i]['id'])){ $tileMatrix[$i]['id'] = (string) $i; } - if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { $tileMatrix[$i]['extent'] = $layer['extent']; } - - //TODO: Compute from $ŧhis->tilesOfExtent() if (!isset($tileMatrix[$i]['matrix_size'])) { - $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); + $tileExtent = $this->tilesOfExtent( + $tileMatrix[$i]['extent'], + $tileMatrix[$i]['origin'], + $tileMatrix[$i]['pixel_size'], + $tileMatrix[$i]['tile_size'] + ); + $tileMatrix[$i]['matrix_size'] = array( + $tileExtent[1] + 1, + $tileExtent[2] + 1 + ); } - if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array( $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4] ); } - if(!isset($tileMatrix[$i]['scale_denominator'])){ $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; } - if(!isset($tileMatrix[$i]['tile_size'])){ $tileSize = 256 * (int) $layer['scale']; $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); @@ -778,24 +781,21 @@ public function parseTileMatrix($layer, $tileMatrix){ * @return array */ public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { - //$minx, $miny, $maxx, $maxy = $extent; - - function minsample($x, $f){ - return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); - } - - function maxsample($x, $f){ - return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); - } - - $tiles = array(); - $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] = minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); + $tiles = array( + $this->minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]), + $this->minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]), + $this->maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]), + $this->maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]), + ); + return $tiles; + } - $tiles[] = maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] = maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); + private function minsample($x, $f){ + return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } - return $tiles; + private function maxsample($x, $f){ + return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); } /** @@ -895,11 +895,11 @@ public function getCapabilities() { //if TileMatrixSet is provided validate it for($i = 0; $i < count($layers); $i++){ - if($layers[$i]['profile'] == 'custom' || isset($layers[$i]['tile_matrix'])){ + if($layers[$i]['profile'] == 'custom'){ $layers[$i]['tile_matrix'] = $this->parseTileMatrix( - $layers[$i], - $layers[$i]['tile_matrix'] - ); + $layers[$i], + $layers[$i]['tile_matrix'] + ); } } @@ -975,7 +975,7 @@ public function getCapabilities() { $tileMatrixSet = 'WGS84'; }elseif ($m['profile'] == 'custom') { $crs = explode(':', $m['crs']); - $tileMatrixSet = 'custom' . $crs[1]; + $tileMatrixSet = 'custom' . $crs[1] . $m['basename']; $customtileMatrixSets .= $this->getTileMatrixSet( $tileMatrixSet, $m['tile_matrix'], From 46d79107e85b5d06f34902abf36795c47b079a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 24 Feb 2016 18:55:42 +0100 Subject: [PATCH 26/74] Minor code fixes --- tileserver.php | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/tileserver.php b/tileserver.php index e1f32cf..321c4df 100644 --- a/tileserver.php +++ b/tileserver.php @@ -808,16 +808,15 @@ public function getMercatorTileMatrixSet(){ $tileMatrixSet = array(); for($i = 0; $i <= 18; $i++){ - $level = new stdClass(); - $level->extent = $extent; - $level->id = (string) $i; $matrixSize = pow(2, $i); - $level->matrix_size = array($matrixSize, $matrixSize); - $level->origin = array($extent[0], $extent[1]); - $level->scale_denominator = $denominatorBase / pow(2, $i); - $level->tile_size = array(256, 256); - - $tileMatrixSet[] = (array) $level; + $tileMatrixSet[] = array( + 'extent' => $extent, + 'id' => (string) $i, + 'matrix_size' => array($matrixSize, $matrixSize), + 'origin' => array($extent[0], $extent[3]), + 'scale_denominator' => $denominatorBase / pow(2, $i), + 'tile_size' => array(256, 256) + ); } return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); @@ -839,15 +838,15 @@ public function getWGS84TileMatrixSet(){ $tileMatrixSet = array(); for($i = 0; $i <= count($scaleDenominators); $i++){ - $level = new stdClass(); - $level->extent = $extent; - $level->id = (string) $i; $matrixSize = pow(2, $i); - $level->matrix_size = array($matrixSize * 2, $matrixSize); - $level->origin = array($extent[0], $extent[1]); - $level->scale_denominator = $scaleDenominators[$i]; - $level->tile_size = array(256, 256); - + $tileMatrixSet[] = array( + 'extent' => $extent, + 'id' => (string) $i, + 'matrix_size' => array($matrixSize * 2, $matrixSize), + 'origin' => array($extent[0], $extent[3]), + 'scale_denominator' => $scaleDenominators[$i], + 'tile_size' => array(256, 256) + ); $tileMatrixSet[] = (array) $level; } @@ -1011,6 +1010,11 @@ public function getCapabilities() { '; } + + // Print custom TileMatrixSets + if (strlen($customtileMatrixSets) > 0) { + echo $customtileMatrixSets; + } // Print PseudoMercator TileMatrixSet echo $this->getMercatorTileMatrixSet(); @@ -1018,11 +1022,6 @@ public function getCapabilities() { // Print WGS84 TileMatrixSet echo $this->getWGS84TileMatrixSet(); - // Print custom TileMatrixSets - if (strlen($customtileMatrixSets) > 0) { - echo $customtileMatrixSets; - } - echo ' '; From 8233047097e45a1e185379c7aae7e09d8e0f2ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 24 Feb 2016 20:18:06 +0100 Subject: [PATCH 27/74] Fixed bug in WGS84 tilematrixset --- tileserver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 321c4df..54885a2 100644 --- a/tileserver.php +++ b/tileserver.php @@ -847,7 +847,6 @@ public function getWGS84TileMatrixSet(){ 'scale_denominator' => $scaleDenominators[$i], 'tile_size' => array(256, 256) ); - $tileMatrixSet[] = (array) $level; } return $this->getTileMatrixSet('WGS84', $tileMatrixSet, 'EPSG:4326'); From f3f2a995e58949465f7ce1c7c6e462ab09549c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 25 Feb 2016 19:23:48 +0100 Subject: [PATCH 28/74] Axis orientaton in wmts #70, bbox fix --- tileserver.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54885a2..0991b61 100644 --- a/tileserver.php +++ b/tileserver.php @@ -751,15 +751,22 @@ public function parseTileMatrix($layer, $tileMatrix){ $tileMatrix[$i]['tile_size'] ); $tileMatrix[$i]['matrix_size'] = array( - $tileExtent[1] + 1, - $tileExtent[2] + 1 + $tileExtent[2] + 1, + $tileExtent[1] + 1 ); } if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array( - $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4] + $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] ); } + if (!isset($layer['axis'])) { + $layer['axis'] = $layer['xy']; + } + // Origins of geographic coordinate systems are setting in opposite order + if ($layer['axis'] == 'yx') { + $tileMatrix[$i]['origin'] = array_reverse($tileMatrix[$i]['origin']); + } if(!isset($tileMatrix[$i]['scale_denominator'])){ $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; } From 7190e90845a435217d003c61aeb25b2a02ed1a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 25 Feb 2016 23:21:40 +0100 Subject: [PATCH 29/74] Order of origin coords based on proj4 definition #70 --- tileserver.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tileserver.php b/tileserver.php index 0991b61..1a9c842 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,7 +734,13 @@ public function get() { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - + + //process projection + if(isset($layer['proj4'])){ + preg_match_all("/([^+= ]+)=([^= ]+)/", $layer['proj4'], $res); + $proj4 = array_combine($res[1], $res[2]); + } + for($i = 0; $i < count($tileMatrix); $i++){ if(!isset($tileMatrix[$i]['id'])){ @@ -760,11 +766,8 @@ public function parseTileMatrix($layer, $tileMatrix){ $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] ); } - if (!isset($layer['axis'])) { - $layer['axis'] = $layer['xy']; - } // Origins of geographic coordinate systems are setting in opposite order - if ($layer['axis'] == 'yx') { + if (isset($proj4) && $proj4['proj'] === 'longlat') { $tileMatrix[$i]['origin'] = array_reverse($tileMatrix[$i]['origin']); } if(!isset($tileMatrix[$i]['scale_denominator'])){ @@ -907,7 +910,7 @@ public function getCapabilities() { ); } } - + header('Content-type: application/xml'); echo ' From e36a7e6a06162ec04585ebe027ceba1a11d7f1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Fri, 26 Feb 2016 08:51:47 +0100 Subject: [PATCH 30/74] Fix of order of origin in geodetic profile --- tileserver.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tileserver.php b/tileserver.php index 1a9c842..46890ee 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,13 +734,13 @@ public function get() { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - + //process projection if(isset($layer['proj4'])){ preg_match_all("/([^+= ]+)=([^= ]+)/", $layer['proj4'], $res); $proj4 = array_combine($res[1], $res[2]); } - + for($i = 0; $i < count($tileMatrix); $i++){ if(!isset($tileMatrix[$i]['id'])){ @@ -766,7 +766,7 @@ public function parseTileMatrix($layer, $tileMatrix){ $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] ); } - // Origins of geographic coordinate systems are setting in opposite order + // Origins of geographic coordinate systems are setting in opposite order if (isset($proj4) && $proj4['proj'] === 'longlat') { $tileMatrix[$i]['origin'] = array_reverse($tileMatrix[$i]['origin']); } @@ -853,7 +853,7 @@ public function getWGS84TileMatrixSet(){ 'extent' => $extent, 'id' => (string) $i, 'matrix_size' => array($matrixSize * 2, $matrixSize), - 'origin' => array($extent[0], $extent[3]), + 'origin' => array($extent[3], $extent[0]), 'scale_denominator' => $scaleDenominators[$i], 'tile_size' => array(256, 256) ); @@ -910,7 +910,7 @@ public function getCapabilities() { ); } } - + header('Content-type: application/xml'); echo ' @@ -1019,7 +1019,7 @@ public function getCapabilities() { '; } - + // Print custom TileMatrixSets if (strlen($customtileMatrixSets) > 0) { echo $customtileMatrixSets; From 92ddcb6e661a42695d86169d4b6c5082643fbef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 29 Feb 2016 12:16:24 +0100 Subject: [PATCH 31/74] WMTS / TileJSON for remote tiles #69 --- tileserver.php | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/tileserver.php b/tileserver.php index 46890ee..fe816a0 100644 --- a/tileserver.php +++ b/tileserver.php @@ -149,9 +149,8 @@ public function isFileLayer($layer) { */ public function metadataFromMetadataJson($jsonFileName) { $metadata = json_decode(file_get_contents($jsonFileName), true); - $metadata = $this->metadataValidation($metadata); $metadata['basename'] = str_replace('/metadata.json', '', $jsonFileName); - return $metadata; + return $this->metadataValidation($metadata); } /** @@ -200,9 +199,9 @@ public function metadataFromMbtiles($mbt) { $s = $this->row2lat($resultdata[0]['s'] - 1, $metadata['maxzoom']); $metadata['bounds'] = implode(',', array($w, $s, $e, $n)); } - $metadata = $this->metadataValidation($metadata); $mbt = explode('.', $mbt); $metadata['basename'] = $mbt[0]; + $metadata = $this->metadataValidation($metadata); return $metadata; } @@ -247,6 +246,18 @@ public function metadataValidation($metadata) { if (!array_key_exists('scale', $metadata)) { $metadata['scale'] = 1; } + if(!array_key_exists('tiles', $metadata)){ + $tiles = array(); + foreach ($this->config['baseUrls'] as $url) { + $url = '' . $this->config['protocol'] . '://' . $url . '/' . + $metadata['basename'] . '/{z}/{x}/{y}'; + if(strlen($metadata['format']) <= 4){ + $url .= '.' . $metadata['format']; + } + $tiles[] = $url; + } + $metadata['tiles'] = $tiles; + } // TODO: detect thumb / SQL for mbtiles @@ -463,7 +474,6 @@ public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { * Returns server info */ public function getInfo() { -// echo $this->config['baseUrls'][0];die; $this->setDatasets(); $maps = array_merge($this->fileLayer, $this->dbLayer); header('Content-Type: text/html;charset=UTF-8'); @@ -579,16 +589,6 @@ public function __construct($params) { public function metadataTileJson($metadata) { $metadata['tilejson'] = '2.0.0'; $metadata['scheme'] = 'xyz'; - $tiles = array(); - foreach ($this->config['baseUrls'] as $url) { - $url = '' . $this->config['protocol'] . '://' . $url . '/' . - $metadata['basename'] . '/{z}/{x}/{y}'; - if(strlen($metadata['format']) <= 4){ - $url .= '.' . $metadata['format']; - } - $tiles[] = $url; - } - $metadata['tiles'] = $tiles; if ($this->isDBLayer($metadata['basename'])) { $this->DBconnect($metadata['basename'] . '.mbtiles'); $res = $this->db->query('SELECT * FROM grids LIMIT 1;'); @@ -996,11 +996,14 @@ public function getCapabilities() { list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); } - $resourceUrlTemplate = $this->config['protocol'] . '://' - . $this->config['baseUrls'][0] . '/wmts/' . $basename . '/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}'; + + $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); + $resourceUrlTemplate = $wmtsHost . 'wmts/' . $basename + . '/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}'; if(strlen($format) <= 4){ $resourceUrlTemplate .= '.' . $format; } + echo' ' . $title . ' From 87906da0c547f84f5b9af2f0f9e38b33d68c38e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 29 Feb 2016 14:16:17 +0100 Subject: [PATCH 32/74] Correct detection of format closes #67 --- tileserver.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index fe816a0..e187a2f 100644 --- a/tileserver.php +++ b/tileserver.php @@ -9,6 +9,7 @@ global $config; $config['serverTitle'] = 'TileServer-php v1'; +$config['availableFormats'] = array('png', 'jpg', 'jpeg', 'gif', 'webp', 'hybrid'); //$config['baseUrls'] = array('t0.server.com', 't1.server.com'); Router::serve(array( @@ -241,7 +242,14 @@ public function metadataValidation($metadata) { $metadata['maxzoom'] = 18; } if (!array_key_exists('format', $metadata)) { - $metadata['format'] = 'png'; + if(array_key_exists('tiles', $metadata)){ + $pos = strrpos($metadata['tiles'][0], '.'); + $metadata['format'] = trim(substr($metadata['tiles'][0], $pos + 1)); + } + } + $formats = $this->config['availableFormats']; + if(!in_array(strtolower($metadata['format']), $formats)){ + $metadata['format'] = 'png'; } if (!array_key_exists('scale', $metadata)) { $metadata['scale'] = 1; @@ -263,6 +271,16 @@ public function metadataValidation($metadata) { return $metadata; } + + /** + * + * @param string $url + * @return string + */ + private function parseFormat($url){ + + return $mime; + } /** * SQLite connection From d304b89eb2d71e27845998b8b4b44b2a1f35e81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 29 Feb 2016 14:19:09 +0100 Subject: [PATCH 33/74] Removed unused code --- tileserver.php | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/tileserver.php b/tileserver.php index e187a2f..dcbf031 100644 --- a/tileserver.php +++ b/tileserver.php @@ -266,21 +266,8 @@ public function metadataValidation($metadata) { } $metadata['tiles'] = $tiles; } - - // TODO: detect thumb / SQL for mbtiles - return $metadata; } - - /** - * - * @param string $url - * @return string - */ - private function parseFormat($url){ - - return $mime; - } /** * SQLite connection From 8206bcccc741e6e3872f7dde179d6a99cef9607b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 29 Feb 2016 20:21:13 +0100 Subject: [PATCH 34/74] GD module dependency closes #53 --- tileserver.php | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tileserver.php b/tileserver.php index dcbf031..8c5ee32 100644 --- a/tileserver.php +++ b/tileserver.php @@ -9,7 +9,7 @@ global $config; $config['serverTitle'] = 'TileServer-php v1'; -$config['availableFormats'] = array('png', 'jpg', 'jpeg', 'gif', 'webp', 'hybrid'); +$config['availableFormats'] = array('png', 'jpg', 'jpeg', 'gif', 'webp', 'pbf', 'hybrid'); //$config['baseUrls'] = array('t0.server.com', 't1.server.com'); Router::serve(array( @@ -399,19 +399,18 @@ public function getCleanTile($scale = 1, $format = 'png') { header('HTTP/1.1 404 Not Found'); header('Content-Type: application/json; charset=utf-8'); echo '{"message":"Tile does not exist"}'; - die; + break; case 'png': default: - $tileSize = 256 * $scale; - $png = imagecreatetruecolor($tileSize, $tileSize); - imagesavealpha($png, true); - $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127); - imagefill($png, 0, 0, $trans_colour); header('Access-Control-Allow-Origin: *'); header('Content-type: image/png'); - imagepng($png); - die; + $a = ''; + for($i=1; $i < 338; $i++){$a .= 'A';} + echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAABFUl' + . 'EQVR42u3BMQEAAADCoPVP7WsIo' . $a . 'eAMBPAAB2ClDBAAAAABJRU5ErkJggg'); + break; } + die; } /** @@ -735,7 +734,7 @@ public function get() { /** * Validates tilematrixset, calculates missing params - * @param Obrject $tileMatrix + * @param Object $tileMatrix * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ From 50630fe1c7e34210813b9bd1ce88479a45ef2fb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 1 Mar 2016 11:57:18 +0100 Subject: [PATCH 35/74] Get config from docker volumes if is provided --- tileserver.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tileserver.php b/tileserver.php index 8c5ee32..c490ce2 100644 --- a/tileserver.php +++ b/tileserver.php @@ -62,7 +62,10 @@ class Server { * Set config */ public function __construct() { - $this->config = $GLOBALS['config']; + //Get config from docker volumes + $envConfig = $_ENV['config'] == null ? array() : $_ENV['config']; + + $this->config = array_merge($GLOBALS['config'], $envConfig); } /** @@ -1000,14 +1003,14 @@ public function getCapabilities() { list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); } - + $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); - $resourceUrlTemplate = $wmtsHost . 'wmts/' . $basename + $resourceUrlTemplate = $wmtsHost . 'wmts/' . $basename . '/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}'; if(strlen($format) <= 4){ $resourceUrlTemplate .= '.' . $format; } - + echo' ' . $title . ' From 8bbfa1d367588cdcbd1a8d64baeab83225621e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 1 Mar 2016 15:05:58 +0100 Subject: [PATCH 36/74] Config from eniviroment if is provided --- tileserver.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tileserver.php b/tileserver.php index c490ce2..fb06b01 100644 --- a/tileserver.php +++ b/tileserver.php @@ -62,10 +62,16 @@ class Server { * Set config */ public function __construct() { - //Get config from docker volumes - $envConfig = $_ENV['config'] == null ? array() : $_ENV['config']; - - $this->config = array_merge($GLOBALS['config'], $envConfig); + $this->config = $GLOBALS['config']; + + //Get config from enviroment + if(isset($_ENV['serverTitle'])){ + $this->config['serverTitle'] = $_ENV['serverTitle']; + } + if(isset($_ENV['baseUrls'])){ + $this->config['baseUrls'] = is_array($_ENV['baseUrls']) ? + $_ENV['baseUrls'] : explode(',', $_ENV['baseUrls']); + } } /** From fdeb010831958d6ebabaefb78132276211635c3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 1 Mar 2016 19:17:46 +0100 Subject: [PATCH 37/74] Get global vars via getenv --- tileserver.php | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tileserver.php b/tileserver.php index fb06b01..a55a323 100644 --- a/tileserver.php +++ b/tileserver.php @@ -65,12 +65,14 @@ public function __construct() { $this->config = $GLOBALS['config']; //Get config from enviroment - if(isset($_ENV['serverTitle'])){ - $this->config['serverTitle'] = $_ENV['serverTitle']; + $envServerTitle = getenv('serverTitle'); + if($envServerTitle !== FALSE){ + $this->config['serverTitle'] = $envServerTitle; } - if(isset($_ENV['baseUrls'])){ - $this->config['baseUrls'] = is_array($_ENV['baseUrls']) ? - $_ENV['baseUrls'] : explode(',', $_ENV['baseUrls']); + $envBaseUrls = getenv('baseUrls'); + if($envBaseUrls !== FALSE){ + $this->config['baseUrls'] = is_array($envBaseUrls) ? + $envBaseUrls : explode(',', $envBaseUrls); } } From 70159a5b298f80f8b898d0f834197ec27ff31962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Fri, 4 Mar 2016 12:07:37 +0100 Subject: [PATCH 38/74] Layer list improved --- tileserver.php | 32 +++++++++++++------------------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/tileserver.php b/tileserver.php index a55a323..49c12e0 100644 --- a/tileserver.php +++ b/tileserver.php @@ -14,7 +14,7 @@ Router::serve(array( '/' => 'Server:getHtml', - '/test' => 'Server:getInfo', + '/maps' => 'Server:getInfo', '/html' => 'Server:getHtml', '/:alpha/:number/:number/:number.grid.json' => 'Json:getUTFGrid', '/:alpha.json' => 'Json:getJson', @@ -492,25 +492,19 @@ public function getInfo() { $this->setDatasets(); $maps = array_merge($this->fileLayer, $this->dbLayer); header('Content-Type: text/html;charset=UTF-8'); - echo '' . $this->config['serverTitle'] . ''; - echo '

' . $this->config['serverTitle'] . '

'; - echo 'TileJSON service: ' . $this->config['baseUrls'][0] . '/index.json
'; - echo 'WMTS service: ' . $this->config['baseUrls'][0] . '/wmts
'; - echo 'TMS service: ' . $this->config['baseUrls'][0] . '/tms'; + echo '' . $this->config['serverTitle'] . '' . + '

' . $this->config['serverTitle'] . '

' . + 'TileJSON service: ' . $this->config['baseUrls'][0] . '/index.json
' . + 'WMTS service: ' . $this->config['baseUrls'][0] . '/wmts
' . + 'TMS service: ' . $this->config['baseUrls'][0] . '/tms'; foreach ($maps as $map) { - $extend = '['; - foreach ($map['bounds'] as $ext) { - $extend = $extend . ' ' . $ext; - } - $extend = $extend . ' ]'; - if (strpos($map['basename'], 'mbtiles') !== false) { - echo '

Available MBtiles tileset: ' . $map['basename'] . '
'; - } else { - echo '

Available file tileset: ' . $map['basename'] . '
'; - } - echo 'Metadata: ' - . $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json
'; - echo 'Bounds: ' . $extend . '

'; + $extend = '[' . implode($map['bounds'], ', ') . ']'; + echo '

Tileset: ' . $map['basename'] . '
' . + 'Metadata: ' . + $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json
' . + 'Bounds: ' . $extend ; + if(isset($map['crs'])){echo '
CRS: ' . $map['crs'];} + echo '

'; } echo '

Copyright (C) 2016 - Klokan Technologies GmbH

'; echo ''; From 2e3633872017ff7cc4a15c70c99410e439fea90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Fri, 4 Mar 2016 13:20:46 +0100 Subject: [PATCH 39/74] Removed dependency of GlobalMercator class closes #74 --- tileserver.php | 172 +++++++------------------------------------------ 1 file changed, 22 insertions(+), 150 deletions(-) diff --git a/tileserver.php b/tileserver.php index 49c12e0..cb197db 100644 --- a/tileserver.php +++ b/tileserver.php @@ -978,7 +978,6 @@ public function getCapabilities() { $customtileMatrixSets = ''; //layers - $mercator = new GlobalMercator(); foreach ($layers as $m) { $basename = $m['basename']; @@ -1000,10 +999,6 @@ public function getCapabilities() { ); } else { $tileMatrixSet = 'GoogleMapsCompatible'; - - list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); - list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); - $bounds3857 = array($minx, $miny, $maxx, $maxy); } $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); @@ -1129,10 +1124,12 @@ public function getCapabilities() { $srs = 'EPSG:4326'; } else { $srs = 'EPSG:3857'; - echo ''; } + $url = $this->config['protocol'] . '://' . $this->config['baseUrls'][0] + . '/tms/' . $basename; + echo ''; } echo ''; } @@ -1154,31 +1151,35 @@ public function getLayerCapabilities() { $bounds = $m['bounds']; if ($m['profile'] == 'geodetic') { $srs = 'EPSG:4326'; - $originx = -180.0; - $originy = -90.0; - $initialResolution = 0.703125; + $initRes = 0.703125; + } elseif ($m['profile'] == 'custom') { + $srs = $m['crs']; + $bounds = $m['extent']; + if(isset($m['tile_matrix'][0]['pixel_size'][0])){ + $initRes = $m['tile_matrix'][0]['pixel_size'][0]; + }else{ + $initRes = 1; + } } else { $srs = 'EPSG:3857'; - $originx = -20037508.342789; - $originy = -20037508.342789; - $mercator = new GlobalMercator(); - list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); - list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); - $bounds = array($minx, $miny, $maxx, $maxy); - $initialResolution = 156543.03392804062; + $bounds = array(-20037508.34,-20037508.34,20037508.34,20037508.34); + $initRes = 156543.03392804062; } $mime = ($m['format'] == 'jpg') ? 'image/jpeg' : 'image/png'; header("Content-type: application/xml"); - echo ' + $serviceUrl = $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/' . $m['basename']; + echo ' ' . htmlspecialchars($title) . ' ' . htmlspecialchars($description) . ' ' . $srs . ' - + '; for ($zoom = $m['minzoom']; $zoom < $m['maxzoom'] + 1; $zoom++) { - echo ''; + $res = $initRes / pow(2, $zoom); + $url = $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/' . $m['basename'] . '/' . $zoom; + echo ''; } echo''; } @@ -1189,135 +1190,6 @@ public function getLayerCapabilities() { public function getTile() { parent::renderTile($this->layer, $this->z, $this->y, $this->x, $this->ext); } - -} - -/* - GlobalMapTiles - part of Aggregate Map Tools - Version 1.0 - Copyright (c) 2009 The Bivings Group - All rights reserved. - Author: John Bafford - - http://www.bivings.com/ - http://bafford.com/softare/aggregate-map-tools/ - - Based on GDAL2Tiles / globalmaptiles.py - Original python version Copyright (c) 2008 Klokan Petr Pridal. All rights reserved. - http://www.klokan.cz/projects/gdal2tiles/ - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublic ense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The abov - e copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - -class GlobalMercator { - - var $tileSize; - var $initialResolution; - var $originShift; - -//Initialize the TMS Global Mercator pyramid - function __construct($tileSize = 256) { - $this->tileSize = $tileSize; - $this->initialResolution = 2 * M_PI * 6378137 / $this->tileSize; -# 156543.03392804062 for tileSize 256 Pixels - $this->originShift = 2 * M_PI * 6378137 / 2.0; -# 20037508.342789244 - } - -//Converts given lat/lon in WGS84 Datum to XY in Spherical Mercator EPSG:900913 - function LatLonToMeters($lat, $lon) { - $mx = $lon * $this->originShift / 180.0; - $my = log(tan((90 + $lat) * M_PI / 360.0)) / (M_PI / 180.0); - - $my *= $this->originShift / 180.0; - - return array($mx, $my); - } - -//Converts XY point from Spherical Mercator EPSG:900913 to lat/lon in WGS84 Datum - function MetersToLatLon($mx, $my) { - $lon = ($mx / $this->originShift) * 180.0; - $lat = ($my / $this->originShift) * 180.0; - - $lat = 180 / M_PI * (2 * atan(exp($lat * M_PI / 180.0)) - M_PI / 2.0); - - return array($lat, $lon); - } - -//Converts pixel coordinates in given zoom level of pyramid to EPSG:900913 - function PixelsToMeters($px, $py, $zoom) { - $res = $this->Resolution($zoom); - $mx = $px * $res - $this->originShift; - $my = $py * $res - $this->originShift; - - return array($mx, $my); - } - -//Converts EPSG:900913 to pyramid pixel coordinates in given zoom level - function MetersToPixels($mx, $my, $zoom) { - $res = $this->Resolution($zoom); - - $px = ($mx + $this->originShift) / $res; - $py = ($my + $this->originShift) / $res; - - return array($px, $py); - } - -//Returns a tile covering region in given pixel coordinates - function PixelsToTile($px, $py) { - $tx = ceil($px / $this->tileSize) - 1; - $ty = ceil($py / $this->tileSize) - 1; - - return array($tx, $ty); - } - -//Returns tile for given mercator coordinates - function MetersToTile($mx, $my, $zoom) { - list($px, $py) = $this->MetersToPixels($mx, $my, $zoom); - - return $this->PixelsToTile($px, $py); - } - -//Returns bounds of the given tile in EPSG:900913 coordinates - function TileBounds($tx, $ty, $zoom) { - list($minx, $miny) = $this->PixelsToMeters($tx * $this->tileSize, $ty * $this->tileSize, $zoom); - list($maxx, $maxy) = $this->PixelsToMeters(($tx + 1) * $this->tileSize, ($ty + 1) * $this->tileSize, $zoom); - - return array($minx, $miny, $maxx, $maxy); - } - -//Returns bounds of the given tile in latutude/longitude using WGS84 datum - function TileLatLonBounds($tx, $ty, $zoom) { - $bounds = $this->TileBounds($tx, $ty, $zoom); - - list($minLat, $minLon) = $this->MetersToLatLon($bounds[0], $bounds[1]); - list($maxLat, $maxLon) = $this->MetersToLatLon($bounds[2], $bounds[3]); - - return array($minLat, $minLon, $maxLat, $maxLon); - } - -//Resolution (meters/pixel) for given zoom level (measured at Equator) - function Resolution($zoom) { - return $this->initialResolution / (1 < $zoom); - } - } /** From 7320f426a14991b4eec9bf8129dfa230f38609df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Fri, 4 Mar 2016 13:28:05 +0100 Subject: [PATCH 40/74] Autodetection fix or warning in router, closes #49 --- tileserver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index cb197db..ffe9c94 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1207,7 +1207,7 @@ public static function serve($routes) { $config['protocol'] = ( isset($_SERVER["HTTPS"]) or $_SERVER['SERVER_PORT'] == '443') ? "https" : "http"; if (!empty($_SERVER['PATH_INFO'])) { $path_info = $_SERVER['PATH_INFO']; - } else if (!empty($_SERVER['ORIG_PATH_INFO']) && $_SERVER['ORIG_PATH_INFO'] !== '/tileserver.php') { + } else if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], 'tileserver.php') === false) { $path_info = $_SERVER['ORIG_PATH_INFO']; } else if (!empty($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/tileserver.php') !== false) { $path_info = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; @@ -1255,7 +1255,7 @@ public static function serve($routes) { } } else { if (!isset($config['baseUrls'][0])) { - $config['baseUrls'][0] = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . '?'; + $config['baseUrls'][0] = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } if (strpos($_SERVER['REQUEST_URI'], '=') != FALSE) { $kvp = explode('=', $_SERVER['REQUEST_URI']); From 709ed4ffce69733bb25bae4fa116309c27ed9b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 7 Mar 2016 14:00:29 +0100 Subject: [PATCH 41/74] Revert "Fix of utfgid detection" This reverts commit 8f6a2ced68af2f85a4fb7882d3b9fe78c618fd75. --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index ffe9c94..cc5ec5d 100644 --- a/tileserver.php +++ b/tileserver.php @@ -600,7 +600,7 @@ public function metadataTileJson($metadata) { $metadata['scheme'] = 'xyz'; if ($this->isDBLayer($metadata['basename'])) { $this->DBconnect($metadata['basename'] . '.mbtiles'); - $res = $this->db->query('SELECT * FROM grids LIMIT 1;'); + $res = $this->db->query('SELECT name FROM sqlite_master WHERE name="grids";'); if ($res) { foreach ($this->config['baseUrls'] as $url) { $grids[] = '' . $this->config['protocol'] . '://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}.grid.json'; From 8f2b068c4fa6492a416b352a3fb3e034426e0f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 7 Mar 2016 14:39:28 +0100 Subject: [PATCH 42/74] Custom template implementation #31 --- tileserver.php | 49 ++++++++++++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/tileserver.php b/tileserver.php index cc5ec5d..be05887 100644 --- a/tileserver.php +++ b/tileserver.php @@ -10,6 +10,7 @@ global $config; $config['serverTitle'] = 'TileServer-php v1'; $config['availableFormats'] = array('png', 'jpg', 'jpeg', 'gif', 'webp', 'pbf', 'hybrid'); +//$config['template'] = 'template.php'; //$config['baseUrls'] = array('t0.server.com', 't1.server.com'); Router::serve(array( @@ -74,6 +75,10 @@ public function __construct() { $this->config['baseUrls'] = is_array($envBaseUrls) ? $envBaseUrls : explode(',', $envBaseUrls); } + $envTemplate = getenv('template'); + if($envBaseUrls !== FALSE){ + $this->config['template'] = $envTemplate; + } } /** @@ -516,28 +521,34 @@ public function getInfo() { public function getHtml() { $this->setDatasets(); $maps = array_merge($this->fileLayer, $this->dbLayer); - header('Content-Type: text/html;charset=UTF-8'); - echo '' . $this->config['serverTitle'] . ''; - echo ' - - -

Welcome to ' . $this->config['serverTitle'] . '

-

This server distributes maps to desktop, web, and mobile applications.

-

The mapping data are available as OpenGIS Web Map Tiling Service (OGC WMTS), OSGEO Tile Map Service (TMS), and popular XYZ urls described with TileJSON metadata.

'; - if (!isset($maps)) { - echo '

No maps available yet

-

- Ready to go - just upload some maps into directory:' . getcwd() . '/ on this server.

-

Note: The maps can be a directory with tiles in XYZ format with metadata.json file.
- You can easily convert existing geodata (GeoTIFF, ECW, MrSID, etc) to this tile structure with MapTiler Cluster or open-source projects such as GDAL2Tiles or MapTiler or simply upload any maps in MBTiles format made by TileMill. Helpful is also the mbutil tool. Serving directly from .mbtiles files is supported, but with decreased performance.

'; + if (isset($this->config['template']) && file_exists($this->config['template'])) { + $baseUrls = $this->config['baseUrls']; + $serverTitle = $this->config['serverTitle']; + include_once $this->config['template']; } else { - echo '
    '; - foreach ($maps as $map) { - echo "
  • " . $map['name'] . '
  • '; + header('Content-Type: text/html;charset=UTF-8'); + echo '' . $this->config['serverTitle'] . ''; + echo ' + + +

    Welcome to ' . $this->config['serverTitle'] . '

    +

    This server distributes maps to desktop, web, and mobile applications.

    +

    The mapping data are available as OpenGIS Web Map Tiling Service (OGC WMTS), OSGEO Tile Map Service (TMS), and popular XYZ urls described with TileJSON metadata.

    '; + if (!isset($maps)) { + echo '

    No maps available yet

    +

    + Ready to go - just upload some maps into directory:' . getcwd() . '/ on this server.

    +

    Note: The maps can be a directory with tiles in XYZ format with metadata.json file.
    + You can easily convert existing geodata (GeoTIFF, ECW, MrSID, etc) to this tile structure with MapTiler Cluster or open-source projects such as GDAL2Tiles or MapTiler or simply upload any maps in MBTiles format made by TileMill. Helpful is also the mbutil tool. Serving directly from .mbtiles files is supported, but with decreased performance.

    '; + } else { + echo '
      '; + foreach ($maps as $map) { + echo "
    • " . $map['name'] . '
    • '; + } + echo '
    '; } - echo '
'; + echo ''; } - echo ''; } } From 6b4fb0fec75c9334d503207bc9cb01d990124e07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 7 Mar 2016 14:57:29 +0100 Subject: [PATCH 43/74] WMTS url to tiles simplified for fastest tile serving --- tileserver.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index be05887..883e05d 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1013,8 +1013,8 @@ public function getCapabilities() { } $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); - $resourceUrlTemplate = $wmtsHost . 'wmts/' . $basename - . '/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}'; + $resourceUrlTemplate = $wmtsHost . $basename + . '/{TileMatrix}/{TileCol}/{TileRow}'; if(strlen($format) <= 4){ $resourceUrlTemplate .= '.' . $format; } From 2dfd2fcb5fe333c9e430a38a10892edde4418619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 21 Mar 2016 10:59:29 +0100 Subject: [PATCH 44/74] Max zoom of Mercator TileMatrixSet is affected with max of layers maxzoom (closes #76) --- tileserver.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 883e05d..882cfd6 100644 --- a/tileserver.php +++ b/tileserver.php @@ -830,14 +830,15 @@ private function maxsample($x, $f){ /** * Default TileMetrixSet for Pseudo Mercator projection 3857 + * @param ?number $maxZoom * @return string TileMatrixSet xml */ - public function getMercatorTileMatrixSet(){ + public function getMercatorTileMatrixSet($maxZoom = 18){ $denominatorBase = 559082264.0287178; $extent = array(-20037508.34,-20037508.34,20037508.34,20037508.34); $tileMatrixSet = array(); - for($i = 0; $i <= 18; $i++){ + for($i = 0; $i <= $maxZoom; $i++){ $matrixSize = pow(2, $i); $tileMatrixSet[] = array( 'extent' => $extent, @@ -1010,6 +1011,7 @@ public function getCapabilities() { ); } else { $tileMatrixSet = 'GoogleMapsCompatible'; + $maxMercatorZoom = max(18, $maxMercatorZoom, $m['maxzoom']); } $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); @@ -1044,7 +1046,7 @@ public function getCapabilities() { } // Print PseudoMercator TileMatrixSet - echo $this->getMercatorTileMatrixSet(); + echo $this->getMercatorTileMatrixSet($maxMercatorZoom); // Print WGS84 TileMatrixSet echo $this->getWGS84TileMatrixSet(); From c158bcbe57779177ae4a6204bc6c7dcc7ebdaf5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 21 Mar 2016 13:40:33 +0100 Subject: [PATCH 45/74] Minor warning with some php configurations fixed. --- tileserver.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index 882cfd6..2c4a37b 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1,5 +1,8 @@ $extent, @@ -988,6 +991,7 @@ public function getCapabilities() { '; $customtileMatrixSets = ''; + $maxMercatorZoom = 18; //layers foreach ($layers as $m) { @@ -1011,7 +1015,7 @@ public function getCapabilities() { ); } else { $tileMatrixSet = 'GoogleMapsCompatible'; - $maxMercatorZoom = max(18, $maxMercatorZoom, $m['maxzoom']); + $maxMercatorZoom = max($maxMercatorZoom, $m['maxzoom']); } $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); From bb48534fe3c2e720973c82f9dbdff792c3eaa418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 21 Mar 2016 13:42:53 +0100 Subject: [PATCH 46/74] Removing of useless code. --- tileserver.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 2c4a37b..b2b929f 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1,8 +1,5 @@ Date: Mon, 18 Apr 2016 21:25:38 +0300 Subject: [PATCH 47/74] Faster and ~70% smaller empty png tile --- tileserver.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tileserver.php b/tileserver.php index b2b929f..55a1f74 100644 --- a/tileserver.php +++ b/tileserver.php @@ -420,10 +420,8 @@ public function getCleanTile($scale = 1, $format = 'png') { default: header('Access-Control-Allow-Origin: *'); header('Content-type: image/png'); - $a = ''; - for($i=1; $i < 338; $i++){$a .= 'A';} - echo base64_decode('iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAABFUl' - . 'EQVR42u3BMQEAAADCoPVP7WsIo' . $a . 'eAMBPAAB2ClDBAAAAABJRU5ErkJggg'); + // 256x256 transparent optimised png tile + echo hex2bin('89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f494441541819edc1010d000000c220fba77e0e37600000000000000000e70221000001f5a2bd040000000049454e44ae426082'); break; } die; From f834ec7fd9e37ef72abf9571ceecf55ac2897c96 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Sat, 23 Apr 2016 00:08:21 +0200 Subject: [PATCH 48/74] Deploy to OpenShift via travis --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis.yml b/.travis.yml index 89e1027..7ce7828 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,3 +7,10 @@ php: - hhvm script: - php tileserver.php +deploy: + provider: openshift + user: osm2vectortiles@klokantech.com + secure: U6KRa+Zcflmz1Imu3cH88Svo2uEvwDXPJqXKG5j0ZzttdritF7nH9ZCu6+XHHrdeWR+KjE31QjWnywA5kp9amJIApd3EJjSkIvAPQr56t+9JXYP7d2L45jQAPXs+eaKgJWwnDELfBdAkM/ChHkmrRWM0NVDiUwvQ1wQbbipBVG8= + domain: tileserver + app: php + skip_cleanup: true From 86a1c68888e3bfd1c43bcebbd3818b529cf2d0b9 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Sat, 23 Apr 2016 00:34:40 +0200 Subject: [PATCH 49/74] Update .travis.yml --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7ce7828..6445712 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,8 @@ script: deploy: provider: openshift user: osm2vectortiles@klokantech.com - secure: U6KRa+Zcflmz1Imu3cH88Svo2uEvwDXPJqXKG5j0ZzttdritF7nH9ZCu6+XHHrdeWR+KjE31QjWnywA5kp9amJIApd3EJjSkIvAPQr56t+9JXYP7d2L45jQAPXs+eaKgJWwnDELfBdAkM/ChHkmrRWM0NVDiUwvQ1wQbbipBVG8= + password: + secure: hiWKBaqh/CMdnQ2qxsRSKYAnk4tP/q2J50TaO+2sH09x+0Q85ygfICCDrEx457xqmGW0e4zZPsL83mMPvGt5KJO6g9DIncj6BFhpZA0ysnRJ3X1fczTiVN5hQfqNpa+/YIrQ0whu1Ur/IfdYTtvArYhuAPeigCloumGk9gNgSIQ= domain: tileserver app: php skip_cleanup: true From 4b53b4c351d89658fb6aa09e6aa2ae7a2f8f7afc Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Tue, 3 May 2016 17:15:54 +0200 Subject: [PATCH 50/74] Sample MBTiles file for OpenShift deploy --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6445712..703955d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,12 @@ php: - hhvm script: - php tileserver.php +after_success: + - wget https://github.com/klokantech/tileserver-php/releases/download/v0.1/grandcanyon.mbtiles + - git config --global user.email "travis@localhost.localdomain" + - git config --global user.name "Travis CI" + - git add --all + - git commit -am "Travis change" deploy: provider: openshift user: osm2vectortiles@klokantech.com From ef5de0607dac23cb890977b9f1d037a7689888ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 3 May 2016 22:48:23 +0200 Subject: [PATCH 51/74] Unpack empty png tile PHP 5.2 compatible --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 55a1f74..daa0689 100644 --- a/tileserver.php +++ b/tileserver.php @@ -421,7 +421,7 @@ public function getCleanTile($scale = 1, $format = 'png') { header('Access-Control-Allow-Origin: *'); header('Content-type: image/png'); // 256x256 transparent optimised png tile - echo hex2bin('89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f494441541819edc1010d000000c220fba77e0e37600000000000000000e70221000001f5a2bd040000000049454e44ae426082'); + echo unpack('H', '89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f494441541819edc1010d000000c220fba77e0e37600000000000000000e70221000001f5a2bd040000000049454e44ae426082'); break; } die; From c28d188e0d9dcf4376e5f0ffa6f566005dec097f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 3 May 2016 23:21:40 +0200 Subject: [PATCH 52/74] Empty tile response for jpg and webp --- tileserver.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tileserver.php b/tileserver.php index daa0689..a282b00 100644 --- a/tileserver.php +++ b/tileserver.php @@ -416,6 +416,18 @@ public function getCleanTile($scale = 1, $format = 'png') { header('Content-Type: application/json; charset=utf-8'); echo '{"message":"Tile does not exist"}'; break; + case 'webp': + default: + header('Access-Control-Allow-Origin: *'); + header('Content-type: image/webp'); + echo base64_decode('UklGRhIAAABXRUJQVlA4TAYAAAAvQWxvAGs='); + break; + case 'jpg': + default: + header('Access-Control-Allow-Origin: *'); + header('Content-type: image/jpg'); + echo base64_decode('/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k='); + break; case 'png': default: header('Access-Control-Allow-Origin: *'); From e4148733ed1ae179e2c820c011ed47679b33b92e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 3 May 2016 23:36:31 +0200 Subject: [PATCH 53/74] Empty tile response for jpg and webp --- tileserver.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tileserver.php b/tileserver.php index a282b00..7b3b57d 100644 --- a/tileserver.php +++ b/tileserver.php @@ -417,13 +417,11 @@ public function getCleanTile($scale = 1, $format = 'png') { echo '{"message":"Tile does not exist"}'; break; case 'webp': - default: header('Access-Control-Allow-Origin: *'); header('Content-type: image/webp'); echo base64_decode('UklGRhIAAABXRUJQVlA4TAYAAAAvQWxvAGs='); break; case 'jpg': - default: header('Access-Control-Allow-Origin: *'); header('Content-type: image/jpg'); echo base64_decode('/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k='); From f7613e04a10c2ca64e95336d4c4169962c4ad6c2 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Wed, 4 May 2016 19:19:33 +0200 Subject: [PATCH 54/74] Updated default title of the page --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 7b3b57d..52a078b 100644 --- a/tileserver.php +++ b/tileserver.php @@ -8,7 +8,7 @@ */ global $config; -$config['serverTitle'] = 'TileServer-php v1'; +$config['serverTitle'] = 'Maps hosted with TileServer-php v2.0'; $config['availableFormats'] = array('png', 'jpg', 'jpeg', 'gif', 'webp', 'pbf', 'hybrid'); //$config['template'] = 'template.php'; //$config['baseUrls'] = array('t0.server.com', 't1.server.com'); From 058df85c2e2c5cc4b6e536ad70cd24625705a329 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Thu, 5 May 2016 12:18:20 +0200 Subject: [PATCH 55/74] Readme mentions MVT vector tiles (pbf requests) --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c6a986c..f44f1ef 100644 --- a/README.md +++ b/README.md @@ -91,13 +91,13 @@ Supported protocols: Exposed at http://[...]/tms -- TileJSON.js +- TileJSON Metadata about the individual maps in a ready to use form for web clients following the standard http://mapbox.com/developers/tilejson/ and with support for JSONP access. - Exposed at http://[...]/layer.jsonp + Exposed at http://[...]/layer.json or .jsonp - Direct access with XYZ tile requests (to existing tiles in a directory or to .mbtiles) @@ -113,6 +113,12 @@ Supported protocols: Exposed at http://[...]/layer/z/x/y.grid.json +- MapBox Vector Tiles (for MBTiles generated by [MapBox Studio Classic](https://www.mapbox.com/mapbox-studio-classic/) or by [OSM2VectorTiles](http://osm2vectortiles.org/) project). + + Example http://osm2vectortiles.tileserver.com/ + TileJSON can be used in MapBox Studio Classic, MapBox SDKs/APIs, OpenLayers, etc. + + Exposed at http://[...]/layer/z/x/y.pbf To use the OGC WMTS standard point your client (desktop or web) to the URL of 'directory' where you installed tileserver.php project with suffix "wmts". From 7405ec3dc3b927378df95fedf564b6f901ef58c3 Mon Sep 17 00:00:00 2001 From: Mark Furland Date: Fri, 26 Aug 2016 11:12:43 -0400 Subject: [PATCH 56/74] Add prefix to mbtiles, return 204 on no tile This adds a configuration option for a prefix to the mbtiles, so you can store the tiles in other locations. It also changes the no tile found 404 to a 204, as the mapbox team will be doing: https://github.com/mapbox/mapbox-gl-js/issues/1800#issuecomment-236190808 --- tileserver.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tileserver.php b/tileserver.php index 52a078b..87b4eb6 100644 --- a/tileserver.php +++ b/tileserver.php @@ -10,6 +10,7 @@ global $config; $config['serverTitle'] = 'Maps hosted with TileServer-php v2.0'; $config['availableFormats'] = array('png', 'jpg', 'jpeg', 'gif', 'webp', 'pbf', 'hybrid'); +$config['mbtilesPrefix'] = './'; //$config['template'] = 'template.php'; //$config['baseUrls'] = array('t0.server.com', 't1.server.com'); @@ -86,7 +87,7 @@ public function __construct() { */ public function setDatasets() { $mjs = glob('*/metadata.json'); - $mbts = glob('*.mbtiles'); + $mbts = glob($this->config['mbtilesPrefix'] . '*.mbtiles'); if ($mjs) { foreach (array_filter($mjs, 'is_readable') as $mj) { $layer = $this->metadataFromMetadataJson($mj); @@ -139,7 +140,7 @@ public function getGlobal($isKey) { * @return boolean */ public function isDBLayer($layer) { - if (is_file($layer . '.mbtiles')) { + if (is_file($this->config['mbtilesPrefix'] . $layer . '.mbtiles')) { return TRUE; } else { return FALSE; @@ -310,7 +311,7 @@ public function DBconnect($tileset) { * @return boolean */ public function isModified($filename) { - $filename = $filename . '.mbtiles'; + $filename = $this->config['mbtilesPrefix'] . $filename . '.mbtiles'; $lastModifiedTime = filemtime($filename); $eTag = md5($lastModifiedTime); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT'); @@ -338,7 +339,7 @@ public function renderTile($tileset, $z, $y, $x, $ext) { header('HTTP/1.1 304 Not Modified'); die; } - $this->DBconnect($tileset . '.mbtiles'); + $this->DBconnect($this->config['mbtilesPrefix'] . $tileset . '.mbtiles'); $z = floatval($z); $y = floatval($y); $x = floatval($x); @@ -412,7 +413,8 @@ public function renderTile($tileset, $z, $y, $x, $ext) { public function getCleanTile($scale = 1, $format = 'png') { switch ($format) { case 'pbf': - header('HTTP/1.1 404 Not Found'); + header('Access-Control-Allow-Origin: *'); + header('HTTP/1.1 204 No Content'); header('Content-Type: application/json; charset=utf-8'); echo '{"message":"Tile does not exist"}'; break; @@ -453,7 +455,7 @@ public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { $y = pow(2, $z) - 1 - $y; } try { - $this->DBconnect($tileset . '.mbtiles'); + $this->DBconnect($this->config['mbtilesPrefix'] . $tileset . '.mbtiles'); $query = 'SELECT grid FROM grids WHERE tile_column = ' . $x . ' AND ' . 'tile_row = ' . $y . ' AND zoom_level = ' . $z; @@ -618,7 +620,7 @@ public function metadataTileJson($metadata) { $metadata['tilejson'] = '2.0.0'; $metadata['scheme'] = 'xyz'; if ($this->isDBLayer($metadata['basename'])) { - $this->DBconnect($metadata['basename'] . '.mbtiles'); + $this->DBconnect($this->config['mbtilesPrefix'] . $metadata['basename'] . '.mbtiles'); $res = $this->db->query('SELECT name FROM sqlite_master WHERE name="grids";'); if ($res) { foreach ($this->config['baseUrls'] as $url) { @@ -1147,7 +1149,7 @@ public function getCapabilities() { } else { $srs = 'EPSG:3857'; } - $url = $this->config['protocol'] . '://' . $this->config['baseUrls'][0] + $url = $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/tms/' . $basename; echo 'config['baseUrls'] as $url) { From d7a4ad03c1a36a41e2347a0af86e7f0ff147d99f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 6 Dec 2016 17:58:22 +0100 Subject: [PATCH 58/74] Use https with X-Forwarded-Proto (issue #92) --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 8c57f41..68d27e5 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1228,7 +1228,7 @@ public static function serve($routes) { $request_method = strtolower($_SERVER['REQUEST_METHOD']); $path_info = '/'; global $config; - $config['protocol'] = ( isset($_SERVER["HTTPS"]) or $_SERVER['SERVER_PORT'] == '443') ? "https" : "http"; + $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $_SERVER['X-Forwarded-Proto']) == 'https' ? 'https' : 'http'; if (!empty($_SERVER['PATH_INFO'])) { $path_info = $_SERVER['PATH_INFO']; } else if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], 'tileserver.php') === false) { From 758b6a1e4de2370ad28395562d86aef53e19f2ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 6 Dec 2016 18:10:06 +0100 Subject: [PATCH 59/74] Fix of X-Forwarded-Proto server variable (issue #92) --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 68d27e5..877030a 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1228,7 +1228,7 @@ public static function serve($routes) { $request_method = strtolower($_SERVER['REQUEST_METHOD']); $path_info = '/'; global $config; - $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $_SERVER['X-Forwarded-Proto']) == 'https' ? 'https' : 'http'; + $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' ? 'https' : 'http'; if (!empty($_SERVER['PATH_INFO'])) { $path_info = $_SERVER['PATH_INFO']; } else if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], 'tileserver.php') === false) { From 5f314fef28a38d21fa4b83fa050f60c50632d63a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 6 Dec 2016 23:18:30 +0100 Subject: [PATCH 60/74] Fixed bug in condition with X-Forwarded-Proto --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 877030a..0018538 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1228,7 +1228,7 @@ public static function serve($routes) { $request_method = strtolower($_SERVER['REQUEST_METHOD']); $path_info = '/'; global $config; - $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https' ? 'https' : 'http'; + $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ? 'https' : 'http'; if (!empty($_SERVER['PATH_INFO'])) { $path_info = $_SERVER['PATH_INFO']; } else if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], 'tileserver.php') === false) { From dc2452e781fee4708c2be2fe8364950116bd9a4c Mon Sep 17 00:00:00 2001 From: Matt Burke Date: Thu, 6 Apr 2017 10:27:04 -0400 Subject: [PATCH 61/74] Fixed issue where tiles are not loaded if HTTP_X_FORWARDED_PROTO is unset. --- tileserver.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 0018538..7b21dcb 100644 --- a/tileserver.php +++ b/tileserver.php @@ -65,7 +65,7 @@ class Server { */ public function __construct() { $this->config = $GLOBALS['config']; - + //Get config from enviroment $envServerTitle = getenv('serverTitle'); if($envServerTitle !== FALSE){ @@ -73,7 +73,7 @@ public function __construct() { } $envBaseUrls = getenv('baseUrls'); if($envBaseUrls !== FALSE){ - $this->config['baseUrls'] = is_array($envBaseUrls) ? + $this->config['baseUrls'] = is_array($envBaseUrls) ? $envBaseUrls : explode(',', $envBaseUrls); } $envTemplate = getenv('template'); @@ -1228,7 +1228,13 @@ public static function serve($routes) { $request_method = strtolower($_SERVER['REQUEST_METHOD']); $path_info = '/'; global $config; - $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ? 'https' : 'http'; + $xForwarded = false; + if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { + if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { + $xForwarded = true; + } + } + $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $xForwarded) ? 'https' : 'http'; if (!empty($_SERVER['PATH_INFO'])) { $path_info = $_SERVER['PATH_INFO']; } else if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], 'tileserver.php') === false) { From bb823a57ffc1c16713f3602e8df4ae967c4a3233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 24 Apr 2017 15:26:57 +0200 Subject: [PATCH 62/74] 0. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 703955d..06810c2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,8 @@ php: - 5.4 - 5.5 - 5.6 + - 7.0 + - 7.1 - hhvm script: - php tileserver.php From f75b1bbfa6a177b4c9290f488bfd82a206969b11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 5 Dec 2017 15:31:40 +0100 Subject: [PATCH 63/74] Don't need trailing slash in dataroot --- tileserver.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tileserver.php b/tileserver.php index 7b21dcb..98093d0 100644 --- a/tileserver.php +++ b/tileserver.php @@ -66,6 +66,11 @@ class Server { public function __construct() { $this->config = $GLOBALS['config']; + if($this->config['dataRoot'] != '' + && substr($this->config['dataRoot'], -1) != '/' ){ + $this->config['dataRoot'] .= '/'; + } + //Get config from enviroment $envServerTitle = getenv('serverTitle'); if($envServerTitle !== FALSE){ From d3ebdec555098e0fc8d62a09636c69ff31ebd641 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 19 Feb 2018 15:52:48 +0100 Subject: [PATCH 64/74] Strip incorrectly encoded property in OMT datasets --- tileserver.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 98093d0..3827fd2 100644 --- a/tileserver.php +++ b/tileserver.php @@ -637,7 +637,9 @@ public function metadataTileJson($metadata) { if (array_key_exists('json', $metadata)) { $mjson = json_decode(stripslashes($metadata['json'])); foreach ($mjson as $key => $value) { - $metadata[$key] = $value; + if ($key != 'Layer'){ + $metadata[$key] = $value; + } } unset($metadata['json']); } From e6af62e1919c9d3e7daf0c82e0a72875bde8de83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 19 Feb 2018 15:59:44 +0100 Subject: [PATCH 65/74] Remove PHP 5.3 check from travis --- .travis.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 06810c2..dd8f16a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 From dca0e642191e08097e66ed920a51dc68ec682d1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 19 Feb 2018 16:15:14 +0100 Subject: [PATCH 66/74] Removed unused var in router --- tileserver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 3827fd2..6813e8d 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1232,7 +1232,6 @@ class Router { * @param array $routes */ public static function serve($routes) { - $request_method = strtolower($_SERVER['REQUEST_METHOD']); $path_info = '/'; global $config; $xForwarded = false; From 2a84c6271f732687e06ab71ca252cfc6a5425790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 19 Feb 2018 16:31:18 +0100 Subject: [PATCH 67/74] Fix Undefined index SERVER_PORT router error in some server configs --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 6813e8d..350603e 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1240,7 +1240,7 @@ public static function serve($routes) { $xForwarded = true; } } - $config['protocol'] = ((isset($_SERVER['HTTPS']) or $_SERVER['SERVER_PORT'] == '443') or $xForwarded) ? 'https' : 'http'; + $config['protocol'] = ((isset($_SERVER['HTTPS']) or (isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)) or $xForwarded) ? 'https' : 'http'; if (!empty($_SERVER['PATH_INFO'])) { $path_info = $_SERVER['PATH_INFO']; } else if (!empty($_SERVER['ORIG_PATH_INFO']) && strpos($_SERVER['ORIG_PATH_INFO'], 'tileserver.php') === false) { From 5ddbfa300a8bc84746ee3c19abba6b3638bca3d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Mon, 2 Jul 2018 11:45:46 +0200 Subject: [PATCH 68/74] Updated readme with tile size, closes #129 and custom CRS --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f44f1ef..d8dbec9 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,9 @@ Supported protocols: TileJSON can be used in MapBox Studio Classic, MapBox SDKs/APIs, OpenLayers, etc. Exposed at http://[...]/layer/z/x/y.pbf + +- Retina / HighDPI routing with 512 tiles +Use @2x suffix in url for JSONs and tiles. For example http://tileserver.maptiler.com/grandcanyon@2x.json To use the OGC WMTS standard point your client (desktop or web) to the URL of 'directory' where you installed tileserver.php project with suffix "wmts". @@ -137,9 +140,12 @@ GetTile RESTful/KVP: http://[...]/layer/[ANYTHING-OPTIONAL][z]/[x]/[y].[ext] http://[...]?service=wmts&request=getTile&layer=[layer]&tilematrix=[z]&tilerow=[y]&tilecol=[y]&format=[ext] - + Other example requests are mentioned in the .htaccess. +TileServer-PHP supports all coordinates system. You have to define it with tilejson with specification on https://github.com/klokantech/tilejson-spec/tree/custom-projection/2.2.0 +Or use MapTiler to produce datasets with this specification. + Performance from the web clients -------------------------------- @@ -174,9 +180,6 @@ Limits of actual implementation ------------------------------- With intention, in this moment the project supports only: -- Mercator tiles (a la OpenStreetMap) and Geodetic tiles (WGS84 unprojected) - with known and described tiling scheme. -- All tiles must be 256x256 pixels. - We enforce and require XYZ (top-left origin) tiling schema (even for TMS). Password protection From d11963d43c28dab5be202bfd1586ad259b628ad7 Mon Sep 17 00:00:00 2001 From: Isaac Besora Vilardaga Date: Mon, 7 Jan 2019 14:01:19 +0100 Subject: [PATCH 69/74] Removes body data from http 204 response --- tileserver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 350603e..ea730dc 100644 --- a/tileserver.php +++ b/tileserver.php @@ -421,7 +421,6 @@ public function getCleanTile($scale = 1, $format = 'png') { header('Access-Control-Allow-Origin: *'); header('HTTP/1.1 204 No Content'); header('Content-Type: application/json; charset=utf-8'); - echo '{"message":"Tile does not exist"}'; break; case 'webp': header('Access-Control-Allow-Origin: *'); From 4c339b8d195b9842804199f073c869610d351b4d Mon Sep 17 00:00:00 2001 From: CodeLingoBot Date: Wed, 3 Apr 2019 11:24:50 +1300 Subject: [PATCH 70/74] Change PHP keywords to comply with PSR2 Signed-off-by: CodeLingoBot --- tileserver.php | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/tileserver.php b/tileserver.php index ea730dc..d26b2d2 100644 --- a/tileserver.php +++ b/tileserver.php @@ -73,16 +73,16 @@ public function __construct() { //Get config from enviroment $envServerTitle = getenv('serverTitle'); - if($envServerTitle !== FALSE){ + if($envServerTitle !== false){ $this->config['serverTitle'] = $envServerTitle; } $envBaseUrls = getenv('baseUrls'); - if($envBaseUrls !== FALSE){ + if($envBaseUrls !== false){ $this->config['baseUrls'] = is_array($envBaseUrls) ? $envBaseUrls : explode(',', $envBaseUrls); } $envTemplate = getenv('template'); - if($envBaseUrls !== FALSE){ + if($envBaseUrls !== false){ $this->config['template'] = $envTemplate; } } @@ -120,7 +120,7 @@ public function setParams($params) { $this->x = $params[1]; $file = explode('.', $params[0]); $this->y = $file[0]; - $this->ext = isset($file[1]) ? $file[1] : NULL; + $this->ext = isset($file[1]) ? $file[1] : null; } } @@ -136,7 +136,7 @@ public function getGlobal($isKey) { return $value; } } - return FALSE; + return false; } /** @@ -146,9 +146,9 @@ public function getGlobal($isKey) { */ public function isDBLayer($layer) { if (is_file($this->config['dataRoot'] . $layer . '.mbtiles')) { - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -159,9 +159,9 @@ public function isDBLayer($layer) { */ public function isFileLayer($layer) { if (is_dir($layer)) { - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -323,9 +323,9 @@ public function isModified($filename) { header('Etag:' . $eTag); if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModifiedTime || @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $eTag) { - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -339,7 +339,7 @@ public function isModified($filename) { */ public function renderTile($tileset, $z, $y, $x, $ext) { if ($this->isDBLayer($tileset)) { - if ($this->isModified($tileset) == TRUE) { + if ($this->isModified($tileset) == true) { header('Access-Control-Allow-Origin: *'); header('HTTP/1.1 304 Not Modified'); die; @@ -354,17 +354,17 @@ public function renderTile($tileset, $z, $y, $x, $ext) { } $result = $this->db->query('select tile_data as t from tiles where zoom_level=' . $z . ' and tile_column=' . $x . ' and tile_row=' . $y); $data = $result->fetchColumn(); - if (!isset($data) || $data === FALSE) { + if (!isset($data) || $data === false) { //if tile doesn't exist //select scale of tile (for retina tiles) $result = $this->db->query('select value from metadata where name="scale"'); $resultdata = $result->fetchColumn(); - $scale = isset($resultdata) && $resultdata !== FALSE ? $resultdata : 1; + $scale = isset($resultdata) && $resultdata !== false ? $resultdata : 1; $this->getCleanTile($scale, $ext); } else { $result = $this->db->query('select value from metadata where name="format"'); $resultdata = $result->fetchColumn(); - $format = isset($resultdata) && $resultdata !== FALSE ? $resultdata : 'png'; + $format = isset($resultdata) && $resultdata !== false ? $resultdata : 'png'; if ($format == 'jpg') { $format = 'jpeg'; } @@ -380,11 +380,11 @@ public function renderTile($tileset, $z, $y, $x, $ext) { } elseif ($this->isFileLayer($tileset)) { $name = './' . $tileset . '/' . $z . '/' . $x . '/' . $y; $mime = 'image/'; - if($ext != NULL){ + if($ext != null){ $name .= '.' . $ext; } if ($fp = @fopen($name, 'rb')) { - if($ext != NULL){ + if($ext != null){ $mime .= $ext; }else{ //detect image type from file @@ -450,9 +450,9 @@ public function getCleanTile($scale = 1, $format = 'png') { * @param integer $y * @param integer $x */ - public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { + public function renderUTFGrid($tileset, $z, $y, $x, $flip = true) { if ($this->isDBLayer($tileset)) { - if ($this->isModified($tileset) == TRUE) { + if ($this->isModified($tileset) == true) { header('HTTP/1.1 304 Not Modified'); } if ($flip) { @@ -466,7 +466,7 @@ public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) { $result = $this->db->query($query); $data = $result->fetch(PDO::FETCH_ASSOC); - if ($data !== FALSE) { + if ($data !== false) { $grid = gzuncompress($data['grid']); $grid = substr(trim($grid), 0, -1); @@ -756,7 +756,7 @@ public function __construct($params) { */ public function get() { $request = $this->getGlobal('Request'); - if ($request !== FALSE && $request == 'gettile') { + if ($request !== false && $request == 'gettile') { $this->getTile(); } else { parent::setDatasets(); @@ -1079,7 +1079,7 @@ public function getCapabilities() { public function getTile() { $request = $this->getGlobal('Request'); if ($request) { - if (strpos('/', $_GET['Format']) !== FALSE) { + if (strpos('/', $_GET['Format']) !== false) { $format = explode('/', $_GET['Format']); $format = $format[1]; } else { @@ -1292,7 +1292,7 @@ public static function serve($routes) { if (!isset($config['baseUrls'][0])) { $config['baseUrls'][0] = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; } - if (strpos($_SERVER['REQUEST_URI'], '=') != FALSE) { + if (strpos($_SERVER['REQUEST_URI'], '=') != false) { $kvp = explode('=', $_SERVER['REQUEST_URI']); $_GET['callback'] = $kvp[1]; $params[0] = 'index'; From 54254f8ef1bd279c95ac9846029a7fa85bc1495c Mon Sep 17 00:00:00 2001 From: Jorgen Date: Thu, 11 Jul 2019 13:27:21 +0200 Subject: [PATCH 71/74] Resolved bug in transparent png tile --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 tileserver.php diff --git a/tileserver.php b/tileserver.php old mode 100644 new mode 100755 index d26b2d2..96f53a0 --- a/tileserver.php +++ b/tileserver.php @@ -437,7 +437,7 @@ public function getCleanTile($scale = 1, $format = 'png') { header('Access-Control-Allow-Origin: *'); header('Content-type: image/png'); // 256x256 transparent optimised png tile - echo unpack('H', '89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f494441541819edc1010d000000c220fba77e0e37600000000000000000e70221000001f5a2bd040000000049454e44ae426082'); + echo pack('H*', '89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c5445000000a77a3dda0000000174524e530040e6d8660000001f494441541819edc1010d000000c220fba77e0e37600000000000000000e70221000001f5a2bd040000000049454e44ae426082'); break; } die; From 43e3cadb8768d718def5e43067767ec5420296c3 Mon Sep 17 00:00:00 2001 From: Dalibor Janak Date: Tue, 28 Jul 2020 22:34:22 +0200 Subject: [PATCH 72/74] Remove old aray syntax --- README.md | 42 ++++++++++++------------ tileserver.php | 86 +++++++++++++++++++++++++------------------------- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index d8dbec9..ce2e32c 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Requirements: ------------- - Apache webserver (with mod_rewrite / .htaccess supported) -- PHP 5.2+ with SQLite module (php5-sqlite) +- PHP 5.6+ with SQLite module (php5-sqlite) (or another webserver implementing mod_rewrite rules and PHP) @@ -50,7 +50,7 @@ Installation: Download the project files as a [zip archive](https://github.com/klokantech/tileserver-php/archive/master.zip) or source code from GitHub and unpack it into a web-hosting of your choice. -If you access the web address relevant to the installation directory, +If you access the web address relevant to the installation directory, the TileServer.php Server should display you a welcome message and further instructions. @@ -70,15 +70,15 @@ Supported protocols: -------------------- - OpenGIS WMTS 1.0.0 - + The Open Geospatial Consortium (OGC) Web Map Tile Service (WMTS) Both KVP and RESTful version 1.0.0: http://www.opengeospatial.org/standards/wmts/ - + Target is maximal compliance to the standard. - + Exposed at http://[...]/wmts - + - OSGeo TMS 1.0.0 The OSGeo Tile Maps Service, but with inverted y-coordinates: @@ -90,7 +90,7 @@ Supported protocols: flipped y-axis. Exposed at http://[...]/tms - + - TileJSON Metadata about the individual maps in a ready to use form for web @@ -98,28 +98,28 @@ Supported protocols: and with support for JSONP access. Exposed at http://[...]/layer.json or .jsonp - + - Direct access with XYZ tile requests (to existing tiles in a directory or to .mbtiles) Compatible with Google Maps API / Bing SDK / OpenStreetMap clients. - + Exposed at http://[...]/layer/z/x/y.ext - -- MapBox UTFgrid request (for existing tiles in .mbtiles with UTFgrid support). Callback is supported + +- MapBox UTFgrid request (for existing tiles in .mbtiles with UTFgrid support). Callback is supported Example https://www.mapbox.com/demo/visiblemap/ Specification https://github.com/mapbox/utfgrid-spec - + Exposed at http://[...]/layer/z/x/y.grid.json - + - MapBox Vector Tiles (for MBTiles generated by [MapBox Studio Classic](https://www.mapbox.com/mapbox-studio-classic/) or by [OSM2VectorTiles](http://osm2vectortiles.org/) project). Example http://osm2vectortiles.tileserver.com/ TileJSON can be used in MapBox Studio Classic, MapBox SDKs/APIs, OpenLayers, etc. Exposed at http://[...]/layer/z/x/y.pbf - + - Retina / HighDPI routing with 512 tiles Use @2x suffix in url for JSONs and tiles. For example http://tileserver.maptiler.com/grandcanyon@2x.json @@ -132,12 +132,12 @@ If you have installed the project into a root directory of a domain, then the ad The supported WMTS requests includes: GetCapabilities RESTful/KVP: - + http://[...]/1.0.0/WMTSCapabilities.xml http://[...]?service=wmts&request=getcapabilities&version=1.0.0 - + GetTile RESTful/KVP: - + http://[...]/layer/[ANYTHING-OPTIONAL][z]/[x]/[y].[ext] http://[...]?service=wmts&request=getTile&layer=[layer]&tilematrix=[z]&tilerow=[y]&tilecol=[y]&format=[ext] @@ -248,17 +248,17 @@ Tested WMTS/TMS clients BSD License ----------- -Copyright (C) 2015 Klokan Technologies GmbH (http://www.klokantech.com/) +Copyright (C) 2020 MapTiler AG (https://www.maptiler.com/) All rights reserved. Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. + list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. + and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED diff --git a/tileserver.php b/tileserver.php index d26b2d2..7270ce6 100644 --- a/tileserver.php +++ b/tileserver.php @@ -1,20 +1,20 @@ 'Server:getHtml', '/maps' => 'Server:getInfo', '/html' => 'Server:getHtml', @@ -29,7 +29,7 @@ '/:alpha/:number/:number/:alpha' => 'Wmts:getTile', '/tms' => 'Tms:getCapabilities', '/tms/:alpha' => 'Tms:getLayerCapabilities', -)); +]); /** * Server base @@ -46,13 +46,13 @@ class Server { * Datasets stored in file structure * @var array */ - public $fileLayer = array(); + public $fileLayer = []; /** * Datasets stored in database * @var array */ - public $dbLayer = array(); + public $dbLayer = []; /** * PDO database connection @@ -182,7 +182,7 @@ public function metadataFromMetadataJson($jsonFileName) { * @return object */ public function metadataFromMbtiles($mbt) { - $metadata = array(); + $metadata = []; $this->DBconnect($mbt); $result = $this->db->query('select * from metadata'); @@ -220,7 +220,7 @@ public function metadataFromMbtiles($mbt) { $e = -180 + 360 * ((1 + $resultdata[0]['e']) / pow(2, $metadata['maxzoom'])); $n = $this->row2lat($resultdata[0]['n'], $metadata['maxzoom']); $s = $this->row2lat($resultdata[0]['s'] - 1, $metadata['maxzoom']); - $metadata['bounds'] = implode(',', array($w, $s, $e, $n)); + $metadata['bounds'] = implode(',', [$w, $s, $e, $n]); } $mbt = explode('.', $mbt); $metadata['basename'] = $mbt[0]; @@ -246,7 +246,7 @@ public function row2lat($r, $zoom) { */ public function metadataValidation($metadata) { if (!array_key_exists('bounds', $metadata)) { - $metadata['bounds'] = array(-180, -85.06, 180, 85.06); + $metadata['bounds'] = [-180, -85.06, 180, 85.06]; } elseif (!is_array($metadata['bounds'])) { $metadata['bounds'] = array_map('floatval', explode(',', $metadata['bounds'])); } @@ -277,7 +277,7 @@ public function metadataValidation($metadata) { $metadata['scale'] = 1; } if(!array_key_exists('tiles', $metadata)){ - $tiles = array(); + $tiles = []; foreach ($this->config['baseUrls'] as $url) { $url = '' . $this->config['protocol'] . '://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}'; @@ -297,7 +297,7 @@ public function metadataValidation($metadata) { */ public function DBconnect($tileset) { try { - $this->db = new PDO('sqlite:' . $tileset, '', '', array(PDO::ATTR_PERSISTENT => true)); + $this->db = new PDO('sqlite:' . $tileset, '', '', [PDO::ATTR_PERSISTENT => true]); } catch (Exception $exc) { echo $exc->getTraceAsString(); die; @@ -388,7 +388,7 @@ public function renderTile($tileset, $z, $y, $x, $ext) { $mime .= $ext; }else{ //detect image type from file - $mimetypes = array('gif', 'jpeg', 'png'); + $mimetypes = ['gif', 'jpeg', 'png']; $mime .= $mimetypes[exif_imagetype($name) - 1]; } header('Access-Control-Allow-Origin: *'); @@ -792,15 +792,15 @@ public function parseTileMatrix($layer, $tileMatrix){ $tileMatrix[$i]['pixel_size'], $tileMatrix[$i]['tile_size'] ); - $tileMatrix[$i]['matrix_size'] = array( + $tileMatrix[$i]['matrix_size'] = [ $tileExtent[2] + 1, $tileExtent[1] + 1 - ); + ]; } if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ - $tileMatrix[$i]['origin'] = array( + $tileMatrix[$i]['origin'] = [ $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] - ); + ]; } // Origins of geographic coordinate systems are setting in opposite order if (isset($proj4) && $proj4['proj'] === 'longlat') { @@ -811,7 +811,7 @@ public function parseTileMatrix($layer, $tileMatrix){ } if(!isset($tileMatrix[$i]['tile_size'])){ $tileSize = 256 * (int) $layer['scale']; - $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); + $tileMatrix[$i]['tile_size'] = [$tileSize, $tileSize]; } } @@ -827,12 +827,12 @@ public function parseTileMatrix($layer, $tileMatrix){ * @return array */ public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { - $tiles = array( + $tiles = [ $this->minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]), $this->minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]), $this->maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]), $this->maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]), - ); + ]; return $tiles; } @@ -851,19 +851,19 @@ private function maxsample($x, $f){ */ public function getMercatorTileMatrixSet($maxZoom = 18){ $denominatorBase = 559082264.0287178; - $extent = array(-20037508.34,-20037508.34,20037508.34,20037508.34); - $tileMatrixSet = array(); + $extent = [-20037508.34,-20037508.34,20037508.34,20037508.34]; + $tileMatrixSet = []; for($i = 0; $i <= $maxZoom; $i++){ $matrixSize = pow(2, $i); - $tileMatrixSet[] = array( + $tileMatrixSet[] = [ 'extent' => $extent, 'id' => (string) $i, - 'matrix_size' => array($matrixSize, $matrixSize), - 'origin' => array($extent[0], $extent[3]), + 'matrix_size' => [$matrixSize, $matrixSize], + 'origin' => [$extent[0], $extent[3]], 'scale_denominator' => $denominatorBase / pow(2, $i), - 'tile_size' => array(256, 256) - ); + 'tile_size' => [256, 256] + ]; } return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); @@ -874,26 +874,26 @@ public function getMercatorTileMatrixSet($maxZoom = 18){ * @return string Xml */ public function getWGS84TileMatrixSet(){ - $extent = array(-180.000000, -90.000000, 180.000000, 90.000000); - $scaleDenominators = array(279541132.01435887813568115234, 139770566.00717943906784057617, + $extent = [-180.000000, -90.000000, 180.000000, 90.000000]; + $scaleDenominators = [279541132.01435887813568115234, 139770566.00717943906784057617, 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, - 2132.72958384978574031265); - $tileMatrixSet = array(); + 2132.72958384978574031265]; + $tileMatrixSet = []; for($i = 0; $i <= 17; $i++){ $matrixSize = pow(2, $i); - $tileMatrixSet[] = array( + $tileMatrixSet[] = [ 'extent' => $extent, 'id' => (string) $i, - 'matrix_size' => array($matrixSize * 2, $matrixSize), - 'origin' => array($extent[3], $extent[0]), + 'matrix_size' => [$matrixSize * 2, $matrixSize], + 'origin' => [$extent[3], $extent[0]], 'scale_denominator' => $scaleDenominators[$i], - 'tile_size' => array(256, 256) - ); + 'tile_size' => [256, 256] + ]; } return $this->getTileMatrixSet('WGS84', $tileMatrixSet, 'EPSG:4326'); @@ -1192,7 +1192,7 @@ public function getLayerCapabilities() { } } else { $srs = 'EPSG:3857'; - $bounds = array(-20037508.34,-20037508.34,20037508.34,20037508.34); + $bounds = [-20037508.34,-20037508.34,20037508.34,20037508.34]; $initRes = 156543.03392804062; } $mime = ($m['format'] == 'jpg') ? 'image/jpeg' : 'image/png'; @@ -1253,14 +1253,14 @@ public static function serve($routes) { } } $discovered_handler = null; - $regex_matches = array(); + $regex_matches = []; if ($routes) { - $tokens = array( + $tokens = [ ':string' => '([a-zA-Z]+)', ':number' => '([0-9]+)', ':alpha' => '([a-zA-Z0-9-_@\.]+)' - ); + ]; //global $config; foreach ($routes as $pattern => $handler_name) { $pattern = strtr($pattern, $tokens); @@ -1281,7 +1281,7 @@ public static function serve($routes) { $discoverered_class = explode(':', $discovered_handler); $discoverered_method = explode(':', $discovered_handler); $handler_instance = new $discoverered_class[0]($regex_matches); - call_user_func(array($handler_instance, $discoverered_method[1])); + call_user_func([$handler_instance, $discoverered_method[1]]); } else { $handler_instance = new $discovered_handler($regex_matches); } From 7800af830a5f56c2d9aba30d2fc925284253839b Mon Sep 17 00:00:00 2001 From: David Eagles Date: Fri, 24 Sep 2021 11:09:17 +1000 Subject: [PATCH 73/74] Modified WMTS Resource URL generation to support hostnames that contain the layer name. If the hostname contained the layer name (eg. https://layername.domain.com/layername/wmts) then the WMTS capabilities document contained an incorrect Resource URL because the hostname was stripped back to simply https://. This modification simply looks for the last occurrence of the layer name instead of the first when forming the Resource URL. --- tileserver.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 7397e01..d4e12d4 100755 --- a/tileserver.php +++ b/tileserver.php @@ -1031,7 +1031,7 @@ public function getCapabilities() { $maxMercatorZoom = max($maxMercatorZoom, $m['maxzoom']); } - $wmtsHost = substr($m['tiles'][0], 0, strpos($m['tiles'][0], $m['basename'])); + $wmtsHost = substr($m['tiles'][0], 0, strrpos($m['tiles'][0], $m['basename'])); $resourceUrlTemplate = $wmtsHost . $basename . '/{TileMatrix}/{TileCol}/{TileRow}'; if(strlen($format) <= 4){ From d0fdeaec69688dc500b652a23669d724d7d53df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Kom=C3=A1rek?= Date: Sat, 30 Jul 2022 02:03:50 +0200 Subject: [PATCH 74/74] grammar check --- README.md | 94 +++++++++++++++++++------------------------------------ 1 file changed, 33 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index ce2e32c..89e756d 100644 --- a/README.md +++ b/README.md @@ -4,36 +4,23 @@ TileServer PHP: MapTiler and MBTiles maps via WMTS [![Build Status](https://travis-ci.org/klokantech/tileserver-php.svg)](https://travis-ci.org/klokantech/tileserver-php) [![Docker Hub](https://img.shields.io/badge/docker-hub-blue.svg)](https://hub.docker.com/r/klokantech/tileserver-php/) -This server distributes maps to desktop, web, and mobile applications from -a standard Apache+PHP web hosting. +This server distributes maps to desktop, web, and mobile applications from a standard Apache+PHP web hosting. -Try a live demo at: http://tileserver.maptiler.com/ +It is a free and open-source project implementing the OGC WMTS standard for pre-rendered map tiles made with any [map tiling software](https://www.maptiler.com/desktop/) like MapTiler Desktop, GDAL2Tiles, or any other MBTiles file. -It is a free and open-source project implementing OGC WMTS standard for -pre-rendered map tiles made with [MapTiler](http://www.maptiler.com/), GDAL2Tiles, -or available as MBTiles files. +It is the easiest and cheapest way how to serve zoomable maps in a standardized way - practically from any ordinary web hosting. -It is the easiest and cheapest way how to serve zoomable maps in a -standardized way - practically from any ordinary web hosting. +It is easy to install - copy the project files to a PHP-enabled directory along with your map data. -It is easy to install - just copy the project files to a PHP-enabled -directory along with your map data. - -It comes with an online interface showing the list of the maps and step-by-step guides for online mapping libraries (Google Maps API, Leaflet, OpenLayers, OL3, MapBox JS, ArcGIS JS) and various desktop GIS software: +It comes with an online interface showing the list of the maps and step-by-step guides for online mapping libraries (Google Maps API, Leaflet, OpenLayers, OL3, MapLibre GL JS, ArcGIS JS) and various desktop GIS software: ![tileserver-screenshot](https://f.cloud.github.com/assets/59284/1041807/a040160c-0fdb-11e3-8941-ab367b2a648d.png) -This project is developed in PHP, not because it is the best language for -development of web applications, but because it maximally simplify the -deployment on large number of web hosting providers including various free -web hostings. +This project is developed in PHP, not because it is the best language for the development of web applications, but because it maximally simplifies the deployment on a large number of web hostings, including various free web hostings providers. -Tiles are served directly by Apache with mod_rewrite rules as static files -and therefore are very fast and with correct HTTP caching headers. -Only XML metadata are delivered via PHP. -MBTiles are served via PHP, and are therfore slower, unless they are unpacked with mbutil. +Tiles are served directly by Apache with mod_rewrite rules as static files and therefore are very fast and with correct HTTP caching headers. Only XML metadata is delivered via PHP. MBTiles are served via PHP and are therefore slower unless they are unpacked with mbutil. -[MapTiler](http://www.maptiler.com/) can render GeoTIFF, ECW, MrSID, GeoPDF into compatible map tiles. JPEG, PNG, GIF and TIFF with scanned maps or images without geolocation can be turned into standard map layers with the visual georeferencing functionality (http://youtu.be/eJxdCe9CNYg). +[MapTiler](http://www.maptiler.com/) can render GeoTIFF, ECW, MrSID, GeoPDF into compatible map tiles. JPEG, PNG, GIF, and TIFF with scanned maps or images without geolocation can be turned into standard map layers with the visual georeferencing functionality (http://youtu.be/eJxdCe9CNYg). [![MapTiler - mapping tiles](https://cloud.githubusercontent.com/assets/59284/3037911/583d7810-e0c6-11e3-877c-6a7747b80dd3.jpg)](http://www.maptiler.com/) @@ -50,21 +37,13 @@ Installation: Download the project files as a [zip archive](https://github.com/klokantech/tileserver-php/archive/master.zip) or source code from GitHub and unpack it into a web-hosting of your choice. -If you access the web address relevant to the installation directory, -the TileServer.php Server should display you a welcome message and further -instructions. +If you access the web address relevant to the installation directory, the TileServer.php Server should display you a welcome message and further instructions. -Then you can upload to the web hosting your mapping data - a directory with -tiles rendered with [MapTiler](http://www.maptiler.com/). +Then you can upload to the web hosting your mapping data - a directory with tiles rendered with [MapTiler](http://www.maptiler.com/). -Tiles produced by open-source GDAL2Tiles or MapTiler and tiles in .mbtiles -files can be easily converted to required structure (XYZ with top-left origin -and metadata.json file). The open-source utility [mbutil](https://github.com/mapbox/mbutil) produces -exactly the required format. +Tiles produced by open-source GDAL2Tiles or MapTiler Desktop and tiles in .mbtiles format can be easily converted to the required structure (XYZ with top-left origin and metadata.json file). The open-source utility [mbutil](https://github.com/mapbox/mbutil) produces exactly the required format. -Direct reading of .mbtiles files is supported, but with decreased performance -compared to the static files in a directory. The advantage is easier data management, -especially upload over FTP or similar protocols. +Direct reading of .mbtiles files is supported but with decreased performance compared to the static files in a directory. The advantage is easier data management, especially upload over FTP or similar protocols. Supported protocols: -------------------- @@ -123,8 +102,7 @@ Supported protocols: - Retina / HighDPI routing with 512 tiles Use @2x suffix in url for JSONs and tiles. For example http://tileserver.maptiler.com/grandcanyon@2x.json -To use the OGC WMTS standard point your client (desktop or web) to the URL -of 'directory' where you installed tileserver.php project with suffix "wmts". +To use the OGC WMTS standard, point your client (desktop or web) to the URL of 'directory' where you installed tileserver.php project with suffix "wmts". For example: http://www.example.com/directory/wmts If you have installed the project into a root directory of a domain, then the address is: http://www.example.com/wmts @@ -143,43 +121,35 @@ GetTile RESTful/KVP: Other example requests are mentioned in the .htaccess. -TileServer-PHP supports all coordinates system. You have to define it with tilejson with specification on https://github.com/klokantech/tilejson-spec/tree/custom-projection/2.2.0 +TileServer-PHP supports all coordinates systems. You have to define it with tilejson with specification on https://github.com/klokantech/tilejson-spec/tree/custom-projection/2.2.0 Or use MapTiler to produce datasets with this specification. Performance from the web clients -------------------------------- It is highly recommended to map several domain names to the service, such as: + http://a.example.com/, http://b.example.com/, http://c.example.com/. -This can be done with DNS CNAME records pointing to your hosting. -The reason for this is that traditionally browsers will not send more then two -simultaneous http request to the same domain - with multiple domains for the -same server you can better saturate the network and receive the maps faster. + +This can be done with DNS CNAME records pointing to your hosting. The reason for this is that traditionally browsers will not send more than two simultaneous HTTP requests to the same domain - with multiple domains for the same server, you can better saturate the network and receive the maps faster. Performance ----------- -In case the data are available in a form of directory with XYZ tiles, then -Apache webserver is serving these files directly as WMTS RESTful or KVP. +In case the data are available in the form of a directory with XYZ tiles, then the Apache webserver is serving these files directly as WMTS RESTful or KVP. -This means performance is excellent, maps are delivered very fast and large -number of concurrent visitors can be handled even with quite a low-end -hardware or cheap/free web hosting providers. +This means performance is excellent, maps are delivered very fast, and a large number of concurrent visitors can be handled even with quite low-end hardware or cheap/free web hosting providers. -Mod_rewrite rules are utilized to ensure the HTTP requests defined in the OCG -WMTS standard are served, and Apache preserve standard caching headers & eTag. +Mod_rewrite rules are utilized to ensure the HTTP requests defined in the OCG WMTS standard are served, and Apache preserves standard caching headers & eTag. -The performance should be significantly better then performance of any other -tile caching project (such as TileCache.org or GeoWebCache). +The performance should be significantly better than any other tile caching project (such as TileCache.org or GeoWebCache). -Performance graph for "apache static" comparing other tile caching projects -is available online at: -http://code.google.com/p/mod-geocache/wiki/PreliminaryBenchmark +Performance graph for "apache static" comparing other tile caching projects is available online at http://code.google.com/p/mod-geocache/wiki/PreliminaryBenchmark Limits of actual implementation ------------------------------- -With intention, in this moment the project supports only: +With intention, at this moment, the project supports only: - We enforce and require XYZ (top-left origin) tiling schema (even for TMS). Password protection @@ -210,22 +180,19 @@ TileServer.php can run without any problems over HTTPS, if required. Microsoft Windows web-hosting ----------------------------- -The TileServer.php should run on Windows-powered webservers with Apache -installation if PHP 5.2+ and mod_rewrite are available. +The TileServer.php should run on Windows-powered webservers with Apache installation if PHP 5.2+ and mod_rewrite are available. -With the IIS webserver hosting, you may need PHP and IIRF module -(http://iirf.codeplex.com/) and alter appropriately the rewrite rules. +With the IIS webserver hosting, you may need PHP and IIRF module (http://iirf.codeplex.com/) and alter appropriately the rewrite rules. Credits / Contributors ---------------------- -Project developed initially by Klokan Technologies GmbH, Switzerland in -cooperation with National Oceanic and Atmospheric Administration - NOAA, USA. +Project developed initially by Klokan Technologies GmbH, Switzerland, in cooperation with National Oceanic and Atmospheric Administration - NOAA, USA. -- Petr Pridal - Klokan Technologies GmbH +- Petr Pridal - Klokan Technologies GmbH - Jason Woolard - NOAA - Jon Sellars - NOAA -- Dalibor Janak - Klokan Technologies GmbH +- Dalibor Janak - Klokan Technologies GmbH Tested WMTS/TMS clients ----------------------- @@ -244,6 +211,11 @@ Tested WMTS/TMS clients http://www.thecarbonproject.com/gaia.php - MapBox.js - the loading of maps via TileJSON, interaction layer supported https://www.mapbox.com/mapbox.js + +Alternative +----------- + +If you need [map server with commercial support](https://www.maptiler.com/server/), explore the possibilities provided by the MapTiler Server. BSD License -----------