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 282b97da..77c9431b 100644
--- a/umap/static/umap/js/umap.js
+++ b/umap/static/umap/js/umap.js
@@ -1,8 +1,6 @@
L.Map.mergeOptions({
overlay: null,
datalayers: [],
- center: [50, 4],
- zoom: 6,
hash: true,
default_color: 'DarkBlue',
default_smoothFactor: 1.0,
@@ -86,11 +84,11 @@ L.U.Map.include({
geojson.properties.fullscreenControl = false
L.Util.setBooleanFromQueryString(geojson.properties, 'scrollWheelZoom')
- // Before calling parent initialize
- if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
-
L.Map.prototype.initialize.call(this, el, geojson.properties)
+ // After calling parent initialize, as we are doing initCenter our-selves
+ if (geojson.geometry) this.options.center = this.latLng(geojson.geometry)
+
this.ui = new L.U.UI(this._container)
this.xhr = new L.U.Xhr(this.ui)
this.xhr.on('dataloading', (e) => this.fire('dataloading', e))
@@ -152,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 = {}
@@ -255,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')
@@ -311,6 +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 }),
})
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 () {
@@ -633,23 +641,44 @@ L.U.Map.include({
}
},
+ _setDefaultCenter: function () {
+ 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 () {
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.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()
})
} else {
- this.options.center = this.latLng(this.options.center)
- this.setView(this.options.center, this.options.zoom)
+ this._setDefaultCenter()
}
},
@@ -1404,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'),
},
],
[
@@ -2048,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
}, {})
@@ -2061,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
new file mode 100644
index 00000000..fa10e18a
--- /dev/null
+++ b/umap/static/umap/test/Map.Init.js
@@ -0,0 +1,46 @@
+describe('L.U.Map.initialize', function () {
+ afterEach(function () {
+ resetMap()
+ })
+
+ 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'))
+ })
+ })
+
+ 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)
+ })
+ })
+})
diff --git a/umap/static/umap/test/_pre.js b/umap/static/umap/test/_pre.js
index c905eb0f..df561c5d 100644
--- a/umap/static/umap/test/_pre.js
+++ b/umap/static/umap/test/_pre.js
@@ -107,10 +107,6 @@ var defaultDatalayerData = function (custom) {
function initMap(options) {
default_options = {
- geometry: {
- type: 'Point',
- coordinates: [5.0592041015625, 52.05924589011585],
- },
type: 'Feature',
properties: {
umap_id: 42,
@@ -197,7 +193,7 @@ function initMap(options) {
allowEdit: true,
moreControl: true,
scaleControl: true,
- miniMap: true,
+ miniMap: false,
datalayersControl: true,
displayCaptionOnLoad: false,
displayPopupFooter: false,
@@ -205,7 +201,12 @@ function initMap(options) {
},
}
default_options.properties.datalayers.push(defaultDatalayerData())
+ options = options || {}
options.properties = L.extend({}, default_options.properties, options)
+ options.geometry = {
+ type: 'Point',
+ coordinates: [5.0592041015625, 52.05924589011585],
+ }
return new L.U.Map('map', options)
}
diff --git a/umap/static/umap/test/index.html b/umap/static/umap/test/index.html
index c3f5da40..b8ed9b10 100644
--- a/umap/static/umap/test/index.html
+++ b/umap/static/umap/test/index.html
@@ -67,6 +67,7 @@
+