From ec9d5a78a7b606a340a81e0c874404fc38f263ef Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Mon, 12 Dec 2016 14:46:14 +0100 Subject: [PATCH] Add action to change map scales (#1344) --- web/client/actions/__tests__/map-test.js | 11 ++++ web/client/actions/map.js | 9 +++ web/client/reducers/__tests__/map-test.js | 70 +++++++++++++++++++++++ web/client/reducers/map.js | 33 ++++++++++- 4 files changed, 121 insertions(+), 2 deletions(-) diff --git a/web/client/actions/__tests__/map-test.js b/web/client/actions/__tests__/map-test.js index 2acbc70d56..471a98d130 100644 --- a/web/client/actions/__tests__/map-test.js +++ b/web/client/actions/__tests__/map-test.js @@ -13,6 +13,7 @@ var { CHANGE_MOUSE_POINTER, CHANGE_ZOOM_LVL, CHANGE_MAP_CRS, + CHANGE_MAP_SCALES, CHANGE_MAP_STYLE, CHANGE_ROTATION, changeMapView, @@ -20,6 +21,7 @@ var { changeMousePointer, changeZoomLevel, changeMapCrs, + changeMapScales, changeMapStyle, changeRotation } = require('../map'); @@ -79,6 +81,15 @@ describe('Test correctness of the map actions', () => { expect(retval.crs).toBe(testVal); }); + it('changeMapScales', () => { + const testScales = [100000, 50000, 25000, 10000, 5000]; + const retval = changeMapScales(testScales); + + expect(retval).toExist(); + expect(retval.type).toBe(CHANGE_MAP_SCALES); + expect(retval.scales).toEqual(testScales); + }); + it('changeMapStyle', () => { let style = {width: 100}; let mapStateSource = "test"; diff --git a/web/client/actions/map.js b/web/client/actions/map.js index 1819e3f6b7..6a7508334a 100644 --- a/web/client/actions/map.js +++ b/web/client/actions/map.js @@ -13,6 +13,7 @@ const CHANGE_ZOOM_LVL = 'CHANGE_ZOOM_LVL'; const PAN_TO = 'PAN_TO'; const ZOOM_TO_EXTENT = 'ZOOM_TO_EXTENT'; const CHANGE_MAP_CRS = 'CHANGE_MAP_CRS'; +const CHANGE_MAP_SCALES = 'CHANGE_MAP_SCALES'; const CHANGE_MAP_STYLE = 'CHANGE_MAP_STYLE'; const CHANGE_ROTATION = 'CHANGE_ROTATION'; @@ -36,6 +37,12 @@ function changeMapCrs(crs) { }; } +function changeMapScales(scales) { + return { + type: CHANGE_MAP_SCALES, + scales: scales + }; +} function clickOnMap(point) { return { @@ -97,6 +104,7 @@ module.exports = { PAN_TO, ZOOM_TO_EXTENT, CHANGE_MAP_CRS, + CHANGE_MAP_SCALES, CHANGE_MAP_STYLE, CHANGE_ROTATION, changeMapView, @@ -104,6 +112,7 @@ module.exports = { changeMousePointer, changeZoomLevel, changeMapCrs, + changeMapScales, zoomToExtent, panTo, changeMapStyle, diff --git a/web/client/reducers/__tests__/map-test.js b/web/client/reducers/__tests__/map-test.js index b9ccac11e0..d6f211bc6e 100644 --- a/web/client/reducers/__tests__/map-test.js +++ b/web/client/reducers/__tests__/map-test.js @@ -81,6 +81,76 @@ describe('Test the map reducer', () => { expect(state.projection).toBe('EPSG:4326'); }); + it('sets new map scales', () => { + // set map scales + const action = { + type: 'CHANGE_MAP_SCALES', + scales: [9600, 960] + }; + const resolutions = [2.54, 0.254]; + const action2 = { + type: 'CHANGE_MAP_SCALES', + scales: [38400, 19200, 9600, 4800] + }; + const resolutions2 = [10.16, 5.08, 2.54, 1.27]; + // reset map scales + const actionReset = { + type: 'CHANGE_MAP_SCALES' + }; + + // add map scales + var state = mapConfig({projection: "EPSG:3857"}, action); + expect(state.mapOptions).toExist(); + expect(state.mapOptions.view).toExist(); + expect(state.mapOptions.view.resolutions).toEqual(resolutions); + expect(state.projection).toBe("EPSG:3857"); + + // update map scales + state = mapConfig(state, action2); + expect(state.mapOptions).toExist(); + expect(state.mapOptions.view).toExist(); + expect(state.mapOptions.view.resolutions).toEqual(resolutions2); + + // remove state.mapOptions on map scales reset + state = mapConfig({ + mapOptions: { + view: { + resolutions: [8, 4, 2] + } + }, + prop: 'prop' + }, actionReset); + expect(state.mapOptions).toNotExist(); + expect(state.prop).toBe('prop'); + + // remove only state.mapOptions.view on map scales reset + state = mapConfig({ + mapOptions: { + view: { + resolutions: [8, 4, 2] + }, + prop: 'prop' + } + }, actionReset); + expect(state.mapOptions).toExist(); + expect(state.mapOptions.view).toNotExist(); + expect(state.mapOptions.prop).toBe('prop'); + + // remove only state.mapOptions.view.resolutions on map scales reset + state = mapConfig({ + mapOptions: { + view: { + resolutions: [8, 4, 2], + prop: 'prop' + } + } + }, actionReset); + expect(state.mapOptions).toExist(); + expect(state.mapOptions.view).toExist(); + expect(state.mapOptions.view.resolutions).toNotExist(); + expect(state.mapOptions.view.prop).toBe('prop'); + }); + it('zoom to extent', () => { const action = { type: 'ZOOM_TO_EXTENT', diff --git a/web/client/reducers/map.js b/web/client/reducers/map.js index d284e22686..913b24b63a 100644 --- a/web/client/reducers/map.js +++ b/web/client/reducers/map.js @@ -7,8 +7,8 @@ */ var {CHANGE_MAP_VIEW, CHANGE_MOUSE_POINTER, - CHANGE_ZOOM_LVL, CHANGE_MAP_CRS, ZOOM_TO_EXTENT, PAN_TO, CHANGE_MAP_STYLE, - CHANGE_ROTATION} = require('../actions/map'); + CHANGE_ZOOM_LVL, CHANGE_MAP_CRS, CHANGE_MAP_SCALES, ZOOM_TO_EXTENT, PAN_TO, + CHANGE_MAP_STYLE, CHANGE_ROTATION} = require('../actions/map'); var assign = require('object-assign'); @@ -33,6 +33,35 @@ function mapConfig(state = null, action) { return assign({}, state, { projection: action.crs }); + case CHANGE_MAP_SCALES: + if (action.scales) { + const dpi = state.mapOptions && state.mapOptions.view && state.mapOptions.view.DPI || null; + const resolutions = MapUtils.getResolutionsForScales(action.scales, state.projection || "EPSG:4326", dpi); + // add or update mapOptions.view.resolutions + let mapOptions = assign({}, state.mapOptions); + mapOptions.view = assign({}, mapOptions.view, { + resolutions: resolutions + }); + return assign({}, state, { + mapOptions: mapOptions + }); + } else if (state.mapOptions && state.mapOptions.view && state.mapOptions.view && state.mapOptions.view.resolutions) { + // deeper clone + let newState = assign({}, state); + newState.mapOptions = assign({}, newState.mapOptions); + newState.mapOptions.view = assign({}, newState.mapOptions.view); + // remove resolutions + delete newState.mapOptions.view.resolutions; + // cleanup state + if (Object.keys(newState.mapOptions.view).length === 0) { + delete newState.mapOptions.view; + } + if (Object.keys(newState.mapOptions).length === 0) { + delete newState.mapOptions; + } + return newState; + } + return state; case ZOOM_TO_EXTENT: { let zoom = 0; let bounds = CoordinatesUtils.reprojectBbox(action.extent, action.crs, state.bbox && state.bbox.crs || "EPSG:4326");