Add ability to get wmts source from capabilities

Added functionality to create a wmts tilegrid and wmts source from the
capabilities object created from ol.format.WMTSCapabilities.read().
Added tests for these functions and an example.

Also altered the REST url template replacement to be case insensitive
and added tests for this. This is because the spec uses both style
and Style and both of these are used by existing WMTS services.
This commit is contained in:
Sara Metz
2015-01-16 09:25:27 +13:00
parent f117cddb34
commit 6894bc8444
9 changed files with 776 additions and 2300 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
<title>WMTS Layer example from capabilities </title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="./"><img src="../resources/logo.png"> OpenLayers 3 Examples</a>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
<div class="row-fluid">
<div class="span12">
<h4 id="title">WMTS Capabilities example</h4>
<p id="shortdesc">Example of a WMTS source created from a WMTS capabilities document.</p>
<div id="docs">
<p>See the <a href="wmts-layer-from-capabilities.js" target="_blank">wmts-layer-from-capabilities.js source</a> to see how this is done.</p>
</div>
<div id="tags">wmts, capabilities, getcapabilities</div>
</div>
</div>
</div>
<script src="../resources/jquery.min.js" type="text/javascript"></script>
<script src="../resources/example-behaviour.js" type="text/javascript"></script>
<script src="loader.js?id=wmts-layer-from-capabilities" type="text/javascript"></script>
</body>
</html>

View File

@@ -0,0 +1,37 @@
goog.require('ol.Map');
goog.require('ol.View');
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.layer.Tile');
goog.require('ol.proj');
goog.require('ol.source.OSM');
goog.require('ol.source.WMTS');
var parser = new ol.format.WMTSCapabilities();
var map;
$.ajax('data/WMTSCapabilities.xml').then(function(response) {
var result = parser.read(response);
var options = ol.source.WMTS.optionsFromCapabilities(result,
{layer: 'layer-7328', matrixSet: 'EPSG:3857'});
var projection = ol.proj.get('EPSG:3857');
var projectionExtent = projection.getExtent();
map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
opacity: 0.7
}),
new ol.layer.Tile({
opacity: 1,
extent: projectionExtent,
source: new ol.source.WMTS(options)
})
],
target: 'map',
view: new ol.View({
center: [19412406.33, -5050500.21],
zoom: 5
})
});
});

View File

@@ -66,10 +66,12 @@ ol.source.WMTS = function(options) {
// we could issue a getCapabilities xhr to retrieve missing configuration
var tileGrid = options.tileGrid;
// context property names are lower case to allow for a case insensitive
// replacement as some services use different naming conventions
var context = {
'Layer': options.layer,
'Style': options.style,
'TileMatrixSet': options.matrixSet
'layer': options.layer,
'style': options.style,
'tilematrixset': options.matrixSet
};
if (requestEncoding == ol.source.WMTSRequestEncoding.KVP) {
@@ -96,7 +98,7 @@ ol.source.WMTS = function(options) {
template = (requestEncoding == ol.source.WMTSRequestEncoding.KVP) ?
goog.uri.utils.appendParamsFromMap(template, context) :
template.replace(/\{(\w+?)\}/g, function(m, p) {
return (p in context) ? context[p] : m;
return (p.toLowerCase() in context) ? context[p.toLowerCase()] : m;
});
return (
@@ -239,90 +241,144 @@ ol.source.WMTS.prototype.updateDimensions = function(dimensions) {
/**
* @param {Object} wmtsCap An object representing the capabilities document.
* @param {string} layer The layer identifier.
* @param {Object} config Configuration properties for the layer. Defaults for
* the layer will apply if not provided.
*
* Required config properties:
* layer - {String} The layer identifier.
*
* Optional config properties:
* matrixSet - {String} The matrix set identifier, required if there is
* more than one matrix set in the layer capabilities.
* projection - {String} The desired CRS when no matrixSet is specified.
* eg: "EPSG:3857". If the desired projection is not available,
* an error is thrown.
* requestEncoding - {String} url encoding format for the layer. Default is the
* first tile url format found in the GetCapabilities response.
* style - {String} The name of the style
* format - {String} Image format for the layer. Default is the first
* format returned in the GetCapabilities response.
* @return {olx.source.WMTSOptions} WMTS source options object.
* @api
*/
ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, layer) {
ol.source.WMTS.optionsFromCapabilities = function(wmtsCap, config) {
/* jshint -W069 */
// TODO: add support for TileMatrixLimits
goog.asserts.assert(!goog.isNull(config['layer']));
var layers = wmtsCap['contents']['layers'];
var layers = wmtsCap['Contents']['Layer'];
var l = goog.array.find(layers, function(elt, index, array) {
return elt['identifier'] == layer;
return elt['Identifier'] == config['layer'];
});
goog.asserts.assert(!goog.isNull(l));
goog.asserts.assert(l['tileMatrixSetLinks'].length > 0);
var matrixSet = /** @type {string} */
(l['tileMatrixSetLinks'][0]['tileMatrixSet']);
var format = /** @type {string} */ (l['formats'][0]);
var idx = goog.array.findIndex(l['styles'], function(elt, index, array) {
return elt['isDefault'];
goog.asserts.assert(l['TileMatrixSetLink'].length > 0);
var idx, matrixSet;
if (l['TileMatrixSetLink'].length > 1) {
idx = goog.array.findIndex(l['TileMatrixSetLink'],
function(elt, index, array) {
return elt['TileMatrixSet'] == config['matrixSet'];
});
} else if (goog.isDef(config['projection'])) {
idx = goog.array.findIndex(l['TileMatrixSetLink'],
function(elt, index, array) {
return elt['TileMatrixSet']['SupportedCRS'].replace(
/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'
) == config['projection'];
});
} else {
idx = 0;
}
if (idx < 0) {
idx = 0;
}
matrixSet = /** @type {string} */
(l['TileMatrixSetLink'][idx]['TileMatrixSet']);
goog.asserts.assert(!goog.isNull(matrixSet));
var format = /** @type {string} */ (l['Format'][0]);
if (goog.isDef(config['format'])) {
format = config['format'];
}
idx = goog.array.findIndex(l['Style'], function(elt, index, array) {
if (goog.isDef(config['style'])) {
return elt['Title'] == config['style'];
} else {
return elt['isDefault'];
}
});
if (idx < 0) {
idx = 0;
}
var style = /** @type {string} */ (l['styles'][idx]['identifier']);
var style = /** @type {string} */ (l['Style'][idx]['Identifier']);
var dimensions = {};
goog.array.forEach(l['dimensions'], function(elt, index, array) {
var key = elt['identifier'];
var value = elt['default'];
if (goog.isDef(value)) {
goog.asserts.assert(goog.array.contains(elt['values'], value));
} else {
value = elt['values'][0];
}
goog.asserts.assert(goog.isDef(value));
dimensions[key] = value;
});
if (goog.isDef(l['Dimension'])) {
goog.array.forEach(l['Dimension'], function(elt, index, array) {
var key = elt['Identifier'];
var value = elt['default'];
if (goog.isDef(value)) {
goog.asserts.assert(goog.array.contains(elt['values'], value));
} else {
value = elt['values'][0];
}
goog.asserts.assert(goog.isDef(value));
dimensions[key] = value;
});
}
var matrixSets = wmtsCap['contents']['tileMatrixSets'];
goog.asserts.assert(matrixSet in matrixSets);
var matrixSetObj = matrixSets[matrixSet];
var matrixSets = wmtsCap['Contents']['TileMatrixSet'];
var matrixSetObj = goog.array.find(matrixSets, function(elt, index, array) {
return elt['Identifier'] == matrixSet;
});
goog.asserts.assert(!goog.isNull(matrixSetObj));
var tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
matrixSetObj);
var projection = ol.proj.get(matrixSetObj['supportedCRS']);
var gets = wmtsCap['operationsMetadata']['GetTile']['dcp']['http']['get'];
var encodings = goog.object.getKeys(
gets[0]['constraints']['GetEncoding']['allowedValues']);
goog.asserts.assert(encodings.length > 0);
var urls;
var requestEncoding;
switch (encodings[0]) {
case 'REST':
case 'RESTful':
// The OGC documentation is not clear if we should use REST or RESTful,
// ArcGis use RESTful, and OpenLayers use REST.
requestEncoding = ol.source.WMTSRequestEncoding.REST;
goog.asserts.assert(l['resourceUrls'].hasOwnProperty('tile'));
goog.asserts.assert(l['resourceUrls']['tile'].hasOwnProperty(format));
urls = /** @type {Array.<string>} */
(l['resourceUrls']['tile'][format]);
break;
case 'KVP':
requestEncoding = ol.source.WMTSRequestEncoding.KVP;
urls = [];
goog.array.forEach(gets, function(elt, index, array) {
if (elt['constraints']['GetEncoding']['allowedValues'].hasOwnProperty(
ol.source.WMTSRequestEncoding.KVP)) {
urls.push(/** @type {string} */ (elt['url']));
}
});
goog.asserts.assert(urls.length > 0);
break;
default:
goog.asserts.fail();
var projection;
if (goog.isDef(config['projection'])) {
projection = ol.proj.get(config['projection']);
} else {
projection = ol.proj.get(matrixSetObj['SupportedCRS'].replace(
/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'));
}
/** @type {!Array.<string>} */
var urls = [];
var requestEncoding = config['requestEncoding'];
if (wmtsCap['OperationsMetadata'].hasOwnProperty('GetTile') &&
requestEncoding != 'REST') {
var gets = wmtsCap['OperationsMetadata']['GetTile']['DCP']['HTTP']['Get'];
var constraint = goog.array.find(gets[0]['Constraint'],
function(elt, index, array) {
return elt['name'] == 'GetEncoding';
});
var encodings = constraint['AllowedValues']['Value'];
if (encodings.length > 0 && goog.array.contains(encodings, 'KVP')) {
requestEncoding = ol.source.WMTSRequestEncoding.KVP;
urls.push(/** @type {string} */ (gets[0]['href']));
}
} else {
// Add REST tile resource url
requestEncoding = ol.source.WMTSRequestEncoding.REST;
goog.array.forEach(l['ResourceURL'], function(elt, index, array) {
if (elt['resourceType'] == 'tile') {
format = elt['format'];
urls.push(/** @type {string} */ (elt['template']));
}
});
}
goog.asserts.assert(urls.length > 0);
return {
urls: urls,
layer: layer,
layer: config['layer'],
matrixSet: matrixSet,
format: format,
projection: projection,

View File

@@ -64,6 +64,7 @@ ol.tilegrid.WMTS.prototype.getMatrixIds = function() {
* @param {Object} matrixSet An object representing a matrixSet in the
* capabilities document.
* @return {ol.tilegrid.WMTS} WMTS tileGrid instance.
* @api
*/
ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
function(matrixSet) {
@@ -77,16 +78,20 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
/** @type {!Array.<number>} */
var tileSizes = [];
var supportedCRSPropName = 'supportedCRS';
var matrixIdsPropName = 'matrixIds';
var identifierPropName = 'identifier';
var scaleDenominatorPropName = 'scaleDenominator';
var topLeftCornerPropName = 'topLeftCorner';
var tileWidthPropName = 'tileWidth';
var tileHeightPropName = 'tileHeight';
var supportedCRSPropName = 'SupportedCRS';
var matrixIdsPropName = 'TileMatrix';
var identifierPropName = 'Identifier';
var scaleDenominatorPropName = 'ScaleDenominator';
var topLeftCornerPropName = 'TopLeftCorner';
var tileWidthPropName = 'TileWidth';
var tileHeightPropName = 'TileHeight';
var projection = ol.proj.get(matrixSet[supportedCRSPropName]);
var projection;
projection = ol.proj.get(matrixSet[supportedCRSPropName].replace(
/urn:ogc:def:crs:(\w+):(.*:)?(\w+)$/, '$1:$3'));
var metersPerUnit = projection.getMetersPerUnit();
// swap origin x and y coordinates if axis orientation is lat/long
var switchOriginXY = projection.getAxisOrientation().substr(0, 2) == 'ne';
goog.array.sort(matrixSet[matrixIdsPropName], function(a, b) {
return b[scaleDenominatorPropName] - a[scaleDenominatorPropName];
@@ -95,7 +100,12 @@ ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet =
goog.array.forEach(matrixSet[matrixIdsPropName],
function(elt, index, array) {
matrixIds.push(elt[identifierPropName]);
origins.push(elt[topLeftCornerPropName]);
if (switchOriginXY) {
origins.push([elt[topLeftCornerPropName][1],
elt[topLeftCornerPropName][0]]);
} else {
origins.push(elt[topLeftCornerPropName]);
}
resolutions.push(elt[scaleDenominatorPropName] * 0.28E-3 /
metersPerUnit);
var tileWidth = elt[tileWidthPropName];

View File

@@ -28,12 +28,10 @@ access interface to some TileMatrixSets</ows:Abstract>
<ows:Address>
<ows:DeliveryPoint>Fac Ciencies UAB</ows:DeliveryPoint>
<ows:City>Bellaterra</ows:City>
<ows:AdministrativeArea>Barcelona
</ows:AdministrativeArea>
<ows:AdministrativeArea>Barcelona</ows:AdministrativeArea>
<ows:PostalCode>08193</ows:PostalCode>
<ows:Country>Spain</ows:Country>
<ows:ElectronicMailAddress>joan.maso@uab.cat
</ows:ElectronicMailAddress>
<ows:ElectronicMailAddress>joan.maso@uab.cat</ows:ElectronicMailAddress>
</ows:Address>
</ows:ContactInfo>
</ows:ServiceContact>
@@ -70,8 +68,7 @@ access interface to some TileMatrixSets</ows:Abstract>
<Contents>
<Layer>
<ows:Title>Blue Marble Next Generation</ows:Title>
<ows:Abstract>Blue Marble Next Generation NASA Product
</ows:Abstract>
<ows:Abstract>Blue Marble Next Generation NASA Product</ows:Abstract>
<ows:WGS84BoundingBox>
<ows:LowerCorner>-180 -90</ows:LowerCorner>
<ows:UpperCorner>180 90</ows:UpperCorner>
@@ -84,8 +81,7 @@ access interface to some TileMatrixSets</ows:Abstract>
</Style>
<Style>
<ows:Title>Thick And Red</ows:Title>
<ows:Abstract>Specify this style if you want your maps to have thick red coastlines.
</ows:Abstract>
<ows:Abstract>Specify this style if you want your maps to have thick red coastlines.</ows:Abstract>
<ows:Identifier>thickAndRed</ows:Identifier>
</Style>
<Format>image/jpeg</Format>
@@ -93,15 +89,206 @@ access interface to some TileMatrixSets</ows:Abstract>
<TileMatrixSetLink>
<TileMatrixSet>BigWorldPixel</TileMatrixSet>
</TileMatrixSetLink>
<TileMatrixSetLink>
<TileMatrixSet>google3857</TileMatrixSet>
</TileMatrixSetLink>
<ResourceURL format="image/png" resourceType="tile" template="http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png"/>
<ResourceURL format="application/gml+xml; version=3.1" resourceType="FeatureInfo" template="http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml"/>
</Layer>
<TileMatrixSet>
<!-- -180 85.05112878 -->
<ows:Identifier>google3857</ows:Identifier>
<ows:BoundingBox crs="urn:ogc:def:crs:EPSG:6.18:3:3857">
<ows:LowerCorner>1799448.394855 6124949.747770</ows:LowerCorner>
<ows:UpperCorner>1848250.442089 6162571.828177</ows:UpperCorner>
</ows:BoundingBox>
<ows:SupportedCRS>urn:ogc:def:crs:EPSG:6.18:3:3857</ows:SupportedCRS>
<WellKnownScaleSet>urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible</WellKnownScaleSet>
<TileMatrix>
<ows:Identifier>0</ows:Identifier>
<ScaleDenominator>559082264.029</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>1</MatrixWidth>
<MatrixHeight>1</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>1</ows:Identifier>
<ScaleDenominator>279541132.015</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>2</MatrixWidth>
<MatrixHeight>2</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>2</ows:Identifier>
<ScaleDenominator>139770566.007</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>4</MatrixWidth>
<MatrixHeight>4</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>3</ows:Identifier>
<ScaleDenominator>69885283.0036</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>8</MatrixWidth>
<MatrixHeight>8</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>4</ows:Identifier>
<ScaleDenominator>34942641.5018</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>16</MatrixWidth>
<MatrixHeight>16</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>5</ows:Identifier>
<ScaleDenominator>17471320.7509</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>32</MatrixWidth>
<MatrixHeight>32</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>6</ows:Identifier>
<ScaleDenominator>8735660.37545</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>64</MatrixWidth>
<MatrixHeight>64</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>7</ows:Identifier>
<ScaleDenominator>4367830.18773</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>128</MatrixWidth>
<MatrixHeight>128</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>8</ows:Identifier>
<ScaleDenominator>2183915.09386</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>256</MatrixWidth>
<MatrixHeight>256</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>9</ows:Identifier>
<ScaleDenominator>1091957.54693</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>512</MatrixWidth>
<MatrixHeight>512</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>10</ows:Identifier>
<ScaleDenominator>545978.773466</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>1024</MatrixWidth>
<MatrixHeight>1024</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>11</ows:Identifier>
<ScaleDenominator>272989.386733</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>2048</MatrixWidth>
<MatrixHeight>2048</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>12</ows:Identifier>
<ScaleDenominator>136494.693366</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>4096</MatrixWidth>
<MatrixHeight>4096</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>13</ows:Identifier>
<ScaleDenominator>68247.3466832</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>8192</MatrixWidth>
<MatrixHeight>8192</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>14</ows:Identifier>
<ScaleDenominator>34123.6733416</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>16384</MatrixWidth>
<MatrixHeight>16384</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>15</ows:Identifier>
<ScaleDenominator>17061.8366708</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>32768</MatrixWidth>
<MatrixHeight>32768</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>16</ows:Identifier>
<ScaleDenominator>8530.91833540</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>65536</MatrixWidth>
<MatrixHeight>65536</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>17</ows:Identifier>
<ScaleDenominator>4265.45916770</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>131072</MatrixWidth>
<MatrixHeight>131072</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>18</ows:Identifier>
<ScaleDenominator>2132.72958385</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>262144</MatrixWidth>
<MatrixHeight>262144</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>19</ows:Identifier>
<ScaleDenominator>1066.36479193</ScaleDenominator>
<TopLeftCorner>-20037508.3428 20037508.3428</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>524288</MatrixWidth>
<MatrixHeight>524288</MatrixHeight>
</TileMatrix>
</TileMatrixSet>
<TileMatrixSet>
<ows:Identifier>BigWorldPixel</ows:Identifier>
<ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84
</ows:SupportedCRS>
<WellKnownScaleSet>urn:ogc:def:wkss:OGC:1.0:GlobalCRS84Pixel
</WellKnownScaleSet>
<ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>
<WellKnownScaleSet>urn:ogc:def:wkss:OGC:1.0:GlobalCRS84Pixel</WellKnownScaleSet>
<TileMatrix>
<ows:Identifier>10000m</ows:Identifier>
<ScaleDenominator>33130800.83133142</ScaleDenominator>
@@ -158,27 +345,27 @@ access interface to some TileMatrixSets</ows:Abstract>
</TileMatrix>
</TileMatrixSet>
<TileMatrixSet>
<ows:Identifier>BigWorld</ows:Identifier>
<ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>
<TileMatrix>
<ows:Identifier>1e6</ows:Identifier>
<ScaleDenominator>1e6</ScaleDenominator>
<TopLeftCorner>-180 84</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>60000</MatrixWidth>
<MatrixHeight>50000</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>2.5e6</ows:Identifier>
<ScaleDenominator>2.5e6</ScaleDenominator>
<TopLeftCorner>-180 84</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>9000</MatrixWidth>
<MatrixHeight>7000</MatrixHeight>
</TileMatrix>
</TileMatrixSet>
<ows:Identifier>BigWorld</ows:Identifier>
<ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>
<TileMatrix>
<ows:Identifier>1e6</ows:Identifier>
<ScaleDenominator>1e6</ScaleDenominator>
<TopLeftCorner>-180 84</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>60000</MatrixWidth>
<MatrixHeight>50000</MatrixHeight>
</TileMatrix>
<TileMatrix>
<ows:Identifier>2.5e6</ows:Identifier>
<ScaleDenominator>2.5e6</ScaleDenominator>
<TopLeftCorner>-180 84</TopLeftCorner>
<TileWidth>256</TileWidth>
<TileHeight>256</TileHeight>
<MatrixWidth>9000</MatrixWidth>
<MatrixHeight>7000</MatrixHeight>
</TileMatrix>
</TileMatrixSet>
</Contents>
<ServiceMetadataURL xlink:href="http://www.maps.bob/wmts/1.0.0/WMTSCapabilities.xml"/>
</Capabilities>

View File

@@ -44,9 +44,11 @@ describe('ol.format.WMTSCapabilities', function() {
expect(layer.Style[0].LegendURL[0].format).to.be.eql('image/png');
expect(layer.TileMatrixSetLink).to.be.an('array');
expect(layer.TileMatrixSetLink).to.have.length(1);
expect(layer.TileMatrixSetLink).to.have.length(2);
expect(layer.TileMatrixSetLink[0].TileMatrixSet).to.be
.eql('BigWorldPixel');
expect(layer.TileMatrixSetLink[1].TileMatrixSet).to.be
.eql('google3857');
var wgs84Bbox = layer.WGS84BoundingBox;
expect(wgs84Bbox).to.be.an('array');
@@ -67,7 +69,7 @@ describe('ol.format.WMTSCapabilities', function() {
it('Can read Capabilities.Content.TileMatrixSet', function() {
expect(capabilities.Contents.TileMatrixSet).to.be.ok();
var bigWorld = capabilities.Contents.TileMatrixSet[1];
var bigWorld = capabilities.Contents.TileMatrixSet[2];
expect(bigWorld).to.be.ok();
expect(bigWorld.Identifier).to.be.eql('BigWorld');
expect(bigWorld.SupportedCRS).to.be.eql('urn:ogc:def:crs:OGC:1.3:CRS84');

View File

@@ -0,0 +1,143 @@
goog.provide('ol.test.source.WMTS');
describe('ol.source.WMTS', function() {
describe('when creating options from capabilities', function() {
var parser = new ol.format.WMTSCapabilities();
var capabilities;
before(function(done) {
afterLoadText('spec/ol/format/wmts/ogcsample.xml', function(xml) {
try {
capabilities = parser.read(xml);
} catch (e) {
done(e);
}
done();
});
});
it('can create KVP options from spec/ol/format/wmts/ogcsample.xml',
function() {
var options;
options = ol.source.WMTS.optionsFromCapabilities(
capabilities,
{ layer: 'BlueMarbleNextGeneration', matrixSet: 'google3857' });
expect(options.urls).to.be.an('array');
expect(options.urls).to.have.length(1);
expect(options.urls[0]).to.be.eql(
'http://www.maps.bob/cgi-bin/MiraMon5_0.cgi?');
expect(options.layer).to.be.eql('BlueMarbleNextGeneration');
expect(options.matrixSet).to.be.eql('google3857');
expect(options.format).to.be.eql('image/jpeg');
expect(options.projection).to.be.a(ol.proj.Projection);
expect(options.projection).to.be.eql(ol.proj.get('EPSG:3857'));
expect(options.requestEncoding).to.be.eql('KVP');
expect(options.tileGrid).to.be.a(ol.tilegrid.WMTS);
expect(options.style).to.be.eql('DarkBlue');
expect(options.dimensions).to.eql({});
});
it('can create REST options from spec/ol/format/wmts/ogcsample.xml',
function() {
var options;
options = ol.source.WMTS.optionsFromCapabilities(
capabilities,
{ layer: 'BlueMarbleNextGeneration', matrixSet: 'google3857',
requestEncoding: 'REST' });
expect(options.urls).to.be.an('array');
expect(options.urls).to.have.length(1);
expect(options.urls[0]).to.be.eql(
'http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png');
expect(options.layer).to.be.eql('BlueMarbleNextGeneration');
expect(options.matrixSet).to.be.eql('google3857');
expect(options.format).to.be.eql('image/png');
expect(options.projection).to.be.a(ol.proj.Projection);
expect(options.projection).to.be.eql(ol.proj.get('EPSG:3857'));
expect(options.requestEncoding).to.be.eql('REST');
expect(options.tileGrid).to.be.a(ol.tilegrid.WMTS);
expect(options.style).to.be.eql('DarkBlue');
expect(options.dimensions).to.eql({});
});
});
describe('when creating tileUrlFunction', function() {
it('can replace lowercase REST parameters',
function() {
var source = new ol.source.WMTS({
layer: 'layer',
style: 'default',
urls: ['http://www.example.com/wmts/coastlines/{layer}/{style}/' +
'{tilematrixset}/{TileMatrix}/{TileCol}/{TileRow}.jpg'],
matrixSet: 'EPSG:3857',
requestEncoding: 'REST',
tileGrid: new ol.tilegrid.WMTS({
origin: [-20037508.342789244, 20037508.342789244],
resolutions: [559082264.029 * 0.28E-3,
279541132.015 * 0.28E-3,
139770566.007 * 0.28E-3],
matrixIds: [0, 1, 2]
})
});
var projection = ol.proj.get('EPSG:3857');
var url = source.tileUrlFunction.call(source,
[1, 1, -2], 1, projection);
expect(url).to.be.eql('http://www.example.com/wmts/coastlines/' +
'layer/default/EPSG:3857/1/1/1.jpg');
});
it('can replace camelcase REST parameters',
function() {
var source = new ol.source.WMTS({
layer: 'layer',
style: 'default',
urls: ['http://www.example.com/wmts/coastlines/{Layer}/{Style}/' +
'{tilematrixset}/{TileMatrix}/{TileCol}/{TileRow}.jpg'],
matrixSet: 'EPSG:3857',
requestEncoding: 'REST',
tileGrid: new ol.tilegrid.WMTS({
origin: [-20037508.342789244, 20037508.342789244],
resolutions: [559082264.029 * 0.28E-3,
279541132.015 * 0.28E-3,
139770566.007 * 0.28E-3],
matrixIds: [0, 1, 2]
})
});
var projection = ol.proj.get('EPSG:3857');
var url = source.tileUrlFunction.call(source,
[1, 1, -2], 1, projection);
expect(url).to.be.eql('http://www.example.com/wmts/coastlines/' +
'layer/default/EPSG:3857/1/1/1.jpg');
});
});
});
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.proj');
goog.require('ol.proj.Projection');
goog.require('ol.tilegrid.WMTS');
goog.require('ol.source.WMTS');

View File

@@ -0,0 +1,68 @@
goog.provide('ol.test.tilegrid.WMTS');
describe('ol.tilegrid.WMTS', function() {
describe('when creating tileGrid from capabilities', function() {
var parser = new ol.format.WMTSCapabilities();
var capabilities;
before(function(done) {
afterLoadText('spec/ol/format/wmts/ogcsample.xml', function(xml) {
try {
capabilities = parser.read(xml);
} catch (e) {
done(e);
}
done();
});
});
it('can create tileGrid for EPSG:3857',
function() {
var matrixSetObj = capabilities.Contents.TileMatrixSet[0];
var tileGrid;
tileGrid = ol.tilegrid.WMTS.createFromCapabilitiesMatrixSet(
matrixSetObj);
expect(tileGrid.matrixIds_).to.be.an('array');
expect(tileGrid.matrixIds_).to.have.length(20);
expect(tileGrid.matrixIds_).to.eql(
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11',
'12', '13', '14', '15', '16', '17', '18', '19']);
expect(tileGrid.resolutions_).to.be.an('array');
expect(tileGrid.resolutions_).to.have.length(20);
expect(tileGrid.resolutions_).to.eql(
[156543.03392811998, 78271.51696419998, 39135.758481959994,
19567.879241008, 9783.939620504, 4891.969810252, 2445.984905126,
1222.9924525644, 611.4962262807999, 305.74811314039994,
152.87405657047998, 76.43702828523999, 38.21851414248,
19.109257071295996, 9.554628535647998, 4.777314267823999,
2.3886571339119995, 1.1943285669559998, 0.5971642834779999,
0.29858214174039993]);
expect(tileGrid.origins_).to.be.an('array');
expect(tileGrid.origins_).to.have.length(20);
expect(tileGrid.origins_).to.eql(
[[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428],
[-20037508.3428, 20037508.3428], [-20037508.3428, 20037508.3428]
]);
expect(tileGrid.tileSizes_).to.be.an('array');
expect(tileGrid.tileSizes_).to.have.length(20);
expect(tileGrid.tileSizes_).to.eql(
[256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
256, 256, 256, 256, 256, 256, 256, 256, 256, 256]);
});
});
});
goog.require('ol.format.WMTSCapabilities');
goog.require('ol.tilegrid.WMTS');