ホーム 記事一覧 ブック DH週間トピックス 検索 このサイトについて
English
MapLibre GL JS + れきちず で多言語対応の歴史地図を実装する

MapLibre GL JS + れきちず で多言語対応の歴史地図を実装する

歴史地図サービス「れきちず」が多言語対応(日本語・ひらがな・英語)したことを受けて、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> 使い方 HTMLファイルをWebサーバーで配信(ローカルファイルでは動作しません) アクセス例: index.html → 日本語(デフォルト) index.html?lang=en → 英語 index.html?lang=ja-Hira → ひらがな ポイント GETパラメータの取得 ...

IIIF Georeference ViewerのMapLibre GL移行と機能改善

IIIF Georeference ViewerのMapLibre GL移行と機能改善

本記事はAIが作成し、人間が追記しました。 概要 IIIF Georeference ViewerにおけるマップコンポーネントをLeafletからMapLibre GLへ移行し、複数の機能改善を実施しました。本記事では、実装した主要な機能とその技術的詳細について説明します。 https://nakamura196.github.io/iiif_geo/ 主要な改善点 1. 画像の自動回転機能 IIIF画像を地図上に正しい向きで表示するため、コントロールポイント(対応点)から自動的に回転角度を計算する機能を実装しました。 機能概要 画像座標と地理座標の対応点から、画像を北が上になるように回転させる角度を自動計算 2点間または3点以上の分布パターンから最適な回転角度を決定 URLパラメータによる回転角度の保存と復元 実装のポイント // utils/calculateImageRotation.ts export function calculateImageRotation(features: Feature[]): RotationCalculationResult | null { // 最も離れた2点を見つける(より正確な角度計算のため) const validFeatures = features.filter((f) => f.properties?.resourceCoords && f.geometry?.coordinates ); // 画像座標系でのベクトルと地理座標系でのベクトルから回転角度を計算 const imgVector = { x: img2.x - img1.x, y: img2.y - img1.y }; const geoVector = { x: geo2.lng - geo1.lng, y: geo2.lat - geo1.lat }; // 北を基準とした角度の差を計算 const rotationDeg = geoAngleFromNorthDeg - imgAngleDeg; return normalizeAngle(rotationDeg); } UI実装 自動回転ボタン(🔧アイコン)をOSDビューアーに配置 rotationパラメータが未指定の場合は自動的に回転角度を計算 手動での角度調整用スライダーも提供 2. LeafletからMapLibre GLへの移行 移行の背景 パフォーマンス向上 : MapLibre GLはWebGLベースのレンダリングにより、大量のマーカー表示時のパフォーマンスが向上 スムーズなアニメーション : 地図の移動やズーム時のアニメーションがより滑らかに ベクタータイルのサポート : ラスタータイルに加えてベクタータイルの表示が可能 実装のポイント import { Map, NavigationControl, Marker, Popup } from "maplibre-gl"; import "maplibre-gl/dist/maplibre-gl.css"; const mapInstance = ref<Map | null>(null); // MapLibre GL初期化 mapInstance.value = new Map({ container: mapContainer.value!, style: mapStyles.value[0].style, center: initialCenter, zoom: zoom_.value, attributionControl: false }); 3. 現在地表示機能 ブラウザのGeolocation APIを使用して、ユーザーの現在地を地図上に表示する機能を実装しました。 ...

「れきちず x Next.js」にルートの登録機能を追加しました。

「れきちず x Next.js」にルートの登録機能を追加しました。

概要 「れきちず x Next.js」はれきちずとNext.jsで作成されたウェブアプリケーションです。 このウェブアプリケーションに、ルートの登録機能を追加しましたので、紹介します。 機能紹介 トップページにアクセスし、「マイルートを管理」ボタンをクリックします。 以下のように、ログインが求められますので、画面右上の「ログイン」ボタンからログインします。 ログイン後、以下のような一覧画面が表示されます。 「ルートをインポート」ボタンを押すと以下のダイアログが表示されます。 「サンプルデータをダウンロード」ボタンを押すと、以下のようなGeoJSON形式のサンプルデータがダウンロードされます。 { "type": "FeatureCollection", "name": "東京観光サンプルルート", "description": "東京駅から皇居への観光ルートのサンプルです", "features": [ { "type": "Feature", "id": "tokyo-station", "properties": { "text": "東京駅", "where": "東京都千代田区丸の内一丁目にある、東日本旅客鉄道・東海旅客鉄道・東京地下鉄の駅", "type": "point" }, "geometry": { "type": "Point", "coordinates": [ 139.7673068, 35.6809591 ] } }, { "type": "Feature", "id": "imperial-palace", "properties": { "text": "皇居", "where": "日本の天皇及び皇族の居所", "type": "point" }, "geometry": { "type": "Point", "coordinates": [ 139.7528, 35.6852 ] } } ] } このファイルをアップロードすると、以下のような編集画面が表示されます。 編集ボタン(鉛筆マーク)から、タイトルや説明文の編集、および個々のマーカーの編集が可能です。 以下のエクスポートボタンを押すと、 geojson.ioでの表示画面に遷移します。 エクスポートの他、ローカル環境にダウンロードすることも可能です。 補足 現在は技術検証を目的として単純な機能の提供のみになっていますが、今後、いろいろな機能拡張を進めたいと思います。 まとめ れきちずやGeoJSONの応用にあたり、参考になりましたら幸いです。

「れきちず x Next.js」サイトにルートの登録機能を追加しました。

「れきちず x Next.js」サイトにルートの登録機能を追加しました。

概要 「れきちず x Next.js」サイトにルートの登録機能を追加しました。以下が表示例です。 参考 「れきちず x Next.js」サイトについては、以下で紹介しています。 この「れきちず」を使ってルートを表示する先行事例として、以下が挙げられます。 https://codh.rois.ac.jp/edomi/route/ 今回は上記の事例を参考に、ルートを作成する機能を追加しました。 使い方 サイトにアクセスします。 https://rekichizu-next.vercel.app/ja/ 「マイルートを管理」をクリックします。 ログインが求められますので、画面右上のボタンからログインします。 「新しいルートを作成」から、ルートを作成します。 以下が編集画面です。 編集アイコンをクリックすると、ルートのタイトルおよび説明を編集できます。 モードを「追加」に設定すると、地図上でクリックした箇所にピンが立ちます。ドラッグ&ドロップで移動させることも可能です。 マーカーはドラッグ&ドロップで順序変更することができます。 インポートとエクスポート エクスポート ルートの一覧画面と編集画面にダウンロードボタンを設置しています。以下のようなJSONファイルがダウンロードされます。 { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "id": "1744639551563", "text": "湯島天神", "where": "神社", "type": "point" }, "geometry": { "type": "Point", "coordinates": [ 139.76809921470056, 35.707702013817155 ] } }, { "type": "Feature", "properties": { "id": "1744639379903", "text": "不忍池", "where": "池", "type": "point" }, "geometry": { "type": "Point", "coordinates": [ 139.77050681034103, 35.71210499496915 ] } }, { "type": "Feature", "properties": { "id": "1744639551563-1744639379903", "path": "[1744639551563] -> [1744639379903]", "type": "line" }, "geometry": { "type": "LineString", "coordinates": [ [ 139.76809921470056, 35.707702013817155 ], [ 139.77050681034103, 35.71210499496915 ] ] } } ] } これをgeojson.ioに貼り付けると、以下のように表示されます。 ...

れきちずをNext.jsで使用する

れきちずをNext.jsで使用する

概要 れきちずをNext.jsで使用する方法を調べてみましたので、備忘録です。 背景 以下の記事で、「れきちず」の使い方を紹介しました。 そして、2025年4月4日に「全国版が公開」されたことを知りました。 https://rekichizu.jp/ そこでNext.jsを用いて作成したアプリケーションへの導入にあたり、その使い方を調べてみました。 デモアプリ 以下のようなアプリケーションを試作しました。 https://rekichizu-next.vercel.app/ja/ 使用方法の調査にあたり、公式サイトで提供されている地図の切り替えや重ね合わせ機能、および検索機能などを再現することを目的としました。この実装にあたり、以下のReactライブラリを使用しました。 https://visgl.github.io/react-maplibre/ 開発メモ 検索機能 検索機能には、GeoLODのAPIを利用させていただきました。なお、「れきちず」の公式サイトでは、専用の検索APIが用いられているようでした。 https://geolod.ex.nii.ac.jp/doc/api/ react-maplibre 本ライブラリを使用して、やりたいことの多くを実現できました。一方、TerrainControlではTerrainのON/OFFと合わせてピッチを変更することが難しい?、useMapではaddLayer/removeLayerが難しい?など、いくつか苦労した点もありました。 まとめ 「れきちず」およびNext.jsを用いたアプリケーション開発にあたり、参考になりましたら幸いです。 「れきちず」の開発に関わる方々に深く感謝いたします。