Introduces getGetLegendGraphic method
Adds the `getGetLegendGraphic` method to `ImageWMS` and `TileWMS` source. Also adds an example and corresponding tests.
This commit is contained in:
15
examples/wms-getlegendgraphic.html
Normal file
15
examples/wms-getlegendgraphic.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
layout: example.html
|
||||||
|
title: WMS GetLegendGraphic
|
||||||
|
shortdesc: Example of a WMS GetLegendGraphic.
|
||||||
|
docs: >
|
||||||
|
WMS supports the [getLegendGraphic request](https://docs.geoserver.org/latest/en/user/services/wms/get_legend_graphic/index.html).
|
||||||
|
This example demonstrates the use of the `getGetLegendGraphicUrl` method.
|
||||||
|
|
||||||
|
|
||||||
|
As a legend can be responsive to the scale it is updated on every change of the resolution.
|
||||||
|
tags: "GetLegendGraphic, getGetLegendGraphicURL, WMS"
|
||||||
|
---
|
||||||
|
<div id="map" class="map"></div>
|
||||||
|
Legend:
|
||||||
|
<div><img id="legend" src=""/></div>
|
||||||
47
examples/wms-getlegendgraphic.js
Normal file
47
examples/wms-getlegendgraphic.js
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
import Map from '../src/ol/Map.js';
|
||||||
|
import View from '../src/ol/View.js';
|
||||||
|
import {Image as ImageLayer, Tile as TileLayer} from '../src/ol/layer.js';
|
||||||
|
import ImageWMS from '../src/ol/source/ImageWMS.js';
|
||||||
|
import OSM from '../src/ol/source/OSM.js';
|
||||||
|
|
||||||
|
const wmsSource = new ImageWMS({
|
||||||
|
url: 'https://ahocevar.com/geoserver/wms',
|
||||||
|
params: {'LAYERS': 'topp:states'},
|
||||||
|
ratio: 1,
|
||||||
|
serverType: 'geoserver'
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateLegend = function(resolution) {
|
||||||
|
const graphicUrl = wmsSource.getGetLegendGraphicUrl(resolution);
|
||||||
|
const img = document.getElementById('legend');
|
||||||
|
img.src = graphicUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
const layers = [
|
||||||
|
new TileLayer({
|
||||||
|
source: new OSM()
|
||||||
|
}),
|
||||||
|
new ImageLayer({
|
||||||
|
extent: [-13884991, 2870341, -7455066, 6338219],
|
||||||
|
source: wmsSource
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
const map = new Map({
|
||||||
|
layers: layers,
|
||||||
|
target: 'map',
|
||||||
|
view: new View({
|
||||||
|
center: [-10997148, 4569099],
|
||||||
|
zoom: 4
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initial legend
|
||||||
|
const resolution = map.getView().getResolution();
|
||||||
|
updateLegend(resolution);
|
||||||
|
|
||||||
|
// Update the legend when the resolution changes
|
||||||
|
map.getView().on('change:resolution', function(event) {
|
||||||
|
const resolution = event.target.getResolution();
|
||||||
|
updateLegend(resolution);
|
||||||
|
});
|
||||||
@@ -191,6 +191,40 @@ class ImageWMS extends ImageSource {
|
|||||||
1, sourceProjectionObj || projectionObj, baseParams);
|
1, sourceProjectionObj || projectionObj, baseParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the GetLegendGraphic URL for the passed resolution.
|
||||||
|
* Return `undefined` if the GetLegendGraphic URL cannot be constructed.
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {!Object} params GetLegendGraphic params. Default `FORMAT` is
|
||||||
|
* `image/png`. `VERSION` should not be specified here.
|
||||||
|
* @return {string|undefined} GetLegendGraphic URL.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
getGetLegendGraphicUrl(resolution, params) {
|
||||||
|
const layers = this.params_.LAYERS;
|
||||||
|
const isSingleLayer = !Array.isArray(layers) || this.params_['LAYERS'].length === 1;
|
||||||
|
if (this.url_ === undefined || !isSingleLayer) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const mpu = this.getProjection() ? this.getProjection().getMetersPerUnit() : 1;
|
||||||
|
const dpi = 25.4 / 0.28;
|
||||||
|
const inchesPerMeter = 39.37;
|
||||||
|
const scale = resolution * mpu * inchesPerMeter * dpi;
|
||||||
|
|
||||||
|
const baseParams = {
|
||||||
|
'SERVICE': 'WMS',
|
||||||
|
'VERSION': DEFAULT_WMS_VERSION,
|
||||||
|
'REQUEST': 'GetLegendGraphic',
|
||||||
|
'FORMAT': 'image/png',
|
||||||
|
'LAYER': layers,
|
||||||
|
'SCALE': scale
|
||||||
|
};
|
||||||
|
assign(baseParams, params);
|
||||||
|
|
||||||
|
return appendParams(/** @type {string} */ (this.url_), baseParams);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the user-provided params, i.e. those passed to the constructor through
|
* Get the user-provided params, i.e. those passed to the constructor through
|
||||||
* the "params" option, and possibly updated using the updateParams method.
|
* the "params" option, and possibly updated using the updateParams method.
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {assert} from '../asserts.js';
|
|||||||
import {buffer, createEmpty} from '../extent.js';
|
import {buffer, createEmpty} from '../extent.js';
|
||||||
import {assign} from '../obj.js';
|
import {assign} from '../obj.js';
|
||||||
import {modulo} from '../math.js';
|
import {modulo} from '../math.js';
|
||||||
import {get as getProjection, transform, transformExtent} from '../proj.js';
|
import {get as getProjection, transform, transformExtent, METERS_PER_UNIT} from '../proj.js';
|
||||||
import {calculateSourceResolution} from '../reproj.js';
|
import {calculateSourceResolution} from '../reproj.js';
|
||||||
import {toSize, buffer as bufferSize, scale as scaleSize} from '../size.js';
|
import {toSize, buffer as bufferSize, scale as scaleSize} from '../size.js';
|
||||||
import TileImage from './TileImage.js';
|
import TileImage from './TileImage.js';
|
||||||
@@ -211,6 +211,41 @@ class TileWMS extends TileImage {
|
|||||||
1, sourceProjectionObj || projectionObj, baseParams);
|
1, sourceProjectionObj || projectionObj, baseParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the GetLegendGraphic URL for the passed resolution.
|
||||||
|
* Return `undefined` if the GetLegendGraphic URL cannot be constructed.
|
||||||
|
* @param {number} resolution Resolution.
|
||||||
|
* @param {!Object} params GetLegendGraphic params. Default `FORMAT` is
|
||||||
|
* `image/png`. `VERSION` should not be specified here.
|
||||||
|
* @return {string|undefined} GetLegendGraphic URL.
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
getGetLegendGraphicUrl(resolution, params) {
|
||||||
|
const layers = this.params_.LAYERS;
|
||||||
|
const isSingleLayer = !Array.isArray(layers) || this.params_['LAYERS'].length === 1;
|
||||||
|
if (this.urls[0] === undefined || !isSingleLayer) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const units = this.getProjection() && this.getProjection().getUnits();
|
||||||
|
const dpi = 25.4 / 0.28;
|
||||||
|
const mpu = METERS_PER_UNIT[units || 'm'];
|
||||||
|
const inchesPerMeter = 39.37;
|
||||||
|
const scale = resolution * mpu * inchesPerMeter * dpi;
|
||||||
|
|
||||||
|
const baseParams = {
|
||||||
|
'SERVICE': 'WMS',
|
||||||
|
'VERSION': DEFAULT_WMS_VERSION,
|
||||||
|
'REQUEST': 'GetLegendGraphic',
|
||||||
|
'FORMAT': 'image/png',
|
||||||
|
'LAYER': this.params_['LAYERS'],
|
||||||
|
'SCALE': scale
|
||||||
|
};
|
||||||
|
assign(baseParams, params);
|
||||||
|
|
||||||
|
return appendParams(/** @type {string} */ (this.urls[0]), baseParams);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritDoc
|
* @inheritDoc
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -330,6 +330,63 @@ describe('ol.source.ImageWMS', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getGetLegendGraphicUrl', function() {
|
||||||
|
|
||||||
|
it('returns the getLegenGraphic url as expected', function() {
|
||||||
|
const source = new ImageWMS(options);
|
||||||
|
const url = source.getGetLegendGraphicUrl(resolution);
|
||||||
|
const uri = new URL(url);
|
||||||
|
expect(uri.protocol).to.be('http:');
|
||||||
|
expect(uri.hostname).to.be('example.com');
|
||||||
|
expect(uri.pathname).to.be('/wms');
|
||||||
|
const queryData = uri.searchParams;
|
||||||
|
expect(queryData.get('FORMAT')).to.be('image/png');
|
||||||
|
expect(queryData.get('LAYER')).to.be('layer');
|
||||||
|
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||||
|
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||||
|
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||||
|
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds additional params as expected', function() {
|
||||||
|
const source = new ImageWMS(options);
|
||||||
|
const url = source.getGetLegendGraphicUrl(resolution, {
|
||||||
|
STYLE: 'STYLE_VALUE',
|
||||||
|
FEATURETYPE: 'FEATURETYPE_VALUE',
|
||||||
|
RULE: 'RULE_VALUE',
|
||||||
|
SLD: 'SLD_VALUE',
|
||||||
|
SLD_BODY: 'SLD_BODY_VALUE',
|
||||||
|
FORMAT: 'FORMAT_VALUE',
|
||||||
|
WIDTH: 'WIDTH_VALUE',
|
||||||
|
HEIGHT: 'HEIGHT_VALUE',
|
||||||
|
EXCEPTIONS: 'EXCEPTIONS_VALUE',
|
||||||
|
LANGUAGE: 'LANGUAGE_VALUE'
|
||||||
|
});
|
||||||
|
const uri = new URL(url);
|
||||||
|
expect(uri.protocol).to.be('http:');
|
||||||
|
expect(uri.hostname).to.be('example.com');
|
||||||
|
expect(uri.pathname).to.be('/wms');
|
||||||
|
const queryData = uri.searchParams;
|
||||||
|
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||||
|
expect(queryData.get('LAYER')).to.be('layer');
|
||||||
|
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||||
|
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||||
|
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||||
|
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||||
|
expect(queryData.get('STYLE')).to.be('STYLE_VALUE');
|
||||||
|
expect(queryData.get('FEATURETYPE')).to.be('FEATURETYPE_VALUE');
|
||||||
|
expect(queryData.get('RULE')).to.be('RULE_VALUE');
|
||||||
|
expect(queryData.get('SLD')).to.be('SLD_VALUE');
|
||||||
|
expect(queryData.get('SLD_BODY')).to.be('SLD_BODY_VALUE');
|
||||||
|
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||||
|
expect(queryData.get('WIDTH')).to.be('WIDTH_VALUE');
|
||||||
|
expect(queryData.get('HEIGHT')).to.be('HEIGHT_VALUE');
|
||||||
|
expect(queryData.get('EXCEPTIONS')).to.be('EXCEPTIONS_VALUE');
|
||||||
|
expect(queryData.get('LANGUAGE')).to.be('LANGUAGE_VALUE');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('#refresh()', function() {
|
describe('#refresh()', function() {
|
||||||
|
|
||||||
let map, source;
|
let map, source;
|
||||||
|
|||||||
@@ -299,6 +299,63 @@ describe('ol.source.TileWMS', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#getGetLegendGraphicUrl', function() {
|
||||||
|
|
||||||
|
it('returns the getLegenGraphic url as expected', function() {
|
||||||
|
const source = new TileWMS(options);
|
||||||
|
const url = source.getGetLegendGraphicUrl(0.1);
|
||||||
|
const uri = new URL(url);
|
||||||
|
expect(uri.protocol).to.be('http:');
|
||||||
|
expect(uri.hostname).to.be('example.com');
|
||||||
|
expect(uri.pathname).to.be('/wms');
|
||||||
|
const queryData = uri.searchParams;
|
||||||
|
expect(queryData.get('FORMAT')).to.be('image/png');
|
||||||
|
expect(queryData.get('LAYER')).to.be('layer');
|
||||||
|
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||||
|
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||||
|
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||||
|
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds additional params as expected', function() {
|
||||||
|
const source = new TileWMS(options);
|
||||||
|
const url = source.getGetLegendGraphicUrl(0.1, {
|
||||||
|
STYLE: 'STYLE_VALUE',
|
||||||
|
FEATURETYPE: 'FEATURETYPE_VALUE',
|
||||||
|
RULE: 'RULE_VALUE',
|
||||||
|
SLD: 'SLD_VALUE',
|
||||||
|
SLD_BODY: 'SLD_BODY_VALUE',
|
||||||
|
FORMAT: 'FORMAT_VALUE',
|
||||||
|
WIDTH: 'WIDTH_VALUE',
|
||||||
|
HEIGHT: 'HEIGHT_VALUE',
|
||||||
|
EXCEPTIONS: 'EXCEPTIONS_VALUE',
|
||||||
|
LANGUAGE: 'LANGUAGE_VALUE'
|
||||||
|
});
|
||||||
|
const uri = new URL(url);
|
||||||
|
expect(uri.protocol).to.be('http:');
|
||||||
|
expect(uri.hostname).to.be('example.com');
|
||||||
|
expect(uri.pathname).to.be('/wms');
|
||||||
|
const queryData = uri.searchParams;
|
||||||
|
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||||
|
expect(queryData.get('LAYER')).to.be('layer');
|
||||||
|
expect(queryData.get('REQUEST')).to.be('GetLegendGraphic');
|
||||||
|
expect(queryData.get('SERVICE')).to.be('WMS');
|
||||||
|
expect(queryData.get('VERSION')).to.be('1.3.0');
|
||||||
|
expect(queryData.get('SCALE')).to.be('357.14214285714274');
|
||||||
|
expect(queryData.get('STYLE')).to.be('STYLE_VALUE');
|
||||||
|
expect(queryData.get('FEATURETYPE')).to.be('FEATURETYPE_VALUE');
|
||||||
|
expect(queryData.get('RULE')).to.be('RULE_VALUE');
|
||||||
|
expect(queryData.get('SLD')).to.be('SLD_VALUE');
|
||||||
|
expect(queryData.get('SLD_BODY')).to.be('SLD_BODY_VALUE');
|
||||||
|
expect(queryData.get('FORMAT')).to.be('FORMAT_VALUE');
|
||||||
|
expect(queryData.get('WIDTH')).to.be('WIDTH_VALUE');
|
||||||
|
expect(queryData.get('HEIGHT')).to.be('HEIGHT_VALUE');
|
||||||
|
expect(queryData.get('EXCEPTIONS')).to.be('EXCEPTIONS_VALUE');
|
||||||
|
expect(queryData.get('LANGUAGE')).to.be('LANGUAGE_VALUE');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
describe('#setUrl()', function() {
|
describe('#setUrl()', function() {
|
||||||
it('sets the correct url', function() {
|
it('sets the correct url', function() {
|
||||||
const source = new TileWMS(options);
|
const source = new TileWMS(options);
|
||||||
|
|||||||
Reference in New Issue
Block a user