ol-ext
Version:
A set of cool extensions for OpenLayers (ol) in node modules structure
319 lines (303 loc) • 11.1 kB
JavaScript
import ol_control_WMSCapabilities from './WMSCapabilities.js';
import ol_View from 'ol/View.js'
import ol_tilegrid_WMTS from 'ol/tilegrid/WMTS.js'
import ol_format_WMTSCapabilities from 'ol/format/WMTSCapabilities.js'
import ol_layer_Tile from 'ol/layer/Tile.js'
import ol_source_WMTS from 'ol/source/WMTS.js'
import { get as ol_proj_get } from 'ol/proj.js'
import { transformExtent as ol_proj_transformExtent } from 'ol/proj.js'
import { getWidth as ol_extent_getWidth } from 'ol/extent.js'
/** WMTSCapabilities
* @constructor
* @fires load
* @fires capabilities
* @extends {ol_control_WMSCapabilities}
* @param {*} options
* @param {string|Element} [options.target] the target to set the dialog, use document.body to have fullwindow dialog
* @param {string} [options.proxy] proxy to use when requesting Getcapabilites, default none (suppose the service use CORS)
* @param {string} [options.placeholder='service url...'] input placeholder, default 'service url...'
* @param {string} [options.title=WMTS] dialog title, default 'WMTS'
* @param {string} [options.searchLabel='search'] Label for search button, default 'search'
* @param {string} [options.loadLabel='load'] Label for load button, default 'load'
* @param {Array<string>} [options.srs] an array of supported srs, default map projection code or 'EPSG:3857'
* @param {number} [options.timeout=1000] Timeout for getCapabilities request, default 1000
* @param {boolean} [options.cors=false] Use CORS, default false
* @param {string} [options.optional] a list of optional url properties (when set in the request url), separated with ','
* @param {boolean} [options.trace=false] Log layer info, default false
* @param {*} [options.services] a key/url object of services for quick access in a menu
*/
var ol_control_WMTSCapabilities = class olcontrolWMTSCapabilities extends ol_control_WMSCapabilities {
constructor(options) {
options = options || {};
options.title = options.title || 'WMTS';
super(options);
this.getDialog().set('className', this.getDialog().get('className') + ' ol-wmtscapabilities' );
}
/** Get service parser
* @private
*/
_getParser() {
var pars = new ol_format_WMTSCapabilities();
return {
read: function (data) {
var resp = pars.read(data);
resp.Capability = {
Layer: resp.Contents,
};
// Generic attribution for layers
resp.Capability.Layer.Attribution = {
Title: resp.ServiceProvider.ProviderName
};
// Remove non image format
var layers = [];
resp.Contents.Layer.forEach(function (l) {
if (l.Format && /jpeg|png/.test(l.Format[0])) {
layers.push(l);
}
});
resp.Contents.Layer = layers;
return resp;
}.bind(this)
};
}
/** Get Capabilities request parameters
* @param {*} options
*/
getRequestParam(options) {
return {
SERVICE: 'WMTS',
REQUEST: 'GetCapabilities',
VERSION: options.version || '1.0.0'
};
}
/** Get tile grid options only for EPSG:3857 projection
* @returns {*}
* @private
*/
_getTG(tileMatrixSet, minZoom, maxZoom, tilePrefix) {
var matrixIds = new Array();
var resolutions = new Array();
var size = ol_extent_getWidth(ol_proj_get('EPSG:3857').getExtent()) / 256;
for (var z = 0; z <= (maxZoom ? maxZoom : 20); z++) {
var id = tilePrefix ? tileMatrixSet + ':' + z : z;
matrixIds[z] = id;
resolutions[z] = size / Math.pow(2, z);
}
return {
origin: [-20037508, 20037508],
resolutions: resolutions,
matrixIds: matrixIds,
minZoom: (minZoom ? minZoom : 0)
};
}
/** Get WMTS tile grid (only EPSG:3857)
* @param {sting} tileMatrixSet
* @param {number} minZoom
* @param {number} maxZoom
* @param {boolean} tilePrefix
* @returns {ol_tilegrid_WMTS}
* @private
*/
getTileGrid(tileMatrixSet, minZoom, maxZoom, tilePrefix) {
return new ol_tilegrid_WMTS(this._getTG(tileMatrixSet, minZoom, maxZoom, tilePrefix));
}
/** Check if the TileMatrixSet is supported
* @param {Object} tm
* @returns {boolean}
*/
isSupportedSet(tm) {
if (/^PM_.*/.test(tm.TileMatrixSet)) return true;
return this.supportedSets.indexOf(tm.TileMatrixSet) >= 0;
}
/** Return a WMTS options for the given capabilities
* @param {*} caps layer capabilities (read from the capabilities)
* @param {*} parent capabilities
* @return {*} options
*/
getOptionsFromCap(caps, parent) {
var bbox = caps.WGS84BoundingBox;
if (bbox) bbox = ol_proj_transformExtent(bbox, 'EPSG:4326', this.getMap().getView().getProjection());
// Tilematrix zoom
var minZoom = Infinity, maxZoom = -Infinity;
var tmatrix;
caps.TileMatrixSetLink.forEach(function (tm) {
if (this.isSupportedSet(tm)) {
tmatrix = tm;
caps.TileMatrixSet = tm.TileMatrixSet;
}
}.bind(this));
if (!tmatrix) {
this.showError({ type: 'TileMatrix' });
return;
}
if (tmatrix.TileMatrixSetLimits) {
var tilePrefix = tmatrix.TileMatrixSetLimits[0].TileMatrix.split(':').length > 1;
tmatrix.TileMatrixSetLimits.forEach(function (tm) {
var zoom = tm.TileMatrix.split(':').pop();
minZoom = Math.min(minZoom, parseInt(zoom));
maxZoom = Math.max(maxZoom, parseInt(zoom));
});
} else {
minZoom = 0;
maxZoom = 20;
}
var view = new ol_View();
view.setZoom(minZoom);
var layer_opt = {
title: caps.Title,
extent: bbox,
abstract: caps.Abstract,
maxResolution: view.getResolution()
};
var source_opt = {
url: parent.url,
layer: caps.Identifier,
matrixSet: caps.TileMatrixSet,
format: caps.Format[0] || 'image/jpeg',
projection: 'EPSG:3857',
//tileGrid: tg,
tilePrefix: tilePrefix,
minZoom: minZoom,
maxZoom: maxZoom,
style: caps.Style ? caps.Style[0].Identifier : 'normal',
attributions: caps.Attribution.Title,
crossOrigin: this.get('cors') ? 'anonymous' : null,
wrapX: (this.get('wrapX') !== false),
};
// Fill form
this._fillForm({
title: layer_opt.title,
layers: source_opt.layer,
style: source_opt.style,
format: source_opt.format,
minZoom: minZoom,
maxZoom: maxZoom,
extent: bbox ? bbox.join(',') : '',
projection: source_opt.projection,
attribution: source_opt.attributions || '',
version: '1.0.0'
});
// Trace
if (this.get('trace')) {
// Source
source_opt.tileGrid = 'TILEGRID';
var tso = JSON.stringify([source_opt], null, "\t").replace(/\\"/g, '"');
tso = tso.replace('"TILEGRID"', 'new ol_tilegrid_WMTS('
+ JSON.stringify(this._getTG(source_opt.matrixSet, source_opt.minZoom, source_opt.maxZoom, source_opt.tilePrefix), null, '\t').replace(/\n/g, '\n\t\t')
+ ')'
);
delete source_opt.tileGrid;
// Layer
layer_opt.source = "SOURCE";
var t = "new ol.layer.Tile (" + JSON.stringify(layer_opt, null, "\t") + ")";
t = t.replace(/\\"/g, '"')
.replace('"SOURCE"', "new ol.source.WMTS(" + tso + ")")
.replace(/\\t/g, "\t").replace(/\\n/g, "\n")
.replace(/"tileGrid": {/g, '"tileGrid": new ol.tilegrid.WMTS({')
.replace(/},\n(\t*)"style"/g, '}),\n$1"style"')
.replace("([\n\t", "(")
.replace("}\n])", "})");
console.log(t);
delete layer_opt.source;
}
var returnedLegend = undefined;
if (caps.Style && caps.Style[0] && caps.Style[0].LegendURL && caps.Style[0].LegendURL[0]) {
returnedLegend = [ caps.Style[0].LegendURL[0].href ];
}
return ({
layer: layer_opt,
source: source_opt,
data: {
title: caps.Title,
abstract: caps.Abstract,
legend: returnedLegend,
}
});
}
/** Get WMS options from control form
* @return {*} original original options
* @return {*} options
* @private
*/
_getFormOptions() {
var options = this._currentOptions || {};
if (!options.layer)
options.layer = {};
if (!options.source)
options.source = {};
if (!options.data)
options.data = {};
var minZoom = parseInt(this._elements.formMinZoom.value) || 0;
var maxZoom = parseInt(this._elements.formMaxZoom.value) || 20;
var ext = [];
if (this._elements.formExtent.value) {
this._elements.formExtent.value.split(',').forEach(function (b) {
ext.push(parseFloat(b));
});
}
if (ext.length !== 4)
ext = undefined;
var attributions = [];
if (this._elements.formAttribution.value)
attributions.push(this._elements.formAttribution.value);
var view = new ol_View({
projection: this.getMap().getView().getProjection()
});
view.setZoom(minZoom);
var layer_opt = {
title: this._elements.formTitle.value,
extent: ext,
abstract: options.layer.abstract || '',
maxResolution: view.getResolution()
};
var source_opt = {
url: this._elements.input.value,
layer: this._elements.formLayer.value,
matrixSet: options.source.matrixSet || 'PM',
format: this._elements.formFormat.options[this._elements.formFormat.selectedIndex].value,
projection: 'EPSG:3857',
minZoom: minZoom,
maxZoom: maxZoom,
// tileGrid: this._getTG(options.source.matrixSet || 'PM', minZoom, maxZoom),
style: this._elements.formStyle.value || 'normal',
attributions: attributions,
crossOrigin: this._elements.formCrossOrigin.checked ? 'anonymous' : null,
wrapX: (this.get('wrapX') !== false),
};
return ({
layer: layer_opt,
source: source_opt,
data: {
title: this._elements.formTitle.value,
abstract: options.data.abstract,
legend: options.data.legend,
}
});
}
/** Create a new layer using options received by getOptionsFromCap method
* @param {*} options
*/
getLayerFromOptions(options) {
if (!options)
return;
options.source.tileGrid = this.getTileGrid(options.source.matrixSet, options.source.minZoom, options.source.maxZoom, options.source.tilePrefix);
options.layer.source = new ol_source_WMTS(options.source);
var layer = new ol_layer_Tile(options.layer);
// Restore options
delete options.layer.source;
delete options.source.tileGrid;
return layer;
}
}
/** An array of supported sets (basically EPSG:3857)
* @api
*/
ol_control_WMSCapabilities.prototype.supportedSets = [
'PM',
'3857',
'EPSG:3857',
'EPSG:900913',
'webmercator',
'GoogleMapsCompatible'
]
export default ol_control_WMTSCapabilities