mirror of
https://github.com/umap-project/umap.git
synced 2025-04-28 19:42:36 +02:00
feat: display an image from Panoramax in OSM template when tag is defined (#2338)
 I initially just wanted to work on that simple Panoramax feature, but faced a bunch of bugs! - one bad var remaining since whatever refactor (and no tests for this popup template!) - title was duplicated, since whatever refactor (and not tests for this…) - title text was in black on blue background
This commit is contained in:
commit
7f3726ddd1
3 changed files with 93 additions and 17 deletions
|
@ -152,6 +152,19 @@ class GeoRSSLink extends PopupTemplate {
|
|||
}
|
||||
|
||||
class OSM extends TitleMixin(PopupTemplate) {
|
||||
renderTitle(feature) {
|
||||
const title = DomUtil.add('h3', 'popup-title')
|
||||
const color = feature.getPreviewColor()
|
||||
title.style.backgroundColor = color
|
||||
const iconUrl = feature.getDynamicOption('iconUrl')
|
||||
const icon = Icon.makeElement(iconUrl, title)
|
||||
DomUtil.addClass(icon, 'icon')
|
||||
Icon.setContrast(icon, title, iconUrl, color)
|
||||
if (DomUtil.contrastedColor(title, color)) title.style.color = 'white'
|
||||
DomUtil.add('span', '', title, this.getName(feature))
|
||||
return title
|
||||
}
|
||||
|
||||
getName(feature) {
|
||||
const props = feature.properties
|
||||
const locale = getLocale()
|
||||
|
@ -162,15 +175,6 @@ class OSM extends TitleMixin(PopupTemplate) {
|
|||
renderBody(feature) {
|
||||
const props = feature.properties
|
||||
const body = document.createElement('div')
|
||||
const title = DomUtil.add('h3', 'popup-title', container)
|
||||
const color = feature.getPreviewColor()
|
||||
title.style.backgroundColor = color
|
||||
const iconUrl = feature.getDynamicOption('iconUrl')
|
||||
const icon = Icon.makeElement(iconUrl, title)
|
||||
DomUtil.addClass(icon, 'icon')
|
||||
Icon.setContrast(icon, title, iconUrl, color)
|
||||
if (DomUtil.contrastedColor(title, color)) title.style.color = 'white'
|
||||
DomUtil.add('span', '', title, this.getName(feature))
|
||||
const street = props['addr:street']
|
||||
if (street) {
|
||||
const row = DomUtil.add('address', 'address', body)
|
||||
|
@ -207,6 +211,13 @@ class OSM extends TitleMixin(PopupTemplate) {
|
|||
Utils.loadTemplate(`<div><a href="mailto:${email}">${email}</a></div>`)
|
||||
)
|
||||
}
|
||||
if (props.panoramax) {
|
||||
body.appendChild(
|
||||
Utils.loadTemplate(
|
||||
`<div><img src="https://api.panoramax.xyz/api/pictures/${props.panoramax}/sd.jpg" /></div>`
|
||||
)
|
||||
)
|
||||
}
|
||||
const id = props['@id'] || props.id
|
||||
if (id) {
|
||||
body.appendChild(
|
||||
|
|
|
@ -170,22 +170,43 @@ L.DomUtil.contrastWCAG21 = (rgb) => {
|
|||
const contrast = (whiteLum + 0.05) / (lum + 0.05)
|
||||
return contrast > 3 ? 1 : 0
|
||||
}
|
||||
L.DomUtil.colorNameToHex = (str) => {
|
||||
const ctx = document.createElement('canvas').getContext('2d')
|
||||
ctx.fillStyle = str
|
||||
return ctx.fillStyle
|
||||
}
|
||||
L.DomUtil.hexToRGB = (hex) => {
|
||||
return hex
|
||||
.replace(
|
||||
/^#?([a-f\d])([a-f\d])([a-f\d])$/i,
|
||||
(m, r, g, b) => `#${r}${r}${g}${g}${b}${b}`
|
||||
)
|
||||
.substring(1)
|
||||
.match(/.{2}/g)
|
||||
.map((x) => Number.parseInt(x, 16))
|
||||
}
|
||||
|
||||
const _CACHE_CONSTRAST = {}
|
||||
L.DomUtil.contrastedColor = (el, bgcolor) => {
|
||||
// Return 0 for black and 1 for white
|
||||
// bgcolor is a human color, it can be a any keyword (purple…)
|
||||
if (typeof _CACHE_CONSTRAST[bgcolor] !== 'undefined') return _CACHE_CONSTRAST[bgcolor]
|
||||
let out = 0
|
||||
let rgb = window.getComputedStyle(el).getPropertyValue('background-color')
|
||||
rgb = L.DomUtil.RGBRegex.exec(rgb)
|
||||
if (!rgb || rgb.length !== 4) return out
|
||||
rgb = [
|
||||
Number.parseInt(rgb[1], 10),
|
||||
Number.parseInt(rgb[2], 10),
|
||||
Number.parseInt(rgb[3], 10),
|
||||
]
|
||||
out = L.DomUtil.contrastWCAG21(rgb)
|
||||
if (rgb && rgb.length === 4) {
|
||||
rgb = [
|
||||
Number.parseInt(rgb[1], 10),
|
||||
Number.parseInt(rgb[2], 10),
|
||||
Number.parseInt(rgb[3], 10),
|
||||
]
|
||||
} else {
|
||||
// The element may not yet be added to the DOM, so let's try
|
||||
// another way
|
||||
const hex = L.DomUtil.colorNameToHex(bgcolor)
|
||||
rgb = L.DomUtil.hexToRGB(hex)
|
||||
}
|
||||
if (!rgb) return 1
|
||||
const out = L.DomUtil.contrastWCAG21(rgb)
|
||||
if (bgcolor) _CACHE_CONSTRAST[bgcolor] = out
|
||||
return out
|
||||
}
|
||||
|
|
44
umap/tests/integration/test_popup.py
Normal file
44
umap/tests/integration/test_popup.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
import pytest
|
||||
from playwright.sync_api import expect
|
||||
|
||||
from ..base import DataLayerFactory
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
OSM_DATA = {
|
||||
"type": "FeatureCollection",
|
||||
"features": [
|
||||
{
|
||||
"type": "Feature",
|
||||
"geometry": {"type": "Point", "coordinates": [2.49, 48.79]},
|
||||
"properties": {
|
||||
"amenity": "restaurant",
|
||||
"cuisine": "italian",
|
||||
"name": "A Casa di Nonna",
|
||||
"panoramax": "d811b398-d930-4cf8-95a2-0c29c34d9fca",
|
||||
"phone": "+33 1 48 89 54 12",
|
||||
"takeaway:covid19": "yes",
|
||||
"wheelchair": "no",
|
||||
"id": "node/1130849864",
|
||||
},
|
||||
"id": "AzMjk",
|
||||
},
|
||||
],
|
||||
"_umap_options": {
|
||||
"popupTemplate": "OSM",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def test_openstreetmap_popup(live_server, map, page):
|
||||
DataLayerFactory(map=map, data=OSM_DATA)
|
||||
page.goto(f"{live_server.url}{map.get_absolute_url()}#18/48.79/2.49")
|
||||
expect(page.locator(".umap-icon-active")).to_be_hidden()
|
||||
page.locator(".leaflet-marker-icon").click()
|
||||
expect(page.get_by_role("heading", name="A Casa di Nonna")).to_be_visible()
|
||||
expect(page.get_by_text("+33 1 48 89 54 12")).to_be_visible()
|
||||
img = page.locator(".umap-popup-content img")
|
||||
expect(img).to_have_attribute(
|
||||
"src",
|
||||
"https://api.panoramax.xyz/api/pictures/d811b398-d930-4cf8-95a2-0c29c34d9fca/sd.jpg",
|
||||
)
|
Loading…
Reference in a new issue