Как локализовать OpenStreetMap с помощью Leaflet в Blazor?

Тестовое приложение на GitHub Blazor Server, где интегрирую OpenStreetMap с Leaflet для отображения карт и маршрутов между двумя координатами.

Необходимо, чтобы карта и инструкции по маршруту отображались на выбранном языке (например, для теста на французском), но столкнулась с проблемой:

Скрин с проблемами интерфейса

Некоторые части интерфейса (справа маршрут) остаются на английском, несмотря на использование французских тайлов, а улицы — на нужном языке.

То есть карта отображается, но некоторые метки и инструкции маршрута остаются на английском языке, хотя я использую "французские" тайлы OpenStreetMap osmfr.

https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png

Слышала про решения с использованием сервисов перевода, таких как Mapbox или MapTiles — не пробовала.

Пробовала добавить параметр accept-language=fr в запрос Nominatim API для получения адресов:

string url = $"https://nominatim.openstreetmap.org/search?format=json&q={encodedAddress}&accept-language=fr";

Но это ничего не поменяло.

Так же я пробовала внедрить сторонний API, использовав нужный скрипт, — тоже не помогло.


LeafletMap.js:

// LeafletMap.js

export function initializeLeafletMap(startCoordinates, endCoordinates) {
    var map = L.map('map').setView(startCoordinates, 13);

    L.tileLayer('https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="https://www.openstreetmap.fr/copyright">OpenStreetMap</a>'
    }).addTo(map);

    L.Routing.control({
        waypoints: [
            L.latLng(startCoordinates),
            L.latLng(endCoordinates)
        ],
        routeWhileDragging: true
    }).addTo(map);
}

LeafletMap.razor:

@rendermode InteractiveServer

@inject HttpClient httpClient
@using Microsoft.JSInterop
@inject IJSRuntime JsRuntimeMap

<div id="map"></div>

@code {
    #region property
    public double[] StartCoordinates { get; set; }
    public double[] EndCoordinates { get; set; }
    [Parameter] public string StartCoordinatesAdresse { get; set; }
    [Parameter] public string EndCoordinatesAdresse { get; set; }

    private IJSObjectReference _jsModule;
    #endregion

    protected override async Task OnInitializedAsync()
    {
        httpClient = new HttpClient();
        httpClient.DefaultRequestHeaders.UserAgent.ParseAdd("TestLeaflet"); //your projectName
    }
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            try
            {
                _jsModule = await JsRuntimeMap.InvokeAsync<IJSObjectReference>("import", "/js/LeafletMap.js");
                StartCoordinates = await GetCoordinatesFromAddress(StartCoordinatesAdresse);
                EndCoordinates = await GetCoordinatesFromAddress(EndCoordinatesAdresse);
                if (StartCoordinates != null && EndCoordinates != null)
                {
                    await _jsModule.InvokeVoidAsync("initializeLeafletMap", StartCoordinates, EndCoordinates);
                }
            }
            catch (Exception ex)
            {
                // Log.WriteLogException(ex);
            }
        }
    }

    private async Task<double[]> GetCoordinatesFromAddress(string address)
    {
        try
        {
            string encodedAddress = Uri.EscapeDataString(address);
            string url = $"https://nominatim.openstreetmap.org/search?format=json&q={encodedAddress}&accept-language=fr";

            var response = await httpClient.GetFromJsonAsync<NominatimResponse[]>(url);

            if (response != null && response.Length > 0)
            {
                return new double[] { response[0].lat, response[0].lon };
            }
        }
        catch (Exception ex)
        {
            // Log.WriteLogException(ex);
        }
        return null;
    }

    public class NominatimResponse
    {
        public double lat { get; set; }
        public double lon { get; set; }
    }

    public async ValueTask DisposeAsync()
    {
        if (_jsModule != null)
        {
            await _jsModule.DisposeAsync();
        }
    }
}

Вопрос:

Как перевести правую сторону, где отображён маршрут?


Ответы (1 шт):

Автор решения: Solomon Fishkin

Нужно добавить указание языка в компоненте Router:

language: 'fr'

как указано здесь

"scripts": [
              "node_modules/leaflet-routing-machine/src/localization.js" 
            ]
L.Routing.control({
/....// <-- your others option
  language: 'nl', // <-- for langage use just this

// you don't need to add formatter
  formatter:  new L.Routing.Formatter({
    language: 'nl'
  }),

}).addTo(map);

или здесь

var text = router._formatter.formatInstruction(router._routes[0].instructions[0], 0);
var distance = router._formatter.formatDistance(router._routes[0].instructions[0].distance);
→ Ссылка