{T}

核心概念

理解百度地图的核心概念是开发地图应用的基础。本文档将介绍地图、图层、覆盖物等关键概念。

地图(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  // 初始地图类型
});
选项类型默认值说明
enableMapClickBooleantrue是否开启地图点击事件
minZoomNumber3最小缩放级别
maxZoomNumber19最大缩放级别
mapTypeMapTypeBMAP_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)不同。

坐标系对比

坐标系说明使用场景偏移
WGS84GPS原始坐标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);
  }
});
坐标类型代码说明
WGS841GPS原始坐标
GCJ023国测局坐标
BD095百度坐标
MapBar4MapBar坐标
51地图751地图坐标
搜狗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);
  }
});

最佳实践

性能优化

  1. 大量标注使用海量点或点聚合
  2. 频繁操作时禁用地图拖拽
  3. 使用事件节流处理频繁事件
  4. 合理使用缓存减少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 = [];
  }
};

下一步