From b783c595859ac1fccf134f9055d69785d3b32d93 Mon Sep 17 00:00:00 2001 From: eyeNsky Date: Thu, 2 Apr 2015 08:19:48 -0400 Subject: [PATCH 01/11] 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 @@ class Wmts extends Server { $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/11] 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 @@ class Wmts extends Server { $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/11] 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 @@ Router::serve(array( '/: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 @@ class Server { $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 @@ class Server { 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 @@ class Server { 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 @@ class Json extends Server { $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 @@ class Wmts extends Server { $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 @@ class Wmts extends Server { 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 @@ class Wmts extends Server { ' . $tileMatrixSet . ' - + '; } echo ' @@ -1160,7 +1179,13 @@ class Wmts extends Server { } 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 @@ class Router { $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/11] 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 @@ class Server { $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 @@ class Server { 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 @@ class Server { * 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/11] 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/11] 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 @@ class Json extends Server { $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/11] 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 @@ Router::serve(array( '/' => '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 @@ class Router { $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/11] 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 @@ class Server { $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/11] 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 @@ Router::serve(array( '/' => '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 @@ class Server { 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/11] 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 @@ class Server { } /** - * + * * @param string $jsonFileName * @return array */ @@ -166,7 +166,7 @@ class Server { $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 @@ class Server { $metadata['basename'] = $mbt[0]; return $metadata; } - + /** * Convert row number to latitude of the top of the row * @param integer $r @@ -406,20 +406,22 @@ class Server { } 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 @@ class Server { 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 @@ class Json extends Server { $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 @@ class Wmts extends Server { } /** - * Returns tilesets getCapabilities + * Returns tilesets getCapabilities */ public function getCapabilities() { header("Content-type: application/xml"); @@ -1184,10 +1190,10 @@ class Wmts extends Server { $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/11] 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 @@ class Server { $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 @@ class Tms extends Server { '; for ($zoom = $m['minzoom']; $zoom < $m['maxzoom'] + 1; $zoom++) { - echo ''; + echo ''; } echo''; }