PMTiles 源和协议
使用 PMTiles 协议加载瓦片数据;
<!DOCTYPE html>
<html lang="en">
<head>
<title>PMTiles 源和协议</title>
<meta property="og:description" content="使用 PMTiles 协议加载瓦片数据" />
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.5.0/dist/maplibre-gl.css' />
<script src='https://unpkg.com/maplibre-gl@5.5.0/dist/maplibre-gl.js'></script>
<script src="https://unpkg.com/pmtiles@2.7.0/dist/index.js"></script>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
.info-box {
position: absolute;
top: 10px;
right: 10px;
background: white;
padding: 15px;
border-radius: 4px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
max-width: 300px;
font-family: 'Arial', sans-serif;
font-size: 14px;
line-height: 1.5;
z-index: 1;
}
.info-box h3 {
margin: 0 0 10px 0;
font-size: 16px;
border-bottom: 1px solid #eee;
padding-bottom: 8px;
}
.info-box p {
margin: 0 0 10px 0;
}
.info-box a {
color: #0078ff;
text-decoration: none;
}
.info-box a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div id="map"></div>
<div class="info-box">
<h3>关于 PMTiles</h3>
<p>PMTiles 是一种用于存储和检索地图瓦片的云优化格式。它允许从任何存储提供商直接提供瓦片数据,无需特殊的瓦片服务器。</p>
<p>此示例展示了如何使用 PMTiles 协议加载矢量瓦片数据。</p>
<p><a href="https://github.com/protomaps/PMTiles" target="_blank">了解更多 PMTiles →</a></p>
</div>
<script>
// 初始化 PMTiles 协议
let protocol = new pmtiles.Protocol();
maplibregl.addProtocol("pmtiles", protocol.tile);
// 创建新的地图
const map = new maplibregl.Map({
container: 'map',
style: {
version: 8,
sources: {
// 添加 PMTiles 源
'pmtiles-source': {
type: 'vector',
url: 'pmtiles://https://r2-public.protomaps.com/protomaps-sample-datasets/protomaps-basemap-opensource-20230408.pmtiles',
attribution: '<a href="https://protomaps.com">Protomaps</a> © <a href="https://openstreetmap.org">OpenStreetMap</a>'
}
},
// 定义一些基本图层以展示地图数据
layers: [
// 背景
{
id: 'background',
type: 'background',
paint: {
'background-color': '#f8f8f8'
}
},
// 水体
{
id: 'water',
type: 'fill',
source: 'pmtiles-source',
'source-layer': 'water',
paint: {
'fill-color': '#a4d1ef'
}
},
// 土地利用区域
{
id: 'landuse',
type: 'fill',
source: 'pmtiles-source',
'source-layer': 'landuse',
paint: {
'fill-color': [
'match',
['get', 'pmap:kind'],
'park', '#c8facc',
'residential', '#fcebe1',
'industrial', '#f9ebe2',
'commercial', '#f1e0e9',
'forest', '#c8facc',
'#e8e8e8' // 默认颜色
],
'fill-opacity': 0.5
}
},
// 道路
{
id: 'roads',
type: 'line',
source: 'pmtiles-source',
'source-layer': 'roads',
paint: {
'line-color': [
'match',
['get', 'pmap:kind'],
'highway', '#ff9900',
'major_road', '#ff9900',
'minor_road', '#ffcc99',
'path', '#d3d3d3',
'#ffffff' // 默认颜色
],
'line-width': [
'interpolate', ['linear'], ['zoom'],
5, 0.5,
10, [
'match',
['get', 'pmap:kind'],
'highway', 3,
'major_road', 2,
'minor_road', 1,
'path', 0.5,
0.5 // 默认宽度
],
15, [
'match',
['get', 'pmap:kind'],
'highway', 6,
'major_road', 4,
'minor_road', 2,
'path', 1,
1 // 默认宽度
]
]
}
},
// 建筑
{
id: 'buildings',
type: 'fill',
source: 'pmtiles-source',
'source-layer': 'buildings',
minzoom: 14,
paint: {
'fill-color': '#e0dcd8',
'fill-outline-color': '#c7c1ba',
'fill-opacity': 0.8
}
},
// 地名标签
{
id: 'places-labels',
type: 'symbol',
source: 'pmtiles-source',
'source-layer': 'places',
layout: {
'text-field': ['get', 'name'],
'text-size': [
'interpolate', ['linear'], ['zoom'],
4, [
'match',
['get', 'pmap:kind'],
'country', 14,
'state', 10,
'city', 8,
'town', 6,
0 // 隐藏其他类型
],
10, [
'match',
['get', 'pmap:kind'],
'country', 22,
'state', 16,
'city', 14,
'town', 12,
'village', 10,
'hamlet', 8,
0 // 隐藏其他类型
]
],
'text-anchor': 'center',
'text-transform': [
'match',
['get', 'pmap:kind'],
'country', 'uppercase',
'normal'
],
'text-letter-spacing': [
'match',
['get', 'pmap:kind'],
'country', 0.1,
0
]
},
paint: {
'text-color': '#4a4a4a',
'text-halo-color': '#ffffff',
'text-halo-width': 1.5
}
}
]
},
center: [0, 20],
zoom: 2
});
// 添加导航控件
map.addControl(new maplibregl.NavigationControl());
// 地图加载时的处理
map.on('load', function() {
// 在此添加任何地图加载后的操作
});
</script>
</body>
</html>