关于 preview-leaflet
用于将 JavaScript 代码或地图文件生成 Leaflet 交互式地图预览的技能,适合制作地理可视化的 Agent。运行脚本会生成 HTML,并可自动在浏览器中打开。
主要功能
- 01预览 Leaflet 交互式地图
- 02显示标记、路线和形状
- 03支持多种地图图层
- 04提供弹出框和悬停提示
- 05生成 HTML 并在浏览器打开
适用场景
- 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 库交互式查看地理数据、标记、路线和自定义叠加层。
Agent 用法
当用户要求创建地图可视化时,编写 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)初始化地图 - 添加瓦片图层(提供地图图像)
- 添加标记、路径或其他要素
执行环境
代码运行时具备:
- 可用作
L的 Leaflet v1.9.4 - 尺寸已设置且在 DOM 中就绪的地图容器
#map
完整示例 - 带标记的简单地图
// 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() - 显示所有要素
- 将数据嵌入代码 - 直接包含坐标
- 确认坐标顺序 - 使用
[lat, lng],而不是[lng, lat]
故障排除
地图显示为空白/灰色
- 确认已使用
.addTo(map)添加瓦片图层 - 检查坐标是否有效(
[lat, lng]格式) - 确认网络连接正常(瓦片从 CDN 加载)
- 检查浏览器控制台中是否有瓦片 404 错误
标记未显示
- 检查坐标格式:
[latitude, longitude] - 确认已对标记调用
.addTo(map) - 确认坐标位于当前视图范围内
- 尝试使用 fitBounds() 查看所有标记
瓦片无法加载
- 检查互联网连接
- 确认瓦片 URL 正确
- 查看浏览器控制台中是否有 404 错误
- 尝试使用其他瓦片提供方
显示的位置不正确
- 确认坐标正确
- 检查坐标顺序(先纬度,后经度)
- 确保缩放级别合适
技术细节
文件要求
- 文件扩展名:
.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/
评论
支持 Markdown