From 0446445248775f24d45db9ef746a35dd26acdaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 3 Feb 2016 15:13:56 +0100 Subject: [PATCH 01/16] Generate tilematrix sets from variables --- tileserver.php | 425 +++++++++---------------------------------------- 1 file changed, 73 insertions(+), 352 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54103aa..323d540 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,6 +718,59 @@ class Wmts extends Server { $this->getCapabilities(); } } + + /** + * Default TileMetrixSet for Pseudo Mercator projection 3857 + * @return string TileMatrixSet xml + */ + public function getMercatorTileMatrixSet(){ + $name = 'GoogleMapsCompatible'; + $corner = array(-20037508.34278925, 20037508.34278925); + $scalesBase = 559082264.0287178; + $scales = array(); + + for($i = 0; $i <= 18; $i++){ + $scales[] = $scalesBase / pow(2, $i); + } + + return $this->getTileMatrixSet($name, $scales, $corner); + } + + /** + * Prints WMTS tilematrixset + * @param string $name + * @param array $scales Array of scales + * @param array $corner Position of TopLeft corner of matrix + * @param string $crs Code of crs eg: EPSG:3857 + * @param array $matrixRatio Ratio of matrix sides + * @param array $tilesize Size of tile in pixels + * @return string TileMatrixSet xml + */ + public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + $srs = explode(':', $crs); + $TileMatrixSet = ' + ' . $name . ' + ' . $name . ' '. $crs .' + ' . $name . ' + urn:ogc:def:crs:'.$srs[0].'::'.$srs[1].''; + // $TileMatrixSet .= 'urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible'; + for($i = 0; $i <= sizeof($scales); $i++){ + $matrixWidth = pow(2, $i); + $TileMatrixSet .= ' + + ' . $i . ' + ' . $scales[$i] . ' + '. $corner[0] . ' ' . $corner[1] .' + ' . $tilesize[0] . ' + ' . $tilesize[1] . ' + ' . $matrixWidth * $matrixRatio[0] . ' + ' . $matrixWidth * $matrixRatio[1] . ' + '; + } + $TileMatrixSet .= ''; + + return $TileMatrixSet; + } /** * Returns tilesets getCapabilities @@ -821,358 +874,26 @@ class Wmts extends Server { '; } - echo ' - - GoogleMapsCompatible - the wellknown \'GoogleMapsCompatible\' tile matrix set defined by OGC WMTS specification - GoogleMapsCompatible - urn:ogc:def:crs:EPSG:6.18:3:3857 - urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible - - 0 - 559082264.0287178 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1 - 1 - - - 1 - 279541132.0143589 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2 - 2 - - - 2 - 139770566.0071794 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4 - 4 - - - 3 - 69885283.00358972 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8 - 8 - - - 4 - 34942641.50179486 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16 - 16 - - - 5 - 17471320.75089743 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32 - 32 - - - 6 - 8735660.375448715 - -20037508.34278925 20037508.34278925 - 256 - 256 - 64 - 64 - - - 7 - 4367830.187724357 - -20037508.34278925 20037508.34278925 - 256 - 256 - 128 - 128 - - - 8 - 2183915.093862179 - -20037508.34278925 20037508.34278925 - 256 - 256 - 256 - 256 - - - 9 - 1091957.546931089 - -20037508.34278925 20037508.34278925 - 256 - 256 - 512 - 512 - - - 10 - 545978.7734655447 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1024 - 1024 - - - 11 - 272989.3867327723 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2048 - 2048 - - - 12 - 136494.6933663862 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4096 - 4096 - - - 13 - 68247.34668319309 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8192 - 8192 - - - 14 - 34123.67334159654 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16384 - 16384 - - - 15 - 17061.83667079827 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32768 - 32768 - - - 16 - 8530.918335399136 - -20037508.34278925 20037508.34278925 - 256 - 256 - 65536 - 65536 - - - 17 - 4265.459167699568 - -20037508.34278925 20037508.34278925 - 256 - 256 - 131072 - 131072 - - - 18 - 2132.729583849784 - -20037508.34278925 20037508.34278925 - 256 - 256 - 262144 - 262144 - - - - WGS84 - GoogleCRS84Quad - urn:ogc:def:crs:EPSG:6.3:4326 - - -180.000000 -90.000000 - 180.000000 90.000000 - - urn:ogc:def:wkss:OGC:1.0:GoogleCRS84Quad - - 0 - 279541132.01435887813568115234 - 90.000000 -180.000000 - 256 - 256 - 2 - 1 - - - 1 - 139770566.00717943906784057617 - 90.000000 -180.000000 - 256 - 256 - 4 - 2 - - - 2 - 69885283.00358971953392028809 - 90.000000 -180.000000 - 256 - 256 - 8 - 4 - - - 3 - 34942641.50179485976696014404 - 90.000000 -180.000000 - 256 - 256 - 16 - 8 - - - 4 - 17471320.75089742988348007202 - 90.000000 -180.000000 - 256 - 256 - 32 - 16 - - - 5 - 8735660.37544871494174003601 - 90.000000 -180.000000 - 256 - 256 - 64 - 32 - - - 6 - 4367830.18772435747087001801 - 90.000000 -180.000000 - 256 - 256 - 128 - 64 - - - 7 - 2183915.09386217873543500900 - 90.000000 -180.000000 - 256 - 256 - 256 - 128 - - - 8 - 1091957.54693108936771750450 - 90.000000 -180.000000 - 256 - 256 - 512 - 256 - - - 9 - 545978.77346554468385875225 - 90.000000 -180.000000 - 256 - 256 - 1024 - 512 - - - 10 - 272989.38673277234192937613 - 90.000000 -180.000000 - 256 - 256 - 2048 - 1024 - - - 11 - 136494.69336638617096468806 - 90.000000 -180.000000 - 256 - 256 - 4096 - 2048 - - - 12 - 68247.34668319308548234403 - 90.000000 -180.000000 - 256 - 256 - 8192 - 4096 - - - 13 - 34123.67334159654274117202 - 90.000000 -180.000000 - 256 - 256 - 16384 - 8192 - - - 14 - 17061.83667079825318069197 - 90.000000 -180.000000 - 256 - 256 - 32768 - 16384 - - - 15 - 8530.91833539912659034599 - 90.000000 -180.000000 - 256 - 256 - 65536 - 32768 - - - 16 - 4265.45916769956329517299 - 90.000000 -180.000000 - 256 - 256 - 131072 - 65536 - - - 17 - 2132.72958384978574031265 - 90.000000 -180.000000 - 256 - 256 - 262144 - 131072 - - - + + //Print mercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + + //Print wgs84 TileMatrixSet + $name = 'WGS84'; + $corner = array(-180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($name, $scales, $corner, $crs, $matrixRatio); + + echo ' '; } From 3a9e74e3b07bc1341dc0729729ce41305a9e3da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 3 Feb 2016 15:13:56 +0100 Subject: [PATCH 02/16] Generate tilematrix sets from variables --- tileserver.php | 425 +++++++++---------------------------------------- 1 file changed, 73 insertions(+), 352 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54103aa..323d540 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,6 +718,59 @@ class Wmts extends Server { $this->getCapabilities(); } } + + /** + * Default TileMetrixSet for Pseudo Mercator projection 3857 + * @return string TileMatrixSet xml + */ + public function getMercatorTileMatrixSet(){ + $name = 'GoogleMapsCompatible'; + $corner = array(-20037508.34278925, 20037508.34278925); + $scalesBase = 559082264.0287178; + $scales = array(); + + for($i = 0; $i <= 18; $i++){ + $scales[] = $scalesBase / pow(2, $i); + } + + return $this->getTileMatrixSet($name, $scales, $corner); + } + + /** + * Prints WMTS tilematrixset + * @param string $name + * @param array $scales Array of scales + * @param array $corner Position of TopLeft corner of matrix + * @param string $crs Code of crs eg: EPSG:3857 + * @param array $matrixRatio Ratio of matrix sides + * @param array $tilesize Size of tile in pixels + * @return string TileMatrixSet xml + */ + public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + $srs = explode(':', $crs); + $TileMatrixSet = ' + ' . $name . ' + ' . $name . ' '. $crs .' + ' . $name . ' + urn:ogc:def:crs:'.$srs[0].'::'.$srs[1].''; + // $TileMatrixSet .= 'urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible'; + for($i = 0; $i <= sizeof($scales); $i++){ + $matrixWidth = pow(2, $i); + $TileMatrixSet .= ' + + ' . $i . ' + ' . $scales[$i] . ' + '. $corner[0] . ' ' . $corner[1] .' + ' . $tilesize[0] . ' + ' . $tilesize[1] . ' + ' . $matrixWidth * $matrixRatio[0] . ' + ' . $matrixWidth * $matrixRatio[1] . ' + '; + } + $TileMatrixSet .= ''; + + return $TileMatrixSet; + } /** * Returns tilesets getCapabilities @@ -821,358 +874,26 @@ class Wmts extends Server { '; } - echo ' - - GoogleMapsCompatible - the wellknown \'GoogleMapsCompatible\' tile matrix set defined by OGC WMTS specification - GoogleMapsCompatible - urn:ogc:def:crs:EPSG:6.18:3:3857 - urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible - - 0 - 559082264.0287178 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1 - 1 - - - 1 - 279541132.0143589 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2 - 2 - - - 2 - 139770566.0071794 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4 - 4 - - - 3 - 69885283.00358972 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8 - 8 - - - 4 - 34942641.50179486 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16 - 16 - - - 5 - 17471320.75089743 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32 - 32 - - - 6 - 8735660.375448715 - -20037508.34278925 20037508.34278925 - 256 - 256 - 64 - 64 - - - 7 - 4367830.187724357 - -20037508.34278925 20037508.34278925 - 256 - 256 - 128 - 128 - - - 8 - 2183915.093862179 - -20037508.34278925 20037508.34278925 - 256 - 256 - 256 - 256 - - - 9 - 1091957.546931089 - -20037508.34278925 20037508.34278925 - 256 - 256 - 512 - 512 - - - 10 - 545978.7734655447 - -20037508.34278925 20037508.34278925 - 256 - 256 - 1024 - 1024 - - - 11 - 272989.3867327723 - -20037508.34278925 20037508.34278925 - 256 - 256 - 2048 - 2048 - - - 12 - 136494.6933663862 - -20037508.34278925 20037508.34278925 - 256 - 256 - 4096 - 4096 - - - 13 - 68247.34668319309 - -20037508.34278925 20037508.34278925 - 256 - 256 - 8192 - 8192 - - - 14 - 34123.67334159654 - -20037508.34278925 20037508.34278925 - 256 - 256 - 16384 - 16384 - - - 15 - 17061.83667079827 - -20037508.34278925 20037508.34278925 - 256 - 256 - 32768 - 32768 - - - 16 - 8530.918335399136 - -20037508.34278925 20037508.34278925 - 256 - 256 - 65536 - 65536 - - - 17 - 4265.459167699568 - -20037508.34278925 20037508.34278925 - 256 - 256 - 131072 - 131072 - - - 18 - 2132.729583849784 - -20037508.34278925 20037508.34278925 - 256 - 256 - 262144 - 262144 - - - - WGS84 - GoogleCRS84Quad - urn:ogc:def:crs:EPSG:6.3:4326 - - -180.000000 -90.000000 - 180.000000 90.000000 - - urn:ogc:def:wkss:OGC:1.0:GoogleCRS84Quad - - 0 - 279541132.01435887813568115234 - 90.000000 -180.000000 - 256 - 256 - 2 - 1 - - - 1 - 139770566.00717943906784057617 - 90.000000 -180.000000 - 256 - 256 - 4 - 2 - - - 2 - 69885283.00358971953392028809 - 90.000000 -180.000000 - 256 - 256 - 8 - 4 - - - 3 - 34942641.50179485976696014404 - 90.000000 -180.000000 - 256 - 256 - 16 - 8 - - - 4 - 17471320.75089742988348007202 - 90.000000 -180.000000 - 256 - 256 - 32 - 16 - - - 5 - 8735660.37544871494174003601 - 90.000000 -180.000000 - 256 - 256 - 64 - 32 - - - 6 - 4367830.18772435747087001801 - 90.000000 -180.000000 - 256 - 256 - 128 - 64 - - - 7 - 2183915.09386217873543500900 - 90.000000 -180.000000 - 256 - 256 - 256 - 128 - - - 8 - 1091957.54693108936771750450 - 90.000000 -180.000000 - 256 - 256 - 512 - 256 - - - 9 - 545978.77346554468385875225 - 90.000000 -180.000000 - 256 - 256 - 1024 - 512 - - - 10 - 272989.38673277234192937613 - 90.000000 -180.000000 - 256 - 256 - 2048 - 1024 - - - 11 - 136494.69336638617096468806 - 90.000000 -180.000000 - 256 - 256 - 4096 - 2048 - - - 12 - 68247.34668319308548234403 - 90.000000 -180.000000 - 256 - 256 - 8192 - 4096 - - - 13 - 34123.67334159654274117202 - 90.000000 -180.000000 - 256 - 256 - 16384 - 8192 - - - 14 - 17061.83667079825318069197 - 90.000000 -180.000000 - 256 - 256 - 32768 - 16384 - - - 15 - 8530.91833539912659034599 - 90.000000 -180.000000 - 256 - 256 - 65536 - 32768 - - - 16 - 4265.45916769956329517299 - 90.000000 -180.000000 - 256 - 256 - 131072 - 65536 - - - 17 - 2132.72958384978574031265 - 90.000000 -180.000000 - 256 - 256 - 262144 - 131072 - - - + + //Print mercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + + //Print wgs84 TileMatrixSet + $name = 'WGS84'; + $corner = array(-180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($name, $scales, $corner, $crs, $matrixRatio); + + echo ' '; } From ea100ad8c2f45d7a01eb3799d6e5cb1d801afdb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 3 Feb 2016 16:50:07 +0100 Subject: [PATCH 03/16] Custom profile testing implemetation --- tileserver.php | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/tileserver.php b/tileserver.php index 323d540..98185d4 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,7 +718,7 @@ class Wmts extends Server { $this->getCapabilities(); } } - + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml @@ -728,14 +728,14 @@ class Wmts extends Server { $corner = array(-20037508.34278925, 20037508.34278925); $scalesBase = 559082264.0287178; $scales = array(); - + for($i = 0; $i <= 18; $i++){ $scales[] = $scalesBase / pow(2, $i); } return $this->getTileMatrixSet($name, $scales, $corner); } - + /** * Prints WMTS tilematrixset * @param string $name @@ -768,7 +768,7 @@ class Wmts extends Server { '; } $TileMatrixSet .= ''; - + return $TileMatrixSet; } @@ -830,6 +830,10 @@ class Wmts extends Server { '; + //TileMatrixSets that will be printed: + $tileMatrixSets = array('GoogleMapsCompatible' => FALSE, 'custom' => FALSE, 'geodetic' => FALSE); + + //layers $maps = array_merge($this->fileLayer, $this->dbLayer); $mercator = new GlobalMercator(); foreach ($maps as $m) { @@ -843,10 +847,18 @@ class Wmts extends Server { $bounds = $m['bounds']; $format = $m['format'] == 'hybrid' ? 'jpgpng' : $m['format']; $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; + if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; + $tileMatrixSets['geodetic'] = TRUE; + }elseif ($m['profile'] == 'custom') { + $crs = explode(':', $m['crs']); + $tileMatrixSet = 'custom' . $crs[1]; + $tileMatrixSets['custom'] = TRUE; } else { $tileMatrixSet = "GoogleMapsCompatible"; + $tileMatrixSets['GoogleMapsCompatible'] = TRUE; + list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); @@ -874,24 +886,30 @@ class Wmts extends Server { '; } - - //Print mercator TileMatrixSet - echo $this->getMercatorTileMatrixSet(); - - //Print wgs84 TileMatrixSet - $name = 'WGS84'; - $corner = array(-180.000000, 90.000000); - $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + + if ($tileMatrixSets['geodetic']) { + //Print wgs84 TileMatrixSet + $corner = array(-180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, - 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, 2132.72958384978574031265); - $crs = 'EPSG::4326'; - $matrixRatio = array(2, 1); - - echo $this->getTileMatrixSet($name, $scales, $corner, $crs, $matrixRatio); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); + + echo $this->getTileMatrixSet($tileMatrixSet, $scales, $corner, $crs, $matrixRatio); + } + if ($tileMatrixSets['custom']) { + // Custom from metadata + echo $this->getTileMatrixSet($tileMatrixSet, $m['scales'], array($m['projected_bounds'][0], $m['projected_bounds'][4]), $m['crs']); + } + if($tileMatrixSets['GoogleMapsCompatible']){ + //Print mercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + } echo ' From 8b49aa2b8c2ed0265a51098e0820db6daa77cdf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 9 Feb 2016 14:36:24 +0100 Subject: [PATCH 04/16] Custom matrix sets generation refactring --- tileserver.php | 65 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/tileserver.php b/tileserver.php index 98185d4..b55d1d3 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,14 +718,14 @@ class Wmts extends Server { $this->getCapabilities(); } } - + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml */ public function getMercatorTileMatrixSet(){ $name = 'GoogleMapsCompatible'; - $corner = array(-20037508.34278925, 20037508.34278925); + $extent = array(-20037508.34,-20037508.34,20037508.34,20037508.34); $scalesBase = 559082264.0287178; $scales = array(); @@ -733,20 +733,20 @@ class Wmts extends Server { $scales[] = $scalesBase / pow(2, $i); } - return $this->getTileMatrixSet($name, $scales, $corner); + return $this->getTileMatrixSet($name, $scales, $extent); } /** * Prints WMTS tilematrixset * @param string $name * @param array $scales Array of scales - * @param array $corner Position of TopLeft corner of matrix + * @param array $extent Boundingbox of matrix * @param string $crs Code of crs eg: EPSG:3857 * @param array $matrixRatio Ratio of matrix sides * @param array $tilesize Size of tile in pixels * @return string TileMatrixSet xml */ - public function getTileMatrixSet($name, $scales, $corner, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + public function getTileMatrixSet($name, $scales, $extent, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ $srs = explode(':', $crs); $TileMatrixSet = ' ' . $name . ' @@ -760,7 +760,7 @@ class Wmts extends Server { ' . $i . ' ' . $scales[$i] . ' - '. $corner[0] . ' ' . $corner[1] .' + '. $extent[0] . ' ' . $extent[3] .' ' . $tilesize[0] . ' ' . $tilesize[1] . ' ' . $matrixWidth * $matrixRatio[0] . ' @@ -830,8 +830,8 @@ class Wmts extends Server { '; - //TileMatrixSets that will be printed: - $tileMatrixSets = array('GoogleMapsCompatible' => FALSE, 'custom' => FALSE, 'geodetic' => FALSE); + + $customtileMatrixSets = ''; //layers $maps = array_merge($this->fileLayer, $this->dbLayer); @@ -850,14 +850,15 @@ class Wmts extends Server { if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; - $tileMatrixSets['geodetic'] = TRUE; }elseif ($m['profile'] == 'custom') { + //TODO: Each custom neads each tileset BUG!! $crs = explode(':', $m['crs']); $tileMatrixSet = 'custom' . $crs[1]; - $tileMatrixSets['custom'] = TRUE; + + $customtileMatrixSets .= $this->getTileMatrixSet($tileMatrixSet, $m['scales'], $m['bounds'], $m['crs']); + } else { $tileMatrixSet = "GoogleMapsCompatible"; - $tileMatrixSets['GoogleMapsCompatible'] = TRUE; list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); @@ -886,30 +887,28 @@ class Wmts extends Server { '; } + // Print PseudoMercator TileMatrixSet + echo $this->getMercatorTileMatrixSet(); + + //Print wgs84 TileMatrixSet + $matrixExtent = array(-180.000000, -90.000000, 180.000000, 90.000000); + $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $crs = 'EPSG::4326'; + $matrixRatio = array(2, 1); - if ($tileMatrixSets['geodetic']) { - //Print wgs84 TileMatrixSet - $corner = array(-180.000000, 90.000000); - $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, - 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, - 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, - 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, - 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, - 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, - 2132.72958384978574031265); - $crs = 'EPSG::4326'; - $matrixRatio = array(2, 1); + echo $this->getTileMatrixSet($tileMatrixSet, $scales, $matrixExtent, $crs, $matrixRatio); + + //Print custom TileMatrixSet + if (strlen($customtileMatrixSets) > 0) { + echo $customtileMatrixSets; + } - echo $this->getTileMatrixSet($tileMatrixSet, $scales, $corner, $crs, $matrixRatio); - } - if ($tileMatrixSets['custom']) { - // Custom from metadata - echo $this->getTileMatrixSet($tileMatrixSet, $m['scales'], array($m['projected_bounds'][0], $m['projected_bounds'][4]), $m['crs']); - } - if($tileMatrixSets['GoogleMapsCompatible']){ - //Print mercator TileMatrixSet - echo $this->getMercatorTileMatrixSet(); - } echo ' From ab7862209a40bb4c9583d2687caeae65f7ada72f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Tue, 9 Feb 2016 14:37:26 +0100 Subject: [PATCH 05/16] Functions for parsing tilematrixset from json --- tileserver.php | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tileserver.php b/tileserver.php index b55d1d3..3ed04f6 100644 --- a/tileserver.php +++ b/tileserver.php @@ -718,6 +718,71 @@ class Wmts extends Server { $this->getCapabilities(); } } + + /** + * Validates tilematrixset, calculates missing params + * @param Obrject $tileMatrix + * @return Object + */ + public function parseTileMatrix($tileMatrix){ + + for($i = 0; $i <= sizeof($tileMatrix[$i]); $i++){ + if(!isset($tileMatrix[$i]['tile_size'])){ + $tileMatrix[$i]['tile_size'] = array(256, 256); + } + + if (!isset($tileMatrix[$i]['matrix_size'])) { + $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); + } + + //když není nebo když + if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ + $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); + } + + if(!isset($tileMatrix[$i]['scale_denominator'])){ + //constants + $tileMatrix[$i]['scale_denominator'] = null; + } + + if(!isset($tileMatrix[$i]['pixel_size']) && $tileMatrix[$i]['pixel_size'][1] > 0){ + + } + + //kontrola jestli piel size je kladná v obou osách + } + + return $tileMatrix; + } + + /** + * Calculates corners of tilematrix + * @param array $extent + * @param array $origin + * @param array $pixel_size + * @param array $tile_size + * @return array + */ + public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { + //$minx, $miny, $maxx, $maxy = $extent; + + function minsample($x, $f){ + return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } + + function maxsample($x, $f){ + return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } + + $tiles = array(); + $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); + $tiles[] =minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); + + $tiles[] =maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); + $tiles[] =maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); + + return $tiles; + } /** * Default TileMetrixSet for Pseudo Mercator projection 3857 From ce485c67135c607f84170c20ad488689e9e4073c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 11:39:16 +0100 Subject: [PATCH 06/16] Allow to read metadata bounding box also as array --- tileserver.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 3ed04f6..9011f93 100644 --- a/tileserver.php +++ b/tileserver.php @@ -221,10 +221,10 @@ class Server { * @return object */ public function metadataValidation($metadata) { - if (array_key_exists('bounds', $metadata)) { + if (!array_key_exists('bounds', $metadata)) { + $metadata['bounds'] = array(-180, -85.06, 180, 85.06); + } elseif (!is_array($metadata['bounds'])) { $metadata['bounds'] = array_map('floatval', explode(',', $metadata['bounds'])); - } else { - $metadata['bounds'] = array(-180, -85.051128779807, 180, 85.051128779807); } if (!array_key_exists('profile', $metadata)) { $metadata['profile'] = 'mercator'; From 0609b25905ab9e0dbed36afda3aaed838d8af5d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 20:29:39 +0100 Subject: [PATCH 07/16] Refactoring of tilematrixsets creation --- tileserver.php | 147 +++++++++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 60 deletions(-) diff --git a/tileserver.php b/tileserver.php index 9011f93..912bc8c 100644 --- a/tileserver.php +++ b/tileserver.php @@ -725,36 +725,36 @@ class Wmts extends Server { * @return Object */ public function parseTileMatrix($tileMatrix){ - + for($i = 0; $i <= sizeof($tileMatrix[$i]); $i++){ if(!isset($tileMatrix[$i]['tile_size'])){ $tileMatrix[$i]['tile_size'] = array(256, 256); } - + if (!isset($tileMatrix[$i]['matrix_size'])) { $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); } - //když není nebo když + //když není nebo když if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); } - + if(!isset($tileMatrix[$i]['scale_denominator'])){ //constants $tileMatrix[$i]['scale_denominator'] = null; } - + if(!isset($tileMatrix[$i]['pixel_size']) && $tileMatrix[$i]['pixel_size'][1] > 0){ - + } - + //kontrola jestli piel size je kladná v obou osách } - + return $tileMatrix; } - + /** * Calculates corners of tilematrix * @param array $extent @@ -765,11 +765,11 @@ class Wmts extends Server { */ public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { //$minx, $miny, $maxx, $maxy = $extent; - + function minsample($x, $f){ return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); } - + function maxsample($x, $f){ return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); } @@ -777,59 +777,94 @@ class Wmts extends Server { $tiles = array(); $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); $tiles[] =minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); - + $tiles[] =maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); $tiles[] =maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); - + return $tiles; } - + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml */ public function getMercatorTileMatrixSet(){ - $name = 'GoogleMapsCompatible'; + $denominatorBase = 559082264.0287178; $extent = array(-20037508.34,-20037508.34,20037508.34,20037508.34); - $scalesBase = 559082264.0287178; - $scales = array(); + $tileMatrixSet = array(); for($i = 0; $i <= 18; $i++){ - $scales[] = $scalesBase / pow(2, $i); + $level = new stdClass(); + $level->extent = $extent; + $level->id = (string) $i; + $matrixSize = pow(2, $i); + $level->matrix_size = array($matrixSize, $matrixSize); + $level->origin = array($extent[0], $extent[1]); + $level->scale_denominator = $denominatorBase / pow(2, $i); + $level->tile_size = array(256, 256); + + $tileMatrixSet[] = (array) $level; } - return $this->getTileMatrixSet($name, $scales, $extent); + return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); + } + + /** + * Default TileMetrixSet for WGS84 projection 4326 + * @return string Xml + */ + public function getWGS84TileMatrixSet(){ + $extent = array(-180.000000, -90.000000, 180.000000, 90.000000); + $scaleDenominators = array(279541132.01435887813568115234, 139770566.00717943906784057617, + 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, + 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, + 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, + 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, + 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, + 2132.72958384978574031265); + $tileMatrixSet = array(); + + for($i = 0; $i <= count($scaleDenominators); $i++){ + $level = new stdClass(); + $level->extent = $extent; + $level->id = (string) $i; + $matrixSize = pow(2, $i); + $level->matrix_size = array($matrixSize * 2, $matrixSize); + $level->origin = array($extent[0], $extent[1]); + $level->scale_denominator = $scaleDenominators[$i]; + $level->tile_size = array(256, 256); + + $tileMatrixSet[] = (array) $level; + } + + return $this->getTileMatrixSet('WGS84', $tileMatrixSet, 'EPSG:4326'); } /** - * Prints WMTS tilematrixset + * Prints WMTS TileMatrixSet * @param string $name - * @param array $scales Array of scales - * @param array $extent Boundingbox of matrix + * @param array $tileMatrixSet Array of levels * @param string $crs Code of crs eg: EPSG:3857 - * @param array $matrixRatio Ratio of matrix sides - * @param array $tilesize Size of tile in pixels * @return string TileMatrixSet xml */ - public function getTileMatrixSet($name, $scales, $extent, $crs = 'EPSG:3857', $matrixRatio = array(1, 1), $tilesize = array(256, 256)){ + public function getTileMatrixSet($name, $tileMatrixSet, $crs = 'EPSG:3857'){ $srs = explode(':', $crs); $TileMatrixSet = ' ' . $name . ' ' . $name . ' '. $crs .' ' . $name . ' urn:ogc:def:crs:'.$srs[0].'::'.$srs[1].''; - // $TileMatrixSet .= 'urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible'; - for($i = 0; $i <= sizeof($scales); $i++){ - $matrixWidth = pow(2, $i); + // urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible; + foreach($tileMatrixSet as $level){ $TileMatrixSet .= ' - ' . $i . ' - ' . $scales[$i] . ' - '. $extent[0] . ' ' . $extent[3] .' - ' . $tilesize[0] . ' - ' . $tilesize[1] . ' - ' . $matrixWidth * $matrixRatio[0] . ' - ' . $matrixWidth * $matrixRatio[1] . ' + ' . $level['id'] . ' + ' . $level['scale_denominator'] . ' + '. $level['origin'][0] . ' ' . $level['origin'][1] .' + ' . $level['tile_size'][0] . ' + ' . $level['tile_size'][1] . ' + ' . $level['matrix_size'][0] . ' + ' . $level['matrix_size'][1] . ' '; } $TileMatrixSet .= ''; @@ -895,9 +930,9 @@ class Wmts extends Server { '; - + $customtileMatrixSets = ''; - + //layers $maps = array_merge($this->fileLayer, $this->dbLayer); $mercator = new GlobalMercator(); @@ -912,19 +947,22 @@ class Wmts extends Server { $bounds = $m['bounds']; $format = $m['format'] == 'hybrid' ? 'jpgpng' : $m['format']; $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; - + if ($profile == 'geodetic') { $tileMatrixSet = "WGS84"; }elseif ($m['profile'] == 'custom') { - //TODO: Each custom neads each tileset BUG!! $crs = explode(':', $m['crs']); $tileMatrixSet = 'custom' . $crs[1]; - - $customtileMatrixSets .= $this->getTileMatrixSet($tileMatrixSet, $m['scales'], $m['bounds'], $m['crs']); - + + $customtileMatrixSets .= $this->getTileMatrixSet( + $tileMatrixSet, + $m['tile_matrix'], + $m['crs'] + ); + } else { $tileMatrixSet = "GoogleMapsCompatible"; - + list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); $bounds3857 = array($minx, $miny, $maxx, $maxy); @@ -952,29 +990,18 @@ class Wmts extends Server { '; } + // Print PseudoMercator TileMatrixSet echo $this->getMercatorTileMatrixSet(); - - //Print wgs84 TileMatrixSet - $matrixExtent = array(-180.000000, -90.000000, 180.000000, 90.000000); - $scales = array(279541132.01435887813568115234, 139770566.00717943906784057617, - 69885283.00358971953392028809, 34942641.50179485976696014404, 17471320.75089742988348007202, - 8735660.37544871494174003601, 4367830.18772435747087001801, 2183915.09386217873543500900, - 1091957.54693108936771750450, 545978.77346554468385875225, 272989.38673277234192937613, - 136494.69336638617096468806, 68247.34668319308548234403, 34123.67334159654274117202, - 17061.83667079825318069197, 8530.91833539912659034599, 4265.45916769956329517299, - 2132.72958384978574031265); - $crs = 'EPSG::4326'; - $matrixRatio = array(2, 1); - echo $this->getTileMatrixSet($tileMatrixSet, $scales, $matrixExtent, $crs, $matrixRatio); - - //Print custom TileMatrixSet + // Print WGS84 TileMatrixSet + echo $this->getWGS84TileMatrixSet(); + + // Print custom TileMatrixSets if (strlen($customtileMatrixSets) > 0) { - echo $customtileMatrixSets; + echo $customtileMatrixSets; } - echo ' '; From 6da6b13fed41e4e14289ba80f55e989ded354490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 21:19:16 +0100 Subject: [PATCH 08/16] Parse TileMatrixSet --- tileserver.php | 74 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 29 deletions(-) diff --git a/tileserver.php b/tileserver.php index 912bc8c..5540200 100644 --- a/tileserver.php +++ b/tileserver.php @@ -241,6 +241,11 @@ class Server { if (!array_key_exists('format', $metadata)) { $metadata['format'] = 'png'; } + + if (!array_key_exists('scale', $metadata)) { + $metadata['scale'] = 1; + } + return $metadata; } @@ -724,32 +729,34 @@ class Wmts extends Server { * @param Obrject $tileMatrix * @return Object */ - public function parseTileMatrix($tileMatrix){ + public function parseTileMatrix($layer, $tileMatrix){ - for($i = 0; $i <= sizeof($tileMatrix[$i]); $i++){ - if(!isset($tileMatrix[$i]['tile_size'])){ - $tileMatrix[$i]['tile_size'] = array(256, 256); + for($i = 0; $i <= count($tileMatrix); $i++){ + if(!isset($tileMatrix[$i]['id'])){ + $tileMatrix[$i]['id'] = (string) $i; } - + + if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { + $tileMatrix[$i]['extent'] = $layer['extent']; + } + + //TODO: Compute from $ŧhis->tilesOfExtent() if (!isset($tileMatrix[$i]['matrix_size'])) { $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); } - - //když není nebo když + if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); } - + if(!isset($tileMatrix[$i]['scale_denominator'])){ - //constants - $tileMatrix[$i]['scale_denominator'] = null; + $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; + } + + if(!isset($tileMatrix[$i]['tile_size'])){ + $tileSize = 256 * (int) $layer['scale']; + $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); } - - if(!isset($tileMatrix[$i]['pixel_size']) && $tileMatrix[$i]['pixel_size'][1] > 0){ - - } - - //kontrola jestli piel size je kladná v obou osách } return $tileMatrix; @@ -802,13 +809,13 @@ class Wmts extends Server { $level->origin = array($extent[0], $extent[1]); $level->scale_denominator = $denominatorBase / pow(2, $i); $level->tile_size = array(256, 256); - + $tileMatrixSet[] = (array) $level; } return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); } - + /** * Default TileMetrixSet for WGS84 projection 4326 * @return string Xml @@ -833,7 +840,7 @@ class Wmts extends Server { $level->origin = array($extent[0], $extent[1]); $level->scale_denominator = $scaleDenominators[$i]; $level->tile_size = array(256, 256); - + $tileMatrixSet[] = (array) $level; } @@ -876,6 +883,19 @@ class Wmts extends Server { * Returns tilesets getCapabilities */ public function getCapabilities() { + + $layers = array_merge($this->fileLayer, $this->dbLayer); + + //if TileMatrixSet is provided validate it + for($i = 0; $i >= count($layers); $i++){ + if($layers[$i]['profile'] == 'custom' || isset($layers[$i]['tile_matrix'])){ + $layers[$i]['tile_matrix'] = $this->parseTileMatrix( + $layers[$i], + $layers[$i]['tile_matrix'] + ); + } + } + header("Content-type: application/xml"); echo ' @@ -934,14 +954,10 @@ class Wmts extends Server { $customtileMatrixSets = ''; //layers - $maps = array_merge($this->fileLayer, $this->dbLayer); $mercator = new GlobalMercator(); - foreach ($maps as $m) { - if (strpos($m['basename'], '.') !== false) { - $basename = explode('.', $m['basename']); - } else { - $basename = $m['basename']; - } + foreach ($layers as $m) { + + $basename = $m['basename']; $title = (array_key_exists('name', $m)) ? $m['name'] : $basename; $profile = $m['profile']; $bounds = $m['bounds']; @@ -955,8 +971,8 @@ class Wmts extends Server { $tileMatrixSet = 'custom' . $crs[1]; $customtileMatrixSets .= $this->getTileMatrixSet( - $tileMatrixSet, - $m['tile_matrix'], + $tileMatrixSet, + $m['tile_matrix'], $m['crs'] ); @@ -990,7 +1006,7 @@ class Wmts extends Server { '; } - + // Print PseudoMercator TileMatrixSet echo $this->getMercatorTileMatrixSet(); From 4ff5d95a38af08ad44df53550c4953f2c66bb90d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 17 Feb 2016 21:29:53 +0100 Subject: [PATCH 09/16] Code formating --- tileserver.php | 80 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/tileserver.php b/tileserver.php index 5540200..d3fd156 100644 --- a/tileserver.php +++ b/tileserver.php @@ -4,7 +4,7 @@ * TileServer.php project * ====================== * https://github.com/klokantech/tileserver-php/ - * Copyright (C) 2014 - Klokan Technologies GmbH + * Copyright (C) 2016 - Klokan Technologies GmbH */ global $config; @@ -143,7 +143,7 @@ class Server { } /** - * + * Get metadata from metadataJson * @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) @@ -175,10 +175,12 @@ class Server { // 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)) + if (!array_key_exists('minzoom', $metadata)){ $metadata['minzoom'] = $resultdata[0]['min']; - if (!array_key_exists('maxzoom', $metadata)) + } + if (!array_key_exists('maxzoom', $metadata)){ $metadata['maxzoom'] = $resultdata[0]['max']; + } } // autodetect format using JPEG magic number FFD8 if (!array_key_exists('format', $metadata)) { @@ -192,10 +194,10 @@ class Server { 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'])); + $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']); + $s = $this->row2lat($resultdata[0]['s'] - 1, $metadata['maxzoom']); $metadata['bounds'] = implode(',', array($w, $s, $e, $n)); } $metadata = $this->metadataValidation($metadata); @@ -211,8 +213,8 @@ class Server { * @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); + $y = $r / pow(2, $zoom - 1 ) - 1; + return rad2deg(2.0 * atan(exp(3.191459196 * $y)) - 1.57079632679489661922); } /** @@ -229,23 +231,25 @@ class Server { if (!array_key_exists('profile', $metadata)) { $metadata['profile'] = 'mercator'; } -// TODO: detect thumb / SQL for mbtiles - if (array_key_exists('minzoom', $metadata)) + if (array_key_exists('minzoom', $metadata)){ $metadata['minzoom'] = intval($metadata['minzoom']); - else + }else{ $metadata['minzoom'] = 0; - if (array_key_exists('maxzoom', $metadata)) + } + if (array_key_exists('maxzoom', $metadata)){ $metadata['maxzoom'] = intval($metadata['maxzoom']); - else + }else{ $metadata['maxzoom'] = 18; + } if (!array_key_exists('format', $metadata)) { $metadata['format'] = 'png'; } - if (!array_key_exists('scale', $metadata)) { $metadata['scale'] = 1; } - + + // TODO: detect thumb / SQL for mbtiles + return $metadata; } @@ -277,8 +281,8 @@ class Server { $filename = $filename . '.mbtiles'; $lastModifiedTime = filemtime($filename); $eTag = md5($lastModifiedTime); - header("Last-Modified: " . gmdate("D, d M Y H:i:s", $lastModifiedTime) . " GMT"); - header("Etag:" . $eTag); + header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastModifiedTime) . ' GMT'); + header('Etag:' . $eTag); if (@strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) == $lastModifiedTime || @trim($_SERVER['HTTP_IF_NONE_MATCH']) == $eTag) { return TRUE; @@ -356,7 +360,7 @@ class Server { die; } else { //scale of tile (for retina tiles) - $meta = json_decode(file_get_contents($tileset.'/metadata.json')); + $meta = json_decode(file_get_contents($tileset . '/metadata.json')); if(!isset($meta->scale)){ $meta->scale = 1; } @@ -364,7 +368,7 @@ class Server { $this->getCleanTile($meta->scale, $ext); } else { header('HTTP/1.1 404 Not Found'); - echo 'Server: Unknown or not specified dataset "'.$tileset.'"'; + echo 'Server: Unknown or not specified dataset "' . $tileset . '"'; die; } } @@ -483,7 +487,7 @@ class Server { . $this->config['baseUrls'][0] . '/' . $map['basename'] . '.json
'; echo 'Bounds: ' . $extend . '

'; } - echo '

Copyright (C) 2014 - Klokan Technologies GmbH

'; + echo '

Copyright (C) 2016 - Klokan Technologies GmbH

'; echo ''; } @@ -643,7 +647,7 @@ class Json extends Server { public function getJson() { parent::setDatasets(); header('Access-Control-Allow-Origin: *'); - header("Content-Type: application/json; charset=utf-8"); + header('Content-Type: application/json; charset=utf-8'); if ($this->callback !== 'grid') { echo $this->callback . '(' . $this->createJson($this->layer) . ');'; die; } else { @@ -657,7 +661,7 @@ class Json extends Server { public function getJsonp() { parent::setDatasets(); header('Access-Control-Allow-Origin: *'); - header("Content-Type: application/javascript; charset=utf-8"); + header('Content-Type: application/javascript; charset=utf-8'); echo $this->callback . '(' . $this->createJson($this->layer) . ');'; } @@ -735,24 +739,24 @@ class Wmts extends Server { if(!isset($tileMatrix[$i]['id'])){ $tileMatrix[$i]['id'] = (string) $i; } - + if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { $tileMatrix[$i]['extent'] = $layer['extent']; } - + //TODO: Compute from $ŧhis->tilesOfExtent() if (!isset($tileMatrix[$i]['matrix_size'])) { $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); } - + if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); } - + if(!isset($tileMatrix[$i]['scale_denominator'])){ $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; } - + if(!isset($tileMatrix[$i]['tile_size'])){ $tileSize = 256 * (int) $layer['scale']; $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); @@ -896,7 +900,7 @@ class Wmts extends Server { } } - header("Content-type: application/xml"); + header('Content-type: application/xml'); echo ' @@ -965,19 +969,17 @@ class Wmts extends Server { $mime = ($format == 'jpg') ? 'image/jpeg' : 'image/' . $format; if ($profile == 'geodetic') { - $tileMatrixSet = "WGS84"; + $tileMatrixSet = 'WGS84'; }elseif ($m['profile'] == 'custom') { $crs = explode(':', $m['crs']); $tileMatrixSet = 'custom' . $crs[1]; - $customtileMatrixSets .= $this->getTileMatrixSet( $tileMatrixSet, $m['tile_matrix'], $m['crs'] ); - } else { - $tileMatrixSet = "GoogleMapsCompatible"; + $tileMatrixSet = 'GoogleMapsCompatible'; list( $minx, $miny ) = $mercator->LatLonToMeters($bounds[1], $bounds[0]); list( $maxx, $maxy ) = $mercator->LatLonToMeters($bounds[3], $bounds[2]); @@ -1094,16 +1096,16 @@ class Tms extends Server { public function getCapabilities() { parent::setDatasets(); $maps = array_merge($this->fileLayer, $this->dbLayer); - header("Content-type: application/xml"); + header('Content-type: application/xml'); echo''; foreach ($maps as $m) { $basename = $m['basename']; $title = (array_key_exists('name', $m) ) ? $m['name'] : $basename; $profile = $m['profile']; if ($profile == 'geodetic') { - $srs = "EPSG:4326"; + $srs = 'EPSG:4326'; } else { - $srs = "EPSG:3857"; + $srs = 'EPSG:3857'; echo ''; @@ -1128,12 +1130,12 @@ class Tms extends Server { $description = (array_key_exists('description', $m)) ? $m['description'] : ""; $bounds = $m['bounds']; if ($m['profile'] == 'geodetic') { - $srs = "EPSG:4326"; + $srs = 'EPSG:4326'; $originx = -180.0; $originy = -90.0; $initialResolution = 0.703125; } else { - $srs = "EPSG:3857"; + $srs = 'EPSG:3857'; $originx = -20037508.342789; $originy = -20037508.342789; $mercator = new GlobalMercator(); From 27fc9a73ca87b3a9c02e8d984cca79f35d1a7a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 18 Feb 2016 08:43:49 +0100 Subject: [PATCH 10/16] Minor loop fixes --- tileserver.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/tileserver.php b/tileserver.php index d3fd156..545f26d 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,12 +734,13 @@ class Wmts extends Server { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - - for($i = 0; $i <= count($tileMatrix); $i++){ + + for($i = 0; $i < count($tileMatrix); $i++){ + if(!isset($tileMatrix[$i]['id'])){ $tileMatrix[$i]['id'] = (string) $i; } - + if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { $tileMatrix[$i]['extent'] = $layer['extent']; } @@ -750,7 +751,9 @@ class Wmts extends Server { } if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ - $tileMatrix[$i]['origin'] = array($tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4]); + $tileMatrix[$i]['origin'] = array( + $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4] + ); } if(!isset($tileMatrix[$i]['scale_denominator'])){ @@ -787,10 +790,10 @@ class Wmts extends Server { $tiles = array(); $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] =minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); + $tiles[] = minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); - $tiles[] =maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] =maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); + $tiles[] = maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); + $tiles[] = maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); return $tiles; } @@ -890,8 +893,8 @@ class Wmts extends Server { $layers = array_merge($this->fileLayer, $this->dbLayer); - //if TileMatrixSet is provided validate it - for($i = 0; $i >= count($layers); $i++){ + //if TileMatrixSet is provided validate it + for($i = 0; $i < count($layers); $i++){ if($layers[$i]['profile'] == 'custom' || isset($layers[$i]['tile_matrix'])){ $layers[$i]['tile_matrix'] = $this->parseTileMatrix( $layers[$i], From a2162eeb991ddeb4eee630ddc4446d1254bb4359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 18 Feb 2016 16:49:48 +0100 Subject: [PATCH 11/16] Computation of matrix size --- tileserver.php | 62 +++++++++++++++++++++++++------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/tileserver.php b/tileserver.php index 545f26d..e1f32cf 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,32 +734,35 @@ class Wmts extends Server { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - + for($i = 0; $i < count($tileMatrix); $i++){ - + if(!isset($tileMatrix[$i]['id'])){ $tileMatrix[$i]['id'] = (string) $i; } - if (!isset($tileMatrix[$i]['extent']) && isset($layer['extent'])) { $tileMatrix[$i]['extent'] = $layer['extent']; } - - //TODO: Compute from $ŧhis->tilesOfExtent() if (!isset($tileMatrix[$i]['matrix_size'])) { - $tileMatrix[$i]['matrix_size'] = array(pow(2, $i), pow(2, $i)); + $tileExtent = $this->tilesOfExtent( + $tileMatrix[$i]['extent'], + $tileMatrix[$i]['origin'], + $tileMatrix[$i]['pixel_size'], + $tileMatrix[$i]['tile_size'] + ); + $tileMatrix[$i]['matrix_size'] = array( + $tileExtent[1] + 1, + $tileExtent[2] + 1 + ); } - if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array( $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4] ); } - if(!isset($tileMatrix[$i]['scale_denominator'])){ $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; } - if(!isset($tileMatrix[$i]['tile_size'])){ $tileSize = 256 * (int) $layer['scale']; $tileMatrix[$i]['tile_size'] = array($tileSize, $tileSize); @@ -778,26 +781,23 @@ class Wmts extends Server { * @return array */ public function tilesOfExtent($extent, $origin, $pixel_size, $tile_size) { - //$minx, $miny, $maxx, $maxy = $extent; - - function minsample($x, $f){ - return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); - } - - function maxsample($x, $f){ - return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); - } - - $tiles = array(); - $tiles[] = minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] = minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]); - - $tiles[] = maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]); - $tiles[] = maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]); - + $tiles = array( + $this->minsample($extent[0] - $origin[0], $pixel_size[0] * $tile_size[0]), + $this->minsample($extent[1] - $origin[1], $pixel_size[1] * $tile_size[1]), + $this->maxsample($extent[2] - $origin[0], $pixel_size[0] * $tile_size[0]), + $this->maxsample($extent[3] - $origin[1], $pixel_size[1] * $tile_size[1]), + ); return $tiles; } + private function minsample($x, $f){ + return $f > 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } + + private function maxsample($x, $f){ + return $f < 0 ? floor($x / $f) : ceil(($x / $f) - 1); + } + /** * Default TileMetrixSet for Pseudo Mercator projection 3857 * @return string TileMatrixSet xml @@ -895,11 +895,11 @@ class Wmts extends Server { //if TileMatrixSet is provided validate it for($i = 0; $i < count($layers); $i++){ - if($layers[$i]['profile'] == 'custom' || isset($layers[$i]['tile_matrix'])){ + if($layers[$i]['profile'] == 'custom'){ $layers[$i]['tile_matrix'] = $this->parseTileMatrix( - $layers[$i], - $layers[$i]['tile_matrix'] - ); + $layers[$i], + $layers[$i]['tile_matrix'] + ); } } @@ -975,7 +975,7 @@ class Wmts extends Server { $tileMatrixSet = 'WGS84'; }elseif ($m['profile'] == 'custom') { $crs = explode(':', $m['crs']); - $tileMatrixSet = 'custom' . $crs[1]; + $tileMatrixSet = 'custom' . $crs[1] . $m['basename']; $customtileMatrixSets .= $this->getTileMatrixSet( $tileMatrixSet, $m['tile_matrix'], From 46d79107e85b5d06f34902abf36795c47b079a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 24 Feb 2016 18:55:42 +0100 Subject: [PATCH 12/16] Minor code fixes --- tileserver.php | 43 +++++++++++++++++++++---------------------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/tileserver.php b/tileserver.php index e1f32cf..321c4df 100644 --- a/tileserver.php +++ b/tileserver.php @@ -808,16 +808,15 @@ class Wmts extends Server { $tileMatrixSet = array(); for($i = 0; $i <= 18; $i++){ - $level = new stdClass(); - $level->extent = $extent; - $level->id = (string) $i; $matrixSize = pow(2, $i); - $level->matrix_size = array($matrixSize, $matrixSize); - $level->origin = array($extent[0], $extent[1]); - $level->scale_denominator = $denominatorBase / pow(2, $i); - $level->tile_size = array(256, 256); - - $tileMatrixSet[] = (array) $level; + $tileMatrixSet[] = array( + 'extent' => $extent, + 'id' => (string) $i, + 'matrix_size' => array($matrixSize, $matrixSize), + 'origin' => array($extent[0], $extent[3]), + 'scale_denominator' => $denominatorBase / pow(2, $i), + 'tile_size' => array(256, 256) + ); } return $this->getTileMatrixSet('GoogleMapsCompatible', $tileMatrixSet, 'EPSG:3857'); @@ -839,15 +838,15 @@ class Wmts extends Server { $tileMatrixSet = array(); for($i = 0; $i <= count($scaleDenominators); $i++){ - $level = new stdClass(); - $level->extent = $extent; - $level->id = (string) $i; $matrixSize = pow(2, $i); - $level->matrix_size = array($matrixSize * 2, $matrixSize); - $level->origin = array($extent[0], $extent[1]); - $level->scale_denominator = $scaleDenominators[$i]; - $level->tile_size = array(256, 256); - + $tileMatrixSet[] = array( + 'extent' => $extent, + 'id' => (string) $i, + 'matrix_size' => array($matrixSize * 2, $matrixSize), + 'origin' => array($extent[0], $extent[3]), + 'scale_denominator' => $scaleDenominators[$i], + 'tile_size' => array(256, 256) + ); $tileMatrixSet[] = (array) $level; } @@ -1011,6 +1010,11 @@ class Wmts extends Server { '; } + + // Print custom TileMatrixSets + if (strlen($customtileMatrixSets) > 0) { + echo $customtileMatrixSets; + } // Print PseudoMercator TileMatrixSet echo $this->getMercatorTileMatrixSet(); @@ -1018,11 +1022,6 @@ class Wmts extends Server { // Print WGS84 TileMatrixSet echo $this->getWGS84TileMatrixSet(); - // Print custom TileMatrixSets - if (strlen($customtileMatrixSets) > 0) { - echo $customtileMatrixSets; - } - echo ' '; From 8233047097e45a1e185379c7aae7e09d8e0f2ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Wed, 24 Feb 2016 20:18:06 +0100 Subject: [PATCH 13/16] Fixed bug in WGS84 tilematrixset --- tileserver.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tileserver.php b/tileserver.php index 321c4df..54885a2 100644 --- a/tileserver.php +++ b/tileserver.php @@ -847,7 +847,6 @@ class Wmts extends Server { 'scale_denominator' => $scaleDenominators[$i], 'tile_size' => array(256, 256) ); - $tileMatrixSet[] = (array) $level; } return $this->getTileMatrixSet('WGS84', $tileMatrixSet, 'EPSG:4326'); From f3f2a995e58949465f7ce1c7c6e462ab09549c6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 25 Feb 2016 19:23:48 +0100 Subject: [PATCH 14/16] Axis orientaton in wmts #70, bbox fix --- tileserver.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tileserver.php b/tileserver.php index 54885a2..0991b61 100644 --- a/tileserver.php +++ b/tileserver.php @@ -751,15 +751,22 @@ class Wmts extends Server { $tileMatrix[$i]['tile_size'] ); $tileMatrix[$i]['matrix_size'] = array( - $tileExtent[1] + 1, - $tileExtent[2] + 1 + $tileExtent[2] + 1, + $tileExtent[1] + 1 ); } if(!isset($tileMatrix[$i]['origin']) && isset($tileMatrix[$i]['extent'])){ $tileMatrix[$i]['origin'] = array( - $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][4] + $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] ); } + if (!isset($layer['axis'])) { + $layer['axis'] = $layer['xy']; + } + // Origins of geographic coordinate systems are setting in opposite order + if ($layer['axis'] == 'yx') { + $tileMatrix[$i]['origin'] = array_reverse($tileMatrix[$i]['origin']); + } if(!isset($tileMatrix[$i]['scale_denominator'])){ $tileMatrix[$i]['scale_denominator'] = count($tileMatrix) - $i; } From 7190e90845a435217d003c61aeb25b2a02ed1a99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Thu, 25 Feb 2016 23:21:40 +0100 Subject: [PATCH 15/16] Order of origin coords based on proj4 definition #70 --- tileserver.php | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/tileserver.php b/tileserver.php index 0991b61..1a9c842 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,7 +734,13 @@ class Wmts extends Server { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - + + //process projection + if(isset($layer['proj4'])){ + preg_match_all("/([^+= ]+)=([^= ]+)/", $layer['proj4'], $res); + $proj4 = array_combine($res[1], $res[2]); + } + for($i = 0; $i < count($tileMatrix); $i++){ if(!isset($tileMatrix[$i]['id'])){ @@ -760,11 +766,8 @@ class Wmts extends Server { $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] ); } - if (!isset($layer['axis'])) { - $layer['axis'] = $layer['xy']; - } // Origins of geographic coordinate systems are setting in opposite order - if ($layer['axis'] == 'yx') { + if (isset($proj4) && $proj4['proj'] === 'longlat') { $tileMatrix[$i]['origin'] = array_reverse($tileMatrix[$i]['origin']); } if(!isset($tileMatrix[$i]['scale_denominator'])){ @@ -907,7 +910,7 @@ class Wmts extends Server { ); } } - + header('Content-type: application/xml'); echo ' From e36a7e6a06162ec04585ebe027ceba1a11d7f1d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Jan=C3=A1k?= Date: Fri, 26 Feb 2016 08:51:47 +0100 Subject: [PATCH 16/16] Fix of order of origin in geodetic profile --- tileserver.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tileserver.php b/tileserver.php index 1a9c842..46890ee 100644 --- a/tileserver.php +++ b/tileserver.php @@ -734,13 +734,13 @@ class Wmts extends Server { * @return Object */ public function parseTileMatrix($layer, $tileMatrix){ - + //process projection if(isset($layer['proj4'])){ preg_match_all("/([^+= ]+)=([^= ]+)/", $layer['proj4'], $res); $proj4 = array_combine($res[1], $res[2]); } - + for($i = 0; $i < count($tileMatrix); $i++){ if(!isset($tileMatrix[$i]['id'])){ @@ -766,7 +766,7 @@ class Wmts extends Server { $tileMatrix[$i]['extent'][0], $tileMatrix[$i]['extent'][3] ); } - // Origins of geographic coordinate systems are setting in opposite order + // Origins of geographic coordinate systems are setting in opposite order if (isset($proj4) && $proj4['proj'] === 'longlat') { $tileMatrix[$i]['origin'] = array_reverse($tileMatrix[$i]['origin']); } @@ -853,7 +853,7 @@ class Wmts extends Server { 'extent' => $extent, 'id' => (string) $i, 'matrix_size' => array($matrixSize * 2, $matrixSize), - 'origin' => array($extent[0], $extent[3]), + 'origin' => array($extent[3], $extent[0]), 'scale_denominator' => $scaleDenominators[$i], 'tile_size' => array(256, 256) ); @@ -910,7 +910,7 @@ class Wmts extends Server { ); } } - + header('Content-type: application/xml'); echo ' @@ -1019,7 +1019,7 @@ class Wmts extends Server { '; } - + // Print custom TileMatrixSets if (strlen($customtileMatrixSets) > 0) { echo $customtileMatrixSets;