From 322c9fe0426426d37652f192aa8e38f169799b11 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Thu, 10 Aug 2023 09:46:17 +0200 Subject: [PATCH 1/2] Make fromZoom and toZoom options available for all layers fix #473 --- umap/static/umap/js/umap.forms.js | 6 ++++ umap/static/umap/js/umap.layer.js | 56 ++++++++++++++++++++---------- umap/static/umap/test/DataLayer.js | 22 ++++++++++++ 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 19f6ad90..d6fdf2c7 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -1096,6 +1096,12 @@ L.U.FormBuilder = L.FormBuilder.extend({ handler: 'ControlChoice', label: L._('Display the star map button'), }, + fromZoom: { + handler: 'IntInput', + label: L._('From zoom'), + helpText: L._('Optional.'), + }, + toZoom: { handler: 'IntInput', label: L._('To zoom'), helpText: L._('Optional.') }, }, initialize: function (obj, fields, options) { diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index 27129f4a..c9a352fc 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -237,11 +237,31 @@ L.U.DataLayer = L.Evented.extend({ this.connectToMap() if (this.displayedOnLoad()) this.show() if (!this.umap_id) this.isDirty = true + + // Retrocompat + if (this.options.remoteData && this.options.remoteData.from) { + this.options.fromZoom = this.options.remoteData.from + } + if (this.options.remoteData && this.options.remoteData.to) { + this.options.toZoom = this.options.remoteData.to + } + this.onceLoaded(function () { - this.map.on('moveend', this.fetchRemoteData, this) + this.map.on('moveend', this.onMoveEnd, this) + this.map.on('zoomend', this.onZoomEnd, this) }) }, + onMoveEnd: function (e) { + if (this.isRemoteLayer()) this.fetchRemoteData() + }, + + onZoomEnd: function (e) { + if (this._forcedVisibility) return + if (!this.showAtZoom() && this.isVisible()) this.hide() + if (this.showAtZoom() && !this.isVisible()) this.show() + }, + displayedOnLoad: function () { return ( (this.map.datalayersOnLoad && @@ -335,6 +355,7 @@ L.U.DataLayer = L.Evented.extend({ this.backupData() this._geojson = null } + this.fire('datachanged') }, backupData: function () { @@ -351,17 +372,16 @@ L.U.DataLayer = L.Evented.extend({ } }, + showAtZoom: function () { + const from = parseInt(this.options.fromZoom, 10), + to = parseInt(this.options.toZoom, 10), + zoom = this.map.getZoom() + return !((!isNaN(from) && zoom < from) || (!isNaN(to) && zoom > to)) + }, + fetchRemoteData: function () { if (!this.isRemoteLayer()) return - const from = parseInt(this.options.remoteData.from, 10), - to = parseInt(this.options.remoteData.to, 10) - if ( - (!isNaN(from) && this.map.getZoom() < from) || - (!isNaN(to) && this.map.getZoom() > to) - ) { - this.clear() - return - } + if (!this.showAtZoom()) return if (!this.options.remoteData.dynamic && this.hasDataLoaded()) return if (!this.isVisible()) return let url = this.map.localizeUrl(this.options.remoteData.url) @@ -840,6 +860,8 @@ L.U.DataLayer = L.Evented.extend({ 'options.smoothFactor', 'options.dashArray', 'options.zoomTo', + 'options.fromZoom', + 'options.toZoom', 'options.labelKey', ] @@ -880,11 +902,8 @@ L.U.DataLayer = L.Evented.extend({ { handler: 'Url', label: L._('Url'), helpEntries: 'formatURL' }, ], ['options.remoteData.format', { handler: 'DataFormat', label: L._('Format') }], - [ - 'options.remoteData.from', - { label: L._('From zoom'), helpText: L._('Optional.') }, - ], - ['options.remoteData.to', { label: L._('To zoom'), helpText: L._('Optional.') }], + 'options.fromZoom', + 'options.toZoom', [ 'options.remoteData.dynamic', { handler: 'Switch', label: L._('Dynamic'), helpEntries: 'dynamicRemoteData' }, @@ -976,9 +995,7 @@ L.U.DataLayer = L.Evented.extend({ buildVersionsFieldset: function (container) { const appendVersion = function (data) { const date = new Date(parseInt(data.at, 10)) - const content = `${date.toLocaleString(L.lang)} (${ - parseInt(data.size) / 1000 - }Kb)` + const content = `${date.toLocaleString(L.lang)} (${parseInt(data.size) / 1000}Kb)` const el = L.DomUtil.create('div', 'umap-datalayer-version', versionsContainer) const a = L.DomUtil.create('a', '', el) L.DomUtil.add('span', '', el, content) @@ -1041,6 +1058,9 @@ L.U.DataLayer = L.Evented.extend({ }, toggle: function () { + // From now on, do not try to how/hide + // automatically this layer. + this._forcedVisibility = true if (!this.isVisible()) this.show() else this.hide() }, diff --git a/umap/static/umap/test/DataLayer.js b/umap/static/umap/test/DataLayer.js index 75d32b16..59d9b1ad 100644 --- a/umap/static/umap/test/DataLayer.js +++ b/umap/static/umap/test/DataLayer.js @@ -432,4 +432,26 @@ describe('L.U.DataLayer', function () { }) }) + describe('#zoomEnd', function () { + it('should honour the fromZoom option', function () { + this.map.setZoom(6, {animate: false}) + assert.ok(qs('path[fill="none"]')) + this.datalayer.options.fromZoom = 6 + this.map.setZoom(5, {animate: false}) + assert.notOk(qs('path[fill="none"]')) + this.map.setZoom(6, {animate: false}) + assert.ok(qs('path[fill="none"]')) + }) + + it('should honour the toZoom option', function () { + this.map.setZoom(6, {animate: false}) + assert.ok(qs('path[fill="none"]')) + this.datalayer.options.toZoom = 6 + this.map.setZoom(7, {animate: false}) + assert.notOk(qs('path[fill="none"]')) + this.map.setZoom(6, {animate: false}) + assert.ok(qs('path[fill="none"]')) + }) + }) + }) From c0dd8901e4da4024d6f8226764d5ff6a7a5a5875 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Tue, 15 Aug 2023 07:57:38 +0200 Subject: [PATCH 2/2] More readable check from DataLayer.showAtZoom --- umap/static/umap/js/umap.layer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/umap/static/umap/js/umap.layer.js b/umap/static/umap/js/umap.layer.js index c9a352fc..09317e7e 100644 --- a/umap/static/umap/js/umap.layer.js +++ b/umap/static/umap/js/umap.layer.js @@ -376,7 +376,8 @@ L.U.DataLayer = L.Evented.extend({ const from = parseInt(this.options.fromZoom, 10), to = parseInt(this.options.toZoom, 10), zoom = this.map.getZoom() - return !((!isNaN(from) && zoom < from) || (!isNaN(to) && zoom > to)) + if (isNaN(from) || isNaN(to)) return false + return (zoom >= from && zoom <= to) }, fetchRemoteData: function () {