开发者可利用SDK提供的接口,使用百度为您提供的基础地图数据。目前百度地图SDK所提供的地图等级为3-21级,所包含的信息有建筑物、道路、河流、学校、公园等内容。
V3.7.0起,地图支持缩放至21级,暂不支持卫星图、热力图、交通路况图层的21级显示,打开以上类型图层,地图会自动缩放到20级。
所有叠加或覆盖到地图的内容,我们统称为地图覆盖物。如标注、矢量图形元素(包括:折线、多边形和圆等)、定位图标等。覆盖物拥有自己的地理坐标,当您拖动或缩放地图时,它们会相应的移动。
百度地图SDK为广大开发者提供的基础地图和上面的各种覆盖物元素,具有一定的层级压盖关系,具体如下(从下至上的顺序):
1、基础底图(包括底图、底图道路、卫星图等);
2、瓦片图层(TileOverlay);
3、地形图图层(GroundOverlay);
4、热力图图层(HeatMap);
5、实时路况图图层(BaiduMap.setTrafficEnabled(true););
6、百度城市热力图(BaiduMap.setBaiduHeatMapEnabled(true););
7、底图标注(指的是底图上面自带的那些POI元素);
8、几何图形图层(点、折线、弧线、圆、多边形);
9、标注图层(Marker),文字绘制图层(Text);
10、指南针图层(当地图发生旋转和视角变化时,默认出现在左上角的指南针);
11、定位图层(BaiduMap.setMyLocationEnabled(true););
12、弹出窗图层(InfoWindow);
13、自定义View(MapView.addView(View););
地图类型
百度地图Android SDK为您提供了3种类型的地图资源(普通矢量地图、卫星图和空白地图),开发者可以利用BaiduMap中的mapType()方法来设置地图类型。核心代码如下:
mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); //普通地图 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL); //卫星地图 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE); //空白地图, 基础地图瓦片将不会被渲染。在地图类型中设置为NONE,将不会使用流量下载基础地图瓦片图层。使用场景:与瓦片图层一起使用,节省流量,提升自定义瓦片图下载速度。 mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
实时交通图
当前,全国范围内已支持多个城市实时路况查询,且会陆续开通其他城市。
在地图上打开实时路况的核心代码如下:
mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); //开启交通图 mBaiduMap.setTrafficEnabled(true);
百度城市热力图
百度地图SDK继为广大开发者开放热力图本地绘制能力之后,再次进一步开放百度自有数据的城市热力图层,帮助开发者构建形式更加多样的移动端应用。
百度城市热力图的性质及使用与实时交通图类似,只需要简单的接口调用,即可在地图上展现样式丰富的百度城市热力图。
在地图上开启百度城市热力图的核心代码如下:
mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); //开启交通图 mBaiduMap.setBaiduHeatMapEnabled(true);
地图控制和手势
地图控制
地图Logo
- 默认在左下角显示,不可以移除。
通过mMapView.setLogoPosition(LogoPosition.logoPostionleftBottom);方法,使用枚举类型控制显示的位置,共支持6个显示位置(左下,中下,右下,左上,中上,右上)。
- 地图Logo不允许遮挡,可通过mBaiduMap.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);方法可以设置地图边界区域,来避免UI遮挡。
其中参数paddingLeft、paddingTop、paddingRight、paddingBottom参数表示距离屏幕边框的左、上、右、下边距的距离,单位为屏幕坐标的像素密度。
指南针
指南针默认为开启状态,可以关闭显示 。
比例尺
比例尺默认为开启状态,可以关闭显示。同时支持设置MaxZoomLevel和minZoomLevel,可通过mMapView.getMapLevel获取当前地图级别下比例尺所表示的距离大小。
地图手势
地图平移
控制是否启用或禁用平移的功能,默认开启。如果启用,则用户可以平移地图
地图缩放
控制是否启用或禁用缩放手势,默认开启。如果启用,用户可以双指点击或缩放地图视图。
地图俯视(3D)
控制是否启用或禁用俯视(3D)功能,默认开启。如果启用,则用户可使用双指 向下或向上滑动到俯视图。
地图旋转
控制是否启用或禁用地图旋转功能,默认开启。如果启用,则用户可使用双指 旋转来旋转地图。
禁止所有手势
控制是否一并禁止所有手势,默认关闭。如果启用,所有手势都将被禁用。
标注覆盖物
地图标注
开发者可根据自己实际的业务需求,利用标注覆盖物,在地图指定的位置上添加标注信息。具体实现方法如下:
//定义Maker坐标点
LatLng point = new LatLng(39.963175, 116.400244); //构建Marker图标 BitmapDescriptor bitmap = BitmapDescriptorFactory .fromResource(R.drawable.icon_marka); //构建MarkerOption,用于在地图上添加Marker OverlayOptions option = new MarkerOptions() .position(point) .icon(bitmap); //在地图上添加Marker,并显示 mBaiduMap.addOverlay(option);
针对已经添加在地图上的标注,可采用如下方式进行手势拖拽:
第一步,设置可拖拽:
OverlayOptions options = new MarkerOptions()
.position(llA) //设置marker的位置 .icon(bdA) //设置marker图标 .zIndex(9) //设置marker所在层级 .draggable(true); //设置手势拖拽 //将marker添加到地图上 marker = (Marker) (mBaiduMap.addOverlay(options));
第二步,设置监听方法:
//调用BaiduMap对象的setOnMarkerDragListener方法设置marker拖拽的监听
mBaiduMap.setOnMarkerDragListener(new OnMarkerDragListener() { public void onMarkerDrag(Marker marker) { //拖拽中 } public void onMarkerDragEnd(Marker marker) { //拖拽结束 } public void onMarkerDragStart(Marker marker) { //开始拖拽 } });
自v3.3.0版本起,SDK提供了给Marker增加动画的能力,具体实现方法如下:
// 通过marker的icons设置一组图片,再通过period设置多少帧刷新一次图片资源
ArrayList<BitmapDescriptor> giflist = new ArrayList<BitmapDescriptor>(); giflist.add(bdA); giflist.add(bdB); giflist.add(bdC); OverlayOptions ooD = new MarkerOptions().position(pt).icons(giflist) .zIndex(0).period(10); mMarkerD = (Marker) (mBaiduMap.addOverlay(ooD));
针对已添加在地图上的标注覆盖物,可利用如下方法进行修改和删除操作:
marker.remove(); //调用Marker对象的remove方法实现指定marker的删除
自v3.6.0版本起,SDK提供了给加载Marker增加动画的能力,加载maker时包含两种加载动画方式:从地上生长和从天上落下。
以生长动画为例,具体实现方法如下:
MarkerOptions ooD = new MarkerOptions().position(llD).icons(giflist) .zIndex(0).period(10); if (animationBox.isChecked()) { // 生长动画 ooD.animateType(MarkerAnimateType.grow); } Marker mMarkerD = (Marker) (mBaiduMap.addOverlay(ooD));
自v3.6.0版本起,SDK提供了给Marker设置透明度的方法,具体实现方法如下:
MarkerOptions ooA = new MarkerOptions().position(llD).icons(giflist) .zIndex(0).period(10).alpha(0.5); mBaiduMap.addOverlay(ooA);
具体源码请在OverlayDemo中查看。
点聚合功能
自v3.6.0版本起,新增点聚合功能,可通过缩小地图层级,将定义范围内的多个标注点,聚合显示成一个标注点,并在MarkerClusterDemo中开放源码,方便开发者自行修改。
// 初始化点聚合管理类
ClusterManager mClusterManager = new ClusterManager<>(this, mBaiduMap); // 向点聚合管理类中添加Marker实例 LatLng llA = new LatLng(39.963175, 116.400244); List<MyItem> items = new ArrayList<>(); items.add(new MyItem(llA)); mClusterManager.addItems(items);
具体源码请在MarkerClusterDemo中查看。
底图标注
自v3.6.0版本起,SDK在BaiduMap提供了控制底图标注的showMapPoi方法,默认显示底图标注。利用此属性可得到仅显示道路信息的地图,方法如下:
// 将底图标注设置为隐藏,方法如下:
mBaiduMap.showMapPoi(false)
运行后,底图标注被隐藏,效果如图:
几何图形覆盖物
地图SDK提供多种结合图形覆盖物,利用这些图形,可帮助您构建更加丰富多彩的地图应用。目前提供的几何图形有:点(Dot)、折线(Polyline)、弧线(Arc)、圆(Circle)、多边形(Polygon)。
下面以多边形为例,向大家介绍如何使用几何图形覆盖物:
//定义多边形的五个顶点
LatLng pt1 = new LatLng(39.93923, 116.357428); LatLng pt2 = new LatLng(39.91923, 116.327428); LatLng pt3 = new LatLng(39.89923, 116.347428); LatLng pt4 = new LatLng(39.89923, 116.367428); LatLng pt5 = new LatLng(39.91923, 116.387428); List<LatLng> pts = new ArrayList<LatLng>(); pts.add(pt1); pts.add(pt2); pts.add(pt3); pts.add(pt4); pts.add(pt5); //构建用户绘制多边形的Option对象 OverlayOptions polygonOption = new PolygonOptions() .points(pts) .stroke(new Stroke(5, 0xAA00FF00)) .fillColor(0xAAFFFF00); //在地图上添加多边形Option,用于显示 mBaiduMap.addOverlay(polygonOption);
运行结果如下:
Android地图SDK自v3.5.0版本起,新增了折线多段颜色绘制能力,实现的核心代码如下:
//构造纹理资源
BitmapDescriptor custom1 = BitmapDescriptorFactory
.fromResource(R.drawable.icon_road_red_arrow); BitmapDescriptor custom2 = BitmapDescriptorFactory .fromResource(R.drawable.icon_road_green_arrow); BitmapDescriptor custom3 = BitmapDescriptorFactory .fromResource(R.drawable.icon_road_blue_arrow); // 定义点 LatLng pt1 = newLatLng(39.93923, 116.357428); LatLng pt2 = newLatLng(39.91923, 116.327428); LatLng pt3 = newLatLng(39.89923, 116.347428); LatLng pt4 = newLatLng(39.89923, 116.367428); LatLng pt5 = newLatLng(39.91923, 116.387428); //构造纹理队列 List<BitmapDescriptor>customList = newArrayList<BitmapDescriptor>(); customList.add(custom1); customList.add(custom2); customList.add(custom3); List<LatLng> points = newArrayList<LatLng>(); List<Integer> index = newArrayList<Integer>(); points.add(pt1);//点元素 index.add(0);//设置该点的纹理索引 points.add(pt2);//点元素 index.add(0);//设置该点的纹理索引 points.add(pt3);//点元素 index.add(1);//设置该点的纹理索引 points.add(pt4);//点元素 index.add(2);//设置该点的纹理索引 points.add(pt5);//点元素 //构造对象 OverlayOptionsooPolyline = newPolylineOptions().width(15).color(0xAAFF0000).points(points).customTextureList(customList).textureIndex(index); //添加到地图 mBaiduMap.addOverlay(ooPolyline);
效果图如下:
自v3.6.0版本起,扩展了折线多段颜色绘制能力:增加支持分段纹理绘制、分段颜色绘制,实现的核心代码如下:
构造PolylineOptions对象,添加折线分段颜色绘制覆盖物,核心代码如下:
// 构造折线点坐标
List<LatLng> points = new ArrayList<LatLng>(); points.add(new LatLng(39.965,116.404)); points.add(new LatLng(39.925,116.454)); points.add(new LatLng(39.955,116.494)); points.add(new LatLng(39.905,116.554)); points.add(new LatLng(39.965,116.604)); //构建分段颜色索引数组 List<Integer> colors = new ArrayList<>(); colors.add(Integer.valueOf(Color.BLUE)); colors.add(Integer.valueOf(Color.RED)); colors.add(Integer.valueOf(Color.YELLOW)); colors.add(Integer.valueOf(Color.GREEN)); OverlayOptions ooPolyline = new PolylineOptions().width(10) .colorsValues(colors).points(points); 添加在地图中 Polyline mPolyline = (Polyline) mBaiduMap.addOverlay(ooPolyline);
运行结果:
文字覆盖物
文字,在地图中也是一种覆盖物,开发者可利用相关的接口,快速实现在地图上书写文字的需求。实现方式如下:
//定义文字所显示的坐标点
LatLng llText = new LatLng(39.86923, 116.397428); //构建文字Option对象,用于在地图上添加文字 OverlayOptions textOption = new TextOptions() .bgColor(0xAAFFFF00) .fontSize(24) .fontColor(0xFFFF00FF) .text("百度地图SDK") .rotate(-30) .position(llText); //在地图上添加该文字对象并显示 mBaiduMap.addOverlay(textOption);
运行结果如下:
弹出窗覆盖物
弹出窗覆盖物的实现方式如下,开发者可利用此接口,构建具有更强交互性的地图页面。
//创建InfoWindow展示的view
Button button = new Button(getApplicationContext()); button.setBackgroundResource(R.drawable.popup); //定义用于显示该InfoWindow的坐标点 LatLng pt = new LatLng(39.86923, 116.397428); //创建InfoWindow , 传入 view, 地理坐标, y 轴偏移量 InfoWindow mInfoWindow = new InfoWindow(button, pt, -47); //显示InfoWindow mBaiduMap.showInfoWindow(mInfoWindow);
下图为点击Marker弹出InfoWindow的示例图,开发者只需将InfoWindow的显示方法写在Maker的点击事件处理中即可实现该效果。
运行结果如下:
地形图图层
地形图图层(GroundOverlay),又可叫做图片图层,即开发者可在地图的指定位置上添加图片。该图片可随地图的平移、缩放、旋转等操作做相应的变换。该图层是一种特殊的Overlay, 它位于底图和底图标注层之间(即该图层不会遮挡地图标注信息)。
在地图中添加使用地形图覆盖物的方式如下:
//定义Ground的显示地理范围
LatLng southwest = new LatLng(39.92235, 116.380338); LatLng northeast = new LatLng(39.947246, 116.414977); LatLngBounds bounds = new LatLngBounds.Builder() .include(northeast) .include(southwest) .build(); //定义Ground显示的图片 BitmapDescriptor bdGround = BitmapDescriptorFactory .fromResource(R.drawable.ground_overlay); //定义Ground覆盖物选项 OverlayOptions ooGround = new GroundOverlayOptions() .positionFromBounds(bounds) .image(bdGround) .transparency(0.8f); //在地图中添加Ground覆盖物 mBaiduMap.addOverlay(ooGround);
运行结果如下:
热力图功能
热力图是用不同颜色的区块叠加在地图上描述人群分布、密度和变化趋势的一个产品,百度地图SDK将绘制热力图的能力为广大开发者开放,帮助开发者利用自有数据,构建属于自己的热力图,提供丰富的展示效果。
利用热力图功能构建自有数据热力图的方式如下:
第一步,设置颜色变化:
//设置渐变颜色值
int[] DEFAULT_GRADIENT_COLORS = {Color.rgb(102, 225, 0), Color.rgb(255, 0, 0) }; //设置渐变颜色起始值 float[] DEFAULT_GRADIENT_START_POINTS = { 0.2f, 1f }; //构造颜色渐变对象 Gradient gradient = new Gradient(DEFAULT_GRADIENT_COLORS, DEFAULT_GRADIENT_START_POINTS);
第二步,准备数据:
//以下数据为随机生成地理位置点,开发者根据自己的实际业务,传入自有位置数据即可
List<LatLng> randomList = new ArrayList<LatLng>(); Random r = new Random(); for (int i = 0; i < 500; i++) { // 116.220000,39.780000 116.570000,40.150000 int rlat = r.nextInt(370000); int rlng = r.nextInt(370000); int lat = 39780000 + rlat; int lng = 116220000 + rlng; LatLng ll = new LatLng(lat / 1E6, lng / 1E6); randomList.add(ll); }
第三步,添加、显示热力图:
//在大量热力图数据情况下,build过程相对较慢,建议放在新建线程实现
HeatMap heatmap = new HeatMap.Builder() .data(randomList) .gradient(gradient) .build(); //在地图上添加热力图 mBaiduMap.addHeatMap(heatmap);
第四步,删除热力图:
heatmap.removeHeatMap();
检索结果覆盖物
针对检索功能模块(POI检索、线路规划等),地图SDK还对外提供相应的覆盖物来快速展示结果信息。这些方法都是开源的,开发者可根据自己的实际去求来做个性化的定制。
利用检索结果覆盖物展示POI搜索结果的方式如下:
第一步,构造自定义 PoiOverlay 类;
private class MyPoiOverlay extends PoiOverlay {
public MyPoiOverlay(BaiduMap baiduMap) { super(baiduMap); } @Override public boolean onPoiClick(int index) { super.onPoiClick(index); return true; } }
第二步,在POI检索回调接口中添加自定义的PoiOverlay;
public void onGetPoiResult(PoiResult result) {
if (result == null || result.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) { return; } if (result.error == SearchResult.ERRORNO.NO_ERROR) { mBaiduMap.clear(); //创建PoiOverlay PoiOverlay overlay = new MyPoiOverlay(mBaiduMap); //设置overlay可以处理标注点击事件 mBaiduMap.setOnMarkerClickListener(overlay); //设置PoiOverlay数据 overlay.setData(result); //添加PoiOverlay到地图中 overlay.addToMap(); overlay.zoomToSpan(); return; } }
运行结果如下:
利用TransitRouteOverlay展示公交换乘结果:
//在公交线路规划回调方法中添加TransitRouteOverlay用于展示换乘信息
public void onGetTransitRouteResult(TransitRouteResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { //未找到结果 return; } if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) { //起终点或途经点地址有岐义,通过以下接口获取建议查询信息 //result.getSuggestAddrInfo() return; } if (result.error == SearchResult.ERRORNO.NO_ERROR) { route = result.getRouteLines().get(0); //创建公交路线规划线路覆盖物 TransitRouteOverlay overlay = new MyTransitRouteOverlay(mBaidumap); //设置公交路线规划数据 overlay.setData(route); //将公交路线规划覆盖物添加到地图中 overlay.addToMap(); overlay.zoomToSpan(); } }
运行结果如下:
OpenGL绘制功能
百度地图SDK为广大开发者开放了OpenGL绘制接口,帮助开发者在地图上实现更灵活的样式绘制,丰富地图使用效果体验。
下面将以在地图上绘制折线为例,向大家介绍如何使用OpenGL绘制接口:
// 定义地图绘制每一帧时 OpenGL 绘制的回调接口
OnMapDrawFrameCallback callback = new OnMapDrawFrameCallback() { public void onMapDrawFrame(GL10 gl, MapStatus drawingMapStatus) { if (mBaiduMap.getProjection() != null) { // 计算折线的 opengl 坐标 calPolylinePoint(drawingMapStatus); // 绘制折线 drawPolyline(gl, Color.argb(255, 255, 0, 0), vertexBuffer, 10, 3, drawingMapStatus); } } } // 设置地图绘制每一帧时的回调接口 mMapView = (MapView) findViewById(R.id.bmapView); mBaiduMap = mMapView.getMap(); mBaiduMap.setOnMapDrawFrameCallback(this); // 计算折线 OpenGL 坐标 public void calPolylinePoint(MapStatus mspStatus) { PointF[] polyPoints = new PointF[latLngPolygon.size()]; vertexs = new float[3 * latLngPolygon.size()]; int i = 0; for (LatLng xy : latLngPolygon) { // 将地理坐标转换成 openGL 坐标 polyPoints[i] = mBaiduMap.getProjection().toOpenGLLocation(xy, mspStatus); vertexs[i * 3] = polyPoints[i].x; vertexs[i * 3 + 1] = polyPoints[i].y; vertexs[i * 3 + 2] = 0.0f; i++; } for (int j = 0; j < vertexs.length; j++) { Log.d(LTAG, "vertexs[" + j + "]: " + vertexs[j]); } vertexBuffer = makeFloatBuffer(vertexs); } //创建OpenGL绘制时的顶点Buffer private FloatBuffer makeFloatBuffer(float[] fs) { ByteBuffer bb = ByteBuffer.allocateDirect(fs.length * 4); bb.order(ByteOrder.nativeOrder()); FloatBuffer fb = bb.asFloatBuffer(); fb.put(fs); fb.position(0); return fb; } // 绘制折线 private void drawPolyline(GL10 gl, int color, FloatBuffer lineVertexBuffer, float lineWidth, int pointSize, MapStatus drawingMapStatus) { gl.glEnable(GL10.GL_BLEND); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA); float colorA = Color.alpha(color