1
0
mirror of https://github.com/klokantech/tileserver-php.git synced 2025-08-21 21:56:18 +02:00

38 Commits
v1.0 ... travis

Author SHA1 Message Date
Petr Pridal
730ffa52f3 Merge branch 'master' into travis 2016-02-02 12:03:45 +01:00
Dalibor Janák
b7960baaaa Travis status icon 2016-02-02 10:57:57 +01:00
Dalibor Janák
8aa58cc6b9 Merge pull request #64 from klokantech/master
Vector tiles and hybrid tiles support
2016-02-02 09:53:57 +01:00
Dalibor Janák
250512168c Fix of syntax error on PHP 5.2 (closes #63) 2016-02-01 20:51:03 +01:00
Dalibor Janák
6b5933e21f Utfgrid empty response bug fixed (related #62) 2016-01-26 22:55:34 +01:00
Dalibor Janák
f5408fd108 Utfgrid routing bug fixed 2016-01-26 22:31:12 +01:00
Dalibor Janák
dc26c831f1 Url for viewer switched to cdn. 2016-01-26 13:51:39 +01:00
Dalibor Janák
28aba6f9e2 Fix of utfgrid serving bug related with changes in #59 2016-01-25 18:32:07 +01:00
Dalibor Janák
8f6a2ced68 Fix of utfgid detection 2016-01-25 18:13:15 +01:00
Petr Pridal
79926b92fc Update README.md 2015-12-16 17:07:04 +01:00
Dalibor Janák
3343f80e09 404 with JSON message for not found tile #56 2015-12-15 16:27:28 +01:00
Dalibor Janák
c660ab8f41 Hybrid tile format support #59 2015-12-04 14:00:48 +01:00
Dalibor Janák
21d7a409fe Merge branch 'eyeNsky-master' 2015-12-01 23:06:12 +01:00
Dalibor Janák
abb4087942 Cleaning of image format choser for wmts #58 2015-12-01 23:03:54 +01:00
Dalibor Janák
0acdc04e32 Merge branch 'master' of https://github.com/eyeNsky/tileserver-php into eyeNsky-master 2015-12-01 22:32:46 +01:00
Petr Pridal
765e0d9ea3 Travis CI integration 2015-09-10 02:09:37 +02:00
Petr Pridal
f9e801849e Implementation of MapBox vector tiles (MBTiles pbf) serving #42 2015-09-05 04:44:45 +02:00
Petr Pridal
e66e577d5d Merge pull request #52 from klokantech/large-mbtiles
Faster check for grids in large mbtiles file. Closes #51.
2015-08-13 13:58:16 +02:00
Petr Pridal
ffedfde75e Faster check for grids in large mbtiles file. Issue #51. 2015-08-12 18:01:28 +02:00
eyeNsky
b783c59585 add jpgpng support for ArcGIS Desktop 2015-04-02 08:19:48 -04:00
Petr Pridal
dd8d884bc6 Update README.md 2015-01-08 22:58:22 +01:00
Petr Pridal
8b4a5142e8 Update README.md 2014-12-05 12:27:55 +01:00
Dalibor Janák
53b379cd67 Empty tiles should have for @2x layers 512x512px Fixes #39 2014-08-15 01:01:35 +02:00
Petr Pridal
2bf8bf6d4b A bug introduced in #38 fixed (missing protocol in the WMTS Resource URL) 2014-08-12 17:23:41 +02:00
Petr Pridal
e4454b12be Merge pull request #38 from kurt-hectic/master
Protocol (such as HTTPS vs HTTP) of the request is used in the metadata
2014-08-12 17:13:15 +02:00
Timo Proescholdt
8002dbbb7d service metadata takes into account request protocol 2014-08-04 17:47:47 +02:00
dala
d4121d86d5 Router: Add support for @ in names of layers 2014-07-23 15:32:10 +02:00
dala
ea6e176ab3 Path to app problem fixed 2014-07-23 15:25:25 +02:00
Dalibor Janák
b13b8d98c8 Merge pull request #34 from Fil/patch-2
Autodetect minzoom, maxzoom and format for mbtiles
2014-07-23 13:42:04 +02:00
Dalibor Janák
f08d72262d CORS for tiles. 2014-06-27 09:19:26 +02:00
Dalibor Janák
4250eff554 Merge pull request #32 from Fil/patch-1
Check which .mbtiles files are readable
2014-06-23 14:44:02 +02:00
Fil
34ffddb765 Autodetect minzoom, maxzoom and format for mbtiles
* `format` is detected via JPEG's magic number `FFD8`
* `minzoom` and `maxzoom` are `min(zoom_level)` and `max(zoom_level)`
2014-06-20 23:15:01 +02:00
Fil
5d2662a6a3 Check which .mbtiles files are readable
In my setup some .mbtiles are links to an external hard drive - don't fail when the external drive is not connected. (Also this would allow to manage "publishing a map" via unix permission.)
2014-06-20 12:24:09 +02:00
dala
8dec7469f1 Bad links in the test were fixed. 2014-06-05 22:04:18 +02:00
dala
8170e02397 Strict standards error in PHP 5.4+ on function declarations Fixes #30 - Classes in server renamed. 2014-06-05 21:54:40 +02:00
dala
779e320dec Fixed problem with line break in MBtiles metadata. 2014-06-05 21:46:00 +02:00
dala
e226ae2cc3 URL encoding in tilejson. Problem with backslashes in url fixed. #29 2014-06-04 09:55:25 +02:00
Petr Pridal
61c866a521 Update README.md 2014-05-29 09:10:23 +02:00
3 changed files with 234 additions and 121 deletions

9
.travis.yml Normal file
View File

@@ -0,0 +1,9 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
script:
- php tileserver.php

View File

@@ -1,5 +1,7 @@
TileServer PHP - OGC Web Map Tiling Server (WMTS)
=================================================
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.
@@ -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

View File

@@ -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)) {