diff --git a/web/client/actions/__tests__/print-test.js b/web/client/actions/__tests__/print-test.js
index e71105efc0..b2fab7a1ad 100644
--- a/web/client/actions/__tests__/print-test.js
+++ b/web/client/actions/__tests__/print-test.js
@@ -88,6 +88,21 @@ describe('Test correctness of the print actions', () => {
expect(retVal.projection).toBe('EPSG:4326');
expect(retVal.currentLocale).toBe('en-US');
});
+ it('configurePrintMap with useFixedScales', () => {
+ const retVal = configurePrintMap({x: 1, y: 1}, 5, 6, 2.0, [], 'EPSG:4326', 'en-US', true);
+ expect(retVal).toExist();
+ expect(retVal.type).toBe(CONFIGURE_PRINT_MAP);
+ expect(retVal.center).toExist();
+ expect(retVal.center.x).toBe(1);
+ expect(retVal.zoom).toBe(5);
+ expect(retVal.scaleZoom).toBe(6);
+ expect(retVal.scale).toBe(2.0);
+ expect(retVal.layers).toExist();
+ expect(retVal.layers.length).toBe(0);
+ expect(retVal.projection).toBe('EPSG:4326');
+ expect(retVal.currentLocale).toBe('en-US');
+ expect(retVal.useFixedScales).toBe(true);
+ });
it('changePrintZoomLevel', () => {
const retVal = changePrintZoomLevel(5, 10000);
diff --git a/web/client/actions/print.js b/web/client/actions/print.js
index 6c54fbb25b..6467727342 100644
--- a/web/client/actions/print.js
+++ b/web/client/actions/print.js
@@ -132,7 +132,7 @@ export function printTransformerAdded(name) {
};
}
-export function configurePrintMap(center, zoom, scaleZoom, scale, layers, projection, currentLocale) {
+export function configurePrintMap(center, zoom, scaleZoom, scale, layers, projection, currentLocale, useFixedScales) {
return {
type: CONFIGURE_PRINT_MAP,
center,
@@ -141,7 +141,8 @@ export function configurePrintMap(center, zoom, scaleZoom, scale, layers, projec
scale,
layers,
projection,
- currentLocale
+ currentLocale,
+ useFixedScales
};
}
diff --git a/web/client/plugins/Print.jsx b/web/client/plugins/Print.jsx
index 937c75c5c4..42ced98c43 100644
--- a/web/client/plugins/Print.jsx
+++ b/web/client/plugins/Print.jsx
@@ -29,9 +29,9 @@ import { layersSelector } from '../selectors/layers';
import { currentLocaleSelector } from '../selectors/locale';
import { mapSelector, scalesSelector } from '../selectors/map';
import { mapTypeSelector } from '../selectors/maptype';
-import { normalizeSRS, reprojectBbox, convertDegreesToRadian } from '../utils/CoordinatesUtils';
+import { normalizeSRS, convertDegreesToRadian } from '../utils/CoordinatesUtils';
import { getMessageById } from '../utils/LocaleUtils';
-import { defaultGetZoomForExtent, getResolutions, mapUpdated, dpi2dpu, DEFAULT_SCREEN_DPI } from '../utils/MapUtils';
+import { defaultGetZoomForExtent, getResolutions, mapUpdated, dpi2dpu, DEFAULT_SCREEN_DPI, getScales, reprojectZoom } from '../utils/MapUtils';
import { isInsideResolutionsLimits } from '../utils/LayersUtils';
import { has, includes } from 'lodash';
import {additionalLayersSelector} from "../selectors/additionallayers";
@@ -289,7 +289,8 @@ export default {
overrideOptions: PropTypes.object,
items: PropTypes.array,
addPrintParameter: PropTypes.func,
- printingService: PropTypes.object
+ printingService: PropTypes.object,
+ printMap: PropTypes.object
};
static contextTypes = {
@@ -340,7 +341,8 @@ export default {
currentLocale: 'en-US',
overrideOptions: {},
items: [],
- printingService: getDefaultPrintingService()
+ printingService: getDefaultPrintingService(),
+ printMap: {}
};
state = {
@@ -569,34 +571,30 @@ export default {
const {
map: newMap,
capabilities,
- minZoom,
configurePrintMap: configurePrintMapProp,
useFixedScales,
- getZoomForExtent,
- maxZoom,
currentLocale,
- scales: scalesProp,
- layers
+ layers,
+ printMap,
+ printSpec
} = props || this.props;
if (newMap && newMap.bbox && capabilities) {
- const bbox = reprojectBbox([
- newMap.bbox.bounds.minx,
- newMap.bbox.bounds.miny,
- newMap.bbox.bounds.maxx,
- newMap.bbox.bounds.maxy
- ], newMap.bbox.crs, newMap.projection);
- const mapSize = this.getMapSize();
+ const selectedPrintProjection = (printSpec && printSpec?.params?.projection) || (printSpec && printSpec?.projection) || (printMap && printMap.projection) || 'EPSG:3857';
+ const printSrs = normalizeSRS(selectedPrintProjection);
+ const mapProjection = newMap.projection;
+ const mapSrs = normalizeSRS(mapProjection);
+ const zoom = reprojectZoom(newMap.zoom, mapSrs, printSrs);
+ const scales = getPrintScales(capabilities);
+ const printMapScales = getScales(printSrs);
+ const scaleZoom = getNearestZoom(zoom, scales, printMapScales);
if (useFixedScales) {
- const mapZoom = getZoomForExtent(bbox, mapSize, minZoom, maxZoom);
- const scales = getPrintScales(capabilities);
- const scaleZoom = getNearestZoom(newMap.zoom, scales);
const scale = scales[scaleZoom];
- configurePrintMapProp(newMap.center, mapZoom, scaleZoom, scale,
- layers, newMap.projection, currentLocale);
+ configurePrintMapProp(newMap.center, zoom, scaleZoom, scale,
+ layers, newMap.projection, currentLocale, useFixedScales);
} else {
- const scale = scalesProp[newMap.zoom];
- configurePrintMapProp(newMap.center, newMap.zoom, newMap.zoom, scale,
- layers, newMap.projection, currentLocale);
+ const scale = printMapScales[zoom];
+ configurePrintMapProp(newMap.center, zoom, scaleZoom, scale,
+ layers, newMap.projection, currentLocale, useFixedScales);
}
}
};
@@ -629,8 +627,9 @@ export default {
scalesSelector,
(state) => state.browser && (!state.browser.ie || state.browser.ie11),
currentLocaleSelector,
- mapTypeSelector
- ], (open, capabilities, printSpec, pdfUrl, error, map, layers, additionalLayers, scales, usePreview, currentLocale, mapType) => ({
+ mapTypeSelector,
+ (state) => state.print.map
+ ], (open, capabilities, printSpec, pdfUrl, error, map, layers, additionalLayers, scales, usePreview, currentLocale, mapType, printMap) => ({
open,
capabilities,
printSpec,
@@ -650,7 +649,8 @@ export default {
scales,
usePreview,
currentLocale,
- mapType
+ mapType,
+ printMap
}));
const PrintPlugin = connect(selector, {
diff --git a/web/client/plugins/__tests__/Print-test.jsx b/web/client/plugins/__tests__/Print-test.jsx
index c410cc1e8e..440c72a321 100644
--- a/web/client/plugins/__tests__/Print-test.jsx
+++ b/web/client/plugins/__tests__/Print-test.jsx
@@ -202,6 +202,88 @@ describe('Print Plugin', () => {
});
});
+ it('test configuration with useFixedScales and enableScalebox = true', (done) => {
+ const printingService = {
+ getMapConfiguration() {
+ return {
+ layers: [],
+ center: {
+ x: 0,
+ y: 0,
+ crs: "EPSG:4326"
+ }
+ };
+ },
+ validate() { return {};}
+ };
+ getPrintPlugin({
+ state: {...initialState,
+ print: {...initialState.print,
+ capabilities: {...initialState.print.capabilities,
+ scales: [1000000, 500000, 100000].map(value => ({name: value, value}))}
+ }}
+ }).then(async({ Plugin }) => {
+ try {
+ await ReactDOM.render(, document.getElementById("container"));
+ const comp = document.getElementById("container");
+ await ReactTestUtils.act(async() => comp);
+ expect(comp).toExist();
+ const scaleBoxComp = document.querySelector("#mappreview-scalebox select");
+ expect(scaleBoxComp).toExist();
+ done();
+ } catch (ex) {
+ done(ex);
+ }
+ });
+ });
+ it('test configuration with useFixedScales and enableScalebox = false', (done) => {
+ const printingService = {
+ getMapConfiguration() {
+ return {
+ layers: [],
+ center: {
+ x: 0,
+ y: 0,
+ crs: "EPSG:4326"
+ }
+ };
+ },
+ validate() { return {};}
+ };
+ getPrintPlugin({
+ state: {...initialState,
+ print: {...initialState.print,
+ capabilities: {...initialState.print.capabilities,
+ scales: [1000000, 500000, 100000].map(value => ({name: value, value}))}
+ }}
+ }).then(async({ Plugin }) => {
+ try {
+ await ReactDOM.render(, document.getElementById("container"));
+ const comp = document.getElementById("container");
+ await ReactTestUtils.act(async() => comp);
+ expect(comp).toExist();
+ const scaleBoxComp = document.querySelector("#mappreview-scalebox select");
+ expect(scaleBoxComp).toNotExist();
+ done();
+ } catch (ex) {
+ done(ex);
+ }
+ });
+ });
it('default configuration with not allowed layers', (done) => {
getPrintPlugin({
layers: [{visibility: true, type: "bing"}]
diff --git a/web/client/plugins/__tests__/print/Projection-test.jsx b/web/client/plugins/__tests__/print/Projection-test.jsx
index 18d83c751f..eb2959a2cb 100644
--- a/web/client/plugins/__tests__/print/Projection-test.jsx
+++ b/web/client/plugins/__tests__/print/Projection-test.jsx
@@ -24,7 +24,8 @@ const initialState = {
map: {
scale: 1784,
scaleZoom: 2,
- projection: "EPSG:3857"
+ projection: "EPSG:3857",
+ zoom: 3
},
capabilities: {
createURL: "http://fakeservice",
@@ -119,11 +120,12 @@ describe('PrintProjection Plugin', () => {
});
it('map transformer with user chosen crs', (done) => {
- getPrintProjectionPlugin().then(({ Plugin, store }) => {
+ getPrintProjectionPlugin().then(async({ Plugin, store }) => {
try {
- ReactDOM.render(, document.getElementById("container"));
+ const comp = ReactDOM.render(, document.getElementById("container"));
+ await ReactTestUtils.act(async() => comp);
const combo = getByXPath("//select");
- ReactTestUtils.Simulate.change(combo, {
+ await ReactTestUtils.Simulate.change(combo, {
target: {
value: "EPSG:4326"
}
@@ -139,11 +141,12 @@ describe('PrintProjection Plugin', () => {
});
it('validator without allowPreview', (done) => {
- getPrintProjectionPlugin().then(({ Plugin, store }) => {
+ getPrintProjectionPlugin().then(async({ Plugin, store }) => {
try {
- ReactDOM.render(, document.getElementById("container"));
+ const comp = ReactDOM.render(, document.getElementById("container"));
+ await ReactTestUtils.act(async() => comp);
const combo = getByXPath("//select");
- ReactTestUtils.Simulate.change(combo, {
+ await ReactTestUtils.Simulate.change(combo, {
target: {
value: "EPSG:4326"
}
diff --git a/web/client/plugins/print/Projection.jsx b/web/client/plugins/print/Projection.jsx
index 1e5a3f3487..03370c90d2 100644
--- a/web/client/plugins/print/Projection.jsx
+++ b/web/client/plugins/print/Projection.jsx
@@ -8,7 +8,7 @@ import { setPrintParameter } from "../../actions/print";
import printReducer from "../../reducers/print";
import Choice from "../../components/print/Choice";
import { getMessageById } from '../../utils/LocaleUtils';
-import {getScales, reprojectZoom} from "../../utils/MapUtils";
+import {getScales} from "../../utils/MapUtils";
import { getAvailableCRS, normalizeSRS } from '../../utils/CoordinatesUtils';
@@ -16,21 +16,19 @@ export const projectionSelector = (state) => state?.print?.spec?.params?.project
function mapTransformer(state, map) {
const projection = projectionSelector(state);
- const mapProjection = mapProjectionSelector(state);
const srs = normalizeSRS(projection);
+ const scales = getScales(srs);
+ const mapProjection = mapProjectionSelector(state);
const mapSrs = normalizeSRS(mapProjection);
if (srs !== mapSrs) {
- const zoom = reprojectZoom(map.scaleZoom, mapSrs, srs);
- const scales = getScales(srs);
return {
...map,
- zoom: zoom,
- scaleZoom: map.scaleZoom, // the selected value from scale DD
- scale: scales[zoom],
+ scale: scales[map.zoom],
+ zoom: map.zoom >= 1 ? map.zoom - 1 : map.zoom, // for print map preview
projection: srs
};
}
- return map;
+ return {...map, scale: scales[map.zoom], zoom: map.zoom >= 1 ? map.zoom - 1 : map.zoom};
}
const validator = (allowPreview) => (state) => {
@@ -67,15 +65,17 @@ export const Projection = ({
addValidator("projection", "map-preview", validator(allowPreview));
}
}, [allowPreview]);
+ function changeProjection(crs) {
+ onChangeParameter("params.projection", crs);
+ onRefresh();
+ }
useEffect(() => {
if (enabled) {
+ changeProjection(projection);
addMapTransformer("projection", mapTransformer);
}
}, []);
- function changeProjection(crs) {
- onChangeParameter("params.projection", crs);
- onRefresh();
- }
+
return enabled ? (
<>
{
expect(state.map.layers.length).toBe(0);
expect(state.map.projection).toBe('EPSG:4326');
});
+ it('configure print map with useFixedScales = true', () => {
+ const state = print({capabilities: {}, spec: {}}, {
+ type: CONFIGURE_PRINT_MAP,
+ center: {x: 1, y: 1},
+ zoom: 5,
+ scaleZoom: 6,
+ scale: 10000,
+ layers: [],
+ projection: 'EPSG:4326',
+ useFixedScales: true
+ });
+ expect(state.map).toExist();
+ expect(state.map.center).toExist();
+ expect(state.map.center.x).toBe(1);
+ expect(state.map.zoom).toBe(5);
+ expect(state.map.scale).toBe(10000);
+ expect(state.map.layers.length).toBe(0);
+ expect(state.map.projection).toBe('EPSG:4326');
+ expect(state.map.useFixedScales).toBe(true);
+ });
it('configure print map title', () => {
const state = print({capabilities: {}, spec: {}}, {
diff --git a/web/client/reducers/print.js b/web/client/reducers/print.js
index c00fa47ace..a904d391a5 100644
--- a/web/client/reducers/print.js
+++ b/web/client/reducers/print.js
@@ -97,7 +97,8 @@ function print(state = {spec: initialSpec, capabilities: null, map: null, isLoad
scale: action.scale,
layers,
size: action.size ?? state.map?.size,
- projection: action.projection
+ projection: action.projection,
+ useFixedScales: action.useFixedScales
},
error: null
}
@@ -108,7 +109,7 @@ function print(state = {spec: initialSpec, capabilities: null, map: null, isLoad
return assign({}, state, {
map: assign({}, state.map, {
scaleZoom: action.zoom,
- zoom: state.map.zoom + diff,
+ zoom: state.map.zoom + diff >= 0 ? state.map.zoom + diff : 0,
scale: action.scale
})
}
diff --git a/web/client/utils/PrintUtils.js b/web/client/utils/PrintUtils.js
index 0d0d9d10bb..ad56a0722d 100644
--- a/web/client/utils/PrintUtils.js
+++ b/web/client/utils/PrintUtils.js
@@ -9,7 +9,7 @@
import { reproject, getUnits, reprojectGeoJson, normalizeSRS } from './CoordinatesUtils';
import {addAuthenticationParameter} from './SecurityUtils';
-import { calculateExtent, getGoogleMercatorScales, getResolutionsForProjection, getScales, reprojectZoom } from './MapUtils';
+import { calculateExtent, getGoogleMercatorScales, getResolutionsForProjection, getScales } from './MapUtils';
import { optionsToVendorParams } from './VendorParamsUtils';
import { colorToHexStr } from './ColorUtils';
import { getLayerConfig } from './TileConfigProvider';
@@ -236,9 +236,10 @@ export const mapProjectionSelector = (state) => state?.print?.map?.projection ??
export const getMapfishPrintSpecification = (rawSpec, state) => {
const {params, ...baseSpec} = rawSpec;
const spec = {...baseSpec, ...params};
- const mapProjection = mapProjectionSelector(state);
+ const printMap = state?.print?.map;
const projectedCenter = reproject(spec.center, 'EPSG:4326', spec.projection);
- const projectedZoom = Math.round(reprojectZoom(spec.scaleZoom, mapProjection, spec.projection));
+ // * use [spec.zoom] the actual zoom in case useFixedScale = false else use [spec.scaleZoom] the fixed zoom scale not actual
+ const projectedZoom = Math.round(printMap?.useFixedScales ? spec.scaleZoom : spec.zoom);
const scales = spec.scales || getScales(spec.projection);
const reprojectedScale = scales[projectedZoom] || defaultScales[projectedZoom];
diff --git a/web/client/utils/__tests__/PrintUtils-test.js b/web/client/utils/__tests__/PrintUtils-test.js
index ad9d53d65d..b43b0ca26a 100644
--- a/web/client/utils/__tests__/PrintUtils-test.js
+++ b/web/client/utils/__tests__/PrintUtils-test.js
@@ -34,7 +34,7 @@ import { KVP1, REST1 } from '../../test-resources/layers/wmts';
import { poi as TMS110_1 } from '../../test-resources/layers/tms';
import { BasemapAT, NASAGIBS, NLS_CUSTOM_URL, LINZ_CUSTOM_URL } from '../../test-resources/layers/tileprovider';
import { setStore } from '../StateUtils';
-import { getGoogleMercatorScales } from '../MapUtils';
+import { getGoogleMercatorScales, getScales } from '../MapUtils';
const layer = {
url: "http://mygeoserver",
@@ -554,18 +554,51 @@ describe('PrintUtils', () => {
...testSpec,
scaleZoom: 3,
scales: [2000000, 1000000, 500000, 100000, 50000]
+ }, {
+ print: {
+ map: {
+ useFixedScales: true
+ }
+ }
});
expect(printSpec).toExist();
expect(printSpec.pages[0].scale).toBe(100000);
});
- it('getMapfishPrintSpecification with standard scales', () => {
+ it('getMapfishPrintSpecification with standard scales for print map with projection 3857 [google web mercator]', () => {
const printSpec = getMapfishPrintSpecification({
...testSpec,
- scaleZoom: 3
+ zoom: 3
});
expect(printSpec).toExist();
expect(printSpec.pages[0].scale).toBe(getGoogleMercatorScales(0, 21)[3]);
});
+ it('getMapfishPrintSpecification with fixed scales for print map with projection 4326', () => {
+ const projection = 'EPSG:4326';
+ const printSpec = getMapfishPrintSpecification({
+ ...testSpec,
+ projection,
+ scaleZoom: 3,
+ scales: [2000000, 1000000, 500000, 100000, 50000]
+ }, {
+ print: {
+ map: {
+ useFixedScales: true
+ }
+ }
+ });
+ expect(printSpec).toExist();
+ expect(printSpec.pages[0].scale).toBe(100000);
+ });
+ it('getMapfishPrintSpecification with standard scales for print map with projection 4326', () => {
+ const projection = 'EPSG:4326';
+ const printSpec = getMapfishPrintSpecification({
+ ...testSpec,
+ zoom: 3,
+ projection
+ });
+ expect(printSpec).toExist();
+ expect(printSpec.pages[0].scale).toBe(getScales(projection)[3]);
+ });
it('from rgba to rgb', () => {
const rgb = rgbaTorgb("rgba(255, 255, 255, 0.1)");
expect(rgb).toExist();