Android百度地图开发03之地图控制 + 定位
前两篇关于百度地图的blog写的是,一些基本图层的展示 和 覆盖物的添加+地理编码和反地理编码。
接下来,这篇blog主要说一些关于地图控制方面的内容和定位功能。
百度地图提供的关于地图的操作主要有:单击、双击、长按、缩放、旋转、俯视等。
地图控制
我们现在已经知道,想要显示一个地图,只需要在xml文件中添加一个MapView控件即可,但是想要对其进行一些控制,就需要通过这个控件返回一个BaiduMap对象。
从API中先看一下MapView的方法:
对于MapView这个类,官方解释是一个显示地图的视图,负责从服务器端获取地图数据,并且会捕捉到屏幕触控手势事件。使用这个类必须按照它的生命周期
进行操作,从上图可以看到,它包括一些类似于activity生命周期的方法:onResume()、onPause()、onDestory()。所以
我们需要在activity的各个生命周期中,把MapView的各个生命周期函数添加进去。
在使用地图控件之前必须调用SDKInitializer.initialize(Context)函数用以提供全局Context信息。
默认情况下,地图显示的时候会带着原生的缩放控件:。还有比例尺控件:
。
通过showZoomControls(boolean show)和showScaleControl(boolean show)这两个方法可以设置显示或者不显示两个控件。还可以通过设置setxxxPosition(Point p)方法来设置控件的位置。
- mapView.showZoomControls(false);// 不显示默认的缩放控件
- mapView.showScaleControl(false);// 不显示默认比例尺控件
要想实现地图的一些控制,就需要使用到BaiduMap,这个类是专门用来操作地图控件的。
上面的四个接口就是用来对地图添加相应的事件的。我们主要看一下下面的两个方法,它们都是以动画的方式更新地图状态。不同的是一个可以指定时长,另一个有默认的动画耗时。
参数MapStatusUpdate描述的是地图状态将要发生的变化。也就是说,要想改变地图的某些状态,需要构造出一个MapStatusUpdate对象,然后使用animateMapStatus()方法来更新地图状态。但是并没有在API中找到它的相关的构造方法。但是在com.baidu.mapapi.map包下面找到了对应的"工厂类"。
打开MapStatusUpdateFactory可以看到很多静态的方法:
通过这些静态的方法能够构造出各种类型的MapStatusUpdate对象。
zoomIn()和zoomOut()分别是放大和缩小地图,分别是在当前基础上增加或较少1个级别。zoomTo()可以自己设置某一个缩放级别。百度地图将地图的级别定义为【3~19】。
放大:
- msu = msuFactory.zoomIn();
- bdMap.animateMapStatus(msu);
缩小:
- msu = msuFactory.zoomOut();
- bdMap.animateMapStatus(msu);
设置地图中心点:
- msu = msuFactory.newLatLng(arg0);
- bdMap.animateMapStatus(msu);
其他的方法就不一一叙述了。
关于地图控制状态的还有两个类:MapStatus和MapStatus.Builder。Builder是MapStatus的一个内部类,用于构造它,我们在API中可以看到MapStatus中是没有构造函数的。
使用这两个类可以对地图进行旋转、俯视、设置中心点、设置缩放级别等操作。通过这些方法构造出MapStatus方法之后,怎么让BaiduMap调用它呢?
查阅BaiduMap的所有方法之后也没有找到参数是MapStatus的方法。那么,猜想可能是通过把MapStatus转换成一个其他的对象,然后在
由BaiduMap调用。而BaiduMap只有animateMapStatus()方法来更新地图状态。所以很定是MapStatus--->MapStatusUpdate。在MSU的工厂类中有这样一个方法:newMapStatus(MapStatus
mapStatus)。OK,通过这个方法,可以把构造的MapStatus对象转成MapStatusUpdate,然后在通过animateMapStatus()调用就行了。
旋转:
- mapStatus = new MapStatus.Builder(bdMap.getMapStatus()).rotate(rotateAngle += 30).build();
- msu = msuFactory.newMapStatus(mapStatus);
- bdMap.animateMapStatus(msu);
俯视(-45°~0):
- mapStatus = new MapStatus.Builder(bdMap.getMapStatus()).overlook(overlookAngle -= 10).build();
- msu = msuFactory.newMapStatus(mapStatus);
- bdMap.animateMapStatus(msu);
这里,lz有一个疑问:MapStaus.Builder中有一个设置地图中心点的方法:
,在MapStatusUpdateFactory中也有一个设置中心点的方法:
。连个都是设置中心点,不知道区别是什么?希望知道的给我留个言,告知一下!!谢谢!~~
截屏:
在BaiduMap中有一个截屏的回调接口和一个截图的请求方法:
很明显,调用这个截图请求方法,参数是上面的回调接口。在回调接口中只有一个方法:onSnapshotReady(Bitmap snapshot)。我们得到这个bitmap之后,就可以生成图片保存起来了。
有Bitmap转成图片就需要用到Bitmap.compress()方法:
- bdMap.snapshot(new SnapshotReadyCallback() {
- @Override
- public void onSnapshotReady(Bitmap bitmap) {
- File file = new File("/mnt/sdcard/test.png");
- FileOutputStream out;
- try {
- out = new FileOutputStream(file);
- if (bitmap.compress(
- Bitmap.CompressFormat.PNG, 100, out)) {
- out.flush();
- out.close();
- }
- Toast.makeText(MapControllActivity.this,
- "屏幕截图成功,图片存在: " + file.toString(),
- Toast.LENGTH_SHORT).show();
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- });
定位
LZ采用的是百度最新版本5.0的SDK,该版本支持全球定位。
开发定位功能一般都是按照以下步骤:
1. 导入库文件。
下载下来lib压缩包之后,会看到很多文件夹(对应很多架构),官方建议全部拷贝到lib下,这样程序兼容性大大提升,不要忘了把locSDK_5.0.jar拷贝到lib下。
2. 添加定位service
- <service
- android:name="com.baidu.location.f"
- android:enabled="true"
- android:process=":remote" >
- </service>
3. 添加权限
- <!-- 这个权限用于进行网络定位 -->
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >
- </uses-permission>
- <!-- 这个权限用于访问GPS定位 -->
- <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >
- </uses-permission>
- <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >
- </uses-permission>
- <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >
- </uses-permission>
- <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
- <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >
- </uses-permission>
- <!-- 用于读取手机当前的状态 -->
- <uses-permission android:name="android.permission.READ_PHONE_STATE" >
- </uses-permission>
- <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >
- </uses-permission>
- <!-- 访问网络,网络定位需要上网 -->
- <uses-permission android:name="android.permission.INTERNET" />
- <!-- SD卡读取权限,用户写入离线定位数据 -->
- <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >
- </uses-permission>
- <!-- 允许应用读取低级别的系统日志文件 -->
- <uses-permission android:name="android.permission.READ_LOGS" >
- </uses-permission>
4. 编写定位程序
这一步才是重点。百度地图可以使用GPS和网络定位(WIFI和基站)进行定位。基本定位功能还支持定位结果的反地理编码功能,离线定位,位置提醒功能和地理围栏功能。
主要会用到LocationClient、BDLocationListener、BDNotifyListener、LocationClientOption等类。
(1)初始化LocationClient类:
LocationClient类是定位SDK的核心类,必须在主线程中声明。需要传入一个Context类型的参数,推荐使用getApplicationContext()来获取全局进程有效的context。
主要会用到该类中的以下几个方法:
(2)设置定位参数:
主要的参数有:定位模式、返回坐标类型、是否打开GPS等。
定位模式分为三种:
1. 高精度定位模式:同时使用网络定位和GPS定位,优先返回最高精度的定位结果。
2. 低功耗定位模式:不使用GPS,只使用网络定位(WiFi和基站)。
3. 仅用设备定位模式: 不适用网络定位,只使用GPS进行定位。但是此模式下不支持室内环境的定位。
在API中主要关注“setxxx”类型的函数。主要用到红色框标注的方法。
- LocationClientOption locOption = new LocationClientOption();
- locOption.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式
- locOption.setCoorType("bd09ll");// 设置定位结果类型
- locOption.setScanSpan(5000);// 设置发起定位请求的间隔时间,ms
- locOption.setIsNeedAddress(true);// 返回的定位结果包含地址信息
- locOption.setNeedDeviceDirect(true);// 设置返回结果包含手机的方向
- locationClient.setLocOption(locOption);
坐标类型分为三种:国测局经纬度坐标系(gcj02),百度墨卡托坐标系(bd09),百度经纬度坐标系(bd09ll)。
设置请求定位时间间隔:
设置返回结果包含地址信息:
设置返回结果中包含手机方向:
(3)设置定位监听函数
- locationClient.registerLocationListener(locationListener);
- //
- class MyLocationListener implements BDLocationListener {
- // 异步返回的定位结果
- @Override
- public void onReceiveLocation(BDLocation location) {
- }
- }
百度官网说明有一些是不准确的。实现BDLocationListener接口的时候,在之前的版本是有两个方法需要实现,新版本(5.0)的只有一个方
法需要实现:onReceiveLocation()。BDLocation类封装了定位SDK的定位结果,通过该可以获取定位返回的结果、位置坐标、精
度半径等信息。
定位成功与否,定位的错误码都是通过getLocType()这个方法得到的,返回值是int类型。
注意:只有在使用网络定位的情况下,才能获取当前位置的反地理编码。
- } else if (locType == BDLocation.TypeNetWorkLocation) {
- addrStr = location.getAddrStr();// 获取反地理编码(文字描述的地址)
- Toast.makeText(LocationActivity.this, addrStr,
- Toast.LENGTH_SHORT).show();
- }
(4)添加位置提醒监听函数
- notifyListener = new MyNotifyListener();
- notifyListener.SetNotifyLocation(longitude, latitude, 3000, "bd09ll");//精度,维度,范围,坐标类型
- locationClient.registerNotify(notifyListener);
- /**
- * 位置提醒监听器
- * @author ys
- *
- */
- class MyNotifyListener extends BDNotifyListener {
- @Override
- public void onNotify(BDLocation bdLocation, float distance) {
- super.onNotify(bdLocation, distance);
- mVibrator.vibrate(1000);//振动提醒已到设定位置附近
- Toast.makeText(LocationActivity.this, "震动提醒", Toast.LENGTH_SHORT).show();
- }
- }
(5)开启定位
LocationClient的start()方法用来启动定位SDK,requestLocation()方法用来请求一次定位,请求过程是异步的。调用start()方法之后,会根据你设置的定位事件间隔来请求定位。
(6)最后不要忘了在不用的时候注销定位监听和位置提醒监听,并且关闭地图。
- @Override
- protected void onDestroy() {
- super.onDestroy();
- mapview.onDestroy();
- locationClient.unRegisterLocationListener(locationListener);
- //取消位置提醒
- locationClient.removeNotifyEvent(notifyListener);
- locationClient.stop();
- }
此时可以完成了一个基本的地图定位功能和位置提醒。如果要显示在地图上,就想百度那样出现一个点表示地图的定位点,就需要用到MyLocationConfiguration(配置定位图层显示方式)和MylocationData(定位数据)。
MyLocationData包含一个内部了Builder用于构建MyLocationData对象:
- // 构造定位数据
- MyLocationData locData = new MyLocationData.Builder()
- .accuracy(radius)//
- .direction(direction)// 方向
- .latitude(latitude)//
- .longitude(longitude)//
- .build();
- // 设置定位数据
- bdMap.setMyLocationData(locData);
通过定位的onReceiveLocation()方法可以得到定位的经纬度,然后可以通过animationMapStatus()方法把定位到的点移动到地图中心。
- LatLng ll = new LatLng(latitude, longitude);
- MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll);
- bdMap.animateMapStatus(msu);
定位图层的显示方式有三种:普通、跟随、罗盘,在MyLocationConfiguration.LocationMode这个内部类中定义为枚举常量。
我们来看一下MyLocationConfiguration的构造函数:
第一个参数就是图层的显示方式(LocationMode类型),第二个参数表示是否显示方向信息(booleab类型),第三个参数是
(bitmapDescriptor类型,我们在前面的blog有过介绍了)。构造出这个对象之后,就可以调用BaiduMap的
setMyLocationConfigeration()方法来设置定位图层配置信息了。
- switch (currentMode) {
- case NORMAL:
- locateBtn.setText("跟随");
- currentMode = MyLocationConfiguration.LocationMode.FOLLOWING;
- break;
- case FOLLOWING:
- locateBtn.setText("罗盘");
- currentMode = MyLocationConfiguration.LocationMode.COMPASS;
- break;
- case COMPASS:
- locateBtn.setText("普通");
- currentMode = MyLocationConfiguration.LocationMode.NORMAL;
- break;
- }
- bdMap.setMyLocationConfigeration(new MyLocationConfiguration(
- currentMode, true, currentMarker));
总结
Android百度地图开发03之地图控制 + 定位的更多相关文章
- C#的百度地图开发(四)前端显示与定位
原文:C#的百度地图开发(四)前端显示与定位 有了这些定位信息,那要如何在前端的页面上显示出来呢?这需要用到百度地图的JavaScript的API.下面是示例代码. 前端代码 <%@ Page ...
- [android] 百度地图开发 (两).所在地的城市定位和城市POI搜索
一个. 百度地图城市位置和POI搜索知识 上一篇文章"百度地图开发(一)"中讲述了怎样申请百度APIKey及解决显示空白网格的问题.该篇文章主要讲述怎样定位城市位置.定 ...
- Android 百度地图开发问题----解决地图有时候加载不出来问题
相信很多人在开发百度地图的时候会出现百度地图有时候会加载不出来,只显示网格图. 这个问题究其原因就是申请百度key的时候填写的SHA1也就是指纹证书有问题.估计很多开发者都是照着百度开放平台上介绍的流 ...
- Android 百度地图开发(一)--- 申请API Key和在项目中显示百度地图
标签: Android百度地图API Key 分类: Android 百度地图开发(2) 最近自己想研究下地图,本来想研究google Map,但是申请API key比较坑爹,于是从百度地 ...
- Android 百度地图API(01)_开发环境 HelloBaiduMap
转载于:http://blog.csdn.net/lmj623565791/article/details/37729091 转载于:http://blog.csdn.net/crazy1235/ar ...
- Android 百度地图开发(一)
在自己的Android项目中增加百度地图的功能. 一 申请API key 在使用百度地图之前,我们必须去申请一个百度地图的API key,申请地址http://lbsyun.baidu.com/api ...
- android 百度地图开发实例(转载)
因为在我的寝室google基站定位返回的数据总是为空,所以换成百度地图,发现百度地图开发起来非常方便,提供了许多有用的工具,地图的加载速度也比google地图快许多. 为了加强记忆,写一点androi ...
- [android] 百度地图开发 (一).申请AK显示地图及解决显示空白网格问题
近期做android百度地图,可是使用baidumapapi_v2_3_1.jar和libBaiduMapSDK_v2_3_1.so显示百度地图时总是遇到问题--仅仅显示网格而没有显示地图,网 ...
- android 百度地图定位开发2
先下载了示例代码 进行配置(可查看开发 指南 Hello BaiDuMap) 第一步:创建并配置工程(具体方法参见工程配置部分的介绍): 第二步:在AndroidManifest中添加开发密钥.所需权 ...
随机推荐
- cnblogs体验
用博客园可以让我更好的关注我们班同学的情况,通过关注他们,浏览他们发布的博客,学习到了很 多,比如不同的设计思想,良好的变成习惯,变量命名,缩进,注释等,而且自己不会的,可以帮助自己 有一些想法,是自 ...
- liferay7中如何Hiding the default Success Message
下面介绍如何把在Liferay 7中如何把action执行成功之后的信息不显示,因为宝宝有需要,就去查了相关源码和资料. 如果想要某个portlet不显示执行成功的信息,在doProcessActio ...
- throttle/debounce: 为你的cpu减减压(前端性能优化)
何为throttle, 何为debounce? 谷歌翻译给出的意思:throttle 掐死??? debounce 去抖 好吧,按理解我们习惯翻译成 ——节流. 那么在什么场景下需要用到? 场景一 ...
- nginx简单反向代理和负载均衡(ubuntu)
nginx简单反向代理与负载均衡 环境:三台ubuntu 12.04.5 虚拟机 均装有nginx 1.1.19 以下u1(192.168.240.129) ,u2(192.168.240.13 ...
- 【python】编码规范(转载)
转自:http://www.cnblogs.com/itech/archive/2012/01/06/2314454.html 1 编码 >>所有的 Python 脚本文件都应在文件头标上 ...
- Hibernate O/R Mapping模拟
作为SSH中的重要一环,有必要理解一下Hibernate对 O/R Mapping的实现. 主要利用java的反射机制来得到完整的SQL语句. 准备工作: 1. Object Student实体类: ...
- Asp.net的服务器推技术 (Server Push)
在以往的和服务器端通信技术中,我们多数使用的是AJAX轮询式访问,也就是在Javascript中控制时间间隔,然后每隔一段时间就访问一次服务器,然后获得数据或通知.但是这种轮询方式的访问有90%是在做 ...
- Apache CXF实现Web Service(4)——Tomcat容器和Spring实现JAX-RS(RESTful) web service
准备 我们仍然使用 Apache CXF实现Web Service(2)——不借助重量级Web容器和Spring实现一个纯的JAX-RS(RESTful) web service 中的代码作为基础,并 ...
- 【面试题043】n个骰子的点数
[面试题043]n个骰子的点数 题目: 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s, 输入n,打印出s的所有可能的值出现的概率. n个骰子的总点数,最小为n,最大为6n,根据排列组 ...
- 【面试题】Google of Greater China Test for New Grads of 2014总结
2014年Google中国校园招聘采用在线技术笔试,在Code Jam平台上,14号9点到15号9点开放测试题,帮助大家熟悉环境.这个周末也有够忙的,当时就上去看了一下,把输入文件下了一下,今天才把题 ...