UI(basemap): add language support: labels now show in the selected language

This commit is contained in:
Pieter Vander Vennet 2025-02-24 16:49:40 +01:00
parent 5dc6d82cd0
commit 2a603852a6
7 changed files with 5458 additions and 45 deletions

View file

@ -30,6 +30,47 @@
"fill-color": "#fcf7e5"
}
},
{
"id": "landcover_low_zooms",
"type": "fill",
"source": "protomaps",
"source-layer": "landcover",
"paint": {
"fill-color": [
"match",
[
"get",
"kind"
],
"grassland",
"#e5f2c9",
"barren",
"rgba(255, 243, 215, 1)",
"urban_area",
"rgba(230, 230, 230, 1)",
"farmland",
"rgba(216, 239, 210, 1)",
"glacier",
"rgba(255, 255, 255, 1)",
"scrub",
"rgba(234, 239, 210, 1)",
"#f0efdd"
],
"fill-opacity": [
"interpolate",
[
"linear"
],
[
"zoom"
],
5,
1,
7,
0
]
}
},
{
"id": "landuse_farmland",
"type": "fill",
@ -70,16 +111,13 @@
"source": "protomaps",
"source-layer": "landuse",
"filter": [
"any",
[
"in",
"kind",
"national_park",
"park",
"cemetery",
"nature_reserve",
"golf_course"
]
"in",
"kind",
"national_park",
"park",
"cemetery",
"nature_reserve",
"golf_course"
],
"paint": {
"fill-color": [

View file

@ -109,15 +109,14 @@
"type": "fill",
"source": "protomaps",
"source-layer": "landuse",
"filter":
[
"in",
"kind",
"national_park",
"park",
"cemetery",
"nature_reserve",
"golf_course"
"filter": [
"in",
"kind",
"national_park",
"park",
"cemetery",
"nature_reserve",
"golf_course"
],
"paint": {
"fill-color": [
@ -3010,19 +3009,16 @@
}
},
{
"id": "physical_line_waterway_label",
"id": "water_waterway_label",
"type": "symbol",
"source": "protomaps",
"source-layer": "physical_line",
"source-layer": "water",
"minzoom": 13,
"filter": [
"all",
[
"in",
"kind",
"river",
"stream"
]
"in",
"kind",
"river",
"stream"
],
"layout": {
"symbol-placement": "line",
@ -3120,10 +3116,10 @@
}
},
{
"id": "pois_ocean",
"id": "water_label_ocean",
"type": "symbol",
"source": "protomaps",
"source-layer": "pois",
"source-layer": "water",
"filter": [
"any",
[
@ -3168,7 +3164,7 @@
}
},
{
"id": "pois_lakes",
"id": "water_label_lakes",
"type": "symbol",
"source": "protomaps",
"source-layer": "water",
@ -3313,7 +3309,7 @@
}
},
{
"id": "pois_important",
"id": "pois",
"type": "symbol",
"source": "protomaps",
"source-layer": "pois",

View file

@ -7,11 +7,11 @@ import { ExportableMap, KeyNavigationEvent, MapProperties } from "../../Models/M
import SvelteUIElement from "../Base/SvelteUIElement"
import MaplibreMap from "./MaplibreMap.svelte"
import * as htmltoimage from "html-to-image"
import RasterLayerHandler from "./RasterLayerHandler"
import Constants from "../../Models/Constants"
import { Protocol } from "pmtiles"
import { GeoOperations } from "../../Logic/GeoOperations"
import { Feature, LineString } from "geojson"
import RasterLayerHandler from "./RasterLayerHandler"
/**
* The 'MapLibreAdaptor' bridges 'MapLibre' with the various properties of the `MapProperties`

View file

@ -66,7 +66,6 @@
_map.resize()
const canvas = _map.getCanvas()
canvas.addEventListener("webglcontextlost", (e) => {
console.warn("A MapLibreMap lost their context. Recovery is", autorecovery, e)
try {
_map?.remove()
} catch (e) {

File diff suppressed because it is too large Load diff

View file

@ -4,9 +4,12 @@ import { RasterLayerPolygon } from "../../Models/RasterLayers"
import { RasterLayerProperties } from "../../Models/RasterLayerProperties"
import { Utils } from "../../Utils"
import { VectorSourceSpecification } from "@maplibre/maplibre-gl-style-spec"
import { ProtomapsLanguageSupport } from "./ProtomapsLanguageSupport"
class SingleBackgroundHandler {
// Value between 0 and 1.0
/**
* Current opacity of this layer, Value between 0 and 1.0
* */
public opacity = new UIEventSource<number>(0.0)
private _map: Store<MLMap>
private _background: UIEventSource<RasterLayerPolygon | undefined>
@ -18,15 +21,18 @@ class SingleBackgroundHandler {
*/
public static readonly DEACTIVATE_AFTER = 60
private fadeStep = 0.1
private _languageSupport: ProtomapsLanguageSupport
constructor(
map: Store<MLMap>,
targetLayer: RasterLayerPolygon,
background: UIEventSource<RasterLayerPolygon | undefined>
background: UIEventSource<RasterLayerPolygon | undefined>,
languageSupport: ProtomapsLanguageSupport
) {
this._targetLayer = targetLayer
this._map = map
this._background = background
this._languageSupport = languageSupport
background.addCallback(async () => {
await this.update()
@ -64,7 +70,7 @@ class SingleBackgroundHandler {
map.removeLayer(<string>this._targetLayer.properties.id)
}
} catch (e) {
console.warn("Could not (try to) remove the raster layer", e)
// Probably already removed
}
}
@ -95,7 +101,7 @@ class SingleBackgroundHandler {
private async enable() {
let ttl = 15
await this.awaitStyleIsLoaded()
while (!this.tryEnable() && ttl > 0) {
while (this._background.data.properties.id === this._targetLayer.properties.id && !this.tryEnable() && ttl > 0) {
ttl--
await Utils.waitFor(250)
}
@ -137,6 +143,11 @@ class SingleBackgroundHandler {
if (background.type === "vector") {
const styleToSet = background.style ?? background.url
map.setStyle(styleToSet)
this.awaitStyleIsLoaded().then(() => {
console.log("UPDATING")
this._languageSupport.update()
})
} else {
map.addLayer(
{
@ -150,6 +161,9 @@ class SingleBackgroundHandler {
addLayerBeforeId
)
this.opacity.addCallbackAndRun((o) => {
if (map.getStyle() === undefined || map.getLayer(background.id) === undefined) {
return true
}
try {
map.setPaintProperty(background.id, "raster-opacity", o)
} catch (e) {
@ -166,27 +180,43 @@ class SingleBackgroundHandler {
Stores.Chronic(
8,
() => this.opacity.data > 0 && this._deactivationTime !== undefined
).addCallback(() => this.opacity.setData(Math.max(0, this.opacity.data - this.fadeStep)))
).addCallback(() => {
try {
this.opacity.setData(Math.max(0, this.opacity.data - this.fadeStep))
} catch (e) {
// The layer probably got pruned; we just unregister
return true
}
})
}
private fadeIn() {
Stores.Chronic(
8,
() => this.opacity.data < 1.0 && this._deactivationTime === undefined
).addCallback(() => this.opacity.setData(Math.min(1.0, this.opacity.data + this.fadeStep)))
).addCallback(() => {
try {
this.opacity.setData(Math.min(1.0, this.opacity.data + this.fadeStep))
} catch (e) {
// The layer probably got pruned; we just unregister
return true
}
})
}
}
export default class RasterLayerHandler {
private _singleLayerHandlers: Record<string, SingleBackgroundHandler> = {}
private _languageSupport: ProtomapsLanguageSupport
constructor(map: Store<MLMap>, background: UIEventSource<RasterLayerPolygon | undefined>) {
background.addCallbackAndRunD((l) => {
const key = l.properties.id
if (!this._singleLayerHandlers[key]) {
this._singleLayerHandlers[key] = new SingleBackgroundHandler(map, l, background)
this._singleLayerHandlers[key] = new SingleBackgroundHandler(map, l, background, this._languageSupport)
}
})
this._languageSupport = new ProtomapsLanguageSupport(map)
}
public static prepareSource(

View file

@ -30,7 +30,7 @@
},
{
"url": "pmtiles://https://api.protomaps.com/tiles/v4.json?key=2af8b969a9e8b692",
"style": "https://api.protomaps.com/styles/v5/white.json?key=2af8b969a9e8b692",
"style": "https://api.protomaps.com/styles/v5/white/en.json?key=2af8b969a9e8b692",
"connect-src": [
"https://protomaps.github.io"
],
@ -63,7 +63,7 @@
"connect-src": [
"https://protomaps.github.io"
],
"style": "https://api.protomaps.com/styles/v5/grayscale.json?key=2af8b969a9e8b692",
"style": "https://api.protomaps.com/styles/v5/grayscale/en.json?key=2af8b969a9e8b692",
"id": "protomaps.grayscale",
"name": "Protomaps Grayscale",
"type": "vector",
@ -78,7 +78,7 @@
"connect-src": [
"https://protomaps.github.io"
],
"style": "https://api.protomaps.com/styles/v5/dark.json?key=2af8b969a9e8b692",
"style": "https://api.protomaps.com/styles/v5/dark/en.json?key=2af8b969a9e8b692",
"id": "protomaps.dark",
"name": "Protomaps Dark",
"type": "vector",
@ -90,7 +90,7 @@
},
{
"url": "pmtiles://https://api.protomaps.com/tiles/v4.json?key=2af8b969a9e8b692",
"style": "https://api.protomaps.com/styles/v5/black.json?key=2af8b969a9e8b692",
"style": "https://api.protomaps.com/styles/v5/black/en.json?key=2af8b969a9e8b692",
"connect-src": [
"https://protomaps.github.io"
],