Merge pull request #1475 from umap-project/iconlayers-polish
Iconlayers polish
This commit is contained in:
commit
3d92a8e845
3 changed files with 158 additions and 19 deletions
|
@ -2,7 +2,10 @@ L.U.BaseAction = L.ToolbarAction.extend({
|
|||
initialize: function (map) {
|
||||
this.map = map
|
||||
if (this.options.label) {
|
||||
this.options.tooltip = this.map.help.displayLabel(this.options.label, withKbdTag=false)
|
||||
this.options.tooltip = this.map.help.displayLabel(
|
||||
this.options.label,
|
||||
(withKbdTag = false)
|
||||
)
|
||||
}
|
||||
this.options.toolbarIcon = {
|
||||
className: this.options.className,
|
||||
|
@ -18,7 +21,7 @@ L.U.ImportAction = L.U.BaseAction.extend({
|
|||
options: {
|
||||
helpMenu: true,
|
||||
className: 'upload-data dark',
|
||||
label: 'IMPORT_PANEL'
|
||||
label: 'IMPORT_PANEL',
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
|
@ -87,7 +90,7 @@ L.U.DrawMarkerAction = L.U.BaseAction.extend({
|
|||
options: {
|
||||
helpMenu: true,
|
||||
className: 'umap-draw-marker dark',
|
||||
label: 'DRAW_MARKER'
|
||||
label: 'DRAW_MARKER',
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
|
@ -99,7 +102,7 @@ L.U.DrawPolylineAction = L.U.BaseAction.extend({
|
|||
options: {
|
||||
helpMenu: true,
|
||||
className: 'umap-draw-polyline dark',
|
||||
label: 'DRAW_LINE'
|
||||
label: 'DRAW_LINE',
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
|
@ -111,7 +114,7 @@ L.U.DrawPolygonAction = L.U.BaseAction.extend({
|
|||
options: {
|
||||
helpMenu: true,
|
||||
className: 'umap-draw-polygon dark',
|
||||
label: 'DRAW_POLYGON'
|
||||
label: 'DRAW_POLYGON',
|
||||
},
|
||||
|
||||
addHooks: function () {
|
||||
|
@ -1184,21 +1187,30 @@ L.U.Map.include({
|
|||
/* Used in view mode to define the current tilelayer */
|
||||
L.U.TileLayerControl = L.Control.IconLayers.extend({
|
||||
initialize: function (map, options) {
|
||||
const layers = []
|
||||
map.eachTileLayer((layer) => {
|
||||
layers.push({
|
||||
title: layer.options.name,
|
||||
layer: layer,
|
||||
icon: L.Util.template(layer.options.url_template, map.demoTileInfos),
|
||||
})
|
||||
})
|
||||
const maxShown = 10
|
||||
L.Control.IconLayers.prototype.initialize.call(this, layers.slice(0, maxShown), {
|
||||
this.map = map
|
||||
L.Control.IconLayers.prototype.initialize.call(this, {
|
||||
position: 'topleft',
|
||||
manageLayers: false
|
||||
manageLayers: false,
|
||||
})
|
||||
this.on('activelayerchange', (e) => map.selectTileLayer(e.layer))
|
||||
},
|
||||
|
||||
setLayers: function (layers) {
|
||||
if (!layers) {
|
||||
layers = []
|
||||
this.map.eachTileLayer((layer) => {
|
||||
layers.push({
|
||||
title: layer.options.name,
|
||||
layer: layer,
|
||||
icon: L.Util.template(layer.options.url_template, this.map.demoTileInfos),
|
||||
})
|
||||
})
|
||||
}
|
||||
const maxShown = 10
|
||||
L.Control.IconLayers.prototype.setLayers.call(this, layers.slice(0, maxShown))
|
||||
if (this.map.selected_tilelayer) this.setActiveLayer(this.map.selected_tilelayer)
|
||||
},
|
||||
|
||||
})
|
||||
|
||||
/* Used in edit mode to define the default tilelayer */
|
||||
|
@ -1261,6 +1273,7 @@ L.U.TileLayerChooser = L.Control.extend({
|
|||
'click',
|
||||
function () {
|
||||
this.map.selectTileLayer(tilelayer)
|
||||
this.map._controls.tilelayers.setLayers()
|
||||
if (options && options.callback) options.callback(tilelayer)
|
||||
},
|
||||
this
|
||||
|
|
|
@ -166,7 +166,7 @@ L.U.Map.include({
|
|||
this.help = new L.U.Help(this)
|
||||
|
||||
if (this.options.hash) this.addHash()
|
||||
this.initTileLayers(this.options.tilelayers)
|
||||
this.initTileLayers()
|
||||
// Needs tilelayer to exist for minimap
|
||||
this.initControls()
|
||||
// Needs locate control and hash to exist
|
||||
|
@ -348,6 +348,7 @@ L.U.Map.include({
|
|||
this.importer = new L.U.Importer(this)
|
||||
this.drop = new L.U.DropControl(this)
|
||||
this._controls.tilelayers = new L.U.TileLayerControl(this)
|
||||
this._controls.tilelayers.setLayers()
|
||||
|
||||
this.renderControls()
|
||||
},
|
||||
|
@ -606,6 +607,7 @@ L.U.Map.include({
|
|||
} else {
|
||||
this.selectTileLayer(this.tilelayers[0])
|
||||
}
|
||||
if (this._controls) this._controls.tilelayers.setLayers()
|
||||
},
|
||||
|
||||
createTileLayer: function (tilelayer) {
|
||||
|
@ -649,8 +651,18 @@ L.U.Map.include({
|
|||
},
|
||||
|
||||
eachTileLayer: function (callback, context) {
|
||||
if (this.customTilelayer) callback.call(context, this.customTilelayer)
|
||||
this.tilelayers.forEach((layer) => callback.call(context, layer))
|
||||
const urls = []
|
||||
const callOne = (layer) => {
|
||||
// Prevent adding a duplicate background,
|
||||
// while adding selected/custom on top of the list
|
||||
const url = layer.options.url_template
|
||||
if (urls.indexOf(url) !== -1) return
|
||||
callback.call(context, layer)
|
||||
urls.push(url)
|
||||
}
|
||||
if (this.selected_tilelayer) callOne(this.selected_tilelayer)
|
||||
if (this.customTilelayer) callOne(this.customTilelayer)
|
||||
this.tilelayers.forEach(callOne)
|
||||
},
|
||||
|
||||
setOverlay: function () {
|
||||
|
|
114
umap/tests/integration/test_tilelayer.py
Normal file
114
umap/tests/integration/test_tilelayer.py
Normal file
|
@ -0,0 +1,114 @@
|
|||
import re
|
||||
|
||||
import pytest
|
||||
from playwright.sync_api import expect
|
||||
|
||||
from umap.models import TileLayer
|
||||
|
||||
from ..base import TileLayerFactory
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tilelayers():
|
||||
# Create one more TileLayer than what we display in the switcher (11 vs 10)
|
||||
TileLayerFactory(
|
||||
rank=1,
|
||||
name="OpenStreetMap",
|
||||
url_template="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=2,
|
||||
name="Forte",
|
||||
url_template="https://{s}.forte.tiles.quaidorsay.fr/fr{r}/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=3,
|
||||
name="Positron",
|
||||
url_template="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=4,
|
||||
name="Humanitarian",
|
||||
url_template="//{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=5,
|
||||
name="Dark Matter",
|
||||
url_template="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=6,
|
||||
name="OSM OpenCycleMap",
|
||||
url_template="https://{s}.tile.thunderforest.com/cycle/{z}/{x}/{y}.png?apikey=e6b144cfc47a48fd928dad578eb026a6",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=7,
|
||||
name="CyclOSM",
|
||||
url_template="//{s}.tile-cyclosm.openstreetmap.fr/cyclosm/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=8,
|
||||
name="Piano",
|
||||
url_template="https://{s}.piano.tiles.quaidorsay.fr/fr{r}/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=9,
|
||||
name="IGN Image aérienne (France)",
|
||||
url_template="https://wxs.ign.fr/pratique/wmts/?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=ORTHOIMAGERY.ORTHOPHOTOS&STYLE=normal&TILEMATRIXSET=PM&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&FORMAT=image%2Fjpeg",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=10,
|
||||
name="OSM OpenRiverboatMap",
|
||||
url_template="//{s}.tile.openstreetmap.fr/openriverboatmap/{z}/{x}/{y}.png",
|
||||
)
|
||||
TileLayerFactory(
|
||||
rank=11,
|
||||
name="OSM OpenTopoMap",
|
||||
url_template="https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
|
||||
)
|
||||
|
||||
|
||||
def test_map_should_display_first_tilelayer_by_default(
|
||||
map, live_server, tilelayers, page
|
||||
):
|
||||
page.goto(f"{live_server.url}/map/new")
|
||||
tiles = page.locator(".leaflet-tile-pane img")
|
||||
expect(tiles.first).to_have_attribute(
|
||||
"src", re.compile(r"https://[abc].tile.openstreetmap.org/\d+/\d+/\d+.png")
|
||||
)
|
||||
|
||||
|
||||
def test_map_should_display_selected_tilelayer(map, live_server, tilelayers, page):
|
||||
piano = TileLayer.objects.get(name="Piano")
|
||||
url_pattern = re.compile(
|
||||
r"https://[abc]{1}.piano.tiles.quaidorsay.fr/fr/\d+/\d+/\d+.png"
|
||||
)
|
||||
map.settings["properties"]["tilelayer"]["url_template"] = piano.url_template
|
||||
map.settings["properties"]["tilelayersControl"] = True
|
||||
map.save()
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
||||
tiles = page.locator(".leaflet-tile-pane img")
|
||||
expect(tiles.first).to_have_attribute("src", url_pattern)
|
||||
iconTiles = page.locator(".leaflet-iconLayers .leaflet-iconLayers-layer")
|
||||
# The second of the list should be the current
|
||||
expect(iconTiles.nth(1)).to_have_css("background-image", url_pattern)
|
||||
|
||||
|
||||
def test_map_should_display_custom_tilelayer(map, live_server, tilelayers, page):
|
||||
# Add one not on the list
|
||||
url_pattern = re.compile(
|
||||
r"https://[abc]{1}.basemaps.cartocdn.com/rastertiles/voyager/\d+/\d+/\d+.png"
|
||||
)
|
||||
map.settings["properties"]["tilelayer"][
|
||||
"url_template"
|
||||
] = "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png"
|
||||
map.settings["properties"]["tilelayersControl"] = True
|
||||
map.save()
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}")
|
||||
tiles = page.locator(".leaflet-tile-pane img")
|
||||
expect(tiles.first).to_have_attribute("src", url_pattern)
|
||||
iconTiles = page.locator(".leaflet-iconLayers .leaflet-iconLayers-layer")
|
||||
# The second of the list should be the current
|
||||
expect(iconTiles.nth(1)).to_have_css("background-image", url_pattern)
|
Loading…
Reference in a new issue