diff --git a/web/client/plugins/Print.jsx b/web/client/plugins/Print.jsx index f9b38ff16e..b3aa9e8fe3 100644 --- a/web/client/plugins/Print.jsx +++ b/web/client/plugins/Print.jsx @@ -11,6 +11,7 @@ import './print/print.css'; import head from 'lodash/head'; import castArray from "lodash/castArray"; import isNil from "lodash/isNil"; +import isEmpty from "lodash/isEmpty"; import PropTypes from 'prop-types'; import React from 'react'; import { PanelGroup, Col, Glyphicon, Grid, Panel, Row } from 'react-bootstrap'; @@ -32,7 +33,7 @@ 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, isEmpty } from 'lodash'; + import {additionalLayersSelector} from "../selectors/additionallayers"; import { MapLibraries } from '../utils/MapTypeUtils'; import FlexBox from '../components/layout/FlexBox'; @@ -315,7 +316,8 @@ export default { getDefaultPrintingService, getLayoutName, getPrintScales, - getNearestZoom + getNearestZoom, + isCompatibleWithSRS } = utilsMod; class Print extends React.Component { static propTypes = { @@ -616,19 +618,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 be79284829..4b5db3c6b0 100644 --- a/web/client/utils/PrintUtils.js +++ b/web/client/utils/PrintUtils.js @@ -33,6 +33,7 @@ import head from "lodash/head"; import isNil from "lodash/isNil"; import get from "lodash/get"; import min from "lodash/min"; +import has from 'lodash/has'; import trimEnd from 'lodash/trimEnd'; import React from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; @@ -1075,7 +1076,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), @@ -1348,7 +1349,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 = { toAbsoluteURL, @@ -1359,5 +1379,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 a1edf77046..113bb12a7a 100644 --- a/web/client/utils/__tests__/PrintUtils-test.js +++ b/web/client/utils/__tests__/PrintUtils-test.js @@ -18,6 +18,7 @@ import { getMapPrintScale, getMapfishPrintSpecification, rgbaTorgb, + isCompatibleWithSRS, specCreators, addTransformer, addMapTransformer, @@ -821,6 +822,90 @@ describe('PrintUtils', () => { }); + 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('specCreators', () => { describe('opacity', () => { const testBase = { @@ -983,8 +1068,8 @@ describe('PrintUtils', () => { expect(layerSpec.type).toEqual("tms"); expect(layerSpec.format).toExist(); // baseURL should not have version in URL - expect(layerSpec.baseURL).toEqual(encodeURI(testLayer.tileMapService).split("/1.0.0")[0]); - expect(layerSpec.layer).toEqual(testLayer.tileMapUrl.split("/1.0.0/")[1]); + expect(layerSpec.baseURL).toEqual(decodeURIComponent(testLayer.tileMapService).split("/1.0.0")[0]); + expect(layerSpec.layer).toEqual(decodeURIComponent(testLayer.tileMapUrl.split("/1.0.0/")[1])); expect(layerSpec.tileSize).toEqual(testLayer.tileSize); expect(layerSpec).toExist(); expect(layerSpec.resolutions.length).toEqual(testLayer.tileSets.length);