可变标签放置
根据缩放级别放置标签;
<!DOCTYPE html>
<html lang="en">
<head>
<title>可变标签放置</title>
<meta property="og:description" content="根据缩放级别放置标签" />
<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>
<style>
body { margin: 0; padding: 0; }
html, body, #map { height: 100%; }
.map-overlay {
position: absolute;
bottom: 20px;
right: 20px;
background: rgba(255, 255, 255, 0.9);
padding: 15px;
border-radius: 5px;
font-family: Arial, sans-serif;
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.15);
max-width: 400px;
z-index: 100;
}
.map-overlay h3 {
margin: 0 0 10px 0;
font-size: 16px;
border-bottom: 1px solid #ddd;
padding-bottom: 5px;
}
.map-overlay p {
font-size: 13px;
line-height: 1.5;
margin: 0 0 8px 0;
color: #333;
}
.map-overlay .zoom-level {
font-weight: bold;
color: #3887be;
font-size: 1.2em;
}
.map-overlay table {
width: 100%;
font-size: 12px;
margin-top: 10px;
border-collapse: collapse;
}
.map-overlay th, .map-overlay td {
padding: 5px;
text-align: left;
border-bottom: 1px solid #eee;
}
.map-overlay th {
font-weight: bold;
}
</style>
</head>
<body>
<div id="map"></div>
<div class="map-overlay">
<h3>可变标签放置</h3>
<p>当前缩放级别: <span id="zoom-level" class="zoom-level">2</span></p>
<p>此示例展示了如何根据地图的缩放级别更改标签的位置。随着地图放大或缩小,标签会在不同的位置显示。</p>
<table>
<tr>
<th>缩放级别范围</th>
<th>标签位置</th>
</tr>
<tr>
<td>0 - 3</td>
<td>中心</td>
</tr>
<tr>
<td>3 - 6</td>
<td>右上</td>
</tr>
<tr>
<td>6 - 9</td>
<td>右下</td>
</tr>
<tr>
<td>9 - 12</td>
<td>左下</td>
</tr>
<tr>
<td>12+</td>
<td>左上</td>
</tr>
</table>
</div>
<script>
// 初始化地图
const map = new maplibregl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/streets/style.json?key=get_your_own_OpIi9ZULNHzrESv6T2vL',
center: [0, 30],
zoom: 2,
maxZoom: 16
});
// 添加导航控件
map.addControl(new maplibregl.NavigationControl());
// 更新页面中显示的缩放级别
const zoomLevelElement = document.getElementById('zoom-level');
map.on('load', () => {
// 添加一些示例点
const cities = [
{ name: '北京', coordinates: [116.4074, 39.9042] },
{ name: '纽约', coordinates: [-74.0060, 40.7128] },
{ name: '伦敦', coordinates: [-0.1278, 51.5074] },
{ name: '东京', coordinates: [139.6917, 35.6895] },
{ name: '悉尼', coordinates: [151.2093, -33.8688] },
{ name: '开罗', coordinates: [31.2357, 30.0444] },
{ name: '里约热内卢', coordinates: [-43.1729, -22.9068] },
{ name: '开普敦', coordinates: [18.4241, -33.9249] },
{ name: '莫斯科', coordinates: [37.6173, 55.7558] },
{ name: '孟买', coordinates: [72.8777, 19.0760] }
];
// 添加示例数据
map.addSource('cities', {
'type': 'geojson',
'data': {
'type': 'FeatureCollection',
'features': cities.map(city => ({
'type': 'Feature',
'properties': {
'name': city.name
},
'geometry': {
'type': 'Point',
'coordinates': city.coordinates
}
}))
}
});
// 添加点图层
map.addLayer({
'id': 'city-points',
'type': 'circle',
'source': 'cities',
'paint': {
'circle-radius': 6,
'circle-color': '#3887be',
'circle-stroke-width': 2,
'circle-stroke-color': 'white'
}
});
// 添加标签图层
map.addLayer({
'id': 'city-labels',
'type': 'symbol',
'source': 'cities',
'layout': {
'text-field': ['get', 'name'],
'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],
'text-size': 12,
// 根据缩放级别变化标签相对于点的位置
'text-anchor': [
'step',
['zoom'],
'center', // 默认是中心
3, 'top-right', // 缩放级别 ≥ 3
6, 'bottom-right', // 缩放级别 ≥ 6
9, 'bottom-left', // 缩放级别 ≥ 9
12, 'top-left' // 缩放级别 ≥ 12
],
'text-offset': [
'step',
['zoom'],
['literal', [0, 0]], // 默认无偏移
3, ['literal', [0.5, -0.5]], // 缩放级别 ≥ 3
6, ['literal', [0.5, 0.5]], // 缩放级别 ≥ 6
9, ['literal', [-0.5, 0.5]], // 缩放级别 ≥ 9
12, ['literal', [-0.5, -0.5]] // 缩放级别 ≥ 12
],
'text-allow-overlap': false,
'text-ignore-placement': false
},
'paint': {
'text-color': '#333',
'text-halo-color': 'rgba(255, 255, 255, 0.9)',
'text-halo-width': 2
}
});
});
// 监听缩放事件并更新标签位置说明
map.on('zoom', () => {
const currentZoom = Math.floor(map.getZoom() * 10) / 10; // 精确到小数点后一位
zoomLevelElement.textContent = currentZoom;
});
</script>
</body>
</html>