Skip to content

Commit

Permalink
#10487: Custom Tile Grids settings for WMS service are not retained w…
Browse files Browse the repository at this point in the history
…hen adding a Background layer from Catalog (#10490)
  • Loading branch information
mahmoudadel54 authored Aug 2, 2024
1 parent d2bee6c commit 574bafc
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 21 deletions.
206 changes: 206 additions & 0 deletions web/client/epics/__tests__/backgroundselector-test.js
Original file line number Diff line number Diff line change
@@ -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 = `<?xml version="1.0" encoding="UTF-8"?>
<Capabilities xmlns="http://www.opengis.net/wmts/1.0" xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gml="http://www.opengis.net/gml" xsi:schemaLocation="http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd" version="1.0.0">
<Contents>
<Layer>
<Title/>
<Abstract/>
<!--Limited list of EPSG projections:-->
<BoundingBox CRS="CRS:84" minx="-124.73142200000001" miny="-43.648056" maxx="148.47914100000003" maxy="49.371735"/>
<Layer queryable="1" opaque="0">
<Name>states_test</Name>
<Title>states_test</Title>
<Abstract>states_test</Abstract>
<KeywordList>
<Keyword>features</Keyword>
<Keyword>states</Keyword>
</KeywordList>
<CRS>EPSG:4326</CRS>
<CRS>CRS:84</CRS>
<EX_GeographicBoundingBox>
<westBoundLongitude>-124.73142200000001</westBoundLongitude>
<eastBoundLongitude>-66.969849</eastBoundLongitude>
<southBoundLatitude>24.955967</southBoundLatitude>
<northBoundLatitude>49.371735</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="CRS:84" minx="-124.73142200000001" miny="24.955967" maxx="-66.969849" maxy="49.371735"/>
<BoundingBox CRS="EPSG:4326" minx="24.955967" miny="-124.73142200000001" maxx="49.371735" maxy="-66.969849"/>
<Style>
<Name>polygon</Name>
<Title>A boring default style</Title>
<Abstract>A sample style that just prints out a transparent red interior with a red outline</Abstract>
<LegendURL width="20" height="20">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://gs-stable.geo-solutions.it/geoserver/topp/ows?service=WMS&amp;request=GetLegendGraphic&amp;format=image%2Fpng&amp;width=20&amp;height=20&amp;layer=states_test"/>
</LegendURL>
</Style>
<Format>image/png</Format>
<Format>image/jpeg</Format>
<Format>image/png8</Format>
</Layer>
</Layer>
</Contents>
</Capabilities>`;

const capabilitiesWMTSXmlResponse = `<?xml version="1.0" encoding="UTF-8"?><WMS_Capabilities version="1.3.0" updateSequence="5167" xmlns="http://www.opengis.net/wms" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wms http://gs-stable.geo-solutions.it/geoserver/schemas/wms/1.3.0/capabilities_1_3_0.xsd">
<Capability>
<Layer>
<Title/>
<Abstract/>
<!--Limited list of EPSG projections:-->
<BoundingBox CRS="CRS:84" minx="-124.73142200000001" miny="-43.648056" maxx="148.47914100000003" maxy="49.371735"/>
<Layer queryable="1" opaque="0">
<Name>states_test</Name>
<Title>states_test</Title>
<Abstract>states_test</Abstract>
<KeywordList>
<Keyword>features</Keyword>
<Keyword>states</Keyword>
</KeywordList>
<CRS>EPSG:4326</CRS>
<CRS>CRS:84</CRS>
<EX_GeographicBoundingBox>
<westBoundLongitude>-124.73142200000001</westBoundLongitude>
<eastBoundLongitude>-66.969849</eastBoundLongitude>
<southBoundLatitude>24.955967</southBoundLatitude>
<northBoundLatitude>49.371735</northBoundLatitude>
</EX_GeographicBoundingBox>
<BoundingBox CRS="CRS:84" minx="-124.73142200000001" miny="24.955967" maxx="-66.969849" maxy="49.371735"/>
<BoundingBox CRS="EPSG:4326" minx="24.955967" miny="-124.73142200000001" maxx="49.371735" maxy="-66.969849"/>
<Style>
<Name>polygon</Name>
<Title>A boring default style</Title>
<Abstract>A sample style that just prints out a transparent red interior with a red outline</Abstract>
<LegendURL width="20" height="20">
<Format>image/png</Format>
<OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:type="simple" xlink:href="http://gs-stable.geo-solutions.it/geoserver/topp/ows?service=WMS&amp;request=GetLegendGraphic&amp;format=image%2Fpng&amp;width=20&amp;height=20&amp;layer=states_test"/>
</LegendURL>
</Style>
</Layer>
</Layer>
</Capability>
</WMS_Capabilities>`;
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();
}, {});
});
});
20 changes: 15 additions & 5 deletions web/client/epics/backgroundselector.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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;
Expand Down
16 changes: 2 additions & 14 deletions web/client/epics/catalog.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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') {
Expand Down
21 changes: 20 additions & 1 deletion web/client/utils/WMSUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
};
35 changes: 34 additions & 1 deletion web/client/utils/__tests__/WMSUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
isValidGetMapFormat,
isValidGetFeatureInfoFormat,
getLayerOptions,
getTileGridFromLayerOptions
getTileGridFromLayerOptions,
getCustomTileGridProperties
} from '../WMSUtils';

describe('Test the WMSUtils', () => {
Expand Down Expand Up @@ -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
}
});
});
});

0 comments on commit 574bafc

Please sign in to comment.