Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use user-preferred language in labels #578

Merged
merged 5 commits into from
Nov 27, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions scripts/taginfo_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
"contact_email": "zelonewolf@gmail.com"
},
"tags": [
{
"key": "name",
"object_types": ["node", "way", "relation", "area"],
"description": "Labels fall back to the local language if none of the user-preferred languages is available."
},
{
"key": "capital",
"value": "yes",
Expand Down
26 changes: 20 additions & 6 deletions src/constants/label.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
"use strict";

// Name fields in order of preference
export const name_en = [
"coalesce",
["get", "name:en"],
["get", "name:latin"],
["get", "name"],
];
export const localizedName = (function () {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The text-field expressions continue to be evaluated statically as the page loads. To dynamically switch languages after the page loads, we could listen for the languagechange and tear down and rebuild all the layers. This would require refactoring americana.js.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let userLocales = navigator.languages ?? [navigator.language];
let locales = [];
let localeSet = new Set(); // avoid duplicates
for (let locale of userLocales) {
// Add progressively less specific variants of each user-specified locale.
let components = locale.split("-");
while (components.length > 0) {
let parent = components.join("-");
if (!localeSet.has(parent)) locales.push(parent);
localeSet.add(parent);
components.pop();
}
}
if (locales.at(-1) === "en") {
locales.push("latin");
1ec5 marked this conversation as resolved.
Show resolved Hide resolved
}
let nameFields = [...locales.map((l) => `name:${l}`), "name"];
return ["coalesce", ...nameFields.map((f) => ["get", f])];
})();
12 changes: 3 additions & 9 deletions src/layer/aeroway.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
"use strict";

import * as Label from "../constants/label.js";
import * as Color from "../constants/color.js";

const name_en = [
"coalesce",
["get", "name:en"],
["get", "name:latin"],
["get", "name"],
];

const minorAirport = [
"any",
["!", ["has", "iata"]],
Expand Down Expand Up @@ -221,7 +215,7 @@ export const airportLabel = {
},
layout: {
visibility: "visible",
"text-field": name_en,
"text-field": Label.localizedName,
"text-font": ["Metropolis Bold"],
"text-size": 10,
...iconLayout,
Expand All @@ -245,7 +239,7 @@ export const minorAirportLabel = {
},
layout: {
visibility: "visible",
"text-field": name_en,
"text-field": Label.localizedName,
"text-font": ["Metropolis Bold"],
"text-size": 10,
},
Expand Down
13 changes: 3 additions & 10 deletions src/layer/park.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,8 @@
"use strict";

import * as Label from "../constants/label.js";
import * as Color from "../constants/color.js";

// Name fields in order of preference
const name_en = [
"coalesce",
["get", "name:en"],
["get", "name:latin"],
["get", "name"],
];

export const fill = {
id: "protected-area-fill",
type: "fill",
Expand Down Expand Up @@ -50,7 +43,7 @@ export const label = {
},
layout: {
visibility: "visible",
"text-field": name_en,
"text-field": Label.localizedName,
"text-font": ["Metropolis Bold"],
"text-size": 10,
"symbol-sort-key": ["get", "rank"],
Expand Down Expand Up @@ -102,7 +95,7 @@ export const parkLabel = {
},
layout: {
visibility: "visible",
"text-field": name_en,
"text-field": Label.localizedName,
"text-font": ["Metropolis Bold"],
"text-size": 10,
"symbol-sort-key": ["get", "rank"],
Expand Down
20 changes: 10 additions & 10 deletions src/layer/place.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as label from "../constants/label.js";
import * as Label from "../constants/label.js";

const cityLabelPaint = {
"text-color": "#444",
Expand Down Expand Up @@ -59,7 +59,7 @@ export const village = {
[11, 0.5],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-anchor": "bottom",
"text-variable-anchor": [
"bottom",
Expand Down Expand Up @@ -122,7 +122,7 @@ export const town = {
[11, 0.7],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-anchor": "bottom",
"text-variable-anchor": [
"bottom",
Expand Down Expand Up @@ -181,7 +181,7 @@ export const city = {
[11, 0.9],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-anchor": "bottom",
"text-variable-anchor": [
"bottom",
Expand Down Expand Up @@ -223,7 +223,7 @@ export const state = {
[6, 14],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-padding": 1,
"text-transform": "uppercase",
"text-letter-spacing": 0.04,
Expand Down Expand Up @@ -266,7 +266,7 @@ export const countryOther = {
[7, 15],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-max-width": 6.25,
"text-transform": "none",
},
Expand Down Expand Up @@ -296,7 +296,7 @@ export const country3 = {
[7, 17],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-max-width": 6.25,
"text-transform": "none",
},
Expand Down Expand Up @@ -326,7 +326,7 @@ export const country2 = {
[5, 17],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-max-width": 6.25,
"text-transform": "none",
},
Expand Down Expand Up @@ -357,7 +357,7 @@ export const country1 = {
[6, 19],
],
},
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-max-width": ["step", ["zoom"], 6.25, 3, 12],
"text-transform": "none",
"text-offset": [
Expand All @@ -383,7 +383,7 @@ export const continent = {
layout: {
"text-font": ["Metropolis Light"],
"text-size": 13,
"text-field": label.name_en,
"text-field": Label.localizedName,
"text-justify": "center",
"text-transform": "uppercase",
},
Expand Down
12 changes: 3 additions & 9 deletions src/layer/water.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use strict";

import * as Label from "../constants/label.js";
import * as Color from "../constants/color.js";

const bigRivers = ["river", "canal"];
Expand Down Expand Up @@ -75,16 +76,9 @@ const labelPaintProperties = {
"text-halo-blur": 0.25,
};

const nameField = [
"coalesce",
["get", "name:en"],
["get", "name_en"],
["get", "name"],
];

const labelLayoutProperties = {
"symbol-placement": "line",
"text-field": nameField,
"text-field": Label.localizedName,
"text-font": ["Metropolis Bold Italic"],
"text-max-angle": 55,
};
Expand Down Expand Up @@ -153,7 +147,7 @@ export const waterPointLabel = {
"source-layer": "water_name",
filter: ["all", ["==", ["geometry-type"], "Point"]],
layout: {
"text-field": nameField,
"text-field": Label.localizedName,
"text-font": ["Metropolis Bold Italic"],
"text-size": [
"interpolate",
Expand Down