diff --git a/web/client/components/TOC/fragments/settings/WMSCacheOptions.jsx b/web/client/components/TOC/fragments/settings/WMSCacheOptions.jsx
index 803b313f16..0df967a465 100644
--- a/web/client/components/TOC/fragments/settings/WMSCacheOptions.jsx
+++ b/web/client/components/TOC/fragments/settings/WMSCacheOptions.jsx
@@ -189,14 +189,12 @@ const infoText = {
* @prop {object} layer layer configuration
* @prop {boolean} disableTileGrids disable tile grids toolbar
* @prop {function} onChange callback triggered after changing the form
- * @prop {string} owner the owner component name like: 'background-dialog'
*/
function WMSCacheOptions({
layer = {},
projection,
onChange,
- disableTileGrids,
- owner = ""
+ disableTileGrids
}) {
const [tileGridLoading, setTileGridLoading] = useState(false);
@@ -268,41 +266,8 @@ function WMSCacheOptions({
.finally(() => setTimeout(() => setTileGridLoading(false), 500));
};
- const handleGetTileGridSettings = () => {
- const newTileGridStrategy = layer.tileGridStrategy !== 'custom'
- ? 'custom'
- : undefined;
- const promise = newTileGridStrategy === 'custom'
- && ((layer?.tileGrids?.length || 0) === 0 || !layer?.tileGridCacheSupport)
- ? onTileMatrixSetsFetch(layer)
- : Promise.resolve(undefined);
- return promise.then(({ tileGrids, tileGridCacheSupport } = {}) => {
- const hasTileGrids = (tileGrids?.length || 0) > 0;
- const tileGridStrategy = hasTileGrids
- ? newTileGridStrategy
- : undefined;
- let tileChangedData = {
- tileGridCacheSupport,
- tileGridStrategy,
- tileGrids
- };
- if (owner === 'background-dialog' && newTileGridStrategy === 'custom') {
- tileChangedData = {
- ...tileChangedData, tiled: true, tileGridStrategy: 'custom'
- };
- }
- handleOnChange(tileChangedData);
- });
- };
-
const InfoText = infoText[layer.tileGridStrategy] || infoText.standard;
- // fetching grid data in case background layers
- React.useEffect(() => {
- if (layer.remoteTileGrids && owner === 'background-dialog') {
- handleGetTileGridSettings();
- }
- }, []);
return (
@@ -355,7 +320,26 @@ function WMSCacheOptions({
glyph={layer.tileGridStrategy === 'custom' ? 'grid-custom' : 'grid-regular'}
bsStyle={layer.tileGridStrategy === 'custom' ? 'success' : 'primary'}
className="square-button-md"
- onClick={handleGetTileGridSettings}
+ onClick={() => {
+ const newTileGridStrategy = layer.tileGridStrategy !== 'custom'
+ ? 'custom'
+ : undefined;
+ const promise = newTileGridStrategy === 'custom'
+ && ((layer?.tileGrids?.length || 0) === 0 || !layer?.tileGridCacheSupport)
+ ? onTileMatrixSetsFetch(layer)
+ : Promise.resolve(undefined);
+ return promise.then(({ tileGrids, tileGridCacheSupport } = {}) => {
+ const hasTileGrids = (tileGrids?.length || 0) > 0;
+ const tileGridStrategy = hasTileGrids
+ ? newTileGridStrategy
+ : undefined;
+ handleOnChange({
+ tileGridCacheSupport,
+ tileGridStrategy,
+ tileGrids
+ });
+ });
+ }}
/>
}
diff --git a/web/client/epics/__tests__/backgroundselector-test.js b/web/client/epics/__tests__/backgroundselector-test.js
new file mode 100644
index 0000000000..87f7092ddf
--- /dev/null
+++ b/web/client/epics/__tests__/backgroundselector-test.js
@@ -0,0 +1,206 @@
+/*
+ * Copyright 2014, GeoSolutions Sas.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import expect from 'expect';
+
+import { addBackgroundProperties, SET_BACKGROUND_MODAL_PARAMS } from '../../actions/backgroundselector';
+import { testEpic } from './epicTestUtils';
+import backgroundEpics from '../backgroundselector';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '../../libs/ajax';
+let mockAxios;
+
+describe('addBackgroundPropertiesEpic Epics', () => {
+ beforeEach((done) => {
+ mockAxios = new MockAdapter(axios);
+ setTimeout(done);
+ });
+ afterEach((done) => {
+ mockAxios.restore();
+ setTimeout(done);
+ });
+ const capabilitiesWMSXmlResponse = `
+
+
+
+
+
+
+
+
+ states_test
+ states_test
+ states_test
+
+ features
+ states
+
+ EPSG:4326
+ CRS:84
+
+ -124.73142200000001
+ -66.969849
+ 24.955967
+ 49.371735
+
+
+
+
+ image/png
+ image/jpeg
+ image/png8
+
+
+
+`;
+
+ const capabilitiesWMTSXmlResponse = `
+
+
+
+
+
+
+
+ states_test
+ states_test
+ states_test
+
+ features
+ states
+
+ EPSG:4326
+ CRS:84
+
+ -124.73142200000001
+ -66.969849
+ 24.955967
+ 49.371735
+
+
+
+
+
+
+
+`;
+ it('test add normal background layer', (done) => {
+ mockAxios.onGet().reply(200, capabilitiesWMSXmlResponse);
+ let addBackgroundPropAction = addBackgroundProperties({
+ layer: {
+ id: "layer01", allowedSRS: {
+ "EPSG:3857": true,
+ "EPSG:900913": true,
+ "EPSG:4326": true
+ },
+ title: "states_test",
+ type: 'wms',
+ name: "states_test",
+ url: ['/geoserver/wms'],
+ group: "background"
+ },
+ editing: false
+ });
+
+ testEpic(backgroundEpics.addBackgroundPropertiesEpic, 2, [addBackgroundPropAction], (res) => {
+ const action1 = res[0];
+ const action2 = res[1];
+ expect(action1).toExist();
+ expect(action1.type).toEqual(SET_BACKGROUND_MODAL_PARAMS);
+ expect(action1.modalParams.loading).toEqual(true);
+ expect(action2).toExist();
+ expect(action2.type).toEqual(SET_BACKGROUND_MODAL_PARAMS);
+ expect(action2.modalParams.loading).toEqual(false);
+ expect(action2.modalParams.capabilities).toExist();
+ done();
+ }, {});
+
+ });
+ it('test add wms as a background layer without enabling remote custom tile grid', (done) => {
+ mockAxios.onGet().reply(200, capabilitiesWMSXmlResponse);
+ let addBackgroundPropAction = addBackgroundProperties({
+ layer: {
+ id: "layer01", allowedSRS: {
+ "EPSG:3857": true,
+ "EPSG:900913": true,
+ "EPSG:4326": true
+ },
+ title: "states_test",
+ type: 'wms',
+ name: "states_test",
+ url: '/geoserver/wms',
+ group: "background"
+ },
+ editing: false
+ });
+
+ testEpic(backgroundEpics.addBackgroundPropertiesEpic, 2, [addBackgroundPropAction], (res) => {
+ const action1 = res[0];
+ const action2 = res[1];
+ expect(action1).toExist();
+ expect(action1.type).toEqual(SET_BACKGROUND_MODAL_PARAMS);
+ expect(action1.modalParams.loading).toEqual(true);
+ expect(action2).toExist();
+ expect(action2.type).toEqual(SET_BACKGROUND_MODAL_PARAMS);
+ expect(action2.modalParams.loading).toEqual(false);
+ expect(action2.modalParams.capabilities).toExist();
+ done();
+ }, {});
+ });
+ it('test add wms as a background layer with enabling remote custom tile grid', (done) => {
+ mockAxios.onGet().replyOnce(200, capabilitiesWMSXmlResponse);
+ mockAxios.onGet().replyOnce(200, capabilitiesWMTSXmlResponse);
+ let addBackgroundPropAction = addBackgroundProperties({
+ layer: {
+ id: "layer01", allowedSRS: {
+ "EPSG:3857": true,
+ "EPSG:900913": true,
+ "EPSG:4326": true
+ },
+ title: "states_test",
+ type: 'wms',
+ name: "states_test",
+ url: '/geoserver/wms',
+ group: "background",
+ remoteTileGrids: true
+ },
+ editing: false
+ });
+
+ testEpic(backgroundEpics.addBackgroundPropertiesEpic, 2, [addBackgroundPropAction], (res) => {
+ const action1 = res[0];
+ const action2 = res[1];
+ expect(action1).toExist();
+ expect(action1.type).toEqual(SET_BACKGROUND_MODAL_PARAMS);
+ expect(action1.modalParams.loading).toEqual(true);
+ expect(action2).toExist();
+ expect(action2.type).toEqual(SET_BACKGROUND_MODAL_PARAMS);
+ expect(action2.modalParams.loading).toEqual(false);
+ expect(action2.modalParams.capabilities).toExist();
+ expect(action2.modalParams.layer.tiled).toEqual(true);
+ expect(action2.modalParams.layer.tileGridStrategy).toEqual('custom');
+ done();
+ }, {});
+ });
+});
diff --git a/web/client/epics/backgroundselector.js b/web/client/epics/backgroundselector.js
index 7f99ca160d..7ea5aee5c1 100644
--- a/web/client/epics/backgroundselector.js
+++ b/web/client/epics/backgroundselector.js
@@ -32,7 +32,9 @@ import { UPDATE_NODE, ADD_LAYER, changeLayerProperties, removeNode} from '../act
import { getLayerFromId, currentBackgroundSelector } from '../selectors/layers';
import { backgroundLayersSelector } from '../selectors/backgroundselector';
import { getLayerCapabilities } from '../observables/wms';
-import { getLayerOptions } from '../utils/WMSUtils';
+import { getCustomTileGridProperties, getLayerOptions } from '../utils/WMSUtils';
+import { getLayerTileMatrixSetsInfo } from '../api/WMTS';
+import { generateGeoServerWMTSUrl } from '../utils/WMTSUtils';
const accessMetadataExplorer = (action$) =>
action$.ofType(ADD_BACKGROUND)
@@ -46,12 +48,20 @@ const addBackgroundPropertiesEpic = (action$) =>
action$.ofType(ADD_BACKGROUND_PROPERTIES)
.switchMap(({modalParams}) => {
const defaultAction = Rx.Observable.of(setBackgroundModalParams({...modalParams, loading: false}));
+ const isTileGridNeeded = (!modalParams.editing && modalParams?.layer?.remoteTileGrids);
return modalParams.layer && modalParams.layer.type === 'wms' ?
Rx.Observable.of(setBackgroundModalParams({...modalParams, loading: true}))
- .concat(getLayerCapabilities(modalParams.layer)
- .switchMap(capabilities => Rx.Observable.of(
- setBackgroundModalParams({...modalParams, loading: false, capabilities: getLayerOptions(capabilities)})
- ))
+ .concat(Rx.Observable.forkJoin(getLayerCapabilities(modalParams.layer), (!isTileGridNeeded) ?
+ Rx.Observable.of(null) :
+ Rx.Observable.defer(() => getLayerTileMatrixSetsInfo(generateGeoServerWMTSUrl(modalParams.layer), modalParams.layer.name, modalParams.layer))
+ .catch(() => Rx.Observable.of(null)))
+
+ .switchMap(([capabilities, tileGridData]) => {
+ const tileGridProperties = tileGridData ? getCustomTileGridProperties(tileGridData) : {};
+ return Rx.Observable.of(
+ setBackgroundModalParams({...modalParams, layer: {...modalParams.layer, ...tileGridProperties}, loading: false, capabilities: getLayerOptions(capabilities)})
+ );
+ })
.catch(() => defaultAction)
)
: defaultAction;
diff --git a/web/client/epics/catalog.js b/web/client/epics/catalog.js
index 7a9c0beeaf..19cc9ea87a 100644
--- a/web/client/epics/catalog.js
+++ b/web/client/epics/catalog.js
@@ -76,7 +76,7 @@ import { extractGeometryType } from '../utils/WFSLayerUtils';
import { createDefaultStyle } from '../utils/StyleUtils';
import { removeDuplicateLines } from '../utils/StringUtils';
import { logError } from '../utils/DebugUtils';
-import { isProjectionAvailable } from '../utils/ProjectionUtils';
+import { getCustomTileGridProperties } from '../utils/WMSUtils';
import {getLayerTileMatrixSetsInfo} from '../api/WMTS';
import { getLayerMetadata } from '../api/ArcGIS';
@@ -283,19 +283,7 @@ export default (API) => ({
.catch(() => Rx.Observable.of(null))
)
.switchMap(([results, tileGridData]) => {
- let tileGridProperties = {};
- if (tileGridData) {
- const filteredTileGrids = tileGridData.tileGrids.filter(({ crs }) => isProjectionAvailable(CoordinatesUtils.normalizeSRS(crs)));
- tileGridProperties = tileGridData !== undefined ? {
- tiled: true,
- tileGrids: tileGridData.tileGrids,
- tileGridStrategy: 'custom',
- tileGridCacheSupport: filteredTileGrids?.length > 0 ?
- tileGridData.formats ? {formats: tileGridData.formats} : {}
- : undefined
- } : {};
-
- }
+ const tileGridProperties = tileGridData ? getCustomTileGridProperties(tileGridData) : {};
if (results) {
let description = find(results, (desc) => desc.name === layer.name );
if (description && description.owsType === 'WFS') {
diff --git a/web/client/utils/WMSUtils.js b/web/client/utils/WMSUtils.js
index 120df9aa37..81439c2de4 100644
--- a/web/client/utils/WMSUtils.js
+++ b/web/client/utils/WMSUtils.js
@@ -7,7 +7,8 @@
*/
import { uniq, isObject, castArray } from 'lodash';
import { getAvailableInfoFormat } from "./MapInfoUtils";
-import { normalizeSRS } from "./CoordinatesUtils";
+import CoordinatesUtils, { normalizeSRS } from "./CoordinatesUtils";
+import { isProjectionAvailable } from './ProjectionUtils';
// this list provides the supported GetMap formats
// and it will be used to validate GetMap formats coming from capabilities
@@ -112,3 +113,21 @@ export const getTileGridFromLayerOptions = ({
&& !!((tileGrid.tileSizes?.[0]?.[0] || tileGrid.tileSize?.[0]) === tileSize)
);
};
+
+/**
+ * Return the tileGrids properties like tiled, tileGrids, tileGridCacheSupport and tileGridStrategy
+ * @param {object} tileGridData tile grid object that includes tileGrids array, formats, tileMatrixSets ..etc
+ * @return {object} the needed tile grid properties to appended to the layer object
+ */
+export const getCustomTileGridProperties = (tileGridData) => {
+ const filteredTileGrids = tileGridData.tileGrids.filter(({ crs }) => isProjectionAvailable(CoordinatesUtils.normalizeSRS(crs)));
+ const tileGridProperties = tileGridData !== undefined ? {
+ tiled: true,
+ tileGrids: tileGridData.tileGrids,
+ tileGridStrategy: 'custom',
+ tileGridCacheSupport: filteredTileGrids?.length > 0 ?
+ tileGridData.formats ? {formats: tileGridData.formats} : {}
+ : undefined
+ } : {};
+ return tileGridProperties;
+};
diff --git a/web/client/utils/__tests__/WMSUtils-test.js b/web/client/utils/__tests__/WMSUtils-test.js
index 6c604655d9..1784efd574 100644
--- a/web/client/utils/__tests__/WMSUtils-test.js
+++ b/web/client/utils/__tests__/WMSUtils-test.js
@@ -11,7 +11,8 @@ import {
isValidGetMapFormat,
isValidGetFeatureInfoFormat,
getLayerOptions,
- getTileGridFromLayerOptions
+ getTileGridFromLayerOptions,
+ getCustomTileGridProperties
} from '../WMSUtils';
describe('Test the WMSUtils', () => {
@@ -63,4 +64,36 @@ describe('Test the WMSUtils', () => {
expect(getTileGridFromLayerOptions({ projection: 'EPSG:32122', tileSize: 512, tileGrids })).toBe(tileGrids[0]);
expect(getTileGridFromLayerOptions({ projection: 'EPSG:4326', tileSize: 256, tileGrids })).toBe(undefined);
});
+ it('test getCustomTileGridProperties', () => {
+ const tileGridData = {
+ formats: ['image/jpeg', 'image/png'],
+ tileGrids: [
+ {
+ id: 'EPSG:32122',
+ crs: 'EPSG:32122',
+ scales: [ 2557541.55271451, 1278770.776357255, 639385.3881786275 ],
+ origins: [ [ 403035.4105968763, 414783 ], [ 403035.4105968763, 414783 ], [ 403035.4105968763, 323121 ] ],
+ tileSizes: [[ 512, 512 ], [ 512, 512 ], [ 512, 512 ]]
+ },
+ {
+ id: 'EPSG:900913',
+ crs: 'EPSG:900913',
+ scales: [ 559082263.9508929, 279541131.97544646, 139770565.98772323 ],
+ origin: [ -20037508.34, 20037508 ],
+ tileSize: [ 256, 256 ]
+ }
+ ],
+ tileMatrixSetLinks: [],
+ tileMatrixSets: [],
+ styles: []
+ };
+ expect(getCustomTileGridProperties(tileGridData)).toEqual({
+ tileGrids: tileGridData.tileGrids,
+ tiled: true,
+ tileGridStrategy: 'custom',
+ tileGridCacheSupport: {
+ formats: tileGridData.formats
+ }
+ });
+ });
});