android百度地图开发总结

项目近期开发加入百度地图的需求,初次使用遇到一些基础问题,总结如下:
百度地图的KEY申请地址http://lbsyun.baidu.com/,基础使用直接看百度地图API就可以,有Demo。
百度地图显示的时候全是网格没有地图,基本肯定就是KEY的问题。

1、BaiduMapOptions

1
2
3
4
5
6
7
8
9
BaiduMapOptions compassEnabled(boolean enabled)//设置是否允许指南针,默认允许。
BaiduMapOptions mapStatus(MapStatus status)//设置地图初始化时的地图状态, 默认地图中心点为北京天安门,缩放级别为 12.0f
BaiduMapOptions mapType(int mapType)//设置地图模式,默认普通地图
BaiduMapOptions overlookingGesturesEnabled(boolean enabled) //设置是否允许俯视手势,默认允许
BaiduMapOptions rotateGesturesEnabled(boolean enabled)//设置是否允许旋转手势,默认允许
BaiduMapOptions scaleControlEnabled(boolean enabled)//设置是否显示比例尺控件
BaiduMapOptions scrollGesturesEnabled(boolean enabled)//设置是否允许拖拽手势,默认允许
BaiduMapOptions zoomControlsEnabled(boolean enabled)//设置是否显示缩放控件
BaiduMapOptions zoomGesturesEnabled(boolean enabled)//设置是否允许缩放手势

2、UiSettings

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MapView mMapView = (MapView)findViewById(R.id.mapview);
BaiduMap mBaiduMap = mMapView.getMap();
UiSettings uiSettings = mBaiduMap.getUiSettings();
//设置是否允许旋转手势
uiSettings.setRotateGesturesEnabled(false);
//设置是否允许指南针
uiSettings.setCompassEnabled(false);
//设置是否允许俯视手势
uiSettings.setOverlookingGesturesEnabled(false);
//设置是否允许拖拽手势
uiSettings.setScrollGesturesEnabled(true);
//设置是否允许缩放手势
uiSettings.setZoomGesturesEnabled(true);
//隐藏地图上百度地图logo图标
mMapView.removeViewAt(1);
//隐藏地图上比例尺
mMapView.showScaleControl(true);
//隐藏缩放按钮
mMapView.showZoomControls(false);

3、根据坐标和级别缩放地图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//地图级别3-2000km
//地图级别4-1000km
//地图级别5-500km
//地图级别6-200km
//地图级别7-100km
//地图级别8-50km
//地图级别9-25km
//地图级别10-20km
//地图级别11-10km
//地图级别12-5km
//地图级别13-2km
//地图级别14-1km
//地图级别15-500m
//地图级别16-200m
//地图级别17-100m
//地图级别18-50m
//地图级别19-20m
//地图级别20-10m
private void scalePosition(LatLng position,int level){
MapStatus.Builder builder = new MapStatus.Builder();
if (level != 0) {
builder.zoom(level);
}
if (position != null) {
builder.target(position);
}
MapStatus mapStatus = builder.build();
MapStatusUpdate statusUpdate = MapStatusUpdateFactory.newMapStatus(mapStatus);
if (mBaiduMap!=null) {
mBaiduMap.animateMapStatus(statusUpdate);//动画缩放,不用动画会直接刷新界面
}
}

4、根据城市名称获取城市中心坐标或根据坐标反编码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
**
* 地理编码查询接口
*/
private GeoCoder geoCoder = GeoCoder.newInstance();

String City = "北京";
geoCoder.geocode(new GeoCodeOption().city(City).address(City));//编码城市获取坐标

Activity实现OnGetGeoCoderResultListener接口有如下方法:

@Override
public void onGetGeoCodeResult(GeoCodeResult arg0) {
LatLng lng = arg0.getLocation();//获取编码城市坐标;
}

@Override
public void onGetReverseGeoCodeResult(ReverseGeoCodeResult arg0) {
// 反编码
}

5、在地图上构建标志

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromResource(R.drawable.worksite_map_feidianshang);
MarkerOptions option = new MarkerOptions().position(point)
.icon(bitmap).zIndex(9).extraInfo(bundle);//bundle可以携带一些区分标志的信息等
try {
mBaiduMap.addOverlay(option);
} catch (Exception e) {
e.printStackTrace();
}
if (bitmap != null) {
bitmap.recycle();
bitmap = null;
}

//构建自定义布局标志

这个用的时候小心,有个bug
//在4.4以下版本,空指针异常
View view = LayoutInflater.from(mContext).inflate(R.layout.worksite_marker_quxian, null);
BitmapDescriptor bitmap = BitmapDescriptorFactory.fromView(view);//view不为空但报空指针异常
//解决办法:
//1、最外层要使用LinearLayout包住,才会不报错,我在第一次使用的RelativeLayout包住报错.
//2、view.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);


View view = LayoutInflater.from(mContext).inflate(
R.layout.worksite_marker_quxian, null);
params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(params);

TextView markerNum = (TextView) view
.findViewById(R.id.worksiteNum);
TextView cityName = (TextView) view
.findViewById(R.id.cityName);
cityName.setVisibility(View.VISIBLE);
cityName.setText(info.get(i).RegionName);
markerNum.setText(count + "");
BitmapDescriptor bitmap = BitmapDescriptorFactory
.fromView(view);
option = new MarkerOptions().position(point)
.icon(bitmap).zIndex(9).extraInfo(bundle);
try {
mBaiduMap.addOverlay(option);
} catch (Exception e) {
e.printStackTrace();
}
if (bitmap != null) {
bitmap.recycle();
bitmap = null;
}

百度地图在合适视野范围内显示所有的点

  • 通常地图会显示出多个点,如像行驶轨迹等,往往在屏幕上一次性就全部显示出来,那要怎么设置地图的显示宽高,才能将所有的点合理的显示出来呢。看看以下的代码实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    private void setMyLocation() {  
    list = new ArrayList<>();
    LatLng ll = new LatLng(24.475982,
    118.093132);
    LatLng ll1 = new LatLng(24.477382,
    118.093232);
    LatLng ll2 = new LatLng(24.478382,
    118.093832);
    LatLng ll3 = new LatLng(24.487382,
    118.094232);
    LatLng ll4 = new LatLng(24.497982,
    118.099562);

    list.add(ll);
    list.add(ll1);
    list.add(ll2);
    list.add(ll3);
    list.add(ll4);

    MapStatus.Builder builder = new MapStatus.Builder();
    builder.target(ll).zoom(18.0f);
    // mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
    for (LatLng latLng : list) {
    mBaiduMap.addOverlay(new BaiduMapUtil().setMarker(latLng));
    }

    mBaiduMap.addOverlay(new BaiduMapUtil().Polyline(list));

    //将所有的坐标显示出来的合理视图
    if (isFrist) {
    mBaiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {

    @Override
    public void onMapLoaded() {
    isFrist=false;
    mBaiduMap.animateMapStatus(new BaiduMapUtil().setLatLngBounds(list, mMapView));
    }
    });
    }else{
    mBaiduMap.animateMapStatus(new BaiduMapUtil().setLatLngBounds(list, mMapView));
    }

    }
  • 以下为工具类BaiduMapUtil的具体实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    public class BaiduMapUtil {  

    /**
    * 绘制Marker,地图上常见的类似气球形状的图层
    */
    public MarkerOptions setMarker(LatLng latLng) {
    return setMarker(latLng, R.drawable.icon_defult_marker);
    }


    public MarkerOptions setMarker(LatLng latLng, int drawableId) {
    MarkerOptions markerOptions = new MarkerOptions();//参数设置类
    markerOptions.position(latLng);//marker坐标位置
    markerOptions.icon(BitmapDescriptorFactory
    .fromResource(drawableId));//marker图标,可以自定义
    markerOptions.draggable(false);//是否可拖拽,默认不可拖拽
    markerOptions.anchor(0.5f, 1.0f);//设置 marker覆盖物与位置点的位置关系,默认(0.5f, 1.0f)水平居中,垂直下对齐
    markerOptions.alpha(0.8f);//marker图标透明度,0~1.0,默认为1.0
    markerOptions.animateType(MarkerOptions.MarkerAnimateType.none);//marker出现的方式,从天上掉下
    markerOptions.flat(false);//marker突变是否平贴地面
    markerOptions.zIndex(1);//index
    return markerOptions;
    }

    /**
    * 绘制折线
    */
    public PolylineOptions Polyline(List<LatLng> points) {
    PolylineOptions polylineOptions = new PolylineOptions();//参数设置类
    polylineOptions.width(10);//宽度,单位:像素
    polylineOptions.color(0xAAFF0000);//设置折线颜色
    polylineOptions.points(points);//折线顶点坐标集
    return polylineOptions;
    }

    /**
    * 多个点,在Android里面显示合理的缩放级
    */
    public MapStatusUpdate setLatLngBounds(List<LatLng> points, MapView mMapView) {
    LatLngBounds.Builder builder2 = new LatLngBounds.Builder();
    for (LatLng p : points) {
    builder2 = builder2.include(p);
    }
    LatLngBounds latlngBounds = builder2.build();
    MapStatusUpdate u = MapStatusUpdateFactory.newLatLngBounds(latlngBounds, mMapView.getWidth(), mMapView.getHeight());
    return u;
    }


    }
1
2
3
4
5
6
7
8
9
10
11
12
if (isFrist) {  
mBaiduMap.setOnMapLoadedCallback(new BaiduMap.OnMapLoadedCallback() {

@Override
public void onMapLoaded() {
isFrist=false;
mBaiduMap.animateMapStatus(new BaiduMapUtil().setLatLngBounds(list, mMapView));
}
});
}else{
mBaiduMap.animateMapStatus(new BaiduMapUtil().setLatLngBounds(list, mMapView));
}
  • 这段代码为显示合理范围的核心代码,加入是否为首次的判断,因为要在OnMapLoadedCallback中实现是关键,否则mapview的with和height取得是0,如果在其他视觉范围内,想恢复到这个合理的范围则经过首次加载后,就不会再执行OnMapLoadedCallback方法,所以要判断是否为第一次加载的状态。