From 0d4d50ab9c169a7163300f2e39b44a1d4919dff6 Mon Sep 17 00:00:00 2001 From: Petr Pridal Date: Sun, 12 Aug 2012 20:28:23 +0200 Subject: [PATCH] Initial .mbtiles implementation. --- .htaccess | 3 +- tileserver-mbtiles.for.php | 132 +++++++++++++++++++++++++++++++++++++ tileserver-mbtiles.php | 51 +------------- tileserver-tms.php | 4 +- tileserver-wmts.php | 2 +- tileserver.php | 6 +- 6 files changed, 142 insertions(+), 56 deletions(-) create mode 100644 tileserver-mbtiles.for.php diff --git a/.htaccess b/.htaccess index 231c089..a49aea1 100644 --- a/.htaccess +++ b/.htaccess @@ -30,8 +30,7 @@ RewriteRule ^([\w\d\._-]+)/.+?(\d+)/(\d+)/(\d+)\.(\w+)$ $1/$2/$3/$4.$5 [L] # MBTiles support at /layer/z/x/y.ext - loads the tile from mbtiles with php # TODO: serve also 404 errors for tiles -RewriteCond %{REQUEST_FILENAME} !-f -RewriteRule ^([^\/]+)\/(\d+)\/(\d+)\/(\d+)\.(\w+)$ tileserver-mbtiles.php?tileset=$1&z=$2&x=$3&y=$4&ext=$5 [L] +RewriteRule ^([^\/]+\.mbtiles)\/.*?(\d+)\/(\d+)\/(\d+)\.(\w+)$ tileserver-mbtiles.php?tileset=$1&z=$2&x=$3&y=$4&ext=$5 [L] # TODO: use mod_sqlite if available to map the tiles to URL directly by apache # WMTS KVP diff --git a/tileserver-mbtiles.for.php b/tileserver-mbtiles.for.php new file mode 100644 index 0000000..fc9f680 --- /dev/null +++ b/tileserver-mbtiles.for.php @@ -0,0 +1,132 @@ +404 Not Found"; + echo "TileServer.php could not found what you requested."; + die(); + // TODO: if ($_GET['ext'] == 'png') { ... + // TODO: better image 256x256px !!! + // header("Content-type: image/png"); + //print("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\rIDAT\x08\xd7c````\x00\x00\x00\x05\x00\x01^\xf3*:\x00\x00\x00\x00IEND\xaeB`\x82"); +} + +if (isset($_GET['tileset']) && preg_match('/^[\w\d_-]+$/', $_GET['tileset'])) { + $tileset = $_GET['tileset']; + $flip = true; + try { + $db = new PDO('sqlite:' . $tileset . '.mbtiles', '', '', array( + PDO::ATTR_PERSISTENT => true + )); + if (!isset($db)) { + header('Content-type: text/plain'); + print 'Not possible to connect to SQLite database in file: ' . $_GET['tileset'] . '.mbtiles'; + exit; + } + // http://c.tile.openstreetmap.org/12/2392/1190.png + $z = floatval($_GET['z']); + $y = floatval($_GET['y']); + $x = floatval($_GET['x']); + if ($flip) { + $y = pow(2, $z) - 1 - $y; + } + $result = $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) { + // TODO: Put here ready to use empty tile!!! + $png = imagecreatetruecolor(256, 256); + imagesavealpha($png, true); + $trans_colour = imagecolorallocatealpha($png, 0, 0, 0, 127); + imagefill($png, 0, 0, $trans_colour); + header('Content-type: image/png'); + imagepng($png); + //header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found'); + } else { + $result = $db->query('select value from metadata where name="format"'); + $resultdata = $result->fetchColumn(); + $format = isset($resultdata) && $resultdata !== FALSE ? $resultdata : 'png'; + if ($format == 'jpg') + $format = 'jpeg'; + header('Content-type: image/' . $format); + print $data; + } + } + catch (PDOException $e) { + header('Content-type: text/plain'); + print 'Error querying the database: ' . $e->getMessage(); + } +} +/* +?> +<?php echo htmlspecialchars($params['name']) ?> + +OSGEO:41001 + + + + + + + + + +MBTiles PHP proxy'; +if( $handle = opendir('.') ) { +$found = false; +while( ($file = readdir($handle)) !== false ) { +if( preg_match('/^[\w\d_-]+\.mbtiles$/', $file) && is_file($file) ) { +try { +$db = new PDO('sqlite:'.$file); +$params = readparams($db); +$zooms = readzooms($db); +$db = null; +print '

'.htmlspecialchars($params['name']).'

'; +if( isset($params['description']) ) +print '

'.htmlspecialchars($params['description']).'

'; +print '

Type: '.$params['type'].', format: '.$params['format'].', version: '.$params['version'].'

'; +if( isset($params['bounds']) ) +print '

Bounds: '.str_replace(',', ', ',$params['bounds']).'

'; +print '

Zoom levels: '.implode(', ', $zooms).'

'; +print '

OpenLayers: new OpenLayers.Layer.OSM("'.htmlspecialchars($params['name']).'", "'.getbaseurl().preg_replace('/\.mbtiles/','',$file).'/${z}/${x}/${y}", {numZoomLevels: '.(end($zooms)+1).', isBaseLayer: '.($params['type']=='baselayer'?'true':'false').'});

'; +print '

TMS: http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/[^\/]+$/','/',$_SERVER['REQUEST_URI']).'1.0.0/'.preg_replace('/\.mbtiles/','',$file).'

'; +} catch( PDOException $e ) {} +} +} +} else { +print 'Error opening script directory.'; +} +} + +function getbaseurl() { +return 'http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/(1.0.0\/)?[^\/]*$/','/',$_SERVER['REQUEST_URI']); +} +*/ +function readparams($db) +{ + $params = array(); + $result = $db->query('select name, value from metadata'); + while ($row = $result->fetch(PDO::FETCH_ASSOC)) { + $params[$row['name']] = $row['value']; + } + return $params; +} + +function readzooms($db) +{ + $zooms = array(); + $result = $db->query('select zoom_level from tiles group by zoom_level order by zoom_level'); + while ($zoom = $result->fetchColumn()) { + $zooms[] = $zoom; + } + return $zooms; +} +?> + diff --git a/tileserver-mbtiles.php b/tileserver-mbtiles.php index 9f8b508..31aa51d 100644 --- a/tileserver-mbtiles.php +++ b/tileserver-mbtiles.php @@ -3,7 +3,7 @@ // Read: https://github.com/klokantech/tileserver-php/issues/1 // TODO: clean the code!!! -if (!is_file($_GET['tileset'].'.mbtiles')) { +if (!is_file($_GET['tileset'])) { header('HTTP/1.0 404 Not Found'); echo "

404 Not Found

"; echo "TileServer.php could not found what you requested."; @@ -14,11 +14,11 @@ if (!is_file($_GET['tileset'].'.mbtiles')) { //print("\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\rIDAT\x08\xd7c````\x00\x00\x00\x05\x00\x01^\xf3*:\x00\x00\x00\x00IEND\xaeB`\x82"); } -if( isset($_GET['tileset']) && preg_match('/^[\w\d_-]+$/', $_GET['tileset']) ) { +if( isset($_GET['tileset']) ) { $tileset = $_GET['tileset']; $flip = true; try { - $db = new PDO('sqlite:'.$tileset.'.mbtiles','','',array(PDO::ATTR_PERSISTENT => true)); + $db = new PDO('sqlite:'.$tileset,'','',array(PDO::ATTR_PERSISTENT => true)); if( !isset($db) ) { header('Content-type: text/plain'); print 'Incorrect tileset name: '.$_GET['tileset']; @@ -57,51 +57,6 @@ if( isset($_GET['tileset']) && preg_match('/^[\w\d_-]+$/', $_GET['tileset']) ) { } } /* - ?> - <?php echo htmlspecialchars($params['name']) ?> - - OSGEO:41001 - - - - - - - - - - MBTiles PHP proxy'; - if( $handle = opendir('.') ) { - $found = false; - while( ($file = readdir($handle)) !== false ) { - if( preg_match('/^[\w\d_-]+\.mbtiles$/', $file) && is_file($file) ) { - try { - $db = new PDO('sqlite:'.$file); - $params = readparams($db); - $zooms = readzooms($db); - $db = null; - print '

'.htmlspecialchars($params['name']).'

'; - if( isset($params['description']) ) - print '

'.htmlspecialchars($params['description']).'

'; - print '

Type: '.$params['type'].', format: '.$params['format'].', version: '.$params['version'].'

'; - if( isset($params['bounds']) ) - print '

Bounds: '.str_replace(',', ', ',$params['bounds']).'

'; - print '

Zoom levels: '.implode(', ', $zooms).'

'; - print '

OpenLayers: new OpenLayers.Layer.OSM("'.htmlspecialchars($params['name']).'", "'.getbaseurl().preg_replace('/\.mbtiles/','',$file).'/${z}/${x}/${y}", {numZoomLevels: '.(end($zooms)+1).', isBaseLayer: '.($params['type']=='baselayer'?'true':'false').'});

'; - print '

TMS: http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/[^\/]+$/','/',$_SERVER['REQUEST_URI']).'1.0.0/'.preg_replace('/\.mbtiles/','',$file).'

'; - } catch( PDOException $e ) {} - } - } - } else { - print 'Error opening script directory.'; - } -} - function getbaseurl() { return 'http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/(1.0.0\/)?[^\/]*$/','/',$_SERVER['REQUEST_URI']); } diff --git a/tileserver-tms.php b/tileserver-tms.php index 7615260..f061122 100644 --- a/tileserver-tms.php +++ b/tileserver-tms.php @@ -26,7 +26,7 @@ if ($layer === ""): \n"; ?> Available maps"; echo ""; @@ -195,7 +195,7 @@ function metadataTileJson( $metadata ) { $metadata['sheme'] = 'xyz'; $tiles = array(); foreach($config['baseUrls'] as $url) - $tiles[] = $url.str_replace('.mbtiles', '', $metadata['basename']).'/{z}/{x}/{y}.'.$metadata['format']; + $tiles[] = $url.$metadata['basename'].'/{z}/{x}/{y}.'.$metadata['format']; #print_r($tiles); $metadata['tiles'] = $tiles; return $metadata; @@ -405,4 +405,4 @@ class GlobalMercator } } $mercator = new GlobalMercator(); -?> \ No newline at end of file +?>