A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 小鲁哥哥 于 2020-1-8 21:50 编辑

【济南中心】Android就业面试技巧系列-技术篇(地图)

百度地图api里大概有30个类,api的链接是http://developer.baidu.com/map/ ,通过这个api可以轻松的获取百度服务和数据,构建功能丰富、交互性强的地图应用程序.
这个api为我们开发者提供了本地搜索、路线规划、地图定位灯等数据的服务。
要使用百度地图api,首先要申请它的API key,申请这个key是为了相对百度系统唯一标识这个应用的。
申请完key之后,把这个key放到我们的常量接口中去。这些做完之后还要添加地图引擎到工程中,这个引擎包含了百度mapapi的jar包和负责定位的locSDK的jar包。
在工程中添加网络状态的一些权限和获取手机信息的权限。
然后在布局文件中添加MapView控件用于展示地图。这个MapView是百度地图api中继承ViewGroup的一个类,是一个自定义控件。
需要注意的是,在我们加载布局之前,要先到百度地图的服务器端校验我们获取到的key,校验时初始化地图引擎,使用地图引擎的管理类BMapManager进行初始化,初始化时会校验key还有网络状态。key为300时表示授权验证失败,网络状态为2时表示未连接上网络。
做了这几步就可以把地图展示在手机上面。
只做以上几步,我遇到了这样一个问题,当第一次显示地图时能够正常显示,但退出后,再进来就看不到地图的。这时候就得考虑到activity的生命周期问题了,得把activity的onResume、onPause、onDestroy这三个方法都覆写后才能正常显示。
使用这个api有三个核心的类BMapManager、MapView、MapController.
BMapManager类用于地图的管理,比如地图的初始化;MapView类用于地图的展示;MapController类用于对地图的控制,主要用于控制地图的移动、缩放和旋转。对当前正在显示的Map进行控制。
效果一:地图的放大与缩小。
通过MapView设置缩放控件,首先要明确缩放级别。在2.0版本之前支持的缩放级别是3-18,在2.0版本之后所支持的缩放级别变成了3-19,所多的这一个级别是使地图呈现3D效果。
一般会在MapView中添加一个能够让用户控制的能放大和缩小的控件,调用MapView里的setBuiltInZoomControls(true)方法添加控件。
也可以使用zoomIn方法和zoomOut方法,分别放大和缩小一个级别。
效果二:地图的移动
百度地图默认的中心点是北京天安门,移动要调用MapController类中的animateTo方法,给这个方法传进一个GeoPoint对象。GeoPoint对象里放的是经纬度信息。
效果三:地图的旋转
地图上的旋转分为水平方向上的旋转和垂直方向上的旋转。
水平方向上的旋转,调用MapController中的setRotation方法,在这个方法里传入旋转角度,逆时针旋转为角度增大方向。
垂直方向上的旋转,调用MapController中的setOverlooking方法,在这个方法里传入旋转角度。这里的角度都为负数,范围在-45-0。
效果三:点击获取兴趣点信息
版本2.0之后在MapView添加了一个MKMapViewListener,它是地图显示事件监听器,这个监听器里有四个方法,第一个onClickMapPoi(MapPoi mapPoiInfo) 方法, 点击到地图可以点击的标注时会回调此接口,需要通过MapController.enableClick(true)方法来控制点击的开关,否则点击会没反应。第二个onGetCurrentMap(Bitmap b)方法,截图成功后会回调此接口,动画结束时会回调消息onMapAnimationFinish(),地图移动完成时会回调接口onMapMoveFinish()。我们调用MapView的regMapViewListener注册监听器,并把我之前说的监听器放进去,就可以实现点击地图上的兴趣点获取信息的功能。
知识点四:地图图层
我们把地图展现出来以后,要想在地图上覆盖一些东西,就设计到了地图图层的知识。地图可以包含一个或多个图层,每个图层在每个级别都是由若干张图块组成的,它们覆盖了地图的整个表面。例如您所看到包括街道、兴趣点、学校、公园等内容的地图展现就是一个图层,另外交通流量的展现也是通过图层来实现的。
图层分为三类:底图、实时交通信息层和卫星图。
地图是基本的地图图层,包括若干个缩放级别,显示基本的地图信息,包括道路、街道、学校、公园等内容。
实时交通信息层可以调用MapView中的setTraffic(true)方法展示出来。
卫星地图是卫星拍摄的真实的地理面貌,所以卫星地图可用来检测地面的信息,你可以了解到地理位置,地形等,调用MapView中的setSatellite(true)方法实现。
效果五:底图展示
底图展示是默认的
效果六:显示实时交通
MapView.setTraffic(true)
效果七:卫星图
MapView.setSatellite(true)
需要注意的是,展示底图的时候要关闭掉实时交通图和卫星图,显示实时交通图的时候关闭掉卫星图,显示卫星图的时候要关闭掉实时交通图,分别setTraffic(false)和setSatellite(false)。
知识点七:覆盖物
有了地图的图层,我们就可以在地图上叠加或覆盖内容,这些内容我们把它称作地图覆盖物。比如说覆盖一些标注,矢量图形元素,定位坐标这些。覆盖物都有自己的地理坐标,当我们拖动或缩放地图时,它们会做相应的处理。
关于覆盖物有一个重要的类Overlay,它表示可以显示在地图上的覆盖物。如果想在图层上画一些东西,就必须继承Overlay,关于Overlay的使用,在MapView上显示Overlay的步骤是固定的。一共三步,
第一步是要获取到MapView中保存Overlay的集合 mapView.getOverlays()。这个集合是一个list.
第二步是在这个集合里添加需要显示的内容。
第三步刷新界面。
我们处理不同的覆盖物所做的不同的地方就是如何给不同的Overlay设置数据。
知识点八:覆盖物的分类
通常我们使用百度地图会用到的覆盖物有:
几何图形绘制覆盖物:GraphicsOverlay
文字绘制覆盖物:TextOverlay
分条目覆盖物:ItemizedOverlay
本地搜索覆盖物:PoiOverlay
驾车路线覆盖物:RouteOverlay
换乘路线覆盖物:TransitOverlay
我的位置覆盖物:MyLocationOverlay
效果九:几何图形绘制覆盖物
几何图形无非是点、线、面,面里面分为圆、矩形、多边形这几种。
使用绘制覆盖物的通用三步。
在这三步中,我们定义自己的覆盖物GraphicsOverlay,然后设置覆盖物的数据。
比如说画一个圆,这里有一个几何图形类Geometry,使用这个类的setCircle方法可以获取一个圆,我们得指定这个圆的圆心和半径,在这个setCircle方法中传进来圆的圆心还有半径(单位是米),这样就把这个圆给确定下来了.接下来给这个圆设置样式,比如圆的颜色,圆的线条,是否填充这个圆。
然后把这个覆盖物添加到集合中就可以显示出来了。
效果九:文字绘制覆盖物
还有一种是文字图形覆盖物,我们可以在地图的某个点上绘制一段文字信息。这里我们要处理的数据是这个点,要显示的文字的内容,以及文字的样式,比如文字的大小还有颜色。Overlay类中提供了addText方法,绘制文字覆盖物方便多了。
效果十:分条目覆盖物
分条目覆盖物所对应的信息就是一个一个的item,比如说我想描述一下我们这个附近有小吃的地儿,我们就可以把搜索到的结果绘制在地图上。这里有个类是ItemizedOverlay,我们在处理某个类型的覆盖物,包含多个类型相同、显示方式相同、处理方式相同的项的时候,使用这个类,比如说我们在附近画一些点,ItemizedOverlay这个类本身包含list,我们分别设置这些点的位置信息,文字片段信息,还有item的标题文本,把这些点一个一个或者批量的添加到list中,这些数据设置好后,再把这个覆盖物添加到Overlay的集合中,就可以显示出来了。
效果十一:点击条目,显示泡泡窗口
我们还会做一个效果,当用户点击这个item的时候,能够显示一个泡泡出来,泡泡的布局文件是一个linearlayout,布局文件里有三个控件,两个ImageView中间加一个TextView,两边的图片一个用来显示路线,一个用作搜索,加载这个布局后,设置泡泡的信息然后添加到mapView中。
当条目被点击的时候,我们会覆盖onTap这个方法,在处理onTap时更新Layout,利用LayoutParams传递点位信息,同时可以获取标题信息,设置给TextView 。这时候,我们再点击条目的时候,就能够显示这个泡泡了。
知识点十二:搜索
百度地图里也集成了很多搜索服务,比如说位置检索、周边检索、范围检索、公交检索、驾乘检索、步行检索这些。
搜索里有两个核心的类MKSearch和MKSearchListener。要实现搜索功能,首先要初始化MKSearch类,然后通过它的init方法注册搜索结果的监听对象MKSearchListener,来实现异步搜索服务。然后通过自定义MySearchListener实现类,处理不同的回调方法,获得搜索结果。
效果十三:在一个圆形区域内进行兴趣点搜索
比如我们搜多本公司周边的饭店,我们要调用MKSearch对象的poiSearchNearBy方法,在这个方法里传入我们要搜索的内容,我们公司的点以及所要搜索的范围。结果的处理要在MKSearchListener的onGetPoiResult方法中,在该方法中可以通过传递的type值来区分是范围搜索还是城市检索。之后的处理是先判断服务器是否返回有效数据,然后创建poi覆盖物,再将服务器返回数据添加到poi覆盖物中,然后添加覆盖物到MapView,最后刷新MapView就实现了搜索的功能,显示我们要搜索的信息。
效果十四:在一个矩形区域内进行兴趣点的搜索
为什么要有这样的一个搜索呢?市面上有这样的应用,在地图上画一条线,要求在这条线的附近搜索我们想要找的东西。这时候的处理是将这条曲线的两个端点作为圆形区域搜索,而把线的部分作为矩形区域来搜索。矩形搜索也是会经常用到的。
矩形搜索所用到的api是poiSearchInbounds,和圆形搜索类似,只是在搜索的时候变为矩形,在方法中传入搜索关键词,左下角地理坐标和左上角地理坐标。通过这两个坐标,我们就能得到所需要的矩形。区域设置好后,我们结果的处理依然是在MKSearchListener的onGetPoiResult方法中,处理的方式不变。
效果十五:全城搜索
全城搜索使用到的方法是poiSearchInCity,这里我们只需要传进来两个参数,一个是城市的名字,一个是我们搜索的关键词。在这里对返回的结果要做处理,因为对于一个城市,我们所搜索的内容对应的地方可能很多,所以这里要做分页处理。我们在处理分页的时候,关注几点内容,当前页、总页数、总记录数以及每一页所显示的条目。这些数据我们都可以从MKPoiResult这个类中获取到,然后获取当前页的所有兴趣点,就可以实现全城搜索的分页显示了。要注意的是要在显示下一页的时候,将当前页显示的overlay清空。我们还可以在调用这个类中的设置每页容量的方法。
效果十六:关于路线的搜索-驾车路线搜索
调用MKSearch里的drivingSearch方法,传进来起点和终点的城市名,搜索的起点位置和终点位置,还可以指定途径点。
这里要注意MKPlanNode内容的设置:可以使用经纬度和地名,需要输入准确的名称,可以通过setDrivingPolicy(int policy)  来设置驾车路线规划策略。
结果的处理在MKSearchListener的onGetDrivingRouteResult方法中。
效果十七:步行路线搜索调用MKSearch里的walkingSearch方法,传进来起点和终点的城市名,搜索的起点位置和终点位置,还可以指定途径点。
这里要注意MKPlanNode内容的设置:可以使用经纬度和地名,需要输入准确的名称,可以通过。结果的处理在MKSearchListener的onGetWalkingRouteResult方法中。
十八:公交换乘路线
调用MKSearch的transitSearch方法,传入城市名,搜索的起点和终点,通过setTransitPolicy设置路线规划策略
结果处理在MKSearchListener类的onGetTransitRouteResult方法中,MKPlanNode可以使用name进行搜索.
在搜索时还要进行新的地图中心点的设置,使用MapController里的setCenter方法,还要使用MapController里的enableClick方法是我们点击的时候提示我们换乘信息。这样就实现了公交换乘路线的搜索。
效果十九:定位
定位到自己的位置,对于这个功能,百度地图的API中有告诉我们怎么去写定位的Demo,里面说的第一步是导入库文件,也就是把sdkjar包拷贝到我们工程的libs里,为了避免各个应用公用一个service出现的权限问题,我们还要在应用的配置文件中配置自己单独拥有的service。添加一些必要的权限。这里需要访问服务器,使用到的类是LocationClient,
有一个负责显示用户当前位置的Overlay,即MyLocationOverlay,MyLocationOverlay只负责显示我的位置,位置数据请使用百度定位SDK获取,将获取的位置数据放在一个LocationData结构中并用该结构设置MyLcationOverlay的数据源,即可创建MyLocationOverlay。
然后就是LocationData数据获取,
先要创建监听器,当获取到位置信息时,将信息添加到LocationData中,监听器需要实现BDLocationListener接口,在这里有两个方法需要实现:
1.接收异步返回的定位结果,参数是BDLocation类型参数。
2.接收异步返回的POI查询结果,参数是BDLocation类型参数。
然后是监听的设置:
先创建LocationClient对象,并注册监听registerLocationListener
设置定位参数(LocationClientOption):定位模式(单次定位,定时定位),返回坐标类型,是否打开GPS等等。
通过LocationClient的start、stop控制定位信息获取,在做中间可以手动发起定位的请求requestLocation。
在百度地图移动版API中,提供一个重要的特色功能:定位,通过这个功能,能获取到用户当前所在位置。
在程序中,如果使用此功能,必须注册GPS和网络的使用权限。
在获取用户位置时,优先使用GPS进行定位;如果GPS定位没有打开或者没有可用位置信息,则会通过判断网络是否连接(即确认手机是否能上网,不论是连接2G/3G或Wi-Fi网络),如果是,则通过请求百度网络定位服务,返回网络定位结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。
目前系统自带的网络定位服务精度低,且服务不稳定、精度低,并且从未来的趋势看,基站定位是不可控的(移动公司随时可能更改基站编号以垄断定位服务),而Wi-Fi定位则不然,它是一种精度更高、不受管制的定位方法。国内其它使用Wi-Fi定位的地图软件,Wi-Fi定位基本不可用,百度的定位服务量化指标优秀,网络接口返回速度快(服务端每次定位响应时间50毫秒以内),平均精度70米,其中Wi-Fi精度40米左右,基站定位精度200米左右,覆盖率98%,在国内处于一枝独秀的地位。
火星坐标系统:
关于火星坐标系统,我们平时用到的地球坐标系统,叫做WGS84(World Geodetic System 1984)坐标,国家保密插件,也叫做加密插件或者加偏或者SM模组,其实就是对真实坐标系统进行人为的加偏处理,按照几行代码的算法,将真实的坐标加密成虚假的坐标,而这个加偏并不是线性的加偏,所以各地的偏移情况都会有所不同。而加密后的坐标也常被人称为火星坐标系统,这是我们的国家又一个伟大的发明,让国外的政府和企业等,都看不懂我们的坐标系统。
现在,所有的电子地图所有的导航设备,都需要加入国家保密插件。第一步,地图公司测绘地图,测绘完成后,送到国家测绘局,将真实坐标的电子地图,加密成“火星坐标”,这样的地图才是可以出版和发布的,然后才可以让GPS公司处理。第二步,所有的GPS公司,只要需要汽车导航的,需要用到导航电子地图的,统统需要在软件中加入国家保密算法,将COM口读出来的真实的坐标信号,加密转换成国家要求的保密的坐标,这样,GPS导航仪和导航电子地图就可以完全匹配啦,GPS也就可以正常工作啦。
我们需要知道真实经纬度坐标转换的算法:
我用到了两个文件:axisoffset.dat和ModifyOffset.java,第一个表示真实坐标与火星坐标的映射关系,第二个修订偏移的java文件,是把标准坐标转换成火星坐标。
在我们自己的代码中声明ModifyOffset对象,也就是得到位置转化工具类的实例,然后调用这个类中的s2c方法,这个方法是将真实坐标转化成火星坐标,传进真实的经纬度就实现了转换。





17 个回复

正序浏览

回帖奖励 +1 黑马币

多谢分享
回复 使用道具 举报

回帖奖励 +1 黑马币

多谢分享
回复 使用道具 举报
cheat 中级黑马 2017-7-10 22:53:19
15#

回帖奖励 +1 黑马币

支持一个啊,都是好资料。
回复 使用道具 举报

回帖奖励 +1 黑马币

面试的时候用的上吧应该
回复 使用道具 举报

回帖奖励 +1 黑马币

可以的 很强势
回复 使用道具 举报
dhj 中级黑马 2017-6-12 17:33:59
12#
感谢分享~~~~~
回复 使用道具 举报
dhj 中级黑马 2017-6-9 11:38:01
11#

回帖奖励 +1 黑马币

快到碗里来,黑马币!!!
回复 使用道具 举报

回帖奖励 +1 黑马币

谢谢分享
回复 使用道具 举报
hrywxn 中级黑马 2017-5-22 22:35:39
9#

回帖奖励 +1 黑马币

谢谢分享!
回复 使用道具 举报

回帖奖励 +1 黑马币

谢谢分享
回复 使用道具 举报

回帖奖励 +1 黑马币

谢谢分享!
回复 使用道具 举报

回帖奖励 +1 黑马币

好东西!谢谢分享!谢谢!!!
回复 使用道具 举报

回帖奖励 +1 黑马币

谢谢分享 赞赞赞!!!!!
回复 使用道具 举报

回帖奖励 +1 黑马币

特别的全面 马
回复 使用道具 举报

回帖奖励 +1 黑马币

不错,很全面
回复 使用道具 举报

回帖奖励 +1 黑马币

谢谢分享
回复 使用道具 举报

回帖奖励 +1 黑马币

好深奥呀!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马