核心概念
理解百度地图的核心概念是开发地图应用的基础。本文档将介绍地图、图层、覆盖物等关键概念。
地图(Map)
地图是百度地图API的核心对象,所有地图操作都基于地图实例。
创建地图
javascript
var map = new BMap.Map('container');
var point = new BMap.Point(116.404, 39.915);
map.centerAndZoom(point, 15);地图配置选项
javascript
var map = new BMap.Map('container', {
enableMapClick: false, // 禁用地图点击热点
minZoom: 3, // 最小缩放级别
maxZoom: 19, // 最大缩放级别
mapType: BMAP_NORMAL_MAP // 初始地图类型
});| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enableMapClick | Boolean | true | 是否开启地图点击事件 |
minZoom | Number | 3 | 最小缩放级别 |
maxZoom | Number | 19 | 最大缩放级别 |
mapType | MapType | BMAP_NORMAL_MAP | 初始地图类型 |
地图状态
| 属性/方法 | 说明 |
|---|---|
centerAndZoom(point, zoom) | 设置中心点和缩放级别 |
setCenter(point) | 设置地图中心点 |
setZoom(zoom) | 设置缩放级别(3-19) |
getCenter() | 获取当前中心点 |
getZoom() | 获取当前缩放级别 |
getBounds() | 获取当前视野范围 |
getSize() | 获取地图容器尺寸 |
地图类型
javascript
map.setMapType(BMAP_NORMAL_MAP);
map.setMapType(BMAP_EARTH_MAP);
map.setMapType(BMAP_SATELLITE_MAP);| 类型常量 | 说明 | 特点 |
|---|---|---|
BMAP_NORMAL_MAP | 标准地图 | 默认地图样式 |
BMAP_EARTH_MAP | 地球模式(3D) | WebGL版本支持 |
BMAP_SATELLITE_MAP | 卫星地图 | 卫星影像 |
BMAP_HYBRID_MAP | 混合地图 | 卫星+路网 |
地图方法详解
javascript
// 平移地图
map.panTo(new BMap.Point(116.404, 39.915)); // 平移到指定点
map.panBy(100, 100); // 平移像素
// 缩放地图
map.zoomIn(); // 放大一级
map.zoomOut(); // 缩小一级
map.setZoom(15); // 设置缩放级别
// 设置视野范围
map.setBounds(bounds); // 设置矩形范围
map.setViewport(points); // 设置点数组范围
map.setViewport(points, { margins: [50, 50, 50, 50] }); // 带边距
// 启用/禁用功能
map.enableDragging(); // 启用拖拽
map.disableDragging(); // 禁用拖拽
map.enableScrollWheelZoom(); // 启用滚轮缩放
map.disableScrollWheelZoom(); // 禁用滚轮缩放坐标系统
百度地图使用BD09坐标系,与GPS坐标(WGS84)和国测局坐标(GCJ02)不同。
坐标系对比
| 坐标系 | 说明 | 使用场景 | 偏移 |
|---|---|---|---|
| WGS84 | GPS原始坐标 | GPS设备、国际标准 | 无偏移 |
| GCJ02 | 国测局坐标(火星坐标) | 高德、腾讯地图 | 加密偏移 |
| BD09 | 百度坐标 | 百度地图 | 二次加密偏移 |
坐标偏移示意图
plaintext
┌─────────────────────────────────────────────────────┐
│ 坐标系统关系 │
├─────────────────────────────────────────────────────┤
│ │
│ WGS84 (GPS原始) │
│ │ │
│ │ 国家测绘局加密 │
│ ▼ │
│ GCJ02 (火星坐标) │
│ │ │
│ │ 百度二次加密 │
│ ▼ │
│ BD09 (百度坐标) │
│ │
└─────────────────────────────────────────────────────┘坐标转换
javascript
var convertor = new BMap.Convertor();
var pointArr = [new BMap.Point(116.32715863448607, 39.990912172420714)];
convertor.translate(pointArr, 1, 5, function(data) {
if (data.status === 0) {
var marker = new BMap.Marker(data.points[0]);
map.addOverlay(marker);
}
});| 坐标类型 | 代码 | 说明 |
|---|---|---|
| WGS84 | 1 | GPS原始坐标 |
| GCJ02 | 3 | 国测局坐标 |
| BD09 | 5 | 百度坐标 |
| MapBar | 4 | MapBar坐标 |
| 51地图 | 7 | 51地图坐标 |
| 搜狗 | 6 | 搜狗坐标 |
批量坐标转换
javascript
// 批量转换坐标(最多支持20个点)
var points = [
new BMap.Point(116.327, 39.990),
new BMap.Point(116.328, 39.991),
new BMap.Point(116.329, 39.992)
];
convertor.translate(points, 1, 5, function(data) {
if (data.status === 0) {
data.points.forEach(function(point) {
map.addOverlay(new BMap.Marker(point));
});
}
});服务端坐标转换
使用Web服务API进行坐标转换,支持批量转换:
javascript
// Web服务API坐标转换
var coords = '116.327,39.990;116.328,39.991';
var url = `https://api.map.baidu.com/geoconv/v1/?coords=${coords}&from=1&to=5&ak=你的密钥`;
fetch(url)
.then(res => res.json())
.then(data => {
console.log('转换结果:', data.result);
});图层(Layer)
图层是地图上显示的各类数据层,可以叠加多个图层。
图层叠加顺序
plaintext
┌─────────────────────────────────────────────────────┐
│ 图层叠加顺序 │
├─────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 覆盖物层 (Overlay Layer) │ │
│ │ - Marker, Polyline, Polygon等 │ │
│ └─────────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 业务图层 (Custom Layer) │ │
│ │ - 自定义瓦片图层 │ │
│ └─────────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 交通图层 (Traffic Layer) │ │
│ │ - 实时路况 │ │
│ └─────────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 卫星图层 (Satellite Layer) │ │
│ │ - 卫星影像 │ │
│ └─────────────────────────────────────────────┘ │
│ ▲ │
│ ┌─────────────────────────────────────────────┐ │
│ │ 底图图层 (Base Layer) │ │
│ │ - 标准地图、卫星地图 │ │
│ └─────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘内置图层
javascript
// 添加交通图层
var traffic = new BMap.TrafficLayer();
map.addTileLayer(traffic);
// 移除图层
map.removeTileLayer(traffic);| 图层类型 | 说明 | 用途 |
|---|---|---|
TileLayer | 自定义瓦片图层 | 自定义底图 |
TrafficLayer | 实时交通图层 | 显示路况 |
SatelliteLayer | 卫星图层 | 卫星影像 |
自定义图层
javascript
var tileLayer = new BMap.TileLayer();
tileLayer.getTilesUrl = function(tileCoord, zoom) {
var x = tileCoord.x;
var y = tileCoord.y;
return 'https://example.com/tile/' + zoom + '/' + x + '/' + y + '.png';
};
map.addTileLayer(tileLayer);图层管理
javascript
// 获取所有图层
var layers = map.getTileLayers();
// 控制图层显示/隐藏
var trafficLayer = new BMap.TrafficLayer();
map.addTileLayer(trafficLayer);
// 隐藏图层
trafficLayer.hide();
// 显示图层
trafficLayer.show();
// 移除图层
map.removeTileLayer(trafficLayer);覆盖物(Overlay)
覆盖物是覆盖在地图上的元素,如标注、折线、多边形等。
覆盖物层级管理
plaintext
┌─────────────────────────────────────────────────────┐
│ 覆盖物层级顺序 │
├─────────────────────────────────────────────────────┤
│ │
│ zIndex: 1000+ InfoWindow (信息窗口) │
│ │
│ zIndex: 100-999 Marker (标注) │
│ │
│ zIndex: 10-99 Label (文字标签) │
│ │
│ zIndex: 1-9 Polygon/Polyline/Circle (图形) │
│ │
└─────────────────────────────────────────────────────┘标注(Marker)
javascript
var point = new BMap.Point(116.404, 39.915);
var marker = new BMap.Marker(point, {
enableDragging: true, // 可拖拽
raiseOnDrag: true, // 拖拽时弹起
draggingCursor: 'move' // 拖拽光标
});
map.addOverlay(marker);
// 标注事件
marker.addEventListener('click', function() {
alert('您点击了标注');
});
// 设置zIndex
marker.setZIndex(100);自定义图标
javascript
var icon = new BMap.Icon(
'marker.png',
new BMap.Size(23, 25),
{
anchor: new BMap.Size(10, 25), // 图标锚点
imageOffset: new BMap.Size(0, 0) // 图片偏移
}
);
var marker = new BMap.Marker(point, {icon: icon});信息窗口(InfoWindow)
javascript
var infoWindow = new BMap.InfoWindow('世界很复杂,百度更懂你', {
width: 250, // 宽度
height: 100, // 高度
title: '信息窗口', // 标题
enableAutoPan: true, // 自动平移
enableCloseOnClick: true // 点击地图关闭
});
marker.addEventListener('click', function() {
map.openInfoWindow(infoWindow, point);
});折线(Polyline)
javascript
var polyline = new BMap.Polyline([
new BMap.Point(116.399, 39.910),
new BMap.Point(116.405, 39.920)
], {
strokeColor: 'blue', // 线颜色
strokeWeight: 3, // 线宽
strokeOpacity: 0.5, // 透明度
strokeStyle: 'solid', // 线样式:solid/dashed/dotted
enableMassClear: true, // 是否在clearOverlays时清除
enableEditing: false // 是否可编辑
});
map.addOverlay(polyline);多边形(Polygon)
javascript
var polygon = new BMap.Polygon([
new BMap.Point(116.387112, 39.920977),
new BMap.Point(116.385243, 39.913063),
new BMap.Point(116.394226, 39.917988)
], {
strokeColor: 'blue', // 边框颜色
strokeWeight: 2, // 边框宽度
fillColor: 'red', // 填充颜色
fillOpacity: 0.3 // 填充透明度
});
map.addOverlay(polygon);圆形(Circle)
javascript
var circle = new BMap.Circle(
new BMap.Point(116.404, 39.915),
1000, // 半径(米)
{
strokeColor: 'blue',
strokeWeight: 2,
fillColor: 'red',
fillOpacity: 0.3
}
);
map.addOverlay(circle);文字标签(Label)
javascript
var label = new BMap.Label('百度大厦', {
position: new BMap.Point(116.404, 39.915),
offset: new BMap.Size(20, -10) // 偏移量
});
label.setStyle({
color: 'red',
fontSize: '12px',
border: '1px solid #ccc',
padding: '5px',
backgroundColor: '#fff',
borderRadius: '3px'
});
map.addOverlay(label);覆盖物管理
javascript
// 添加覆盖物
map.addOverlay(marker);
// 移除单个覆盖物
map.removeOverlay(marker);
// 清除所有覆盖物
map.clearOverlays();
// 获取所有覆盖物
var overlays = map.getOverlays();
// 根据类型筛选覆盖物
var markers = overlays.filter(function(item) {
return item instanceof BMap.Marker;
});控件(Control)
控件是地图上的UI组件,用于交互或信息展示。
添加控件
javascript
map.addControl(new BMap.NavigationControl());
map.addControl(new BMap.ScaleControl());
map.addControl(new BMap.MapTypeControl());
map.addControl(new BMap.OverviewMapControl());常用控件
| 控件 | 说明 | 主要配置 |
|---|---|---|
NavigationControl | 平移缩放控件 | anchor, type, enableGeolocation |
ScaleControl | 比例尺控件 | anchor, offset |
MapTypeControl | 地图类型切换控件 | mapTypes |
OverviewMapControl | 缩略地图控件 | isOpen, anchor |
CopyrightControl | 版权控件 | anchor, copyright |
GeolocationControl | 定位控件 | anchor, enableAutoLocation |
控件位置
javascript
// 控件锚点位置
BMAP_ANCHOR_TOP_LEFT // 左上
BMAP_ANCHOR_TOP_RIGHT // 右上
BMAP_ANCHOR_BOTTOM_LEFT // 左下
BMAP_ANCHOR_BOTTOM_RIGHT // 右下
// 添加控件到指定位置
map.addControl(new BMap.NavigationControl({
anchor: BMAP_ANCHOR_TOP_RIGHT,
type: BMAP_NAVIGATION_CONTROL_LARGE,
offset: new BMap.Size(10, 10)
}));自定义控件
javascript
function ZoomControl() {
this.defaultAnchor = BMAP_ANCHOR_TOP_LEFT;
this.defaultOffset = new BMap.Size(10, 10);
}
ZoomControl.prototype = new BMap.Control();
ZoomControl.prototype.initialize = function(map) {
var div = document.createElement('div');
div.innerHTML = '放大';
div.style.cursor = 'pointer';
div.style.padding = '5px 10px';
div.style.backgroundColor = '#fff';
div.style.border = '1px solid #ccc';
div.style.borderRadius = '3px';
div.onclick = function() {
map.zoomIn();
};
map.getContainer().appendChild(div);
return div;
};
var zoomCtrl = new ZoomControl();
map.addControl(zoomCtrl);事件系统
百度地图提供完整的事件系统,支持地图、覆盖物等各类对象的事件监听。
事件监听模式
javascript
// 方式1:使用addEventListener
var listener = map.addEventListener('click', function(e) {
console.log('点击位置:' + e.point.lng + ', ' + e.point.lat);
});
// 方式2:使用on方法(WebGL版本)
map.on('click', function(e) {
console.log(e.latlng);
});
// 移除事件监听
map.removeEventListener('click', listener);地图事件
javascript
// 点击事件
map.addEventListener('click', function(e) {
console.log('点击位置:' + e.point.lng + ', ' + e.point.lat);
});
// 缩放事件
map.addEventListener('zoomend', function() {
console.log('缩放结束,当前级别:' + map.getZoom());
});
map.addEventListener('zoomstart', function() {
console.log('缩放开始');
});
// 移动事件
map.addEventListener('moveend', function() {
console.log('移动结束');
});
map.addEventListener('movestart', function() {
console.log('移动开始');
});
// 地图加载完成
map.addEventListener('tilesloaded', function() {
console.log('地图加载完成');
});覆盖物事件
javascript
marker.addEventListener('click', function() {
console.log('标注被点击');
});
marker.addEventListener('mouseover', function() {
console.log('鼠标移入标注');
});
marker.addEventListener('mouseout', function() {
console.log('鼠标移出标注');
});
marker.addEventListener('dragend', function(e) {
console.log('拖拽结束,新位置:', e.point);
});常用事件
| 事件类型 | 事件名 | 说明 |
|---|---|---|
| 鼠标事件 | click | 单击 |
| 鼠标事件 | dblclick | 双击 |
| 鼠标事件 | mouseover | 鼠标移入 |
| 鼠标事件 | mouseout | 鼠标移出 |
| 鼠标事件 | mousemove | 鼠标移动 |
| 鼠标事件 | rightclick | 右键点击 |
| 地图事件 | moveend | 移动结束 |
| 地图事件 | movestart | 移动开始 |
| 地图事件 | zoomend | 缩放结束 |
| 地图事件 | zoomstart | 缩放开始 |
| 地图事件 | resize | 窗口大小改变 |
| 地图事件 | tilesloaded | 瓦片加载完成 |
| 覆盖物事件 | remove | 移除覆盖物 |
| 覆盖物事件 | add | 添加覆盖物 |
事件对象
javascript
map.addEventListener('click', function(e) {
console.log('经度:' + e.point.lng);
console.log('纬度:' + e.point.lat);
console.log('像素坐标X:' + e.pixel.x);
console.log('像素坐标Y:' + e.pixel.y);
console.log('触发事件的目标:' + e.target);
console.log('原始DOM事件:' + e.domEvent);
});事件冒泡和阻止
javascript
// 阻止事件冒泡
marker.addEventListener('click', function(e) {
e.domEvent.stopPropagation();
console.log('标注点击,事件不会冒泡到地图');
});
// 地图上的点击事件
map.addEventListener('click', function(e) {
console.log('地图点击');
});服务类
百度地图提供多种服务类,用于地点检索、路线规划等功能。
本地搜索
javascript
var local = new BMap.LocalSearch(map, {
renderOptions: {
map: map,
panel: 'results', // 结果面板容器ID
autoViewport: true // 自动调整视野
},
onSearchComplete: function(results) {
console.log('搜索完成,共找到 ' + results.getCurrentNumPois() + ' 个结果');
},
onSearchMarkersSet: function(pois) {
console.log('标注设置完成');
}
});
local.search('餐厅');
local.searchNearby('餐厅', point, 1000);
local.searchInBounds('餐厅', map.getBounds());路线规划
javascript
var driving = new BMap.DrivingRoute(map, {
renderOptions: {
map: map,
panel: 'route',
autoViewport: true
},
policy: BMAP_DRIVING_POLICY_LEAST_TIME,
onSearchComplete: function(results) {
var plan = results.getPlan(0);
console.log('距离:' + plan.getDistance() + '米');
console.log('时间:' + plan.getDuration() + '秒');
}
});
driving.search('北京西站', '百度大厦');
// 带途经点的路线规划
driving.search(startPoint, endPoint, {
waypoints: [waypoint1, waypoint2]
});地理编码
javascript
var geocoder = new BMap.Geocoder();
// 地址解析
geocoder.getPoint('北京市海淀区上地十街10号', function(point) {
if (point) {
map.centerAndZoom(point, 16);
map.addOverlay(new BMap.Marker(point));
}
}, '北京市');
// 逆地址解析
geocoder.getLocation(point, function(result) {
if (result) {
console.log('地址:' + result.address);
console.log('省份:' + result.addressComponents.province);
console.log('城市:' + result.addressComponents.city);
console.log('区县:' + result.addressComponents.district);
console.log('街道:' + result.addressComponents.street);
}
});最佳实践
性能优化
- 大量标注使用海量点或点聚合
- 频繁操作时禁用地图拖拽
- 使用事件节流处理频繁事件
- 合理使用缓存减少API调用
内存管理
javascript
// 及时移除不需要的覆盖物
function clearMarkers() {
markers.forEach(function(marker) {
map.removeOverlay(marker);
});
markers = [];
}
// 销毁地图实例
function destroyMap() {
map.clearOverlays();
map = null;
}事件管理
javascript
// 使用事件管理器统一管理
var EventManager = {
listeners: [],
add: function(target, event, handler) {
var listener = target.addEventListener(event, handler);
this.listeners.push({ target: target, event: event, listener: listener });
return listener;
},
clear: function() {
this.listeners.forEach(function(item) {
item.target.removeEventListener(item.event, item.listener);
});
this.listeners = [];
}
};