From f66f6845c793af5af7594a5826214a207675cdca Mon Sep 17 00:00:00 2001 From: rldhont Date: Fri, 27 Sep 2024 16:05:23 +0200 Subject: [PATCH 1/2] JS: Extent add center property --- assets/src/modules/utils/Extent.js | 11 +++++++++++ tests/js-units/node/utils/extent.test.js | 3 +++ 2 files changed, 14 insertions(+) diff --git a/assets/src/modules/utils/Extent.js b/assets/src/modules/utils/Extent.js index b26d162399..a564c30cca 100644 --- a/assets/src/modules/utils/Extent.js +++ b/assets/src/modules/utils/Extent.js @@ -63,6 +63,16 @@ export class Extent extends Array { return this[3]; } + /** + * @type {number[]} + */ + get center() { + return [ + this.xmin + (this.xmax-this.xmin)/2, + this.ymin + (this.ymax-this.ymin)/2 + ]; + } + /** * Checks equality with an other extent or array * @param {Extent|Array} anOther - An other extent or array with 4 values @@ -76,4 +86,5 @@ export class Extent extends Array { && anOther[2] == this[2] && anOther[3] == this[3]) } + } diff --git a/tests/js-units/node/utils/extent.test.js b/tests/js-units/node/utils/extent.test.js index afc2c2d405..d11c4a633c 100644 --- a/tests/js-units/node/utils/extent.test.js +++ b/tests/js-units/node/utils/extent.test.js @@ -15,6 +15,7 @@ describe('Extent', function () { expect(ext.ymin).to.be.eq(-1) expect(ext.xmax).to.be.eq(1) expect(ext.ymax).to.be.eq(1) + expect(ext.center).to.be.deep.eq([0, 0]) ext = new Extent('-2','-2.0','2','2.0') expect(ext.length).to.be.eq(4) @@ -26,6 +27,7 @@ describe('Extent', function () { expect(ext.ymin).to.be.eq(-2) expect(ext.xmax).to.be.eq(2) expect(ext.ymax).to.be.eq(2) + expect(ext.center).to.be.deep.eq([0, 0]) ext = new Extent(...[-1,-1,1,1]) expect(ext.length).to.be.eq(4) @@ -37,6 +39,7 @@ describe('Extent', function () { expect(ext.ymin).to.be.eq(-1) expect(ext.xmax).to.be.eq(1) expect(ext.ymax).to.be.eq(1) + expect(ext.center).to.be.deep.eq([0, 0]) }) it('Equals', function () { From 5e73fd13722ce542c479db9672686b0ad871b9ce Mon Sep 17 00:00:00 2001 From: rldhont Date: Fri, 27 Sep 2024 16:05:55 +0200 Subject: [PATCH 2/2] JS Map State: transform initial extent on projection changes --- assets/src/modules/state/Map.js | 25 +++- tests/js-units/node/state/map.test.js | 159 ++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 5 deletions(-) diff --git a/assets/src/modules/state/Map.js b/assets/src/modules/state/Map.js index 6646d2940d..2101825e89 100644 --- a/assets/src/modules/state/Map.js +++ b/assets/src/modules/state/Map.js @@ -12,7 +12,7 @@ import { convertNumber, convertBoolean } from './../utils/Converters.js'; import { Extent } from './../utils/Extent.js'; import { OptionsConfig } from './../config/Options.js'; import Utils from './../Utils.js'; -import { get as getProjection } from 'ol/proj.js'; +import { get as getProjection, transformExtent } from 'ol/proj.js'; /** * Build scales @@ -153,10 +153,7 @@ export class MapState extends EventDispatcher { this._maxZoom = this._scales.length - 1; this._projection = options.projection.ref; this._initialExtent = new Extent(...(options.initialExtent)); - this._center = [ - this._initialExtent.xmin + (this._initialExtent.xmax-this._initialExtent.xmin)/2, - this._initialExtent.ymin + (this._initialExtent.ymax-this._initialExtent.ymin)/2 - ]; + this._center = this._initialExtent.center; } this._startupFeatures = startupFeatures; @@ -178,6 +175,7 @@ export class MapState extends EventDispatcher { * @fires MapState#map.state.changed */ update(evt) { + const oldProjection = this._projection; let updatedProperties = {}; for (const prop in mapStateProperties) { if (evt.hasOwnProperty(prop)) { @@ -229,6 +227,23 @@ export class MapState extends EventDispatcher { } } } + + // If projection has changed some extents have to be updated + if (updatedProperties.hasOwnProperty('projection') && oldProjection && updatedProperties['projection']) { + const newProjection = updatedProperties['projection'] + // The initial extent + if (this._initialExtent && !this._initialExtent.equals([0,0,0,0])) { + this._initialExtent = new Extent(...(transformExtent(this._initialExtent, oldProjection, newProjection))); + } + // The extent if it has not been yet updated + if (!updatedProperties.hasOwnProperty('extent') && this._extent && !this._extent.equals([0,0,0,0])) { + this._extent = new Extent(...(transformExtent(this._extent, oldProjection, newProjection))); + this._center = this._extent.center; + updatedProperties['extent'] = new Extent(...this._extent); + updatedProperties['center'] = [...this.center]; + } + } + // Dispatch event only if something have changed if (Object.getOwnPropertyNames(updatedProperties).length != 0) { const neededProperties = ['center', 'size', 'extent', 'resolution']; diff --git a/tests/js-units/node/state/map.test.js b/tests/js-units/node/state/map.test.js index 4a9a50ee9e..b5c2466528 100644 --- a/tests/js-units/node/state/map.test.js +++ b/tests/js-units/node/state/map.test.js @@ -261,6 +261,165 @@ describe('MapState', function () { expect(mapStateChangedEvt).to.be.null // event not dispatch }) + it('Transform', function () { + let mapState = new MapState(); + expect(mapState).to.be.instanceOf(MapState) + expect(mapState).to.be.instanceOf(EventDispatcher) + + // Update all properties + mapState.update({ + "type": "map.state.changing", + "projection": "EPSG:3857", + "center": [ + 432082.33132450003, + 5404877.667855 + ], + "zoom": 4, + "size": [ + 1822, + 634 + ], + "extent": [ + 397265.26494544884, + 5392762.398873487, + 466899.3977035512, + 5416992.936836514 + ], + "resolution": 38.218514137268066, + "scaleDenominator": 144447.63855208742, + "pointResolution": 27.673393466176645, + "pointScaleDenominator": 104592.14407328397 + }); + + let mapStateChangedEvt = null + + mapState.addListener(evt => { + mapStateChangedEvt = evt + }, 'map.state.changed'); + + // update projection + mapState.update({ + "type": "map.state.changing", + "projection": "EPSG:4326" + }); + + expect(mapState.projection).to.be.eq('EPSG:4326') + expect(mapState.center).to.be.an('array').that.have.lengthOf(2).that.deep.equal([ + 3.881461622267935, + 43.60729361373798 + ]) + expect(mapState.extent).to.be.instanceOf(Extent).that.have.lengthOf(4).that.deep.equal([ + 3.568694593502878, + 43.52848921560505, + 4.194228651032991, + 43.68609801187091, + ]) + + expect(mapStateChangedEvt).to.not.be.null // event dispatch + expect(mapStateChangedEvt.projection).to.be.eq('EPSG:4326') // the projection has not changed + expect(mapStateChangedEvt.center).to.be.an('array').that.have.lengthOf(2).that.deep.equal([ + 3.881461622267935, + 43.60729361373798 + ]) + expect(mapStateChangedEvt.extent).to.be.an('array').that.have.lengthOf(4).that.deep.equal([ + 3.568694593502878, + 43.52848921560505, + 4.194228651032991, + 43.68609801187091, + ]) + + + const opt = new OptionsConfig({ + "projection": { + "proj4": "+proj=longlat +datum=WGS84 +no_defs", + "ref": "EPSG:4326" + }, + "bbox": [ + "-3.5", + "-1.0", + "3.5", + "1.0" + ], + "mapScales": [ + 10000, + 25000, + 50000, + 100000, + 250000, + 500000 + ], + "minScale": 10000, + "maxScale": 500000, + "initialExtent": [ + -3.5, + -1.0, + 3.5, + 1.0 + ], + "popupLocation": "dock", + "pointTolerance": 25, + "lineTolerance": 10, + "polygonTolerance": 5, + "hideProject": "True", + "tmTimeFrameSize": 10, + "tmTimeFrameType": "seconds", + "tmAnimationFrameLength": 1000, + "datavizLocation": "dock", + "theme": "light", + //"wmsMaxHeight": 3000, + //"wmsMaxWidth": 3000, + //"fixed_scale_overview_map": true, + //"use_native_zoom_levels": false, + //"hide_numeric_scale_value": false, + //"hideGroupCheckbox": false, + //"activateFirstMapTheme": false, + }) + mapState = new MapState(opt); + + // Initial state + expect(mapState.projection).to.be.eq('EPSG:4326') + expect(mapState.center).to.be.an('array').that.have.lengthOf(2).that.deep.equal([ + 0, + 0 + ]) + expect(mapState.extent).to.be.instanceOf(Extent).that.have.lengthOf(4).that.deep.equal([ + 0, + 0, + 0, + 0 + ]) + expect(mapState.initialExtent).to.be.instanceOf(Extent).that.have.lengthOf(4).that.deep.equal([ + -3.5, + -1.0, + 3.5, + 1.0 + ]) + + // update projection + mapState.update({ + "type": "map.state.changing", + "projection": "EPSG:3857" + }); + + expect(mapState.projection).to.be.eq('EPSG:3857') + expect(mapState.center).to.be.an('array').that.have.lengthOf(2).that.deep.equal([ + 0, + 0 + ]) + expect(mapState.extent).to.be.instanceOf(Extent).that.have.lengthOf(4).that.deep.equal([ + 0, + 0, + 0, + 0 + ]) + expect(mapState.initialExtent).to.be.instanceOf(Extent).that.have.lengthOf(4).that.deep.equal([ + -389618.21777645755, + -111325.14286638453, + 389618.21777645755, + 111325.14286638486, + ]) + }) + it('ConversionError && ValidationError', function () { let mapState = new MapState(); expect(mapState).to.be.instanceOf(MapState)