mirror of
https://github.com/klokantech/tileserver-php.git
synced 2025-08-06 14:47:21 +02:00
Initial .mbtiles implementation.
This commit is contained in:
@@ -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
|
# MBTiles support at /layer/z/x/y.ext - loads the tile from mbtiles with php
|
||||||
# TODO: serve also 404 errors for tiles
|
# TODO: serve also 404 errors for tiles
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
RewriteRule ^([^\/]+\.mbtiles)\/.*?(\d+)\/(\d+)\/(\d+)\.(\w+)$ tileserver-mbtiles.php?tileset=$1&z=$2&x=$3&y=$4&ext=$5 [L]
|
||||||
RewriteRule ^([^\/]+)\/(\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
|
# TODO: use mod_sqlite if available to map the tiles to URL directly by apache
|
||||||
|
|
||||||
# WMTS KVP
|
# WMTS KVP
|
||||||
|
132
tileserver-mbtiles.for.php
Normal file
132
tileserver-mbtiles.for.php
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<?php
|
||||||
|
// Based on: https://github.com/Zverik/mbtiles-php
|
||||||
|
// Read: https://github.com/klokantech/tileserver-php/issues/1
|
||||||
|
// TODO: clean the code!!!
|
||||||
|
|
||||||
|
if (!is_file($_GET['tileset'] . '.mbtiles')) {
|
||||||
|
header('HTTP/1.0 404 Not Found');
|
||||||
|
echo "<h1>404 Not Found</h1>";
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
?><TileMap version="1.0.0" tilemapservice="<?php echo $basetms ?>1.0.0/">
|
||||||
|
<Title><?php echo htmlspecialchars($params['name']) ?></Title>
|
||||||
|
<Abstract><?php echo htmlspecialchars($params['description']) ?></Abstract>
|
||||||
|
<SRS>OSGEO:41001</SRS>
|
||||||
|
<BoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
|
||||||
|
<Origin x="0" y="0"/>
|
||||||
|
<TileFormat width="256" height="256" mime-type="image/<?php echo $params['format'] == 'jpg' ? 'jpeg' : 'png' ?>" extension="<?php echo $params['format']?>"/>
|
||||||
|
<TileSets profile="global-mercator">
|
||||||
|
<?php foreach( readzooms($db) as $zoom ) { ?>
|
||||||
|
<TileSet href="<?php echo $basetms.'1.0.0/'.$layer.'/'.$zoom ?>" units-per-pixel="<?php echo 78271.516 / pow(2, $zoom) ?>" order="<?php echo $zoom ?>" />
|
||||||
|
<?php } ?>
|
||||||
|
</TileSets>
|
||||||
|
</TileMap>
|
||||||
|
<?php
|
||||||
|
} catch( PDOException $e ) {}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// show list of all tilesets along with links
|
||||||
|
print '<h2>MBTiles PHP proxy</h2>';
|
||||||
|
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 '<h3>'.htmlspecialchars($params['name']).'</h3>';
|
||||||
|
if( isset($params['description']) )
|
||||||
|
print '<p>'.htmlspecialchars($params['description']).'</p>';
|
||||||
|
print '<p>Type: '.$params['type'].', format: '.$params['format'].', version: '.$params['version'].'</p>';
|
||||||
|
if( isset($params['bounds']) )
|
||||||
|
print '<p>Bounds: '.str_replace(',', ', ',$params['bounds']).'</p>';
|
||||||
|
print '<p>Zoom levels: '.implode(', ', $zooms).'</p>';
|
||||||
|
print '<p>OpenLayers: <tt>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').'});</tt></p>';
|
||||||
|
print '<p>TMS: <tt>http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/[^\/]+$/','/',$_SERVER['REQUEST_URI']).'1.0.0/'.preg_replace('/\.mbtiles/','',$file).'</tt></p>';
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
@@ -3,7 +3,7 @@
|
|||||||
// Read: https://github.com/klokantech/tileserver-php/issues/1
|
// Read: https://github.com/klokantech/tileserver-php/issues/1
|
||||||
// TODO: clean the code!!!
|
// TODO: clean the code!!!
|
||||||
|
|
||||||
if (!is_file($_GET['tileset'].'.mbtiles')) {
|
if (!is_file($_GET['tileset'])) {
|
||||||
header('HTTP/1.0 404 Not Found');
|
header('HTTP/1.0 404 Not Found');
|
||||||
echo "<h1>404 Not Found</h1>";
|
echo "<h1>404 Not Found</h1>";
|
||||||
echo "TileServer.php could not found what you requested.";
|
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");
|
//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'];
|
$tileset = $_GET['tileset'];
|
||||||
$flip = true;
|
$flip = true;
|
||||||
try {
|
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) ) {
|
if( !isset($db) ) {
|
||||||
header('Content-type: text/plain');
|
header('Content-type: text/plain');
|
||||||
print 'Incorrect tileset name: '.$_GET['tileset'];
|
print 'Incorrect tileset name: '.$_GET['tileset'];
|
||||||
@@ -57,51 +57,6 @@ if( isset($_GET['tileset']) && preg_match('/^[\w\d_-]+$/', $_GET['tileset']) ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
?><TileMap version="1.0.0" tilemapservice="<?php echo $basetms ?>1.0.0/">
|
|
||||||
<Title><?php echo htmlspecialchars($params['name']) ?></Title>
|
|
||||||
<Abstract><?php echo htmlspecialchars($params['description']) ?></Abstract>
|
|
||||||
<SRS>OSGEO:41001</SRS>
|
|
||||||
<BoundingBox minx="-180" miny="-90" maxx="180" maxy="90" />
|
|
||||||
<Origin x="0" y="0"/>
|
|
||||||
<TileFormat width="256" height="256" mime-type="image/<?php echo $params['format'] == 'jpg' ? 'jpeg' : 'png' ?>" extension="<?php echo $params['format']?>"/>
|
|
||||||
<TileSets profile="global-mercator">
|
|
||||||
<?php foreach( readzooms($db) as $zoom ) { ?>
|
|
||||||
<TileSet href="<?php echo $basetms.'1.0.0/'.$layer.'/'.$zoom ?>" units-per-pixel="<?php echo 78271.516 / pow(2, $zoom) ?>" order="<?php echo $zoom ?>" />
|
|
||||||
<?php } ?>
|
|
||||||
</TileSets>
|
|
||||||
</TileMap>
|
|
||||||
<?php
|
|
||||||
} catch( PDOException $e ) {}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// show list of all tilesets along with links
|
|
||||||
print '<h2>MBTiles PHP proxy</h2>';
|
|
||||||
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 '<h3>'.htmlspecialchars($params['name']).'</h3>';
|
|
||||||
if( isset($params['description']) )
|
|
||||||
print '<p>'.htmlspecialchars($params['description']).'</p>';
|
|
||||||
print '<p>Type: '.$params['type'].', format: '.$params['format'].', version: '.$params['version'].'</p>';
|
|
||||||
if( isset($params['bounds']) )
|
|
||||||
print '<p>Bounds: '.str_replace(',', ', ',$params['bounds']).'</p>';
|
|
||||||
print '<p>Zoom levels: '.implode(', ', $zooms).'</p>';
|
|
||||||
print '<p>OpenLayers: <tt>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').'});</tt></p>';
|
|
||||||
print '<p>TMS: <tt>http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/[^\/]+$/','/',$_SERVER['REQUEST_URI']).'1.0.0/'.preg_replace('/\.mbtiles/','',$file).'</tt></p>';
|
|
||||||
} catch( PDOException $e ) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
print 'Error opening script directory.';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getbaseurl() {
|
function getbaseurl() {
|
||||||
return 'http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/(1.0.0\/)?[^\/]*$/','/',$_SERVER['REQUEST_URI']);
|
return 'http://'.$_SERVER['HTTP_HOST'].preg_replace('/\/(1.0.0\/)?[^\/]*$/','/',$_SERVER['REQUEST_URI']);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,7 @@ if ($layer === ""):
|
|||||||
<TileMaps>
|
<TileMaps>
|
||||||
<?php
|
<?php
|
||||||
foreach ($maps as $m) {
|
foreach ($maps as $m) {
|
||||||
$basename = str_replace('.mbtiles', '', $m['basename']);
|
$basename = $m['basename'];
|
||||||
$title = (array_key_exists('name', $m )) ? $m['name'] : $basename;
|
$title = (array_key_exists('name', $m )) ? $m['name'] : $basename;
|
||||||
$profile = $m['profile'];
|
$profile = $m['profile'];
|
||||||
if ($profile == 'geodetic')
|
if ($profile == 'geodetic')
|
||||||
@@ -45,7 +45,7 @@ die;
|
|||||||
# ---------
|
# ---------
|
||||||
else:
|
else:
|
||||||
$m = layer($layer);
|
$m = layer($layer);
|
||||||
$basename = str_replace('.mbtiles', '', $m['basename']);
|
$basename = $m['basename'];
|
||||||
$title = (array_key_exists('name', $m )) ? $m['name'] : $basename;
|
$title = (array_key_exists('name', $m )) ? $m['name'] : $basename;
|
||||||
$description = (array_key_exists('description', $m )) ? $m['description'] : "";
|
$description = (array_key_exists('description', $m )) ? $m['description'] : "";
|
||||||
$bounds = $m['bounds'];
|
$bounds = $m['bounds'];
|
||||||
|
@@ -70,7 +70,7 @@ echo "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"; ?>
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
foreach ($maps as $m) {
|
foreach ($maps as $m) {
|
||||||
$basename = str_replace('.mbtiles', '', $m['basename']);
|
$basename = $m['basename'];
|
||||||
$title = (array_key_exists('name', $m )) ? $m['name'] : $basename;
|
$title = (array_key_exists('name', $m )) ? $m['name'] : $basename;
|
||||||
$profile = $m['profile'];
|
$profile = $m['profile'];
|
||||||
$bounds = $m['bounds'];
|
$bounds = $m['bounds'];
|
||||||
|
@@ -83,7 +83,7 @@ You can easily convert existing geodata (GeoTIFF, ECW, MrSID, etc) to this tile
|
|||||||
echo "<h3>Available maps</h3>";
|
echo "<h3>Available maps</h3>";
|
||||||
echo "<ul>";
|
echo "<ul>";
|
||||||
foreach ($maps as $map) {
|
foreach ($maps as $map) {
|
||||||
// echo "<li><a href=\"".str_replace('.mbtiles', '', $map['basename'])."\">".$map['name']."</a>" ;
|
// echo "<li><a href=\"".$map['basename']."\">".$map['name']."</a>" ;
|
||||||
echo "<li>".$map['name'];
|
echo "<li>".$map['name'];
|
||||||
}
|
}
|
||||||
echo "</ul>";
|
echo "</ul>";
|
||||||
@@ -195,7 +195,7 @@ function metadataTileJson( $metadata ) {
|
|||||||
$metadata['sheme'] = 'xyz';
|
$metadata['sheme'] = 'xyz';
|
||||||
$tiles = array();
|
$tiles = array();
|
||||||
foreach($config['baseUrls'] as $url)
|
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);
|
#print_r($tiles);
|
||||||
$metadata['tiles'] = $tiles;
|
$metadata['tiles'] = $tiles;
|
||||||
return $metadata;
|
return $metadata;
|
||||||
@@ -405,4 +405,4 @@ class GlobalMercator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$mercator = new GlobalMercator();
|
$mercator = new GlobalMercator();
|
||||||
?>
|
?>
|
||||||
|
Reference in New Issue
Block a user