From bdbde7cfd2ba19e878f8aacdb9f9de7d0e735689 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Fri, 25 Aug 2023 09:59:02 +0200 Subject: [PATCH] Ensure default view when map as no data at load --- umap/static/umap/js/umap.forms.js | 2 +- umap/static/umap/js/umap.js | 47 +++++++++++++++++++++++-------- umap/static/umap/test/Map.Init.js | 44 ++++++++++++++++++++++++----- 3 files changed, 73 insertions(+), 20 deletions(-) diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index e3569a2d..c401d56f 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -420,7 +420,7 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({ L.FormBuilder.DefaultView = L.FormBuilder.Select.extend({ selectOptions: [ ['center', L._('Saved center and zoom')], - ['bounds', L._('Layers bounds')], + ['data', L._('Fit all data')], ['latest', L._('Latest feature')], ['locate', L._('User location')], ], diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index fe89d216..77c9431b 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -84,7 +84,6 @@ L.U.Map.include({ geojson.properties.fullscreenControl = false L.Util.setBooleanFromQueryString(geojson.properties, 'scrollWheelZoom') - L.Map.prototype.initialize.call(this, el, geojson.properties) // After calling parent initialize, as we are doing initCenter our-selves @@ -151,7 +150,8 @@ L.U.Map.include({ this.options.slideshow.active === undefined ) this.options.slideshow.active = true - if (this.options.advancedFilterKey) this.options.facetKey = this.options.advancedFilterKey + if (this.options.advancedFilterKey) + this.options.facetKey = this.options.advancedFilterKey // Global storage for retrieving datalayers and features this.datalayers = {} @@ -254,7 +254,11 @@ L.U.Map.include({ if (L.Util.queryString('share')) this.renderShareBox() else if (this.options.onLoadPanel === 'databrowser') this.openBrowser() else if (this.options.onLoadPanel === 'caption') this.displayCaption() - else if (this.options.onLoadPanel === 'facet' || this.options.onLoadPanel === 'datafilters') this.openFacet() + else if ( + this.options.onLoadPanel === 'facet' || + this.options.onLoadPanel === 'datafilters' + ) + this.openFacet() }) this.onceDataLoaded(function () { const slug = L.Util.queryString('feature') @@ -310,7 +314,7 @@ L.U.Map.include({ icon: 'umap-fake-class', iconLoading: 'umap-fake-class', flyTo: this.options.easing, - onLocationError: (err) => this.ui.alert({content: err.message}) + onLocationError: (err) => this.ui.alert({ content: err.message }), }) this._controls.fullscreen = new L.Control.Fullscreen({ title: { false: L._('View Fullscreen'), true: L._('Exit Fullscreen') }, @@ -407,7 +411,11 @@ L.U.Map.include({ if (datalayer.displayedOnLoad()) datalayer.onceDataLoaded(decrementDataToLoad) else decrementDataToLoad() } - if (seen === 0) loaded() && dataLoaded() // no datalayer + if (seen === 0) { + // no datalayer + loaded() + dataLoaded() + } }, indexDatalayers: function () { @@ -634,8 +642,14 @@ L.U.Map.include({ }, _setDefaultCenter: function () { - this.options.center = this.latLng(this.options.center) - this.setView(this.options.center, this.options.zoom) + this.options.center = this.latLng(this.options.center) + this.setView(this.options.center, this.options.zoom) + }, + + hasData: function () { + for (const datalayer of this.datalayers_index) { + if (datalayer.hasData()) return true + } }, initCenter: function () { @@ -645,10 +659,20 @@ L.U.Map.include({ } else if (this.options.defaultView === 'locate' && !this.options.noControl) { this.once('locationerror', this._setDefaultCenter) this._controls.locate.start() - } else if (this.options.defaultView === 'bounds') { - this.onceDataLoaded(() => this.fitBounds(this.getLayersBounds())) + } else if (this.options.defaultView === 'data') { + this.onceDataLoaded(() => { + if (!this.hasData()) { + this._setDefaultCenter() + return + } + this.fitBounds(this.getLayersBounds()) + }) } else if (this.options.defaultView === 'latest') { this.onceDataLoaded(() => { + if (!this.hasData()) { + this._setDefaultCenter() + return + } const datalayer = this.defaultDataLayer(), feature = datalayer.getFeatureByIndex(-1) if (feature) feature.zoomTo() @@ -1409,7 +1433,7 @@ L.U.Map.include({ handler: 'Input', helpEntries: 'facetKey', placeholder: L._('Example: key1,key2,key3'), - label: L._('Facet keys') + label: L._('Facet keys'), }, ], [ @@ -2053,7 +2077,7 @@ L.U.Map.include({ getFacetKeys: function () { return (this.options.facetKey || '').split(',').reduce((acc, curr) => { - const els = curr.split("|") + const els = curr.split('|') acc[els[0]] = els[1] || els[0] return acc }, {}) @@ -2066,5 +2090,4 @@ L.U.Map.include({ }) return bounds }, - }) diff --git a/umap/static/umap/test/Map.Init.js b/umap/static/umap/test/Map.Init.js index 5d57c626..fa10e18a 100644 --- a/umap/static/umap/test/Map.Init.js +++ b/umap/static/umap/test/Map.Init.js @@ -3,14 +3,44 @@ describe('L.U.Map.initialize', function () { resetMap() }) - it("should not show a minimap by default", function () { - this.map = initMap() - assert.notOk(qs('.leaflet-control-minimap')) + describe('Controls', function () { + it('should not show a minimap by default', function () { + this.map = initMap() + assert.notOk(qs('.leaflet-control-minimap')) + }) + + it('should show a minimap', function () { + this.map = initMap({ miniMap: true }) + assert.ok(qs('.leaflet-control-minimap')) + }) }) - it("should show a minimap", function () { - this.map = initMap({ miniMap: true }) - assert.ok(qs('.leaflet-control-minimap')) - }) + describe('DefaultView', function () { + it('should set default view in default mode without data', function (done) { + this.map = initMap({ datalayers: [] }) + // Did not find a better way to wait for tiles to be actually loaded + window.setTimeout(() => { + assert.ok(qs('#map .leaflet-tile-pane img.leaflet-tile.leaflet-tile-loaded')) + done() + }, 1000) + }) + it("should set default view in 'data' mode without data", function (done) { + this.map = initMap({ datalayers: [], defaultView: 'data' }) + // Did not find a better way to wait for tiles to be actually loaded + window.setTimeout(() => { + assert.ok(qs('#map .leaflet-tile-pane img.leaflet-tile.leaflet-tile-loaded')) + done() + }, 1000) + }) + + it("should set default view in 'latest' mode without data", function (done) { + this.map = initMap({ datalayers: [], defaultView: 'latest' }) + // Did not find a better way to wait for tiles to be actually loaded + window.setTimeout(() => { + assert.ok(qs('#map .leaflet-tile-pane img.leaflet-tile.leaflet-tile-loaded')) + done() + }, 1000) + }) + }) })