歴史地図サービス「れきちず」が多言語対応(日本語・ひらがな・英語)したことを受けて、MapLibre GL JS で言語切り替えに対応した地図を実装する方法を紹介します。

れきちずとは

れきちずは、江戸時代後期(1800〜1840年ごろ)の地図を現代風のデザインで閲覧できるWebサービスです。2025年11月に多言語対応が追加され、以下の3つのスタイルが提供されています。

言語スタイルURL
日本語https://mierune.github.io/rekichizu-style/styles/street/style.json
ひらがなhttps://mierune.github.io/rekichizu-style/styles/street/style_hira.json
英語https://mierune.github.io/rekichizu-style/styles/street/style_en.json

シンプルなHTML版

フレームワークを使わず、素のHTML + JavaScriptだけで実装する例です。GETパラメータ(?lang=en)に応じて表示言語を切り替えます。

完全なHTMLファイル

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>れきちず 多言語対応デモ</title>
  <script src="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
  <link href="https://unpkg.com/maplibre-gl@4.7.1/dist/maplibre-gl.css" rel="stylesheet" />
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: sans-serif; }
    #map { width: 100%; height: calc(100vh - 50px); }
    .controls {
      height: 50px;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 8px;
      background: #f5f5f5;
      border-bottom: 1px solid #ddd;
    }
    .lang-btn {
      padding: 8px 16px;
      border: 1px solid #ccc;
      border-radius: 4px;
      background: white;
      cursor: pointer;
      font-size: 14px;
      transition: all 0.2s;
    }
    .lang-btn:hover { background: #e0e0e0; }
    .lang-btn.active {
      background: #2196F3;
      color: white;
      border-color: #2196F3;
    }
  </style>
</head>
<body>
  <div class="controls">
    <button class="lang-btn" data-lang="ja">日本語</button>
    <button class="lang-btn" data-lang="ja-Hira">ひらがな</button>
    <button class="lang-btn" data-lang="en">English</button>
  </div>
  <div id="map"></div>

  <script>
    // れきちずのスタイルURL
    const STYLES = {
      'ja': 'https://mierune.github.io/rekichizu-style/styles/street/style.json',
      'ja-Hira': 'https://mierune.github.io/rekichizu-style/styles/street/style_hira.json',
      'en': 'https://mierune.github.io/rekichizu-style/styles/street/style_en.json'
    };

    // GETパラメータから言語を取得
    function getLangFromUrl() {
      const params = new URLSearchParams(window.location.search);
      const lang = params.get('lang');
      return STYLES[lang] ? lang : 'ja'; // デフォルトは日本語
    }

    // 現在の言語
    let currentLang = getLangFromUrl();

    // 地図を初期化
    const map = new maplibregl.Map({
      container: 'map',
      style: STYLES[currentLang],
      center: [139.7671, 35.6812], // 東京駅
      zoom: 12
    });

    map.addControl(new maplibregl.NavigationControl(), 'top-right');

    // ボタンのアクティブ状態を更新
    function updateButtons() {
      document.querySelectorAll('.lang-btn').forEach(btn => {
        btn.classList.toggle('active', btn.dataset.lang === currentLang);
      });
    }

    // URLを更新(履歴に追加)
    function updateUrl(lang) {
      const url = new URL(window.location);
      url.searchParams.set('lang', lang);
      window.history.pushState({}, '', url);
    }

    // 言語切り替え
    function switchLang(lang) {
      if (lang === currentLang) return;

      currentLang = lang;
      map.setStyle(STYLES[lang]);
      updateUrl(lang);
      updateButtons();
    }

    // ボタンのクリックイベント
    document.querySelectorAll('.lang-btn').forEach(btn => {
      btn.addEventListener('click', () => switchLang(btn.dataset.lang));
    });

    // ブラウザの戻る/進むに対応
    window.addEventListener('popstate', () => {
      const lang = getLangFromUrl();
      if (lang !== currentLang) {
        currentLang = lang;
        map.setStyle(STYLES[lang]);
        updateButtons();
      }
    });

    // 初期状態を設定
    updateButtons();
  </script>
</body>
</html>

使い方

  1. HTMLファイルをWebサーバーで配信(ローカルファイルでは動作しません)
  2. アクセス例:
    • index.html → 日本語(デフォルト)
    • index.html?lang=en → 英語
    • index.html?lang=ja-Hira → ひらがな

ポイント

GETパラメータの取得

const params = new URLSearchParams(window.location.search);
const lang = params.get('lang'); // 'en', 'ja-Hira', または null

URLの更新(ページ遷移なし)

const url = new URL(window.location);
url.searchParams.set('lang', 'en');
window.history.pushState({}, '', url); // 履歴に追加

ブラウザの戻る/進む対応

window.addEventListener('popstate', () => {
  // URLから言語を再取得して地図を更新
});

注意点

スタイル切り替え時のレイヤー再設定

map.setStyle() を呼ぶと、追加したソースやレイヤーがすべてリセットされます。そのため、style.load イベントを監視して再設定する必要があります。

map.setStyle(STYLES[lang]);

// 重要: スタイル読み込み後にレイヤーを再設定
map.once('style.load', () => {
  setupLayers();
});

データ利用について

れきちずのタイルデータ・スタイルは CC BY-NC-ND 4.0 の下で利用できます。商用利用の場合は、れきちずの運営(株式会社MIERUNE)にお問い合わせください。

まとめ

  • れきちずは日本語・ひらがな・英語の3つのスタイルを提供
  • GETパラメータで言語を指定(?lang=en
  • map.setStyle() で動的にスタイルを切り替え
  • スタイル変更後は style.load イベントでレイヤーを再設定

歴史地図と多言語対応を組み合わせることで、海外の方にも日本の歴史的な地名や街道を楽しんでもらえるアプリケーションが作れます。

参考リンク