Skip to content

Commit

Permalink
Merge pull request #4800 from rldhont/fix-js-state-map-initialextent-…
Browse files Browse the repository at this point in the history
…zoom

JS Map State: transform initial extent on projection changes
  • Loading branch information
rldhont authored Sep 27, 2024
2 parents a940d7b + c784cf2 commit f361033
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 5 deletions.
25 changes: 20 additions & 5 deletions assets/src/modules/state/Map.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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)) {
Expand Down Expand Up @@ -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'];
Expand Down
11 changes: 11 additions & 0 deletions assets/src/modules/utils/Extent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -76,4 +86,5 @@ export class Extent extends Array {
&& anOther[2] == this[2]
&& anOther[3] == this[3])
}

}
159 changes: 159 additions & 0 deletions tests/js-units/node/state/map.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions tests/js-units/node/utils/extent.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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 () {
Expand Down

2 comments on commit f361033

@3liz-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest weekly run of end2end "playwright" tests failed with this latest commit on the branch release_3_6 😣

CC @nboisteault and @Gustry, please have a look to the logs. Maybe it's a false positive ?

Visit https://github.com/3liz/lizmap-web-client/actions/runs/11098857268

@3liz-bot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latest weekly run of end2end "cypress" tests failed with this latest commit on the branch release_3_6 😣

CC @nboisteault and @Gustry, please have a look to the logs. Maybe it's a false positive ?

Visit https://github.com/3liz/lizmap-web-client/actions/runs/11098857268

Please sign in to comment.