UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

167 lines (164 loc) 6.36 kB
import Source from "./Source.js"; import URLBuilder from "../Provider/URLBuilder.js"; import { Extent, CRS } from '@itowns/geographic'; const _extent = new Extent('EPSG:4326'); /** * Proj provides an optional param to define axis order and orientation for a * given projection. 'enu' for instance stands for east, north, up. * Elevation is not needed here. The two first characters are sufficient to map * proj axis to iTowns bbox order formalism. * 'enu' corresponds to 'wsen' because bbox starts by lower value coordinates * and preserves axis ordering, here long/lat. */ const projAxisToBboxMappings = { en: 'wsen', es: 'wnes', wn: 'eswn', ws: 'enws', ne: 'swne', se: 'nwse', nw: 'senw', sw: 'nesw' }; /** * Provides the bbox axis order matching provided proj4 axis * @param {string} projAxis the CRS axis order as defined in proj4 * @returns {string} the corresponding bbox axis order to use for WMS 1.3.0 */ function projAxisToWmsBbox(projAxis) { return projAxis && projAxisToBboxMappings[projAxis.slice(0, 2)] || 'wsen'; } /** * An object defining the source of images to get from a * [WMS](http://www.opengeospatial.org/standards/wms) server. It inherits * from {@link Source}. * * @extends Source * * @property {boolean} isWMSSource - Used to checkout whether this source is a * WMSSource. Default is true. You should not change this, as it is used * internally for optimisation. * @property {string} name - The name of the layer, used in the generation of * the url. * @property {string} version - The version of the WMS server to request on. * Default value is '1.3.0'. * @property {string} style - The style to query on the WMS server. Default * value is 'normal'. * @property {number} width - The width of the image to fetch, in pixel. * Default value is the height if set or 256. * @property {number} height - The height of the image to fetch, in pixel. * Default value is the width if set or 256. * @property {string} axisOrder - The order of the axis, that helps building the * BBOX to put in the url requesting a resource. Default value is 'wsen', other * value can be 'swne'. * @property {boolean} transparent - Tells if the image to fetch needs * transparency support. Default value is false. * @property {Object} zoom - Object containing the minimum and maximum values of * the level, to zoom in the source. * @property {number} zoom.min - The minimum level of the source. Default value * is 0. * @property {number} zoom.max - The maximum level of the source. Default value * is 21. * @property {string} bboxDigits - The bbox digits precision used in URL * @property {Object} vendorSpecific - An object containing vendor specific * parameters. See for example a [list of these parameters for GeoServer]( * https://docs.geoserver.org/latest/en/user/services/wms/vendor.html). This * object is read simply with the `key` being the name of the parameter and * `value` being the value of the parameter. If used, this property should be * set in the constructor parameters. * * @example * // Create the source * const wmsSource = new itowns.WMSSource({ * url: 'https://server.geo/wms', * version: '1.3.0', * name: 'REGION.2016', * style: '', * crs: 'EPSG:3857', * extent: { * west: '-6880639.13557728', * east: '6215707.87974825', * south: '-2438399.00148845', * north: '7637050.03850605', * }, * transparent: true, * }); * * // Create the layer * const colorlayer = new itowns.ColorLayer('Region', { * source: wmsSource, * }); * * // Add the layer * view.addLayer(colorlayer); */ class WMSSource extends Source { /** * @param {Object} source - An object that can contain all properties of * WMSSource and {@link Source}. `url`, `name`, `extent` and `crs` * are mandatory. */ constructor(source) { if (!source.name) { throw new Error('source.name is required.'); } if (!source.extent) { throw new Error('source.extent is required'); } if (!source.crs && !source.projection) { throw new Error('source.crs is required'); } source.format = source.format || 'image/png'; super(source); this.isWMSSource = true; this.name = source.name; this.zoom = { min: 0, max: Infinity }; this.style = source.style || ''; this.width = source.width || source.height || 256; this.height = source.height || source.width || 256; this.version = source.version || '1.3.0'; this.transparent = source.transparent || false; this.bboxDigits = source.bboxDigits; if (source.axisOrder) { this.axisOrder = source.axisOrder; } else if (this.version === '1.3.0') { // If not set, axis order depends on WMS version // Version 1.3.0 depends on CRS axis order as defined in epsg.org database this.axisOrder = projAxisToWmsBbox(CRS.axisOrder(this.crs)); } else { // Versions 1.X.X mandate long/lat order, east-north orientation this.axisOrder = 'wsen'; } const crsPropName = this.version === '1.3.0' ? 'CRS' : 'SRS'; const urlObj = new URL(this.url); urlObj.searchParams.set('SERVICE', 'WMS'); urlObj.searchParams.set('REQUEST', 'GetMap'); urlObj.searchParams.set('LAYERS', this.name); urlObj.searchParams.set('VERSION', this.version); urlObj.searchParams.set('STYLES', this.style); urlObj.searchParams.set('FORMAT', this.format); urlObj.searchParams.set('TRANSPARENT', this.transparent); urlObj.searchParams.set('BBOX', '%bbox'); urlObj.searchParams.set(crsPropName, this.crs); urlObj.searchParams.set('WIDTH', this.width); urlObj.searchParams.set('HEIGHT', this.height); this.vendorSpecific = source.vendorSpecific; for (const name in this.vendorSpecific) { if (Object.prototype.hasOwnProperty.call(this.vendorSpecific, name)) { urlObj.searchParams.set(name, this.vendorSpecific[name]); } } this.url = decodeURIComponent(urlObj.toString()); } urlFromExtent(extentOrTile) { const extent = extentOrTile.isExtent ? extentOrTile.as(this.crs, _extent) : extentOrTile.toExtent(this.crs, _extent); return URLBuilder.bbox(extent, this); } extentInsideLimit(extent) { return this.extent.intersectsExtent(extent); } } export default WMSSource;