I was trying to translate a {mapgl} MapLibre map's continent/country/city labels, following these instructions, but could not make it work:
library(mapgl)
# Expresión que toma el nombre en español y, si no existe, usa el nombre por defecto
etiqueta_es <- list("coalesce", list("get", "name:es"), list("get", "name"))
maplibre(
style = carto_style("dark-matter"),
attributionControl = FALSE,
minZoom = 2,
maxZoom = 11
) |>
set_layout_property(
layer_id = "place_country_1",
name = "text-field",
value = etiqueta_es
) |>
set_layout_property(
layer_id = "place_country_2",
name = "text-field",
value = etiqueta_es
) |>
# Opcional: continente y estados/provincias también en español
set_layout_property(
layer_id = "place_continent",
name = "text-field",
value = etiqueta_es
) |>
set_layout_property(
layer_id = "place_state",
name = "text-field",
value = etiqueta_es
)
After some fiddling, documentation reading, and help from Posit Assistant, I was able to translate the base map into Spanish using the following function:
library(mapgl)
#' Translate map labels to a different language
#'
#' Rewrites the `text-field` layout property of label layers in a MapLibre /
#' Mapbox style so that place names are displayed in the requested language.
#' This works around the fact that setting `text-field` after the map has
#' rendered (via [set_layout_property()]) can fail to take effect when the
#' vector source loads asynchronously: instead, the style itself is modified
#' before the map is created.
#'
#' The style's vector tiles must expose localized name fields following the
#' OpenMapTiles convention (`name:es`, `name:fr`, ...). Carto basemaps
#' (e.g. `carto_style("dark-matter")`) and other OpenMapTiles-based styles
#' satisfy this. If a feature has no name in the requested language, the
#' default `name` field is used as a fallback.
#'
#' @param style Either a URL to a style JSON or an already-parsed style as a
#' list (e.g. from [jsonlite::fromJSON()] with `simplifyVector = FALSE`).
#' @param language ISO language code used to build the localized name field,
#' e.g. `"es"`, `"fr"`, `"pt"`, `"de"`.
#' @param source_layers Character vector of `source-layer` names whose symbol
#' layers should be translated. Defaults to `"place"`, which covers country,
#' continent, state and city labels in OpenMapTiles styles.
#'
#' @return The modified style as a list, ready to pass to [maplibre()] (or
#' [mapboxgl()]) via the `style` argument.
#'
#' @examples
#' \dontrun{
#' maplibre(style = translate_labels(carto_style("dark-matter"), "es"))
#'
#' # Translate water and road labels too
#' maplibre(
#' style = translate_labels(
#' carto_style("positron"),
#' language = "fr",
#' source_layers = c("place", "water_name", "transportation_name")
#' )
#' )
#' }
#'
#' @export
translate_labels <- function(style, language = "en", source_layers = "place") {
if (is.character(style)) {
style <- jsonlite::fromJSON(style, simplifyVector = FALSE)
}
# Use the localized name, falling back to the default name when missing
text_field <- list(
"coalesce",
list("get", paste0("name:", language)),
list("get", "name")
)
style$layers <- lapply(style$layers, function(layer) {
is_label <- identical(layer$type, "symbol") &&
!is.null(layer$`source-layer`) &&
layer$`source-layer` %in% source_layers
if (is_label) {
layer$layout$`text-field` <- text_field
}
layer
})
style
}
maplibre(
style = translate_labels(carto_style("dark-matter"), language = "es"),
attributionControl = FALSE,
minZoom = 2,
maxZoom = 11
)
Now base map text appears in Spanish instead of english!
I was wondering if there was another proper method for translating base map text with {mapgl} that I missed, of if I did a mistake with set_layout_property(), or maybe this is missing functionality that could be improved with the proposed function.
I was trying to translate a {mapgl} MapLibre map's continent/country/city labels, following these instructions, but could not make it work:
After some fiddling, documentation reading, and help from Posit Assistant, I was able to translate the base map into Spanish using the following function:
Now base map text appears in Spanish instead of english!
I was wondering if there was another proper method for translating base map text with {mapgl} that I missed, of if I did a mistake with
set_layout_property(), or maybe this is missing functionality that could be improved with the proposed function.