Android百度地图(二):百度地图sdk显示位置点、图层绘制

转载、引用请标明出处
http://www.jianshu.com/p/fdd1ba783495
本文出自zhh_happig的简书博客,谢谢

Android百度地图(一):百度地图定位sdk 类方法参数、定位原理详细介绍
Android百度地图(三):百度地图画运动轨迹及图层点击事件处理
Android百度地图(四):百度地图运动轨迹纠偏、去噪、绑路之百度鹰眼sdk服务
Android百度地图(五):百度地图鹰眼sdk监控进出地理围栏(区域)
Android百度地图(六):百度地图POI检索,行政区边界、公交、线路规划查询,地理编码介绍

上一篇文章介绍定位sdk 类方法参数、定位原理,讲述了如何利用定位sdk进行定位。这篇文章将讲解如何显示定位位置和绘制图层,以及地图相关api的讲解。

一 百度地图sdk介绍

通过定位sdk获取的BDLocation类中包含了当前位置的:经纬度,省、市、区、街道等地址信息。如果应用只需要获取用户当前位置所在的市、县、区等信息,那么定位sdk就可以满足你的需求。如果要具体显示位置在哪,除了通过定位sdk获取经纬度之外,还需要通过百度地图来显示。

百度地图sdk提供了Mapview、BaiduMap、OverlayOptions、Overlay等api,用于地图的操作与图层绘制。

MapView就是一张图,就是一个View,它不会产生位置。

定位sdk能获取经纬度,相当于x、y坐标;地图根据坐标找到对应的点,在地图图层上画一个图标标识,这就是我们在地图上看到的定位


地图+定位位置

了解这些,如何在地图上显示出定位点就简单了,我们需要地图与位置。

二 百度地图与定位sdk的结合使用

1.初始化地图

//伪代码
// 地图初始化
MapView mMapView = (MapView) findViewById(R.id.bmapView);
BaiduMap mBaiduMap = mMapView.getMap();//获取地图实例
// 开启定位图层,一定不要少了这句,否则对在地图的设置、绘制定位点将无效
mBaiduMap.setMyLocationEnabled(true);

这样地图就获取到了,接着对定位图标进行配置,非常简单,一句代码。也可以不配置,百度会用默认的图标

/**
* 对定位的图标进行配置,需要MyLocationConfiguration实例,这个类是用设置定位图标的显示方式的
 */
mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(locationMode, true, bitmapDescriptor));

MyLocationConfiguration有2个构造方法

new MyLocationConfiguration(LocationMode lm, boolean direction, BitmapDescriptor bd);
new MyLocationConfiguration(LocationMode lm, boolean direction, BitmapDescriptor bd,int fillColor,int strokeColor);

LocationMode:图标类型
有三种:
LocationMode.NORMAL:普通


普通图标:圆点,不显示方向;地图方位固定,上北下南左西右东

LocationMode.FOLLOWING:跟随


跟随图标:地图方位固定,上北下南左西右东;箭头转动,箭头表示手机头部所朝的方向,

LocationMode.COMPASS:罗盘
罗盘图标:地图会随方向转动,有指南针的方向标识;可观察箭头方向偏离北的情况

direction:是否允许显示方向信息,如果设置为false,则图标任何情况下都不会有箭头

BitmapDescriptor:用户自定义定位图标,可以更换定位图标样式

fillColor:精度圈填充颜色(半径等于location.getRadius())
strokeColor:精度圈边框颜色
如果不想要这个精度圈,使用location.getRadius() = 0;

3.定位sdk初始化

// 定位初始化
LocationClient mLocClient = new LocationClient(this);
mLocClient.registerLocationListener(myListener);//注册定位位置监听回调
LocationClientOption option = new LocationClientOption();//定位方式参数设置
option.setOpenGps(true); // 打开gps
option.setCoorType("bd09ll"); // 设置坐标类型
option.setScanSpan(1000);//周期性请求定位,1秒返回一次位置
mLocClient.setLocOption(option);//参数设置
mLocClient.start();//开始定位

定位sdk更多api详解请阅读百度地图(一):百度地图定位sdk 类方法参数、定位原理详细介绍

4.位置监听回调

//伪代码
public class MyLocationListenner implements BDLocationListener {

    @Override
    public void onReceiveLocation(BDLocation location) {
        //定位位置回调
        /**
        * MyLocationData 定位数据类,地图上的定位位置需要经纬度、精度、方向这几个参数,所以这里我们把这个几个参数传给地图
        * 如果不需要要精度圈,推荐builder.accuracy(0);
        * mCurrentDirection 是通过手机方向传感器获取的方向;也可以设置option.setNeedDeviceDirect(true)获取location.getDirection(),
          但是这不会时时更新位置的方向,因为周期性请求定位有时间间隔。
        * location.getLatitude()和location.getLongitude()经纬度,如果你只需要在地图上显示某个固定的位置,完全可以写入固定的值,
          如纬度36.958454,经度114.137588,这样就不要要同过定位sdk来获取位置了
        */
        MyLocationData locData = new MyLocationData.Builder().accuracy(location.getRadius())
        .direction(mCurrentDirection).latitude(location.getLatitude()).longitude(location.getLongitude()).build();

        mBaiduMap.setMyLocationData(locData);//给地图设置定位数据,这样地图就显示位置了

        /**
        *当首次定位时,记得要放大地图,便于观察具体的位置
        * LatLng是缩放的中心点,这里注意一定要和上面设置给地图的经纬度一致;
        * MapStatus.Builder 地图状态构造器
        */
        if (isFirstLoc) {
            isFirstLoc = false;
            LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
            MapStatus.Builder builder = new MapStatus.Builder();
            //设置缩放中心点;缩放比例;
            builder.target(ll).zoom(18.0f);
           //给地图设置状态
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
        }
    }
}

5.绘制图层

/**
* 绘制Marker,地图上常见的类似气球形状的图层
*/
MarkerOptions markerOptions = new MarkerOptions();//参数设置类
markerOptions.position(latLng);//marker坐标位置
markerOptions.icon(icon);//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(MarkerAnimateType.drop);//marker出现的方式,从天上掉下
markerOptions.flat(false);//marker突变是否平贴地面
markerOptions.zIndex(1);//index

//Marker动画效果
markerOptions.icons(bitmapList);//如果需要显示动画,可以设置多张图片轮番显示
markerOptions.period(10);//每个10ms显示bitmapList里面的图片
...
mMarker = (Marker) mBaiduMap.addOverlay(markerOptions);//在地图上增加mMarker图层

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

/**
* colorValue:List<Integer>,折线颜色集合
* 如果这里设置了折现颜色集合,那么options.color()中设置的颜色会被覆盖
* 例:5个点能画出4条线段,每条线段绘制时按照索引依次取值,
  如果颜色个数小于线段个数,剩余线段取最后一个颜色绘制
*/
polylineOptions.colorsValues(colorValue);
polylineOptions.dottedLine(false);//是否是虚线,默认为false
polylineOptions.zIndex(9);//index
polylineOptions.visible(true);//是否可见,默认可见
polylineOptions.extraInfo(bundle);//附加bundle

/**
* 设置线段纹理样式,所以折线纹理样式是可以自己定义的
* textureList:折现纹理样式集合 
* textureIndexs:折线纹理索引,绘制时按照索引从textureList里面取样式,
  如下面代码中,0和1就是textureList的索引,这样就会先取a再取b,
  如果textureIndexs.add(1)然后再textureIndexs.add(0)就先取b再取a了,
  所以textureIndexs里面的值不能乱加,应该是小于等于textureList个数的值,不然就出错了。
*/
List<BitmapDescriptor> textureList = new ArrayList<BitmapDescriptor>();
textureList.add(BitmapDescriptorFactory.fromResource(R.drawable.a));
textureList.add(BitmapDescriptorFactory.fromResource(R.drawable.b));
polylineOptions.customTextureList(textureList);//设置折现纹理样式
List<Integer> textureIndexs = new ArrayList<Integer>();
textureIndexs.add(0);
textureIndexs.add(1);
polylineOptions.textureIndex(textureIndexs);
...
mPolyline = (Polyline) mBaiduMap.addOverlay(polylineOptions);//在地图上增加mPolyline图层

/**
* 绘制多边形
*/
PolygonOptions polygonOptions = new PolygonOptions();
polygonOptions.points(pts);//多边形顶点坐标集
polygonOptions.stroke(new Stroke(5, 0xAA00FF00));//边框样式
polygonOptions.fillColor(0xAAFFFF00);//填充颜色
mPolygon = mBaiduMap.addOverlay(polygonOptions);//在地图上增加mPolygon 图层

/**
* 绘制圆形
*/
OverlayOptions oCircle = new CircleOptions().fillColor(0x000000FF)
                .center(latLngCircle).stroke(new Stroke(5, 0xAA000000))
                .radius(1400);
mBaiduMap.addOverlay(oCircle);

/**
* 绘制弧形
*/
OverlayOptions oArc = new ArcOptions().color(0xAA00FF00).width(4)
                .points(p1, p2, p3);//三点绘制一个弧形
mBaiduMap.addOverlay(oArc);

/**
* 绘制文本文字
*/
OverlayOptions ooText = new TextOptions().bgColor(0xAAFFFF00)
                .fontSize(24).fontColor(0xFFFF00FF).text("文字内容").rotate(-30)
                .position(latLngText);
mBaiduMap.addOverlay(ooText);

6.地图关键api介绍

//是将地理坐标转换为屏幕上的坐标,其中point.y是地理位置点相对于MapView左上角的y轴坐标。
Point point = mBaiduMap.getProjection().toScreenLocation(latLng);

//截图
mBaiduMap.snapshot(new SnapshotReadyCallback() {
    @Override
    public void onSnapshotReady(Bitmap arg0) {

    }
});

//截图, Rect指定区域
mBaiduMap.snapshotScope(new Rect(), new SnapshotReadyCallback() {
    @Override
    public void onSnapshotReady(Bitmap arg0) {

    }
});

mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);//设置地图类型,卫星地图

mBaiduMap.clear();//清空地图所有的 Overlay 覆盖物以及 InfoWindow

//Overlay所有图层父类
mOverlay.setVisible(true);//设置图层是否可见
mOverlay.remove();//删除该图层,只删除这一个;mBaiduMap.clear()会把所有的图层清空,这有时候不是我们需要看到。

更多百度地图api会在后续文章中介绍

7.地图事件监听

// 点击Marker事件响应
mBaiduMap.setOnMarkerClickListener(new OnMarkerClickListener() {
    @Override
    public boolean onMarkerClick(Marker marker) {
        if(marker.getZIndex() == mMarker.getZIndex()){//判断是哪个marker
            //获取mMarker的信息
        }
        return false;
    }
});

// Marker拖拽事件响应
mBaiduMap.setOnMarkerDragListener(new OnMarkerDragListener() {      
    @Override
    public void onMarkerDragStart(Marker arg0) {
        //拖拽开始
    }
            
    @Override
    public void onMarkerDragEnd(Marker arg0) {
        //拖拽结束  
    }
            
    @Override
    public void onMarkerDrag(Marker arg0) {
        //拖拽中
    }
});

// 点击Polyline事件响应
mBaiduMap.setOnPolylineClickListener(new BaiduMap.OnPolylineClickListener() {
    @Override
    public boolean onPolylineClick(Polyline polyline) {      
        if(polyline.getZIndex() == mPolyline.getZIndex()){//判断是哪个mPolyline
                mPolyline.getPoints();//获取折线点集合
                mPolyline.getExtraInfo();//获取附加的信息
                ...
        }
        return false;
    }
});

//地图点击事件响应
mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener() {
    @Override
    public void onMapClick(LatLng latLng) {
        //点击地图某个位置获取经纬度latLng.latitude、latLng.longitude
    }

    @Override
    public boolean onMapPoiClick(MapPoi mapPoi) {
        //点击地图上的poi图标获取描述信息:mapPoi.getName(),经纬度:mapPoi.getPosition()
        return false;
    }
});

//地图加载完成事件响应
mBaiduMap.setOnMapLoadedCallback(new OnMapLoadedCallback() {
    @Override
    public void onMapLoaded() {
        //地图的有些操作需要再加载完成之后进行
    }
});

//地图中心、缩放状态改变事件响应
mBaiduMap.setOnMapStatusChangeListener(new OnMapStatusChangeListener() {
    @Override
    public void onMapStatusChangeStart(MapStatus status) {
        //开始
    }
            
    @Override
    public void onMapStatusChangeFinish(MapStatus status) {//完成
        status.target;//当前中心点
        status.zoom;//当前缩放比例
        ...
    }
            
    @Override
    public void onMapStatusChange(MapStatus status) {
                
    }
});

//地图定位图标点击响应事件
mBaiduMap.setOnMyLocationClickListener(new OnMyLocationClickListener() {
    @Override
    public boolean onMyLocationClick() {
        ...
        return false;
    }
});

地图响应事件还有很多,不一一列举了,想了解更多,阅读api就可以了,比较简单,难的是如何将这些结合起来实现功能,后续文章将会讲到。

退出时记得释放资源

//伪代码
protected void onDestroy() {
    // 退出时销毁定位
    mLocClient.unRegisterLocationListener(myListener);
    mLocClient.stop();
    // 关闭定位图层
    mBaiduMap.setMyLocationEnabled(false);
    mBaiduMap.clear();
    mMapView.onDestroy();
    mMapView = null;
}

到这里,百度地图sdk就介绍了,还是很简单的,更多api会在后续文章中讲解。

如果各位看官觉得文章不错,别忘了点个喜欢。
源码下载地址

以上文章内容,是本人工作中的总结,供大家参考,有误的地方还请指正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容