覆盖层图层 (OverlayLayer)
覆盖层图层用于在地图上叠加单个 HTML 元素,适合标注、弹窗等场景。
信息
每个 OverlayLayer 只能显示一个覆盖层。如果需要多个覆盖层,请创建多个 OverlayLayer 实例。
基本用法
import { OverlayLayer } from 'mapjar';
// 创建覆盖层图层
const overlayLayer = new OverlayLayer('popup');
engine.addLayer(overlayLayer);
// 创建 HTML 元素
const element = document.createElement('div');
element.innerHTML = `
<div style="
background: white;
padding: 10px 15px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
">
<h3 style="margin: 0 0 5px 0;">北京</h3>
<p style="margin: 0; color: #666;">中国首都</p>
</div>
`;
// 设置覆盖层
overlayLayer.setOverlay({
element: element,
position: {
lon: 116.4074,
lat: 39.9042,
offset: [0, -20],
anchor: [0.5, 1.0],
},
visible: true,
});
接口定义
Overlay
interface Overlay {
element: HTMLElement; // HTML 元素
position: OverlayPosition; // 位置配置
visible?: boolean; // 是否可见(默认 true)
properties?: Record<string, unknown>; // 自定义属性
}
OverlayPosition
interface OverlayPosition {
lon: number; // 经度
lat: number; // 纬度
offset?: [number, number]; // 偏移 [x, y](默认 [0, 0])
anchor?: [number, number]; // 锚点 [x, y](默认 [0.5, 0.5])
}
锚点说明
锚点决定 HTML 元素相对于地理位置的对齐方式:
// 锚点坐标系:
// [0, 0] - 左上角
// [0.5, 0] - 顶部中心
// [1, 0] - 右上角
// [0, 0.5] - 左侧中心
// [0.5, 0.5] - 中心(默认)
// [1, 0.5] - 右侧中心
// [0, 1] - 左下角
// [0.5, 1] - 底部中心(适合标注)
// [1, 1] - 右下角
常用锚点示例
// 标注(Marker)- 底部中心
overlayLayer.setOverlay({
element: markerElement,
position: {
lon: 116.4074,
lat: 39.9042,
anchor: [0.5, 1.0], // 底部中心
offset: [0, -10], // 向上偏移 10px
},
});
// 弹窗(Popup)- 底部中心
overlayLayer.setOverlay({
element: popupElement,
position: {
lon: 116.4074,
lat: 39.9042,
anchor: [0.5, 1.0], // 底部中心
offset: [0, -20], // 向上偏移 20px
},
});
// 图标(Icon)- 中心
overlayLayer.setOverlay({
element: iconElement,
position: {
lon: 116.4074,
lat: 39.9042,
anchor: [0.5, 0.5], // 中心
},
});
管理覆盖层
更新覆盖层
// 更新部分属性
overlayLayer.updateOverlay({
position: {
lon: 116.5,
lat: 40.0,
},
});
// 更新可见性
overlayLayer.updateOverlay({
visible: false,
});
// 更新元素内容
const newElement = document.createElement('div');
newElement.innerHTML = '<h3>更新后的内容</h3>';
overlayLayer.updateOverlay({
element: newElement,
});
获取覆盖层
const overlay = overlayLayer.getOverlay();
if (overlay) {
console.log('当前位置:', overlay.position);
console.log('是否可见:', overlay.visible);
}
清除覆盖层
overlayLayer.clearOverlay();
多个覆盖层
如果需要显示多个覆盖层,创建多个 OverlayLayer 实例:
// 标注图层
const markerLayer = new OverlayLayer('marker');
markerLayer.setZIndex(20);
engine.addLayer(markerLayer);
// 弹窗图层
const popupLayer = new OverlayLayer('popup');
popupLayer.setZIndex(30);
engine.addLayer(popupLayer);
// 设置标注
markerLayer.setOverlay({
element: markerElement,
position: { lon: 116.4074, lat: 39.9042 },
});
// 设置弹窗
popupLayer.setOverlay({
element: popupElement,
position: { lon: 116.4074, lat: 39.9042, offset: [0, -40] },
});
完整示例
点击显示弹窗
import { MapEngine, TileLayer, OverlayLayer } from 'mapjar';
const engine = new MapEngine('#map', {
center: [116.4074, 39.9042],
zoom: 10,
});
// 添加底图
const tileLayer = new TileLayer(
'osm',
'https://tile.openstreetmap.org/{z}/{x}/{y}.png'
);
engine.addLayer(tileLayer);
// 创建弹窗图层
const popupLayer = new OverlayLayer('popup');
popupLayer.setZIndex(100);
engine.addLayer(popupLayer);
// 监听点击事件
engine.on('click', (event) => {
// 创建弹窗元素
const element = document.createElement('div');
element.innerHTML = `
<div style="
background: white;
padding: 12px 16px;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0,0,0,0.3);
min-width: 200px;
">
<h3 style="margin: 0 0 8px 0; font-size: 16px;">点击位置</h3>
<p style="margin: 0; color: #666; font-size: 14px;">
经度: ${event.lon.toFixed(4)}<br>
纬度: ${event.lat.toFixed(4)}
</p>
<button id="close-popup" style="
margin-top: 8px;
padding: 4px 12px;
border: none;
background: #1890ff;
color: white;
border-radius: 4px;
cursor: pointer;
">关闭</button>
</div>
`;
// 关闭按钮事件
element.querySelector('#close-popup').addEventListener('click', () => {
popupLayer.clearOverlay();
});
// 显示弹窗
popupLayer.setOverlay({
element: element,
position: {
lon: event.lon,
lat: event.lat,
offset: [0, -20],
anchor: [0.5, 1.0],
},
});
});
自定义标注
// 创建标注元素
function createMarker(text, color = '#ff0000') {
const marker = document.createElement('div');
marker.innerHTML = `
<div style="
position: relative;
text-align: center;
">
<div style="
background: ${color};
color: white;
padding: 4px 8px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap;
box-shadow: 0 2px 4px rgba(0,0,0,0.3);
">${text}</div>
<div style="
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 8px solid ${color};
margin: 0 auto;
"></div>
</div>
`;
return marker;
}
// 使用标注
const markerLayer = new OverlayLayer('marker');
engine.addLayer(markerLayer);
markerLayer.setOverlay({
element: createMarker('北京', '#1890ff'),
position: {
lon: 116.4074,
lat: 39.9042,
anchor: [0.5, 1.0],
},
properties: { name: '北京' },
});
应用场景
- 🏷️ 地图标注(Marker):显示位置标记
- 💬 信息弹窗(Popup):显示详细信息
- 🎯 工具提示(Tooltip):鼠标悬停提示
- 🎨 自定义控件:地图控制按钮
- 📊 数据展示:图表、统计信息
- 🖼️ 媒体内容:图片、视频预览
注意事项
- 单个覆盖层:每个 OverlayLayer 只能显示一个覆盖层
- 多个覆盖层:需要创建多个 OverlayLayer 实例
- 层级控制:使用
setZIndex()控制显示顺序 - 性能考虑:避免创建过多的 OverlayLayer 实例
- 事件处理:HTML 元素的事件需要自行管理
- 内存管理:不需要时及时调用
clearOverlay()