mirror of
https://github.com/klokantech/tileserver-php.git
synced 2025-08-21 21:56:18 +02:00
Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
730ffa52f3 | ||
|
b7960baaaa | ||
|
8aa58cc6b9 | ||
|
250512168c | ||
|
6b5933e21f | ||
|
f5408fd108 | ||
|
dc26c831f1 | ||
|
28aba6f9e2 | ||
|
8f6a2ced68 | ||
|
79926b92fc | ||
|
3343f80e09 | ||
|
c660ab8f41 | ||
|
21d7a409fe | ||
|
abb4087942 | ||
|
0acdc04e32 | ||
|
765e0d9ea3 | ||
|
f9e801849e | ||
|
e66e577d5d | ||
|
ffedfde75e | ||
|
b783c59585 | ||
|
dd8d884bc6 | ||
|
8b4a5142e8 | ||
|
53b379cd67 | ||
|
2bf8bf6d4b | ||
|
e4454b12be | ||
|
8002dbbb7d | ||
|
d4121d86d5 | ||
|
ea6e176ab3 | ||
|
b13b8d98c8 | ||
|
f08d72262d | ||
|
4250eff554 | ||
|
34ffddb765 | ||
|
5d2662a6a3 | ||
|
8dec7469f1 | ||
|
8170e02397 | ||
|
779e320dec | ||
|
e226ae2cc3 | ||
|
61c866a521 |
9
.travis.yml
Normal file
9
.travis.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
language: php
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
script:
|
||||
- php tileserver.php
|
30
README.md
30
README.md
@@ -1,5 +1,7 @@
|
||||
TileServer PHP - OGC Web Map Tiling Server (WMTS)
|
||||
=================================================
|
||||
TileServer PHP: MapTiler and MBTiles maps via WMTS
|
||||
==================================================
|
||||
|
||||
[](https://travis-ci.org/klokantech/tileserver-php)
|
||||
|
||||
This server distributes maps to desktop, web, and mobile applications from
|
||||
a standard Apache+PHP web hosting.
|
||||
@@ -38,9 +40,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:
|
||||
-------------
|
||||
@@ -111,15 +113,11 @@ Supported protocols:
|
||||
Exposed at http://[...]/layer/z/x/y.grid.json
|
||||
|
||||
|
||||
To use the OGC WMTS services point your client (desktop or web) to the URL
|
||||
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
|
||||
|
||||
You can also install the project into a root directory of a virtual server:
|
||||
Then the address is: http://www.example.com/wmts
|
||||
|
||||
Similarly for another end points.
|
||||
If you have installed the project into a root directory of a domain, then the address is: http://www.example.com/wmts
|
||||
|
||||
The supported WMTS requests includes:
|
||||
|
||||
@@ -133,7 +131,7 @@ 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]
|
||||
|
||||
Another example requests are mentioned in the .htaccess.
|
||||
Other example requests are mentioned in the .htaccess.
|
||||
|
||||
Performance from the web clients
|
||||
--------------------------------
|
||||
@@ -180,10 +178,10 @@ Password protection
|
||||
HTTP Simple Authentication can be easily added to the server.
|
||||
Edit the .htaccess and add these lines:
|
||||
|
||||
AuthUserFile /full/path/to/.htpasswd
|
||||
AuthType Basic
|
||||
AuthName "Secure WMTS"
|
||||
Require valid-user
|
||||
AuthUserFile /full/path/to/.htpasswd
|
||||
AuthType Basic
|
||||
AuthName "Secure WMTS"
|
||||
Require valid-user
|
||||
|
||||
Create a file called .htpasswd with user:password format.
|
||||
You can use a command-line utility:
|
||||
@@ -240,7 +238,7 @@ Tested WMTS/TMS clients
|
||||
BSD License
|
||||
-----------
|
||||
|
||||
Copyright (C) 2012 Klokan Technologies GmbH
|
||||
Copyright (C) 2015 Klokan Technologies GmbH (http://www.klokantech.com/)
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
316
tileserver.php
316
tileserver.php
@@ -9,21 +9,21 @@
|
||||
|
||||
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',
|
||||
'/test' => 'Server:getInfo',
|
||||
'/html' => 'Server:getHtml',
|
||||
'/:alpha/:number/:number/:number.grid.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/: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',
|
||||
));
|
||||
@@ -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;
|
||||
|
||||
@@ -71,13 +71,13 @@ class Server {
|
||||
$mjs = glob('*/metadata.json');
|
||||
$mbts = glob('*.mbtiles');
|
||||
if ($mjs) {
|
||||
foreach ($mjs as $mj) {
|
||||
foreach (array_filter($mjs, 'is_readable') as $mj) {
|
||||
$layer = $this->metadataFromMetadataJson($mj);
|
||||
array_push($this->fileLayer, $layer);
|
||||
}
|
||||
}
|
||||
if ($mbts) {
|
||||
foreach ($mbts as $mbt) {
|
||||
foreach (array_filter($mbts, 'is_readable') as $mbt) {
|
||||
$this->dbLayer[] = $this->metadataFromMbtiles($mbt);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +143,7 @@ class Server {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param string $jsonFileName
|
||||
* @return array
|
||||
*/
|
||||
@@ -167,7 +166,37 @@ class Server {
|
||||
|
||||
$resultdata = $result->fetchAll();
|
||||
foreach ($resultdata as $r) {
|
||||
$metadata[$r['name']] = $r['value'];
|
||||
$value = preg_replace('/(\\n)+/','',$r['value']);
|
||||
$metadata[$r['name']] = addslashes($value);
|
||||
}
|
||||
if (!array_key_exists('minzoom', $metadata)
|
||||
|| !array_key_exists('maxzoom', $metadata)
|
||||
) {
|
||||
// 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))
|
||||
$metadata['minzoom'] = $resultdata[0]['min'];
|
||||
if (!array_key_exists('maxzoom', $metadata))
|
||||
$metadata['maxzoom'] = $resultdata[0]['max'];
|
||||
}
|
||||
// autodetect format using JPEG magic number FFD8
|
||||
if (!array_key_exists('format', $metadata)) {
|
||||
$result = $this->db->query('select hex(substr(tile_data,1,2)) as magic from tiles limit 1');
|
||||
$resultdata = $result->fetchAll();
|
||||
$metadata['format'] = ($resultdata[0]['magic'] == 'FFD8')
|
||||
? 'jpg'
|
||||
: 'png';
|
||||
}
|
||||
// autodetect bounds
|
||||
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']));
|
||||
$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 = $this->metadataValidation($metadata);
|
||||
$mbt = explode('.', $mbt);
|
||||
@@ -175,6 +204,17 @@ class Server {
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert row number to latitude of the top of the row
|
||||
* @param integer $r
|
||||
* @param integer $zoom
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Valids metaJSON
|
||||
* @param object $metadata
|
||||
@@ -182,7 +222,6 @@ class Server {
|
||||
*/
|
||||
public function metadataValidation($metadata) {
|
||||
if (array_key_exists('bounds', $metadata)) {
|
||||
// TODO: Calculate bounds from tiles if bounds is missing - with GlobalMercator
|
||||
$metadata['bounds'] = array_map('floatval', explode(',', $metadata['bounds']));
|
||||
} else {
|
||||
$metadata['bounds'] = array(-180, -85.051128779807, 180, 85.051128779807);
|
||||
@@ -190,8 +229,7 @@ class Server {
|
||||
if (!array_key_exists('profile', $metadata)) {
|
||||
$metadata['profile'] = 'mercator';
|
||||
}
|
||||
// TODO: detect format, minzoom, maxzoom, thumb
|
||||
// scandir() for directory / SQL for mbtiles
|
||||
// TODO: detect thumb / SQL for mbtiles
|
||||
if (array_key_exists('minzoom', $metadata))
|
||||
$metadata['minzoom'] = intval($metadata['minzoom']);
|
||||
else
|
||||
@@ -203,11 +241,6 @@ class Server {
|
||||
if (!array_key_exists('format', $metadata)) {
|
||||
$metadata['format'] = 'png';
|
||||
}
|
||||
/*
|
||||
if (!array_key_exists('thumb', $metadata )) {
|
||||
$metadata['profile'] = 'mercator';
|
||||
}
|
||||
*/
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
@@ -257,9 +290,10 @@ class Server {
|
||||
* @param integer $x
|
||||
* @param string $ext
|
||||
*/
|
||||
public function getTile($tileset, $z, $y, $x, $ext) {
|
||||
public function renderTile($tileset, $z, $y, $x, $ext) {
|
||||
if ($this->isDBLayer($tileset)) {
|
||||
if ($this->isModified($tileset) == TRUE) {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('HTTP/1.1 304 Not Modified');
|
||||
die;
|
||||
}
|
||||
@@ -274,7 +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) {
|
||||
$this->getCleanTile();
|
||||
//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, $ext);
|
||||
} else {
|
||||
$result = $this->db->query('select value from metadata where name="format"');
|
||||
$resultdata = $result->fetchColumn();
|
||||
@@ -282,36 +321,72 @@ class Server {
|
||||
if ($format == 'jpg') {
|
||||
$format = 'jpeg';
|
||||
}
|
||||
header('Content-type: image/' . $format);
|
||||
if ($format == 'pbf') {
|
||||
header('Content-type: application/x-protobuf');
|
||||
header('Content-Encoding:gzip');
|
||||
} else {
|
||||
header('Content-type: image/' . $format);
|
||||
}
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
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')) {
|
||||
header('Content-Type: image/' . $ext);
|
||||
if($ext != NULL){
|
||||
$mime .= $ext;
|
||||
}else{
|
||||
//detect image type from file
|
||||
$mimetypes = array('gif', 'jpeg', 'png');
|
||||
$mime .= $mimetypes[exif_imagetype($name) - 1];
|
||||
}
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Content-Type: ' . $mime);
|
||||
header('Content-Length: ' . filesize($name));
|
||||
fpassthru($fp);
|
||||
die;
|
||||
} else {
|
||||
$this->getCleanTile();
|
||||
//scale of tile (for retina tiles)
|
||||
$meta = json_decode(file_get_contents($tileset.'/metadata.json'));
|
||||
if(!isset($meta->scale)){
|
||||
$meta->scale = 1;
|
||||
}
|
||||
}
|
||||
$this->getCleanTile($meta->scale, $ext);
|
||||
} else {
|
||||
echo 'Server: Unknown or not specified dataset';
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
echo 'Server: Unknown or not specified dataset "'.$tileset.'"';
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns clean tile
|
||||
* @param integer $scale Default 1
|
||||
*/
|
||||
public function getCleanTile() {
|
||||
$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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,7 +396,7 @@ class Server {
|
||||
* @param integer $y
|
||||
* @param integer $x
|
||||
*/
|
||||
public function getUTFGrid($tileset, $z, $y, $x, $flip = TRUE) {
|
||||
public function renderUTFGrid($tileset, $z, $y, $x, $flip = TRUE) {
|
||||
if ($this->isDBLayer($tileset)) {
|
||||
if ($this->isModified($tileset) == TRUE) {
|
||||
header('HTTP/1.1 304 Not Modified');
|
||||
@@ -331,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'] . ',';
|
||||
}
|
||||
@@ -352,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;
|
||||
}
|
||||
} else {
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
echo '{}';
|
||||
die;
|
||||
}
|
||||
} catch (PDOException $e) {
|
||||
} catch (Exception $e) {
|
||||
header('Content-type: text/plain');
|
||||
print 'Error querying the database: ' . $e->getMessage();
|
||||
}
|
||||
@@ -373,14 +454,15 @@ class Server {
|
||||
* 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');
|
||||
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>' . $this->config['serverTitle'] . '</title></head><body>';
|
||||
echo '<h1>' . $this->config['serverTitle'] . '</h1>';
|
||||
echo 'TileJSON service: <a href="' . $this->config['baseUrls'][0] . '/index.json">' . $this->config['baseUrls'][0] . '/index.json</a><br>';
|
||||
echo 'WMTS service: <a href="' . $this->config['baseUrls'][0] . '/wmts">' . $this->config['baseUrls'][0] . '/wmts</a><br>';
|
||||
echo 'TMS service: <a href="' . $this->config['baseUrls'][0] . '/tms">' . $this->config['baseUrls'][0] . '/tms</a>';
|
||||
echo 'TileJSON service: <a href="//' . $this->config['baseUrls'][0] . '/index.json">' . $this->config['baseUrls'][0] . '/index.json</a><br>';
|
||||
echo 'WMTS service: <a href="//' . $this->config['baseUrls'][0] . '/wmts">' . $this->config['baseUrls'][0] . '/wmts</a><br>';
|
||||
echo 'TMS service: <a href="//' . $this->config['baseUrls'][0] . '/tms">' . $this->config['baseUrls'][0] . '/tms</a>';
|
||||
foreach ($maps as $map) {
|
||||
$extend = '[';
|
||||
foreach ($map['bounds'] as $ext) {
|
||||
@@ -392,7 +474,7 @@ class Server {
|
||||
} else {
|
||||
echo '<p>Available file tileset: ' . $map['basename'] . '<br>';
|
||||
}
|
||||
echo 'Metadata: <a href="' . $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json">'
|
||||
echo 'Metadata: <a href="//' . $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json">'
|
||||
. $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json</a><br>';
|
||||
echo 'Bounds: ' . $extend . '</p>';
|
||||
}
|
||||
@@ -408,9 +490,9 @@ class Server {
|
||||
$maps = array_merge($this->fileLayer, $this->dbLayer);
|
||||
header('Content-Type: text/html;charset=UTF-8');
|
||||
echo '<!DOCTYPE html><html><head><meta charset="UTF-8"><title>' . $this->config['serverTitle'] . '</title>';
|
||||
echo '<link rel="stylesheet" type="text/css" href="//tileserver.com/v1/index.css" />
|
||||
<script src="//tileserver.com/v1/index.js"></script><body>
|
||||
<script>tileserver({index:"http://' . $this->config['baseUrls'][0] . '/index.json", tilejson:"http://' . $this->config['baseUrls'][0] . '/%n.json", tms:"http://' . $this->config['baseUrls'][0] . '/tms", wmts:"http://' . $this->config['baseUrls'][0] . '/wmts"});</script>
|
||||
echo '<link rel="stylesheet" type="text/css" href="//cdn.klokantech.com/tileviewer/v1/index.css" />
|
||||
<script src="//cdn.klokantech.com/tileviewer/v1/index.js"></script><body>
|
||||
<script>tileserver({index:"' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/index.json", tilejson:"' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/%n.json", tms:"' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/tms", wmts:"' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/wmts"});</script>
|
||||
<h1>Welcome to ' . $this->config['serverTitle'] . '</h1>
|
||||
<p>This server distributes maps to desktop, web, and mobile applications.</p>
|
||||
<p>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.</p>';
|
||||
@@ -439,7 +521,7 @@ class Json extends Server {
|
||||
|
||||
/**
|
||||
* Callback for JSONP default grid
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
private $callback = 'grid';
|
||||
|
||||
@@ -449,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) {
|
||||
@@ -490,19 +572,31 @@ class Json extends Server {
|
||||
$metadata['scheme'] = 'xyz';
|
||||
$tiles = array();
|
||||
foreach ($this->config['baseUrls'] as $url) {
|
||||
$tiles[] = 'http://' . $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'])) {
|
||||
$this->DBconnect($metadata['basename'] . '.mbtiles');
|
||||
$res = $this->db->query('SELECT grid FROM grids LIMIT 1');
|
||||
$res = $this->db->query('SELECT * FROM grids LIMIT 1;');
|
||||
if ($res) {
|
||||
foreach ($this->config['baseUrls'] as $url) {
|
||||
$grids[] = 'http://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}.grid.json';
|
||||
$grids[] = '' . $this->config['protocol'] . '://' . $url . '/' . $metadata['basename'] . '/{z}/{x}/{y}.grid.json';
|
||||
}
|
||||
$metadata['grids'] = $grids;
|
||||
}
|
||||
}
|
||||
if (array_key_exists('json', $metadata)) {
|
||||
$mjson = json_decode(stripslashes($metadata['json']));
|
||||
foreach ($mjson as $key => $value) {
|
||||
$metadata[$key] = $value;
|
||||
}
|
||||
unset($metadata['json']);
|
||||
}
|
||||
return $metadata;
|
||||
}
|
||||
|
||||
@@ -535,7 +629,7 @@ class Json extends Server {
|
||||
echo 'TileServer: unknown map ' . $basename;
|
||||
die;
|
||||
}
|
||||
return $output;
|
||||
return stripslashes($output);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -544,7 +638,7 @@ class Json extends Server {
|
||||
public function getJson() {
|
||||
parent::setDatasets();
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header("Content-Type:application/javascript charset=utf-8");
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
if ($this->callback !== 'grid') {
|
||||
echo $this->callback . '(' . $this->createJson($this->layer) . ');'; die;
|
||||
} else {
|
||||
@@ -558,7 +652,7 @@ class Json extends Server {
|
||||
public function getJsonp() {
|
||||
parent::setDatasets();
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header("Content-Type:text/javascript charset=utf-8");
|
||||
header("Content-Type: application/javascript; charset=utf-8");
|
||||
echo $this->callback . '(' . $this->createJson($this->layer) . ');';
|
||||
}
|
||||
|
||||
@@ -566,7 +660,7 @@ class Json extends Server {
|
||||
* Returns UTFGrid in JSON format
|
||||
*/
|
||||
public function getUTFGrid() {
|
||||
parent::getUTFGrid($this->layer, $this->z, $this->y, $this->x);
|
||||
parent::renderUTFGrid($this->layer, $this->z, $this->y, $this->x);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -582,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) {
|
||||
@@ -626,7 +720,7 @@ class Wmts extends Server {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns tilesets getCapabilities
|
||||
* Returns tilesets getCapabilities
|
||||
*/
|
||||
public function getCapabilities() {
|
||||
header("Content-type: application/xml");
|
||||
@@ -643,7 +737,7 @@ class Wmts extends Server {
|
||||
<ows:Operation name="GetCapabilities">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://' . $this->config['baseUrls'][0] . '/wmts/1.0.0/WMTSCapabilities.xml">
|
||||
<ows:Get xlink:href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/wmts/1.0.0/WMTSCapabilities.xml">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>RESTful</ows:Value>
|
||||
@@ -651,7 +745,7 @@ class Wmts extends Server {
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
<!-- add KVP binding in 10.1 -->
|
||||
<ows:Get xlink:href="http://' . $this->config['baseUrls'][0] . '/wmts?">
|
||||
<ows:Get xlink:href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/wmts?">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>KVP</ows:Value>
|
||||
@@ -664,14 +758,14 @@ class Wmts extends Server {
|
||||
<ows:Operation name="GetTile">
|
||||
<ows:DCP>
|
||||
<ows:HTTP>
|
||||
<ows:Get xlink:href="http://' . $this->config['baseUrls'][0] . '/wmts/">
|
||||
<ows:Get xlink:href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/wmts/">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>RESTful</ows:Value>
|
||||
</ows:AllowedValues>
|
||||
</ows:Constraint>
|
||||
</ows:Get>
|
||||
<ows:Get xlink:href="http://' . $this->config['baseUrls'][0] . '/wmts?">
|
||||
<ows:Get xlink:href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/wmts?">
|
||||
<ows:Constraint name="GetEncoding">
|
||||
<ows:AllowedValues>
|
||||
<ows:Value>KVP</ows:Value>
|
||||
@@ -694,8 +788,8 @@ class Wmts extends Server {
|
||||
$title = (array_key_exists('name', $m)) ? $m['name'] : $basename;
|
||||
$profile = $m['profile'];
|
||||
$bounds = $m['bounds'];
|
||||
$format = $m['format'];
|
||||
$mime = ($format == 'jpg') ? 'image/jpeg' : 'image/png';
|
||||
$format = $m['format'] == 'hybrid' ? 'jpgpng' : $m['format'];
|
||||
$mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format;
|
||||
if ($profile == 'geodetic') {
|
||||
$tileMatrixSet = "WGS84";
|
||||
} else {
|
||||
@@ -704,6 +798,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'
|
||||
<Layer>
|
||||
<ows:Title>' . $title . '</ows:Title>
|
||||
@@ -719,8 +818,7 @@ class Wmts extends Server {
|
||||
<TileMatrixSetLink>
|
||||
<TileMatrixSet>' . $tileMatrixSet . '</TileMatrixSet>
|
||||
</TileMatrixSetLink>
|
||||
<ResourceURL format="' . $mime . '" resourceType="tile" template="http://'
|
||||
. $this->config['baseUrls'][0] . '/wmts/' . $basename . '/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.' . $format . '"/>
|
||||
<ResourceURL format="' . $mime . '" resourceType="tile" template="' . $resourceUrlTemplate . '"/>
|
||||
</Layer>';
|
||||
}
|
||||
echo '
|
||||
@@ -1075,7 +1173,7 @@ class Wmts extends Server {
|
||||
</TileMatrix>
|
||||
</TileMatrixSet>
|
||||
</Contents>
|
||||
<ServiceMetadataURL xlink:href="http://' . $this->config['baseUrls'][0] . '/wmts/1.0.0/WMTSCapabilities.xml"/>
|
||||
<ServiceMetadataURL xlink:href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/wmts/1.0.0/WMTSCapabilities.xml"/>
|
||||
</Capabilities>';
|
||||
}
|
||||
|
||||
@@ -1091,9 +1189,15 @@ class Wmts extends Server {
|
||||
} else {
|
||||
$format = $this->getGlobal('Format');
|
||||
}
|
||||
parent::getTile($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::getTile($this->layer, $this->z, $this->y, $this->x, $this->ext);
|
||||
parent::renderTile($this->layer, $this->z, $this->y, $this->x, $this->ext);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1110,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) {
|
||||
@@ -1156,7 +1260,7 @@ class Tms extends Server {
|
||||
$srs = "EPSG:3857";
|
||||
echo '<TileMap title="' . $title . '" srs="' . $srs
|
||||
. '" type="InvertedTMS" ' . 'profile="global-' . $profile
|
||||
. '" href="http://' . $this->config['baseUrls'][0] . '/tms/' . $basename . '" />';
|
||||
. '" href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/tms/' . $basename . '" />';
|
||||
}
|
||||
}
|
||||
echo '</TileMaps></TileMapService>';
|
||||
@@ -1194,7 +1298,7 @@ class Tms extends Server {
|
||||
}
|
||||
$mime = ($m['format'] == 'jpg') ? 'image/jpeg' : 'image/png';
|
||||
header("Content-type: application/xml");
|
||||
echo '<TileMap version="1.0.0" tilemapservice="http://' . $this->config['baseUrls'][0] . '/' . $m['basename'] . '" type="InvertedTMS">
|
||||
echo '<TileMap version="1.0.0" tilemapservice="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/' . $m['basename'] . '" type="InvertedTMS">
|
||||
<Title>' . htmlspecialchars($title) . '</Title>
|
||||
<Abstract>' . htmlspecialchars($description) . '</Abstract>
|
||||
<SRS>' . $srs . '</SRS>
|
||||
@@ -1203,7 +1307,7 @@ class Tms extends Server {
|
||||
<TileFormat width="256" height="256" mime-type="' . $mime . '" extension="' . $m['format'] . '"/>
|
||||
<TileSets profile="global-' . $m['profile'] . '">';
|
||||
for ($zoom = $m['minzoom']; $zoom < $m['maxzoom'] + 1; $zoom++) {
|
||||
echo '<TileSet href="http://' . $this->config['baseUrls'] [0] . '/' . $m['basename'] . '/' . $zoom . '" units-per-pixel="' . $initialResolution / pow(2, $zoom) . '" order="' . $zoom . '" />';
|
||||
echo '<TileSet href="' . $this->config['protocol'] . '://' . $this->config['baseUrls'][0] . '/' . $m['basename'] . '/' . $zoom . '" units-per-pixel="' . $initialResolution / pow(2, $zoom) . '" order="' . $zoom . '" />';
|
||||
}
|
||||
echo'</TileSets></TileMap>';
|
||||
}
|
||||
@@ -1212,7 +1316,7 @@ class Tms extends Server {
|
||||
* Process getTile request
|
||||
*/
|
||||
public function getTile() {
|
||||
parent::getTile($this->layer, $this->z, $this->y, $this->x, $this->ext);
|
||||
parent::renderTile($this->layer, $this->z, $this->y, $this->x, $this->ext);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1356,6 +1460,8 @@ class Router {
|
||||
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";
|
||||
if (!empty($_SERVER['PATH_INFO'])) {
|
||||
$path_info = $_SERVER['PATH_INFO'];
|
||||
} else if (!empty($_SERVER['ORIG_PATH_INFO']) && $_SERVER['ORIG_PATH_INFO'] !== '/tileserver.php') {
|
||||
@@ -1375,9 +1481,9 @@ class Router {
|
||||
$tokens = array(
|
||||
':string' => '([a-zA-Z]+)',
|
||||
':number' => '([0-9]+)',
|
||||
':alpha' => '([a-zA-Z0-9-_]+)'
|
||||
':alpha' => '([a-zA-Z0-9-_@\.]+)'
|
||||
);
|
||||
global $config;
|
||||
//global $config;
|
||||
foreach ($routes as $pattern => $handler_name) {
|
||||
$pattern = strtr($pattern, $tokens);
|
||||
if (preg_match('#/?' . $pattern . '/?$#', $path_info, $matches)) {
|
||||
|
Reference in New Issue
Block a user