🗣️

Mapbox Newsletter WEEKLY TIPSの解説 -「マップの言語を変更」

2023/11/30に公開

はじめに

この記事は、先日配信されたMapbox NewsletterのWEEKLY TIPSで紹介されていた「マップの言語を変更」についての解説です。Mapbox Streets v8ベクタータイルセットは多言語対応なので簡単に表示する言語を切り替えることができます。また、Newsletterの購読はこちらからお申し込みいただけます。

以下が本サンプルのデモです。

コードを確認

まずExamplesのコードを見に行きましょう。

日本語サイト

英語サイト

基本的に同じコードですが、英語版はスタイルがMapbox Light v11にアップグレードされているのでこちらを使用します。Mapbox Light v10ではデフォルトのプロジェクションがWebメルカトルであるのに対し、Mapbox Light v11ではGlobe(3D表示された地球)なので、印象がかなり異なります。

HTML/CSS

まずCSSです。

以下はボタンをまとめるulタグのスタイルです。

#buttons {
  width: 90%;
  margin: 0 auto;
}

以下は各ボタンを表現するliタグのスタイルです。

.button {
  display: inline-block;
  position: relative;
  cursor: pointer;
  width: 20%;
  padding: 8px;
  border-radius: 3px;
  margin-top: 10px;
  font-size: 12px;
  text-align: center;
  color: #fff;
  background: #ee8a65;
  font-family: sans-serif;
  font-weight: bold;
}

次にHTMLです。

以下は地図を表示するエレメントを作成しています。

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

以下はボタンです。

<ul id="buttons">
<li id="button-fr" class="button">French</li>
<li id="button-ru" class="button">Russian</li>
<li id="button-de" class="button">German</li>
<li id="button-es" class="button">Spanish</li>
</ul>

Mapの作成

JavaScriptのコードを見ていきます。以下のコードはいつも通り、Mapオブジェクトを作成しています。containerで地図を表示するHTMLエレメントのidを指定します。

const map = new mapboxgl.Map({
  container: 'map',
  // Choose from Mapbox's core styles, or make your own style with Mapbox Studio
  style: 'mapbox://styles/mapbox/light-v11',
  center: [16.05, 48],
  zoom: 2.9
});

次にボタンクリック時の動作を記述します。

getElementByIdbuttonsエレメント(ボタンをまとめるulタグ)を取得し、それに対しaddEventListenerclickイベントの処理を記述します。

document.getElementById('buttons').addEventListener('click', (event) => {
  //中身
});

ulに対するクリックイベントですが、子要素のliがクリックされるとevent.target.idにはliidが格納されています。idbutton-という文字列を削除したものがlanguageに格納されます。これはbutton-length分を飛ばした位置を開始位置とする文字列を取得しているためです。

const language = event.target.id.substr('button-'.length);

Map#setLayoutPropertyは第一引数にレイヤーID、第二引数に変更したいレイヤープロパティの名称、第三引数に変更後の値を入れます。country-labelはシンボルレイヤーなので、文字列ラベルはtext-fieldプロパティで指定します。この値を言語コードに対応したソースプロパティから読んできます。

例えば、Frenchがクリックされた場合、country-labeltext-fieldプロパティに対し、['get', 'name_fr']という値が使用されます。

map.setLayoutProperty('country-label', 'text-field', [
  'get',
  `name_${language}`
]);

実際、データを見てみるとname_言語コードというプロパティが入っています。
country label

サポートされている言語一覧についてはこちらをご参照ください。

まとめ

元のデータが多言語対応だったので、setLayoutProertyで参照するソースプロパティを切り替えるだけで言語を変更できました。だたし、今回はcountry-labelのみ変更したので、都市名等は英語のままです。すべての表示言語を切り替えるためにはstate-label等、関連するレイヤー全てに対し同様の変更が必要です。

GitHubで編集を提案
マップボックス・ジャパン合同会社

Discussion