preview-leaflet について
JavaScriptコードや地図ファイルから、Leafletのインタラクティブな地図をブラウザーでプレビューするスキルです。HTMLを生成する実行スクリプトを備え、地理データの可視化を行うエージェント向けです。
主な機能
- 01Leafletのインタラクティブ地図をプレビュー
- 02マーカー、ルート、図形の表示
- 03複数のタイルレイヤーに対応
- 04ポップアップとホバーツールチップ
- 05HTMLを生成してブラウザーで表示
活用シーン
- 01地図上への地点のプロット
- 02地点間ルートの可視化
- 03サービスエリアや地域の表示
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ veelenga/ preview-skills --skill preview-leafletインストール後、Claude Code で/preview-leafletを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
config.shrun.shlib/browser-utils.shcontent-utils.shhtml-generator.shtemplates/user-code-template.htmltemplates/scripts/common-ui.jsleaflet-renderer.jsutils.jstemplates/styles/common.csslayout.cssleaflet.css詳細
Leaflet スキルをプレビュー
Leaflet ライブラリを使用して、地理データ、マーカー、ルート、カスタムオーバーレイをインタラクティブな地図で表示します。
エージェントでの使用方法
ユーザーから地図の可視化を求められたら、Leaflet コードを記述してスクリプトにパイプで渡します。Bash ツールを使用して、このスキルの run.sh スクリプトを実行します。
# Pipe Leaflet code
cat route.js | ./run.sh
# Or from a file
./run.sh city-map.leaflet
このスクリプトは HTML の生成をすべて処理し、結果をブラウザーで自動的に開きます。タブが重複して開くのを避けるため、ファイルを手動で開かないでください。
使用方法
# Preview a Leaflet map file
/preview-leaflet city-map.leaflet
# Or use .map extension
/preview-leaflet route.map
# Pipe Leaflet code (preferred for temporary content)
cat route.js | /preview-leaflet
echo "const map = L.map('map').setView([51.505, -0.09], 13);" | /preview-leaflet
ベストプラクティス: 一時的な地図や生成する地図には、一時ファイルを作成するのではなく、パイプで渡す方法をおすすめします。ファイルシステムが散らからず、内容も自動的にクリーンアップされます。
オプション
スクリプトは適切なデフォルト値で動作しますが、柔軟に使用できる以下のフラグにも対応しています。
-o, --output PATH- 出力先のカスタムパス--no-browser- ブラウザーを開かず、出力ファイルのパスのみを表示
機能
- インタラクティブな地図:パンとズームに対応
- マーカーとポップアップ:地点を表示
- ルートとパス:ポリラインで表示
- 図形とエリア:ポリゴンや円で表示
- 複数のタイルレイヤー(OpenStreetMap、CartoDB など)
- ホバー時のツールチップ
- すべての地点が表示されるように表示範囲を調整
- 表示をリセットするボタン
- コードビューアーの切り替え
- レスポンシブデザイン:ウィンドウサイズに合わせて調整
このスキルを使用する場面
ユーザーが以下を希望する場合に、このスキルを使用します。
- 地図上に地理データを表示する
- マーカーで地点をプロットする
- 地点間のルートを描画する
- サービスエリアや地域を表示する
- 位置情報に基づくインタラクティブな可視化を作成する
Leaflet コードの要件
コードでは、以下を行う必要があります。
L.map('map').setView([lat, lng], zoom)で地図を初期化する- タイルレイヤーを追加する(地図画像を提供します)
- マーカー、パス、その他のフィーチャーを追加する
実行コンテキスト
コードは以下の環境で実行されます。
- Leaflet v1.9.4 を
Lとして利用可能 - 地図コンテナー
#mapは DOM 内でサイズが設定され、使用可能な状態
完全な例 - マーカー付きのシンプルな地図
// Initialize map centered on London
const map = L.map('map').setView([51.505, -0.09], 13);
// Add OpenStreetMap tiles (REQUIRED - map is blank without this)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 18,
}).addTo(map);
// Add a marker
L.marker([51.505, -0.09]).addTo(map).bindPopup('Hello World!').openPopup();
完全な例 - 複数地点を結ぶルート
// Initialize map
const map = L.map('map').setView([40.7128, -74.006], 12);
// Add tiles (REQUIRED)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 18,
}).addTo(map);
// Define route points
const route = [
[40.7128, -74.006], // New York
[40.758, -73.9855], // Times Square
[40.7614, -73.9776], // Central Park
];
// Draw route
L.polyline(route, {
color: 'red',
weight: 3,
}).addTo(map);
// Add markers
route.forEach((point, i) => {
L.marker(point)
.addTo(map)
.bindPopup(`Stop ${i + 1}`);
});
// Fit map to show all points
map.fitBounds(L.latLngBounds(route), { padding: [50, 50] });
よく使われるパターン
マーカー
// Simple marker
L.marker([51.5, -0.09]).addTo(map);
// With popup
L.marker([51.5, -0.09]).addTo(map).bindPopup('Location name');
// Circle marker (fixed pixel size)
L.circleMarker([51.5, -0.09], {
radius: 8,
fillColor: '#3498db',
color: 'white',
weight: 2,
fillOpacity: 0.9,
}).addTo(map);
線と図形
// Polyline (route/path)
L.polyline(
[
[51.5, -0.09],
[51.51, -0.08],
[51.52, -0.07],
],
{
color: 'red',
weight: 3,
}
).addTo(map);
// Polygon (area)
L.polygon(
[
[51.5, -0.09],
[51.51, -0.08],
[51.52, -0.09],
],
{
color: 'blue',
fillOpacity: 0.5,
}
).addTo(map);
// Circle (fixed radius in meters)
L.circle([51.5, -0.09], {
radius: 500, // meters
color: 'red',
fillOpacity: 0.5,
}).addTo(map);
ポップアップとツールチップ
// HTML in popup
marker.bindPopup(`
<div>
<h3>Location Name</h3>
<p>Description here</p>
</div>
`);
// Tooltip (shows on hover)
marker.bindTooltip('Tooltip text', {
permanent: false,
direction: 'top',
});
// Permanent tooltip (always visible)
marker.bindTooltip('Always visible', {
permanent: true,
direction: 'right',
});
表示範囲の制御
// Set view (instant)
map.setView([51.5, -0.09], 13);
// Fly to (animated)
map.flyTo([51.5, -0.09], 13, {
duration: 2, // seconds
});
// Fit bounds to show all features
const bounds = L.latLngBounds([
[51.49, -0.1],
[51.51, -0.08],
]);
map.fitBounds(bounds, {
padding: [50, 50],
});
タイルレイヤー(地図スタイル)
OpenStreetMap(無料、デフォルト)
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
maxZoom: 18,
}).addTo(map);
CartoDB Light(すっきりとしたミニマルなスタイル)
L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap, © CartoDB',
maxZoom: 18,
}).addTo(map);
CartoDB Dark
L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap, © CartoDB',
maxZoom: 18,
}).addTo(map);
完全な例 - 複数の地点
// Initialize map
const map = L.map('map').setView([37.7749, -122.4194], 10);
// Add tiles
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
}).addTo(map);
// Locations data
const locations = [
{ name: 'San Francisco', coords: [37.7749, -122.4194], type: 'city' },
{ name: 'Oakland', coords: [37.8044, -122.2712], type: 'city' },
{ name: 'Berkeley', coords: [37.8715, -122.273], type: 'city' },
];
// Add markers
locations.forEach((loc) => {
const color = loc.type === 'city' ? 'blue' : 'red';
L.circleMarker(loc.coords, {
radius: 8,
fillColor: color,
color: 'white',
weight: 2,
fillOpacity: 0.8,
})
.addTo(map)
.bindPopup(`<strong>${loc.name}</strong><br/>Type: ${loc.type}`);
});
// Fit map to show all locations
const allCoords = locations.map((loc) => loc.coords);
map.fitBounds(L.latLngBounds(allCoords), { padding: [50, 50] });
座標の形式
Leaflet では [latitude, longitude] の形式を使用します。
- 緯度:-90~90(南から北)
- 経度:-180~180(西から東)
例:
- ニューヨーク:
[40.7128, -74.0060] - ロンドン:
[51.5074, -0.1278] - 東京:
[35.6762, 139.6503] - シドニー:
[-33.8688, 151.2093]
よくある間違い: 座標を [lng, lat] の順に逆にすることです。必ず [lat, lng] を使用してください。
組み込み機能
- パン/ズーム - クリックしてドラッグするとパンし、スクロールするとズームします
- ズームボタン - 左上の +/- コントロール
- 表示をリセット - 初期表示に戻すボタン
- コードビューアー - ソースの表示/非表示を切り替え
- レスポンシブ対応 - ウィンドウに合わせて自動的にサイズを変更
ズームレベル
- 1:世界全体
- 5:大陸
- 10:都市
- 15:道路
- 18:建物
ベストプラクティス
- 必ずタイルレイヤーを追加する - 追加しないと地図は空白になります
- 適切なズームレベルを使用する - 1(世界全体)~18(道路レベル)
- 複数地点の地図には fitBounds() を使用する - すべてのフィーチャーが表示されます
- データをコードに埋め込む - 座標を直接含めます
- 座標の順序を確認する -
[lng, lat]ではなく[lat, lng]を使用します
トラブルシューティング
地図が空白または灰色で表示される
.addTo(map)でタイルレイヤーを追加していることを確認します- 座標が有効な形式(
[lat, lng])であることを確認します - インターネット接続を確認します(タイルは CDN から読み込まれます)
- ブラウザーのコンソールで、タイルに関する 404 エラーを確認します
マーカーが表示されない
- 座標の形式を確認します:
[latitude, longitude] - マーカーに
.addTo(map)が呼び出されていることを確認します - 座標が現在の表示範囲内にあることを確認します
- すべてのマーカーを表示するには、fitBounds() を使用してみてください
タイルが読み込まれない
- インターネット接続を確認してください
- タイルの URL が正しいことを確認してください
- ブラウザーのコンソールで 404 エラーを確認してください
- 別のタイルプロバイダーを試してください
表示される場所が正しくない
- 座標が正しいことを確認してください
- 座標の順序を確認してください(最初が緯度、2 番目が経度)
- ズームレベルが適切であることを確認してください
技術的な詳細
ファイル要件
- ファイル拡張子:
.leaflet - 最大サイズ:10MB(設定可能)
- 有効な JavaScript コード
- 自己完結型(外部データファイルは不要)
ブラウザーの互換性
- 最新のブラウザー(Chrome、Firefox、Safari、Edge)
- JavaScript の有効化が必要です
- タイルの読み込みにはインターネット接続が必要です
- CDN に依存:Leaflet v1.9.4
出力
このスキルは、次の場所にスタンドアロンの HTML ファイルを生成します。
.preview-skills/leaflet/{filename}.html
開発
このスキルはスタンドアロンで、すべての依存関係を含みます。
- 共有ライブラリは
lib/にバンドルされています - テンプレートは
templates/にバンドルされています - 外部 CDN 依存関係:Leaflet v1.9.4
スキルを変更するには:
- 設定を変更するには
config.shを編集します - 動作を変更するには
templates/scripts/leaflet-renderer.jsを編集します - スタイルを変更するには
templates/styles/leaflet.cssを編集します - 変更をテストするには
run.shを実行します
詳細はこちら
- Leaflet ドキュメント:https://leafletjs.com/
- Leaflet チュートリアル:https://leafletjs.com/examples.html
- タイルプロバイダー:https://leaflet-extras.github.io/leaflet-providers/preview/