diff --git a/web/client/plugins/Print.jsx b/web/client/plugins/Print.jsx index 14277d54c9f..7acaeaa76c8 100644 --- a/web/client/plugins/Print.jsx +++ b/web/client/plugins/Print.jsx @@ -32,7 +32,6 @@ import { normalizeSRS, convertDegreesToRadian } from '../utils/CoordinatesUtils' import { getMessageById } from '../utils/LocaleUtils'; import { defaultGetZoomForExtent, getResolutions, mapUpdated, dpi2dpu, DEFAULT_SCREEN_DPI, getScales, reprojectZoom } from '../utils/MapUtils'; import { getDerivedLayersVisibility, isInsideResolutionsLimits } from '../utils/LayersUtils'; -import { has, includes } from 'lodash'; import {additionalLayersSelector} from "../selectors/additionallayers"; import { MapLibraries } from '../utils/MapTypeUtils'; import FlexBox from '../components/layout/FlexBox'; @@ -295,7 +294,8 @@ export default { getDefaultPrintingService, getLayoutName, getPrintScales, - getNearestZoom + getNearestZoom, + isCompatibleWithSRS } = utilsMod; class Print extends React.Component { static propTypes = { @@ -587,19 +587,9 @@ export default { addParameter = (name, value) => { this.props.addPrintParameter("params." + name, value); }; - isCompatibleWithSRS = (projection, layer) => { - return projection === "EPSG:3857" || includes([ - "wms", - "wfs", - "vector", - "graticule", - "empty", - "arcgis" - ], layer.type) || layer.type === "wmts" && has(layer.allowedSRS, projection); - }; isAllowed = (layer, projection) => { return this.props.ignoreLayers.indexOf(layer.type) === -1 && - this.isCompatibleWithSRS(normalizeSRS(projection), layer); + isCompatibleWithSRS(normalizeSRS(projection), layer); }; isBackgroundIgnored = (layers, projection) => { diff --git a/web/client/utils/PrintUtils.js b/web/client/utils/PrintUtils.js index dbd94c34023..2f7e0723fac 100644 --- a/web/client/utils/PrintUtils.js +++ b/web/client/utils/PrintUtils.js @@ -34,6 +34,7 @@ import isNil from "lodash/isNil"; import get from "lodash/get"; import min from "lodash/min"; import trimEnd from 'lodash/trimEnd'; +import has from 'lodash/has'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { toPng } from 'html-to-image'; @@ -1049,7 +1050,7 @@ export const specCreators = { map: (layer) => { // layer.tileMapService is like tileMapUrl, but with the layer name in the tail. // e.g. "https://server.org/gwc/service/tms/1.0.0" - "https://server.org/gwc/service/tms/1.0.0/workspace%3Alayer@EPSG%3A3857@png" - const layerName = layer.tileMapUrl.split(layer.tileMapService + "/")[1]; + const layerName = decodeURIComponent(layer.tileMapUrl.split(layer.tileMapService + "/")[1]); return { type: 'tms', opacity: getOpacity(layer), @@ -1322,6 +1323,26 @@ export const getOlDefaultStyle = (layer, styleType) => { } } }; +/** + * check compatibility between layer options and print projection + * @param {string} projection the projection code, e.g. EPSG:3857 + * @param {object} layer the layer options + * @returns {boolean} if layer is compatible with CRS selected for printing +*/ +export const isCompatibleWithSRS = (projection, layer) => { + const isProjectionCompatible = projection === "EPSG:3857"; + const isValidType = includes([ + "tms", // #10734 added tms among valid types to be printed + "wms", + "wfs", + "vector", + "graticule", + "empty", + "arcgis" + ], layer?.type); + const isValidWMTS = layer?.type === "wmts" && has(layer.allowedSRS, projection); + return isProjectionCompatible || isValidType || isValidWMTS; +}; PrintUtils = { @@ -1333,5 +1354,6 @@ PrintUtils = { toOpenLayers2Style, toOpenLayers2TextStyle, getWMTSMatrixIds, - getOlDefaultStyle + getOlDefaultStyle, + isCompatibleWithSRS }; diff --git a/web/client/utils/__tests__/PrintUtils-test.js b/web/client/utils/__tests__/PrintUtils-test.js index 72dfdd91201..8df847b6620 100644 --- a/web/client/utils/__tests__/PrintUtils-test.js +++ b/web/client/utils/__tests__/PrintUtils-test.js @@ -17,6 +17,7 @@ import { getNearestZoom, getMapfishPrintSpecification, rgbaTorgb, + isCompatibleWithSRS, specCreators, addTransformer, addMapTransformer, @@ -1223,6 +1224,90 @@ describe('PrintUtils', () => { expect(reqLayersCreditTxt).toEqual('OSM Simple Light Rendering GeoSolutions Data © OpenStreetMap contributors, ODbL | Attribution layer 02 | Attribution layer 03 @ polygon layer'); }); }); + it("test isCompatibleWithSRS", () => { + const prj3857 = "EPSG:3857"; + const prj4326 = "EPSG:4326"; + const tests = [{ + args: { + projection: prj3857, + layer: undefined + }, + result: true + }, + { + args: { + projection: undefined, + layer: {type: "wms"} + }, + result: true + }, + { + args: { + projection: undefined, + layer: {type: "wfs"} + }, + result: true + }, + { + args: { + projection: undefined, + layer: {type: "vector"} + }, + result: true + }, + { + args: { + projection: undefined, + layer: {type: "graticule"} + }, + result: true + }, + { + args: { + projection: undefined, + layer: {type: "empty"} + }, + result: true + }, + { + args: { + projection: undefined, + layer: {type: "arcgis"} + }, + result: true + }, + { + args: { + projection: prj4326, + layer: {type: "tms"} + }, + result: true + }, + { + args: { + projection: prj4326, + layer: {type: "incompatible"} + }, + result: false + }, + { + args: { + projection: prj4326, + layer: {type: "wmts"} + }, + result: false + }, { + args: { + projection: prj4326, + layer: {type: "wmts", allowedSRS: {"EPSG:4326": {}}} + }, + result: true + }]; + tests.forEach(({args, result}) => { + let res = isCompatibleWithSRS(args.projection, args.layer); + expect(res).toBe(result); + }); + }); }); describe('renderVectorLegendToBase64', () => { let toPngSpy;