diff --git a/web/client/api/WMS.js b/web/client/api/WMS.js index 054418ad3e..cfe3c9e4fe 100644 --- a/web/client/api/WMS.js +++ b/web/client/api/WMS.js @@ -92,6 +92,13 @@ export const flatLayers = (root) => { : rootName && [root] || []; }; +const getFormats = (response) => { + const root = response.Capability; + const imageFormats = castArray(root?.Request?.GetMap?.Format || []).filter(isValidGetMapFormat); + const infoFormats = castArray(root?.Request?.GetFeatureInfo?.Format || []).filter(isValidGetFeatureInfoFormat); + return { imageFormats, infoFormats }; +}; + export const getOnlineResource = (c) => { return c.Request && c.Request.GetMap && c.Request.GetMap.DCPType && c.Request.GetMap.DCPType.HTTP && c.Request.GetMap.DCPType.HTTP.Get && c.Request.GetMap.DCPType.HTTP.Get.OnlineResource && c.Request.GetMap.DCPType.HTTP.Get.OnlineResource.$ || undefined; }; @@ -228,7 +235,7 @@ export const textSearch = (url, startPosition, maxRecords, text) => { export const parseLayerCapabilities = (json, layer) => { const root = json.Capability; const layersCapabilities = flatLayers(root); - return layersCapabilities.find((layerCapability) => { + const capabilities = layersCapabilities.find((layerCapability) => { const capabilityName = layerCapability.Name; if (layer.name.split(":").length === 2 && capabilityName && capabilityName.split(":").length === 2) { return layer.name === capabilityName && layerCapability; @@ -241,6 +248,17 @@ export const parseLayerCapabilities = (json, layer) => { } return layer.name === capabilityName && layerCapability; }); + if (capabilities) { + const { imageFormats, infoFormats } = getFormats(json); + return { + ...capabilities, + layerOptions: { + imageFormats, + infoFormats + } + }; + } + return null; }; export const getBBox = (record, bounds) => { let layer = record; @@ -294,10 +312,8 @@ export const reset = () => { export const getSupportedFormat = (url, includeGFIFormats = false) => { return getCapabilities(url) .then((response) => { - const root = response.Capability; - const imageFormats = castArray(root?.Request?.GetMap?.Format || []).filter(isValidGetMapFormat); + const { imageFormats, infoFormats } = getFormats(response); if (includeGFIFormats) { - const infoFormats = castArray(root?.Request?.GetFeatureInfo?.Format || []).filter(isValidGetFeatureInfoFormat); return { imageFormats, infoFormats }; } return imageFormats; diff --git a/web/client/api/__tests__/WMS-test.js b/web/client/api/__tests__/WMS-test.js index 45279918d9..69b0518db2 100644 --- a/web/client/api/__tests__/WMS-test.js +++ b/web/client/api/__tests__/WMS-test.js @@ -180,6 +180,82 @@ describe('Test correctness of the WMS APIs', () => { const capability = API.parseLayerCapabilities(capabilities, {name: 'mytest'}); expect(capability).toBeTruthy(); }); + it('parseLayerCapabilities formats', () => { + const capabilities = { + Capability: { + Request: { + GetMap: { + Format: [ + "image/png", + "application/atom+xml", + "application/json;type=geojson", + "application/json;type=topojson", + "application/json;type=utfgrid", + "application/pdf", + "application/rss+xml", + "application/vnd.google-earth.kml+xml", + "application/vnd.google-earth.kml+xml;mode=networklink", + "application/vnd.google-earth.kmz", + "application/vnd.mapbox-vector-tile", + "image/geotiff", + "image/geotiff8", + "image/gif", + "image/jpeg", + "image/png; mode=8bit", + "image/svg+xml", + "image/tiff", + "image/tiff8", + "image/vnd.jpeg-png", + "image/vnd.jpeg-png8", + "text/html; subtype=openlayers", + "text/html; subtype=openlayers2", + "text/html; subtype=openlayers3" + ] + }, + GetFeatureInfo: { + Format: [ + "text/plain", + "application/vnd.ogc.gml", + "text/xml", + "application/vnd.ogc.gml/3.1.1", + "text/xml; subtype=gml/3.1.1", + "text/html", + "application/json" + ] + } + }, + Layer: { + Layer: { + Layer: [ + { + Name: "mytest" + }, + { + Name: "mytest2" + } + ] + } + } + } + }; + + const capability = API.parseLayerCapabilities(capabilities, {name: 'mytest'}); + expect(capability).toBeTruthy(); + expect(capability.layerOptions).toBeTruthy(); + expect(capability.layerOptions.imageFormats).toEqual([ + 'image/png', + 'image/gif', + 'image/jpeg', + 'image/png; mode=8bit', + 'image/vnd.jpeg-png', + 'image/vnd.jpeg-png8' + ]); + expect(capability.layerOptions.infoFormats).toEqual([ + 'text/plain', + 'text/html', + 'application/json' + ]); + }); it('should parse nested layers from capabilities', () => { expect(API.flatLayers({ Layer: { diff --git a/web/client/components/background/BackgroundDialog.jsx b/web/client/components/background/BackgroundDialog.jsx index 32f8fff202..e719a69ed4 100644 --- a/web/client/components/background/BackgroundDialog.jsx +++ b/web/client/components/background/BackgroundDialog.jsx @@ -170,7 +170,11 @@ export default class BackgroundDialog extends React.Component { onChange={event => this.setState({ format: event && event.value })} value={this.state.format || this.props.defaultFormat} clearable - options={this.props.formatOptions} + isLoading={!this.props.capabilities} + options={ + (this.props.capabilities?.capabilities?.layerOptions?.imageFormats || this.props.formatOptions || []) + .map((format) => format?.value ? format : ({ value: format, label: format })) + } /> {this.renderStyleSelector()}