Skip to content

Commit

Permalink
[Backport 2023.01.xx] geosolutions-it#8167 add serverType option to w…
Browse files Browse the repository at this point in the history
…ms & csw catalog entries (geosolutions-it#9048) (geosolutions-it#9063)

* geosolutions-it#8167 add serverType option to wms & csw catalog entries (geosolutions-it#9048)

 geosolutions-it#7809 failure to print WMS layers coming from mapproxy
 geosolutions-it#7877 set TILED=true only when printing layers from geoserver
 geosolutions-it#7879 set TILED=true only when loading layers from geoserver
---------

Co-authored-by: allyoucanmap <[email protected]>

* geosolutions-it#8905 Add missing translations (geosolutions-it#9055)

* geosolutions-it#8905 Add missing translations

* fix failing tests

---------

Co-authored-by: Landry Breuil <[email protected]>
  • Loading branch information
allyoucanmap and landryb authored Mar 29, 2023
1 parent bcb7434 commit de8c606
Show file tree
Hide file tree
Showing 24 changed files with 191 additions and 48 deletions.
1 change: 1 addition & 0 deletions docs/developer-guide/local-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ Set `selectedService` value to one of the ID of the services object ("Demo CSW S
"format": "image/png8" // the image format to use by default for layers coming from this catalog (or tiles).
"layerOptions": { // optional
"format": "image/png8", // image format needs to be configured also inside layerOptions
"serverType": "geoserver or no-vendor, depending on this some geoserver vendor extensions will be used for WMS requests.",
"tileSize": 512 // determine the default tile size for the catalog, valid for WMS and CSW catalogs
},
"filter": { // applicable only for CSW service
Expand Down
4 changes: 3 additions & 1 deletion web/client/api/catalog/WMS.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ const recordToLayer = (record, {
map = {},
layerBaseConfig,
localizedLayerStyles,
allowUnsecureLayers
allowUnsecureLayers,
service
} = {}) => {
if (!record || !record.references) {
// we don't have a valid record so no buttons to add
Expand Down Expand Up @@ -103,6 +104,7 @@ const recordToLayer = (record, {
allowedSRS: allowedSRS,
catalogURL,
...layerBaseConfig,
...service?.layerOptions,
...record.layerOptions,
localizedLayerStyles: !isNil(localizedLayerStyles) ? localizedLayerStyles : undefined,
...(!isEmpty(formats) && {imageFormats: formats.imageFormats, infoFormats: formats.infoFormats}),
Expand Down
4 changes: 3 additions & 1 deletion web/client/api/catalog/__tests__/WMS-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,14 @@ describe('Test correctness of the WMS APIs', () => {
}, {
url: 'http://sample',
layerOptions: {
tileSize: 512
tileSize: 512,
serverType: "no-vendor"
}
});
expect(records.length).toBe(1);
const layer = getLayerFromRecord(records[0]);
expect(layer.tileSize).toBe(512);
expect(layer.serverType).toBe("no-vendor");
});

it('wms layer with visibility limits', () => {
Expand Down
18 changes: 10 additions & 8 deletions web/client/components/TOC/fragments/settings/Display.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Message from '../../../I18N/Message';
import InfoPopover from '../../../widgets/widget/InfoPopover';
import Legend from '../legend/Legend';
import VisibilityLimitsForm from './VisibilityLimitsForm';
import { ServerTypes } from '../../../../utils/LayersUtils';
import Select from 'react-select';
import { DEFAULT_FORMAT_WMS, getSupportedFormat } from '../../../../api/WMS';
export default class extends React.Component {
Expand Down Expand Up @@ -155,7 +156,7 @@ export default class extends React.Component {
</Col>
<Col xs={12}>
<FormGroup>
<ControlLabel><Message msgId="WMS Layer tile size" /></ControlLabel>
<ControlLabel><Message msgId="layerProperties.wmsLayerTileSize" /></ControlLabel>
<Select
key="wsm-layersize-dropdown"
clearable={false}
Expand Down Expand Up @@ -218,18 +219,19 @@ export default class extends React.Component {
<FormGroup>
<Checkbox key="transparent" checked={this.props.element && (this.props.element.transparent === undefined ? true : this.props.element.transparent)} onChange={(event) => {this.props.onChange("transparent", event.target.checked); }}>
<Message msgId="layerProperties.transparent"/></Checkbox>
<Checkbox value="tiled" key="tiled"
disabled={!!this.props.element.singleTile}
onChange={(e) => this.props.onChange("tiled", e.target.checked)}
checked={this.props.element && this.props.element.tiled !== undefined ? this.props.element.tiled : true} >
<Message msgId="layerProperties.cached"/>
</Checkbox>
{(this.props.element?.serverType !== ServerTypes.NO_VENDOR && (
<Checkbox value="tiled" key="tiled"
disabled={!!this.props.element.singleTile}
onChange={(e) => this.props.onChange("tiled", e.target.checked)}
checked={this.props.element && this.props.element.tiled !== undefined ? this.props.element.tiled : true} >
<Message msgId="layerProperties.cached"/>
</Checkbox>))}
<Checkbox key="singleTile" value="singleTile"
checked={this.props.element && (this.props.element.singleTile !== undefined ? this.props.element.singleTile : false )}
onChange={(e) => this.props.onChange("singleTile", e.target.checked)}>
<Message msgId="layerProperties.singleTile"/>
</Checkbox>
{(this.props.isLocalizedLayerStylesEnabled && (
{(this.props.isLocalizedLayerStylesEnabled && this.props.element?.serverType !== ServerTypes.NO_VENDOR && (
<Checkbox key="localizedLayerStyles" value="localizedLayerStyles"
data-qa="display-lacalized-layer-styles-option"
checked={this.props.element && (this.props.element.localizedLayerStyles !== undefined ? this.props.element.localizedLayerStyles : false )}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ describe('Test CatalogServiceEditor', () => {

const formatFormGroups = [...document.querySelectorAll('.form-group')].filter(fg => {
const labels = [...fg.querySelectorAll('label')];
return labels.length === 1 && labels[0].textContent === 'Format';
return labels.length === 1 && labels[0].textContent === 'layerProperties.format.title';
});
expect(formatFormGroups.length).toBe(1);
const formatSelect = formatFormGroups[0].querySelector('.Select-value-label');
Expand Down Expand Up @@ -95,7 +95,7 @@ describe('Test CatalogServiceEditor', () => {

const wmstileSizeFormGroups = [...document.querySelectorAll('.form-group')].filter(fg => {
const labels = [...fg.querySelectorAll('label')];
return labels.length === 1 && labels[0].textContent === 'WMS Layer tile size';
return labels.length === 1 && labels[0].textContent === 'layerProperties.wmsLayerTileSize';
});
expect(wmstileSizeFormGroups.length).toBe(1);
const tileSizeSelect = wmstileSizeFormGroups[0].querySelector('.Select-value-label');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export default ({
}, [code.dynamicFilter]);

return (
<div className={"catalog-csw-filters"}>
<div className={"catalog-csw-filters"} style={{ position: 'relative', zIndex: 0 }}>
<FilterCode type={"static"} {...cmProps} />
<FilterCode type={"dynamic"} {...cmProps} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import localizedProps from '../../../misc/enhancers/localizedProps';
const Select = localizedProps('noResultsText')(RS);

import CommonAdvancedSettings from './CommonAdvancedSettings';
import {isNil} from "lodash";
import {isNil, camelCase} from "lodash";
import ReactQuill from '../../../../libs/quill/react-quill-suspense';
import { ServerTypes } from '../../../../utils/LayersUtils';

import InfoPopover from '../../../widgets/widget/InfoPopover';
import CSWFilters from "./CSWFilters";
Expand All @@ -28,6 +29,9 @@ import WMSDomainAliases from "./WMSDomainAliases";
const getTileSizeSelectOptions = (opts) => {
return opts.map(opt => ({label: `${opt}x${opt}`, value: opt}));
};
const getServerTypeOptions = () => {
return Object.keys(ServerTypes).map((key) => ({ label: <Message msgId={`layerProperties.serverTypeOption.${camelCase(key)}`} />, value: ServerTypes[key] }));
};

/**
* Raster advanced settings form, used by WMS/CSW
Expand All @@ -46,6 +50,7 @@ const getTileSizeSelectOptions = (opts) => {
*
* **WMS|CSW**
* - tileSize: Option allows to select and configure the default tile size of the layer to be requested with
* - serverType: Option allows to specify whether some geoserver vendor options can be used or should be avoided
* - format: Option allows to select and configure the default format of the layer to be requested with
* - autoload: Option allows automatic fetching of the results upon selecting the service from Service dropdown
* - hideThumbnail: Options allows to hide the thumbnail on the result
Expand All @@ -72,6 +77,7 @@ export default ({
}, [props.autoSetVisibilityLimits]);

const tileSelectOptions = getTileSizeSelectOptions(tileSizeOptions);
const serverTypeOptions = getServerTypeOptions();
return (<CommonAdvancedSettings {...props} onChangeServiceProperty={onChangeServiceProperty} service={service} >
{(isLocalizedLayerStylesEnabled && !isNil(service.type) ? service.type === "wms" : false) && (<FormGroup controlId="localized-styles" key="localized-styles">
<Col xs={12}>
Expand All @@ -96,7 +102,7 @@ export default ({
<Checkbox
onChange={(e) => onChangeServiceProperty("layerOptions", { ...service.layerOptions, singleTile: e.target.checked })}
checked={!isNil(service?.layerOptions?.singleTile) ? service.layerOptions.singleTile : false}>
<Message msgId="catalog.singleTile.label" />&nbsp;<InfoPopover text={<Message msgId="catalog.singleTile.tooltip" />} />
<Message msgId="layerProperties.singleTile" />&nbsp;<InfoPopover text={<Message msgId="catalog.singleTile.tooltip" />} />
</Checkbox>
</Col>
</FormGroup>}
Expand Down Expand Up @@ -154,7 +160,7 @@ export default ({
</FormGroup>)}
<FormGroup style={advancedRasterSettingsStyles}>
<Col xs={6}>
<ControlLabel>Format</ControlLabel>
<ControlLabel><Message msgId="layerProperties.format.title" /></ControlLabel>
</Col >
<Col xs={6} style={{marginBottom: '5px'}}>
<Select
Expand All @@ -170,7 +176,7 @@ export default ({
</FormGroup>
<FormGroup style={advancedRasterSettingsStyles}>
<Col xs={6} >
<ControlLabel>WMS Layer tile size</ControlLabel>
<ControlLabel><Message msgId="layerProperties.wmsLayerTileSize" /></ControlLabel>
</Col >
<Col xs={6} style={{marginBottom: '5px'}}>
<Select
Expand All @@ -179,6 +185,17 @@ export default ({
onChange={event => onChangeServiceProperty("layerOptions", { ...service.layerOptions, tileSize: event && event.value })} />
</Col >
</FormGroup>
<FormGroup style={advancedRasterSettingsStyles}>
<Col xs={6} >
<ControlLabel><Message msgId="layerProperties.serverType" /></ControlLabel>
</Col >
<Col xs={6} style={{marginBottom: '5px'}}>
<Select
value={service.layerOptions?.serverType}
options={serverTypeOptions}
onChange={event => onChangeServiceProperty("layerOptions", { ...service.layerOptions, serverType: event?.value })} />
</Col >
</FormGroup>
{!isNil(service.type) && service.type === "csw" &&
<CSWFilters filter={service?.filter} onChangeServiceProperty={onChangeServiceProperty}/>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ describe('Test Raster advanced settings', () => {
const advancedSettingPanel = document.getElementsByClassName("mapstore-switch-panel");
expect(advancedSettingPanel).toBeTruthy();
const fields = document.querySelectorAll(".form-group");
expect(fields.length).toBe(10);
expect(fields.length).toBe(11);
});
it('test csw advanced options', () => {
ReactDOM.render(<RasterAdvancedSettings service={{type: "csw", autoload: false}}/>, document.getElementById("container"));
const advancedSettingPanel = document.getElementsByClassName("mapstore-switch-panel");
expect(advancedSettingPanel).toBeTruthy();
const fields = document.querySelectorAll(".form-group");
const cswFilters = document.getElementsByClassName("catalog-csw-filters");
expect(fields.length).toBe(8);
expect(fields.length).toBe(9);
expect(cswFilters).toBeTruthy();
});
it('test component onChangeServiceProperty autoload', () => {
Expand Down Expand Up @@ -217,11 +217,29 @@ describe('Test Raster advanced settings', () => {
const advancedSettingsPanel = document.getElementsByClassName("mapstore-switch-panel");
expect(advancedSettingsPanel).toBeTruthy();
const formGroup = document.querySelectorAll('.form-group')[3];
expect(formGroup.textContent.trim()).toBe('catalog.singleTile.label');
expect(formGroup.textContent.trim()).toBe('layerProperties.singleTile');
const singleTileLayer = formGroup.querySelector('input[type="checkbox"]');
expect(singleTileLayer).toBeTruthy();
TestUtils.Simulate.change(singleTileLayer, { "target": { "checked": true }});
expect(spyOn).toHaveBeenCalled();
expect(spyOn.calls[0].arguments).toEqual([ 'layerOptions', { singleTile: true } ]);
});
it('test component onChangeServiceProperty serverType', () => {
const action = {
onChangeServiceProperty: () => {}
};
const spyOn = expect.spyOn(action, 'onChangeServiceProperty');
ReactDOM.render(<RasterAdvancedSettings
onChangeServiceProperty={action.onChangeServiceProperty}
service={{ type: "wms", layerOptions: {serverType: 'no-vendor'} }}
/>, document.getElementById("container"));
const advancedSettingsPanel = document.getElementsByClassName("mapstore-switch-panel");
expect(advancedSettingsPanel).toBeTruthy();
const serverTypeOption = document.querySelectorAll('input[role="combobox"]')[2];
expect(serverTypeOption).toBeTruthy();
TestUtils.Simulate.change(serverTypeOption, { target: { value: "geoserver" }});
TestUtils.Simulate.keyDown(serverTypeOption, { keyCode: 9, key: 'Tab' });
expect(spyOn).toHaveBeenCalled();
expect(spyOn.calls[0].arguments).toEqual([ 'layerOptions', { serverType: "geoserver" } ]);
});
});
4 changes: 2 additions & 2 deletions web/client/components/map/cesium/plugins/WMSLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import GeoServerBILTerrainProvider from '../../../../utils/cesium/GeoServerBILTe
import assign from 'object-assign';
import {isArray, isEqual} from 'lodash';
import WMSUtils from '../../../../utils/cesium/WMSUtils';
import { getAuthenticationParam, getURLs } from '../../../../utils/LayersUtils';
import { getAuthenticationParam, getURLs, getWMSVendorParams } from '../../../../utils/LayersUtils';
import { optionsToVendorParams } from '../../../../utils/VendorParamsUtils';
import { addAuthenticationToSLD, getAuthenticationHeaders } from '../../../../utils/SecurityUtils';

Expand All @@ -30,7 +30,7 @@ function wmsToCesiumOptionsSingleTile(options) {
format: isVectorFormat(options.format) && 'image/png' || options.format || 'image/png',
transparent: options.transparent !== undefined ? options.transparent : true,
opacity: opacity,
tiled: options.tiled !== undefined ? options.tiled : true,
...getWMSVendorParams(options),
layers: options.name,
width: options.size || 2000,
height: options.size || 2000,
Expand Down
4 changes: 2 additions & 2 deletions web/client/components/map/leaflet/plugins/WMSLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import objectAssign from 'object-assign';
import {isArray, isNil} from 'lodash';
import {addAuthenticationToSLD, addAuthenticationParameter} from '../../../../utils/SecurityUtils';
import { loadTile, getElevation } from '../../../../utils/ElevationUtils';
import { creditsToAttribution } from '../../../../utils/LayersUtils';
import { creditsToAttribution, getWMSVendorParams } from '../../../../utils/LayersUtils';

import { isVectorFormat } from '../../../../utils/VectorTileUtils';

Expand Down Expand Up @@ -170,7 +170,7 @@ function wmsToLeafletOptions(options) {
styles: options.style || "",
format: isVectorFormat(options.format) && 'image/png' || options.format || 'image/png',
transparent: options.transparent !== undefined ? options.transparent : true,
tiled: options.tiled !== undefined ? options.tiled : true,
...getWMSVendorParams(options),
opacity: opacity,
zIndex: options.zIndex,
version: options.version || "1.3.0",
Expand Down
4 changes: 2 additions & 2 deletions web/client/components/map/openlayers/plugins/WMSLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { getConfigProp } from '../../../../utils/ConfigUtils';

import {optionsToVendorParams} from '../../../../utils/VendorParamsUtils';
import {addAuthenticationToSLD, addAuthenticationParameter, getAuthenticationHeaders} from '../../../../utils/SecurityUtils';
import { creditsToAttribution } from '../../../../utils/LayersUtils';
import { creditsToAttribution, getWMSVendorParams } from '../../../../utils/LayersUtils';

import MapUtils from '../../../../utils/MapUtils';
import {loadTile, getElevation as getElevationFunc} from '../../../../utils/ElevationUtils';
Expand Down Expand Up @@ -123,7 +123,7 @@ function wmsToOpenlayersOptions(options) {
TRANSPARENT: options.transparent !== undefined ? options.transparent : true,
SRS: CoordinatesUtils.normalizeSRS(options.srs || 'EPSG:3857', options.allowedSRS),
CRS: CoordinatesUtils.normalizeSRS(options.srs || 'EPSG:3857', options.allowedSRS),
TILED: options.singleTile ? false : (!isNil(options.tiled) ? options.tiled : true),
...getWMSVendorParams(options),
VERSION: options.version || "1.3.0"
}, assign(
{},
Expand Down
5 changes: 3 additions & 2 deletions web/client/epics/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ export default (API) => ({
API[format]
.textSearch(url, startPosition, maxRecords, text, { ...layerOptions, ...service, options: { service } })
.catch(() => ({ records: [] }))
).map(r => ({ ...r, format, url, text, layerOptions }));
).map(r => ({ ...r, format, url, text, layerOptions, service }));
});
return Rx.Observable.forkJoin(actions)
.switchMap((results) => {
if (isArray(results) && results.length) {
return Rx.Observable.of(results.map(r => {
const { format, url, text, layerOptions, ...result } = r;
const { format, url, text, layerOptions, service, ...result } = r;
const locales = currentMessagesSelector(state);
const records = API[format].getCatalogRecords(result, layerOptions, locales) || [];
const record = head(records.filter(rec => rec.identifier || rec.name === text)); // exact match of text and record identifier
Expand All @@ -198,6 +198,7 @@ export default (API) => ({
const layerBaseConfig = {}; // DO WE NEED TO FETCH IT FROM STATE???
const authkeyParamName = authkeyParamNameSelector(state);
const layer = API[format].getLayerFromRecord(record, {
service,
removeParams: authkeyParamName,
catalogURL: format === 'csw' && url
? url + "?request=GetRecordById&service=CSW&version=2.0.2&elementSetName=full&id=" + record.identifier
Expand Down
Loading

0 comments on commit de8c606

Please sign in to comment.