From d008bc75396cf377ced6500701dadff4568f1f28 Mon Sep 17 00:00:00 2001 From: Yohan Boniface Date: Sat, 12 Aug 2023 07:39:13 +0200 Subject: [PATCH] Better control of default view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix #40 Let the user choose the map behaviour to define default view: - saved center and zoom: current behaviour, and default - bounds: will compute the view to fit all the map data, useful for having the same view in different sized devices (mobile…) - latest feature: useful in some situation, where the map tracks some progress (travel…), this will certainly needs a bit more iterations, mainly to have an explicit default datalayer - user location: this option used to exist but was then removed, I can remember when and why Note: when there is a URL hash, the hash will be used --- umap/static/umap/js/umap.forms.js | 17 ++++++++-- umap/static/umap/js/umap.js | 52 ++++++++++++++++++++----------- 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/umap/static/umap/js/umap.forms.js b/umap/static/umap/js/umap.forms.js index 19f6ad90..98ab44e1 100644 --- a/umap/static/umap/js/umap.forms.js +++ b/umap/static/umap/js/umap.forms.js @@ -417,7 +417,16 @@ L.FormBuilder.DataLayerSwitcher = L.FormBuilder.Select.extend({ }, }) -L.FormBuilder.onLoadPanel = L.FormBuilder.Select.extend({ +L.FormBuilder.DefaultView = L.FormBuilder.Select.extend({ + selectOptions: [ + ['center', L._('Saved center and zoom')], + ['bounds', L._('Layers bounds')], + ['latest', L._('Latest feature')], + ['locate', L._('User location')], + ], +}) + +L.FormBuilder.OnLoadPanel = L.FormBuilder.Select.extend({ selectOptions: [ ['none', L._('None')], ['caption', L._('Caption')], @@ -1008,9 +1017,13 @@ L.U.FormBuilder = L.FormBuilder.extend({ label: L._('Do you want to display the scale control?'), }, onLoadPanel: { - handler: 'onLoadPanel', + handler: 'OnLoadPanel', label: L._('Do you want to display a panel on load?'), }, + defaultView: { + handler: 'DefaultView', + label: L._('Default view'), + }, displayPopupFooter: { handler: 'Switch', label: L._('Do you want to display popup footer?'), diff --git a/umap/static/umap/js/umap.js b/umap/static/umap/js/umap.js index f9926541..10f82db3 100644 --- a/umap/static/umap/js/umap.js +++ b/umap/static/umap/js/umap.js @@ -144,18 +144,6 @@ L.U.Map.include({ // Certainly IE8, which has a limited version of defineProperty } - if (this.options.hash) this.addHash() - this.initCenter() - this.handleLimitBounds() - - this.initTileLayers(this.options.tilelayers) - - // Global storage for retrieving datalayers and features - this.datalayers = {} - this.datalayers_index = [] - this.dirty_datalayers = [] - this.features_index = {} - // Retrocompat if ( this.options.slideshow && @@ -164,9 +152,17 @@ L.U.Map.include({ ) this.options.slideshow.active = true - this.initControls() + // Global storage for retrieving datalayers and features + this.datalayers = {} + this.datalayers_index = [] + this.dirty_datalayers = [] + this.features_index = {} - // create datalayers + if (this.options.hash) this.addHash() + this.initControls() + this.initCenter() + this.handleLimitBounds() + this.initTileLayers(this.options.tilelayers) this.initDatalayers() if (this.options.displayCaptionOnLoad) { @@ -636,10 +632,16 @@ L.U.Map.include({ if (this.options.hash && this._hash.parseHash(location.hash)) { // FIXME An invalid hash will cause the load to fail this._hash.update() - } else if (this.options.locate && this.options.locate.setView) { - // Prevent from making two setViews at init - // which is not very fluid... - this.locate(this.options.locate) + } else if (this.options.defaultView === 'locate' && !this.options.noControl) { + this._controls.locate.start() + } else if (this.options.defaultView === 'bounds') { + this.onceDataLoaded(() => this.fitBounds(this.getLayersBounds())) + } else if (this.options.defaultView === 'latest') { + this.onceDataLoaded(() => { + const datalayer = this.defaultDataLayer(), + feature = datalayer.getFeatureByIndex(-1) + if (feature) feature.zoomTo() + }) } else { this.options.center = this.latLng(this.options.center) this.setView(this.options.center, this.options.zoom) @@ -1036,6 +1038,7 @@ L.U.Map.include({ 'miniMap', 'displayPopupFooter', 'onLoadPanel', + 'defaultView', 'tilelayersControl', 'name', 'description', @@ -1273,6 +1276,9 @@ L.U.Map.include({ } }, + // TODO: allow to control the default datalayer + // (edit and viewing) + // cf https://github.com/umap-project/umap/issues/585 defaultDataLayer: function () { let datalayer, fallback datalayer = this.lastUsedDataLayer @@ -1314,6 +1320,7 @@ L.U.Map.include({ 'options.miniMap', 'options.scaleControl', 'options.onLoadPanel', + 'options.defaultView', 'options.displayPopupFooter', 'options.captionBar', 'options.captionMenus', @@ -2098,4 +2105,13 @@ L.U.Map.include({ getAdvancedFilterKeys: function () { return (this.options.advancedFilterKey || '').split(',') }, + + getLayersBounds: function () { + const bounds = new L.latLngBounds() + this.eachBrowsableDataLayer((d) => { + if (d.isVisible()) bounds.extend(d.layer.getBounds()) + }) + return bounds + }, + })