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)方法来设置控件的位置。

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mapView.showZoomControls(false);// 不显示默认的缩放控件  
  2. mapView.showScaleControl(false);// 不显示默认比例尺控件  

    要想实现地图的一些控制,就需要使用到BaiduMap,这个类是专门用来操作地图控件的。



    上面的四个接口就是用来对地图添加相应的事件的。我们主要看一下下面的两个方法,它们都是以动画的方式更新地图状态。不同的是一个可以指定时长,另一个有默认的动画耗时。

    参数MapStatusUpdate描述的是地图状态将要发生的变化。也就是说,要想改变地图的某些状态,需要构造出一个MapStatusUpdate对象,然后使用animateMapStatus()方法来更新地图状态。但是并没有在API中找到它的相关的构造方法。但是在com.baidu.mapapi.map包下面找到了对应的"工厂类"。


    打开MapStatusUpdateFactory可以看到很多静态的方法:


    通过这些静态的方法能够构造出各种类型的MapStatusUpdate对象。

    zoomIn()和zoomOut()分别是放大和缩小地图,分别是在当前基础上增加或较少1个级别。zoomTo()可以自己设置某一个缩放级别。百度地图将地图的级别定义为【3~19】。

放大:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. msu = msuFactory.zoomIn();  
  2. bdMap.animateMapStatus(msu);  

缩小:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. msu = msuFactory.zoomOut();  
  2. bdMap.animateMapStatus(msu);  

设置地图中心点:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. msu = msuFactory.newLatLng(arg0);  
  2. bdMap.animateMapStatus(msu);  

    其他的方法就不一一叙述了。
    关于地图控制状态的还有两个类:MapStatusMapStatus.Builder。Builder是MapStatus的一个内部类,用于构造它,我们在API中可以看到MapStatus中是没有构造函数的。

    使用这两个类可以对地图进行旋转、俯视、设置中心点、设置缩放级别等操作。通过这些方法构造出MapStatus方法之后,怎么让BaiduMap调用它呢?

    查阅BaiduMap的所有方法之后也没有找到参数是MapStatus的方法。那么,猜想可能是通过把MapStatus转换成一个其他的对象,然后在 由BaiduMap调用。而BaiduMap只有animateMapStatus()方法来更新地图状态。所以很定是MapStatus--->MapStatusUpdate。在MSU的工厂类中有这样一个方法:newMapStatus(MapStatus mapStatus)。OK,通过这个方法,可以把构造的MapStatus对象转成MapStatusUpdate,然后在通过animateMapStatus()调用就行了。

旋转:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mapStatus = new MapStatus.Builder(bdMap.getMapStatus()).rotate(rotateAngle += 30).build();  
  2. msu = msuFactory.newMapStatus(mapStatus);  
  3. bdMap.animateMapStatus(msu);  

俯视(-45°~0):

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. mapStatus = new MapStatus.Builder(bdMap.getMapStatus()).overlook(overlookAngle -= 10).build();  
  2. msu = msuFactory.newMapStatus(mapStatus);  
  3. bdMap.animateMapStatus(msu);  

    这里,lz有一个疑问:MapStaus.Builder中有一个设置地图中心点的方法:

,在MapStatusUpdateFactory中也有一个设置中心点的方法:。连个都是设置中心点,不知道区别是什么?希望知道的给我留个言,告知一下!!谢谢!~~
截屏:

    在BaiduMap中有一个截屏的回调接口和一个截图的请求方法:



很明显,调用这个截图请求方法,参数是上面的回调接口。在回调接口中只有一个方法:onSnapshotReady(Bitmap snapshot)。我们得到这个bitmap之后,就可以生成图片保存起来了。

    有Bitmap转成图片就需要用到Bitmap.compress()方法:

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. bdMap.snapshot(new SnapshotReadyCallback() {  
  2.         @Override  
  3.         public void onSnapshotReady(Bitmap bitmap) {  
  4.             File file = new File("/mnt/sdcard/test.png");  
  5.             FileOutputStream out;  
  6.             try {  
  7.                 out = new FileOutputStream(file);  
  8.                 if (bitmap.compress(  
  9.                         Bitmap.CompressFormat.PNG, 100, out)) {  
  10.                     out.flush();  
  11.                     out.close();  
  12.                 }  
  13.                 Toast.makeText(MapControllActivity.this,  
  14.                         "屏幕截图成功,图片存在: " + file.toString(),  
  15.                         Toast.LENGTH_SHORT).show();  
  16.             } catch (FileNotFoundException e) {  
  17.                 e.printStackTrace();  
  18.             } catch (IOException e) {  
  19.                 e.printStackTrace();  
  20.             }  
  21.         }  
  22.     });  

定位

    LZ采用的是百度最新版本5.0的SDK,该版本支持全球定位。

    开发定位功能一般都是按照以下步骤:

1. 导入库文件。

    下载下来lib压缩包之后,会看到很多文件夹(对应很多架构),官方建议全部拷贝到lib下,这样程序兼容性大大提升,不要忘了把locSDK_5.0.jar拷贝到lib下。
2. 添加定位service

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <service  
  2.         android:name="com.baidu.location.f"  
  3.         android:enabled="true"  
  4.         android:process=":remote" >  
  5. </service>  

3. 添加权限

 

[html] view plaincopy在CODE上查看代码片派生到我的代码片
  1. <!-- 这个权限用于进行网络定位 -->  
  2.     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" >  
  3.     </uses-permission>  
  4.     <!-- 这个权限用于访问GPS定位 -->  
  5.     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" >  
  6.     </uses-permission>  
  7.     <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->  
  8.     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >  
  9.     </uses-permission>  
  10.     <!-- 获取运营商信息,用于支持提供运营商信息相关的接口 -->  
  11.     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >  
  12.     </uses-permission>  
  13.     <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->  
  14.     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >  
  15.     </uses-permission>  
  16.     <!-- 用于读取手机当前的状态 -->  
  17.     <uses-permission android:name="android.permission.READ_PHONE_STATE" >  
  18.     </uses-permission>  
  19.     <!-- 写入扩展存储,向扩展卡写入数据,用于写入离线定位数据 -->  
  20.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" >  
  21.     </uses-permission>  
  22.     <!-- 访问网络,网络定位需要上网 -->  
  23.     <uses-permission android:name="android.permission.INTERNET" />  
  24.     <!-- SD卡读取权限,用户写入离线定位数据 -->  
  25.     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" >  
  26.     </uses-permission>  
  27.     <!-- 允许应用读取低级别的系统日志文件 -->  
  28.     <uses-permission android:name="android.permission.READ_LOGS" >  
  29.     </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”类型的函数。主要用到红色框标注的方法。

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. LocationClientOption locOption = new LocationClientOption();  
  2.         locOption.setLocationMode(LocationMode.Hight_Accuracy);// 设置定位模式  
  3.         locOption.setCoorType("bd09ll");// 设置定位结果类型  
  4.         locOption.setScanSpan(5000);// 设置发起定位请求的间隔时间,ms  
  5.         locOption.setIsNeedAddress(true);// 返回的定位结果包含地址信息  
  6.         locOption.setNeedDeviceDirect(true);// 设置返回结果包含手机的方向  
  7.   
  8.         locationClient.setLocOption(locOption);  

    坐标类型分为三种:国测局经纬度坐标系(gcj02),百度墨卡托坐标系(bd09),百度经纬度坐标系(bd09ll)。


    设置请求定位时间间隔:


    设置返回结果包含地址信息:


    设置返回结果中包含手机方向:


    (3)设置定位监听函数

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. locationClient.registerLocationListener(locationListener);  
  2. //  
  3. class MyLocationListener implements BDLocationListener {  
  4.         // 异步返回的定位结果  
  5.         @Override  
  6.         public void onReceiveLocation(BDLocation location) {  
  7.     }  
  8. }  

    百度官网说明有一些是不准确的。实现BDLocationListener接口的时候,在之前的版本是有两个方法需要实现,新版本(5.0)的只有一个方 法需要实现:onReceiveLocation()。BDLocation类封装了定位SDK的定位结果,通过该可以获取定位返回的结果、位置坐标、精 度半径等信息。



    定位成功与否,定位的错误码都是通过getLocType()这个方法得到的,返回值是int类型。


    注意:只有在使用网络定位的情况下,才能获取当前位置的反地理编码。

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. else if (locType == BDLocation.TypeNetWorkLocation) {  
  2.                 addrStr = location.getAddrStr();// 获取反地理编码(文字描述的地址)  
  3.                 Toast.makeText(LocationActivity.this, addrStr,  
  4.                         Toast.LENGTH_SHORT).show();  
  5.             }  

    (4)添加位置提醒监听函数

 

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. notifyListener = new MyNotifyListener();  
  2. notifyListener.SetNotifyLocation(longitude, latitude, 3000, "bd09ll");//精度,维度,范围,坐标类型  
  3. locationClient.registerNotify(notifyListener);  
[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. /** 
  2.      * 位置提醒监听器 
  3.      * @author ys 
  4.      * 
  5.      */  
  6.     class MyNotifyListener extends BDNotifyListener {  
  7.         @Override  
  8.         public void onNotify(BDLocation bdLocation, float distance) {  
  9.             super.onNotify(bdLocation, distance);  
  10.             mVibrator.vibrate(1000);//振动提醒已到设定位置附近  
  11.             Toast.makeText(LocationActivity.this, "震动提醒", Toast.LENGTH_SHORT).show();  
  12.         }  
  13.     }  

    (5)开启定位
    LocationClient的start()方法用来启动定位SDK,requestLocation()方法用来请求一次定位,请求过程是异步的。调用start()方法之后,会根据你设置的定位事件间隔来请求定位。

    (6)最后不要忘了在不用的时候注销定位监听和位置提醒监听,并且关闭地图。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.     protected void onDestroy() {  
  3.         super.onDestroy();  
  4.         mapview.onDestroy();  
  5.         locationClient.unRegisterLocationListener(locationListener);  
  6.         //取消位置提醒  
  7.         locationClient.removeNotifyEvent(notifyListener);  
  8.         locationClient.stop();  
  9.     }  

    此时可以完成了一个基本的地图定位功能和位置提醒。如果要显示在地图上,就想百度那样出现一个点表示地图的定位点,就需要用到MyLocationConfiguration(配置定位图层显示方式)MylocationData(定位数据)

    MyLocationData包含一个内部了Builder用于构建MyLocationData对象:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. // 构造定位数据  
  2.             MyLocationData locData = new MyLocationData.Builder()  
  3.                     .accuracy(radius)//  
  4.                     .direction(direction)// 方向  
  5.                     .latitude(latitude)//  
  6.                     .longitude(longitude)//  
  7.                     .build();  
  8.             // 设置定位数据  
  9.             bdMap.setMyLocationData(locData);  

    通过定位的onReceiveLocation()方法可以得到定位的经纬度,然后可以通过animationMapStatus()方法把定位到的点移动到地图中心。

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. LatLng ll = new LatLng(latitude, longitude);  
  2.             MapStatusUpdate msu = MapStatusUpdateFactory.newLatLng(ll);  
  3.             bdMap.animateMapStatus(msu);  

    定位图层的显示方式有三种:普通、跟随、罗盘,在MyLocationConfiguration.LocationMode这个内部类中定义为枚举常量。

    我们来看一下MyLocationConfiguration的构造函数:


    第一个参数就是图层的显示方式(LocationMode类型),第二个参数表示是否显示方向信息(booleab类型),第三个参数是 (bitmapDescriptor类型,我们在前面的blog有过介绍了)。构造出这个对象之后,就可以调用BaiduMap的 setMyLocationConfigeration()方法来设置定位图层配置信息了。


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. switch (currentMode) {  
  2.             case NORMAL:  
  3.                 locateBtn.setText("跟随");  
  4.                 currentMode = MyLocationConfiguration.LocationMode.FOLLOWING;  
  5.                 break;  
  6.             case FOLLOWING:  
  7.                 locateBtn.setText("罗盘");  
  8.                 currentMode = MyLocationConfiguration.LocationMode.COMPASS;  
  9.                 break;  
  10.             case COMPASS:  
  11.                 locateBtn.setText("普通");  
  12.                 currentMode = MyLocationConfiguration.LocationMode.NORMAL;  
  13.                 break;  
  14.             }  
  15.             bdMap.setMyLocationConfigeration(new MyLocationConfiguration(  
  16.                     currentMode, true, currentMarker));  

总结

OK,本篇blog主要讲解了地图的控制(缩放、旋转、俯视等)和定位功能,其中定位方面比较复杂一些。
lz也是自己一个人研究,未免有遗漏或者错误之处,希望大家指出,谢谢!

demo下载地址!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA 版 Postman 面世了,功能真心强大!

IDEA是最常用的开发工具&#xff0c;很多程序员都想把它打造成一站式开发平台&#xff0c;于是安装了各种各样的插件。最近发现了一款IDEA插件RestfulFastRequest&#xff0c;细节做的真心不错&#xff0c;说它是IDEA版的Postman也不为过&#xff0c;推荐给大家&#xff01;Res…

DNS子域授权

转载于:https://blog.51cto.com/changeflyhigh/1697257

mongo数据库插入数据_深入研究Mongo数据库

mongo数据库插入数据More popularly known as "mongoDB". It is a no-sql based database. 俗称“ mongoDB” 。 这是一个基于无SQL的数据库。 BASIC STRUCTURE OF MONGO DB MONGO DB的基本结构 A COLLECTION IN MONGODB having 3 DOCUMENTS MONGODB中有3个文档的集…

五分钟,手撸一个Spring容器!

Spring是我们最常用的开源框架&#xff0c;经过多年发展&#xff0c;Spring已经发展成枝繁叶茂的大树&#xff0c;让我们难以窥其全貌。这节&#xff0c;我们回归Spring的本质&#xff0c;五分钟手撸一个Spring容器&#xff0c;揭开Spring神秘的面纱&#xff01;从什么是IOC开始…

Spring Cloud OpenFeign 的 5 个优化小技巧!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;OpenFeign 是 Spring 官方推出的一种声明式服务调用和负载均衡组件。它的出现就是为了替代已经进入停更维护状态的 Feign&am…

Java常用类:7000字一次性帮你总结好啦!

来源&#xff1a;cnblogs.com/lwtyyds/p/15678152.html常用类概述内部类内部类的分类&#xff1a;1.成员内部类&#xff08;非静态内部类&#xff09;2.局部内部类4.匿名内部类Object类Object类常用方法&#xff1a;1.equals方法2.hashCode方法3.toString方法4.finzlize方法包装…

CentOS6.4系统启动失败故障排查

转&#xff1a;http://www.centoscn.com/CentosBug/osbug/2014/1028/4011.html 操作系统启动失败如下图报错&#xff1a; 故障现象&#xff1a; 从图中可以看到&#xff0c;操作系统启动的过程中&#xff0c;fsck在执行文件系统检测时出现了错误&#xff0c;并且是在检查/dev/m…

Linux内存管理--物理内存分配【转】

转自&#xff1a;http://blog.csdn.net/myarrow/article/details/8682819 1. First Fit分配器 First Fit分配器是最基本的内存分配器&#xff0c;它使用bitmap而不是空闲块列表来表示内存。在bitmap中&#xff0c;如果page对应位为1&#xff0c;则表示此page已经被分配&#xf…

JDK的一个Bug,监听文件变更要小心了

背景 在某些业务场景下&#xff0c;我们需要自己实现文件内容变更监听的功能&#xff0c;比如&#xff1a;监听某个文件是否发生变更&#xff0c;当变更时重新加载文件的内容。看似比较简单的一个功能&#xff0c;但如果在某些JDK版本下&#xff0c;可能会出现意想不到的Bug。本…

推荐 17 个压箱底的常用类库

前言在java的庞大体系中&#xff0c;其实有很多不错的小工具&#xff0c;也就是我们平常说的&#xff1a;轮子。如果在我们的日常工作当中&#xff0c;能够将这些轮子用户&#xff0c;再配合一下idea的快捷键&#xff0c;可以极大得提升我们的开发效率。今天我决定把一些压箱底…

02、django中的上下文

2019独角兽企业重金招聘Python工程师标准>>> 1、譬如设置网站的名称,setting中设置变量&#xff1a; # setting.py SITE_NAME "我的小站"2、在view中写函数将该变量转换成字典,做返回值 from django.conf import settings def site_key(request):# 这里使…

实战:10 种实现延迟任务的方法,附代码!

作者 | 磊哥来源 | Java中文社群&#xff08;ID&#xff1a;javacn666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;这篇文章的诞生要感谢一位读者&#xff0c;是他让这篇优秀的文章有了和大家见面的机会&#xff0c;重点是优秀文章&#xff…

面渣逆袭:Redis连环五十二问!三万字+八十图详解!

基础1.说说什么是Redis?Redis图标Redis是一种基于键值对&#xff08;key-value&#xff09;的NoSQL数据库。比一般键值对数据库强大的地方&#xff0c;Redis中的value支持string&#xff08;字符串&#xff09;、hash&#xff08;哈希&#xff09;、 list&#xff08;列表&…

EasyExcel太方便易用了,强烈推荐!

背景 系统中经常要导出大量的数据&#xff0c;格式基本上都是Excel&#xff0c;然而每次导表都是对系统内存的一次挑战。在Java领域&#xff0c;生成或解析Excel的框架比较有名的当属Apache的poi和jxl了。但使用它们&#xff0c;会面临着严重的内存损耗问题。如果系统的并发量还…

【端午】送3本书!

白天在公司搬砖&#xff0c;晚上到家赶紧给小伙伴们安排一波福利&#xff0c;这次送的书是 H 大新出的《深入理解Java核心技术&#xff1a;写给Java工程师的干货笔记&#xff08;基础篇&#xff09;》。书中介绍了普通Java工程师必须要学习的相关知识点&#xff0c;包括面向对象…

面试突击51:为什么单例一定要加 volatile?

.作者 | 磊哥来源 | Java面试真题解析&#xff08;ID&#xff1a;aimianshi666&#xff09;转载请联系授权&#xff08;微信ID&#xff1a;GG_Stone&#xff09;单例模式的实现方法有很多种&#xff0c;如饿汉模式、懒汉模式、静态内部类和枚举等&#xff0c;当面试官问到“为什…

聊聊保证线程安全的10个小技巧

前言对于从事后端开发的同学来说&#xff0c;线程安全问题是我们每天都需要考虑的问题。线程安全问题通俗的讲&#xff1a;主要是在多线程的环境下&#xff0c;不同线程同时读和写公共资源&#xff08;临界资源&#xff09;&#xff0c;导致的数据异常问题。比如&#xff1a;变…

Raid控制器

转载于:https://blog.51cto.com/xuepengdou/1699799

并行计算机架构_计算机科学组织| 并行处理

并行计算机架构并行处理 (Parallel Processing) Parallel processing is processing of the data concurrently. We process the data concurrently to fulfill the demands of the increasingly high performance so that to achieve better throughput instead of processing…

15个必知的Mysql索引失效场景,别再踩坑了!

背景 无论你是技术大佬&#xff0c;还是刚入行的小白&#xff0c;时不时都会踩到Mysql数据库不走索引的坑。常见的现象就是&#xff1a;明明在字段上添加了索引&#xff0c;但却并未生效。前些天就遇到一个稍微特殊的场景&#xff0c;同一条SQL语句&#xff0c;在某些参数下生效…