Better control of default view

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
This commit is contained in:
Yohan Boniface 2023-08-12 07:39:13 +02:00
parent 8758c0dc65
commit d008bc7539
2 changed files with 49 additions and 20 deletions

View file

@ -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: [ selectOptions: [
['none', L._('None')], ['none', L._('None')],
['caption', L._('Caption')], ['caption', L._('Caption')],
@ -1008,9 +1017,13 @@ L.U.FormBuilder = L.FormBuilder.extend({
label: L._('Do you want to display the scale control?'), label: L._('Do you want to display the scale control?'),
}, },
onLoadPanel: { onLoadPanel: {
handler: 'onLoadPanel', handler: 'OnLoadPanel',
label: L._('Do you want to display a panel on load?'), label: L._('Do you want to display a panel on load?'),
}, },
defaultView: {
handler: 'DefaultView',
label: L._('Default view'),
},
displayPopupFooter: { displayPopupFooter: {
handler: 'Switch', handler: 'Switch',
label: L._('Do you want to display popup footer?'), label: L._('Do you want to display popup footer?'),

View file

@ -144,18 +144,6 @@ L.U.Map.include({
// Certainly IE8, which has a limited version of defineProperty // 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 // Retrocompat
if ( if (
this.options.slideshow && this.options.slideshow &&
@ -164,9 +152,17 @@ L.U.Map.include({
) )
this.options.slideshow.active = true 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() this.initDatalayers()
if (this.options.displayCaptionOnLoad) { if (this.options.displayCaptionOnLoad) {
@ -636,10 +632,16 @@ L.U.Map.include({
if (this.options.hash && this._hash.parseHash(location.hash)) { if (this.options.hash && this._hash.parseHash(location.hash)) {
// FIXME An invalid hash will cause the load to fail // FIXME An invalid hash will cause the load to fail
this._hash.update() this._hash.update()
} else if (this.options.locate && this.options.locate.setView) { } else if (this.options.defaultView === 'locate' && !this.options.noControl) {
// Prevent from making two setViews at init this._controls.locate.start()
// which is not very fluid... } else if (this.options.defaultView === 'bounds') {
this.locate(this.options.locate) 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 { } else {
this.options.center = this.latLng(this.options.center) this.options.center = this.latLng(this.options.center)
this.setView(this.options.center, this.options.zoom) this.setView(this.options.center, this.options.zoom)
@ -1036,6 +1038,7 @@ L.U.Map.include({
'miniMap', 'miniMap',
'displayPopupFooter', 'displayPopupFooter',
'onLoadPanel', 'onLoadPanel',
'defaultView',
'tilelayersControl', 'tilelayersControl',
'name', 'name',
'description', '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 () { defaultDataLayer: function () {
let datalayer, fallback let datalayer, fallback
datalayer = this.lastUsedDataLayer datalayer = this.lastUsedDataLayer
@ -1314,6 +1320,7 @@ L.U.Map.include({
'options.miniMap', 'options.miniMap',
'options.scaleControl', 'options.scaleControl',
'options.onLoadPanel', 'options.onLoadPanel',
'options.defaultView',
'options.displayPopupFooter', 'options.displayPopupFooter',
'options.captionBar', 'options.captionBar',
'options.captionMenus', 'options.captionMenus',
@ -2098,4 +2105,13 @@ L.U.Map.include({
getAdvancedFilterKeys: function () { getAdvancedFilterKeys: function () {
return (this.options.advancedFilterKey || '').split(',') 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
},
}) })