美文网首页
百度地图 SDK(2)----显示地图,标注位置

百度地图 SDK(2)----显示地图,标注位置

作者: 做梦枯岛醒 | 来源:发表于2017-07-31 17:34 被阅读568次

    上一篇文章我们初次认识了百度地图,并且使用它写了获取地理位置的Demo,

    这一篇文章,我们来实现地图的显示。
    地图,是一个view,它只是一个界面,而真正的位置,是通过叠加图层来显示的,而这个图层的位置是通过我们位置监听器的经纬度来确定的

    显示地图

    修改上一篇文章的布局文件

    [activity_main.xml]
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        tools:context="com.surine.onemap.MainActivity"
        tools:showIn="@layout/app_bar_main">
    
        <TextView
            android:id="@+id/first"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:text="Hello World!"
            />
    
        <com.baidu.mapapi.map.MapView
            android:id="@+id/map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"
            />
    </LinearLayout>
    

    增加了百度地图的一个view,

    然后我们在java里添加代码

    //首先我们的initmap肯定是在onCreate里调用,findview
     private void initMap() {
            //sdk的初始化
            SDKInitializer.initialize(getApplicationContext());
            mmap = (MapView) findViewById(R.id.map);
        }
    
    //然后这个管理地图的生命周期
    //onResume状态   
     @Override
        protected void onResume() {
            super.onResume();
            mmap.onResume();
        }
    
    //pause状态
        @Override
        protected void onPause() {
            super.onPause();
            mmap.onPause();
        }
    

    大概这个样子,我们可以运行了。
    一番编译之后,终于start activity……
    然后,结果是一个fc。

    好吧,保持冷静。fc我见多了,冷静解决好了。
    我们先看一下日志

    log.PNG

    这里是一个反射错误,出现这种错误大概就几种情况,布局嵌套,没有找到view等,由于我也是第一次使用baidumap,我肯定不知道它里面的view使用规则,所以我就上网查了一下,大多数人说是初始化不对,也就是说初始化未完成,我们找不到view。

    那么我猜测这个初始化应该是建立在setContentView()之前的,我直接新建了自定义Application,在APP打开的时候就进行初始化。

    [MyApplication.java]
    
    
    public class MyApplication extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            // 在使用 SDK 各组间之前初始化 context 信息,传入 ApplicationContext
            SDKInitializer.initialize(this);
        }
    }
    

    那么相应的我们的清单文件内容需要修改,也就是给<Application>标签添加name

    android:name=".MyApplication"
    

    有网友说需要带上包名,经过测试不带也可以,如果你需要的话,可以在前面加上包名。

     android:name="com.xxx.xxx.MyApplication"
    

    这个样子之后我们可以删掉,我们刚才在MainActivity里的初始化代码。(不删也可以其实)

    最后我们来运行一下。


    Map

    可以看到我们已经得到了地图界面,并且可以滑动操作(注意联网……不联网说啥呢,哈哈)

    显示自己的位置

    可以看到当前我们的地图显示的北京市区,我们下面要实现将位置自动移到我当前的位置,我们先来看一下代码

    //首先我们创建一个BaiduMap对象,然后用他来获取map
    //注意这一行代码写的位置,应该是findview mapview之后,防止出现空指针
     baidumap = mmap.getMap();
    

    然后我们新建一个方法叫moveTo();

      private void moveTo(BDLocation bdLocation) {
            if(isFirstLocate){
              //传入经纬度
                LatLng ll = new LatLng(bdLocation.getLatitude(),bdLocation.getLongitude());
              //建立更新工厂           
     MapStatusUpdate update = MapStatusUpdateFactory.newLatLng(ll);
              //执行更新            
    baidumap.animateMapStatus(update);
            //建立缩放更新            
    update = MapStatusUpdateFactory.zoomTo(16f);
            //执行更新            
    baidumap.animateMapStatus(update);
                isFirstLocate = false;
            }
        }
    

    然后在什么时候调用这个方法?答案很显然,就是在我们上一篇文章写的监听器里,因为地理位置是从那里获取来的,我们传入bdlocation这个参数,可以用它来获取相关信息。

    那么我们现在梳理一下代码。
    首先我们获取了baidumap这么个对象,作用是什么呢?
    BaiduMap类是百度地图SDK里提供的一个类,通过getMap这个方法获取map实例,然后我们就可以对地图进行各种各样的操作了。
    可以看到我们的MoveTo代码,首先是一个if判断,根据我变量名的命名大家也可以知道,他就是判断有没有移动过,是不是第一次定位(当然默认值给true),如果是true就执行操作,否则结束。
    条件语句里面是一些对地图的操作,
    Latlng这个对象主要存放经纬度,接受两个参数,经纬度,接下来我们就创建一个update工厂管理,传入Latlng,最后让地图执行update,逻辑还是很清晰的,baidu地图 sdk封装的已经很简单了,同样zoomto是一个控制缩放级别的方法(范围为浮点3f-19f)
    更新结束之后我们就可以给 isfirstloca复制false,当然可能执行速度太快,我们根本看不到动画,这个时候,我们给第二次更新加个2s延时就可以,你看看你能不能实现呢?

    我们看一下结果


    位置

    一不小心暴露了自己的位置,这是第一次定位结果,具体操作中可以看到更新动画。

    地图标注

    我们经常看到地图定位标注,比如说小黄车ofo的小黄车都是通过标注显示到地图上的。

    标注这个功能叫做marker
    具体代码如下:

     private void moveTo(BDLocation bdLocation) {
    
            .... (省略的代码)
    
    //检查是否有过标注,如果有,清除
            if(marker!=null) {
                marker.remove();
            }
         //创建latlng对象管理位置
            LatLng latLng = baidumap.getMapStatus().target;
            //准备 marker 的图片
            BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_marka);
           //准备 marker option 添加 marker 使用
            markerOptions = new MarkerOptions().icon(bitmap).position(latLng);
            //获取添加的 marker 这样便于后续的操作
            marker = (Marker) baidumap.addOverlay(markerOptions);
    
            //对 marker 添加点击相应事件
            baidumap.setOnMarkerClickListener(new OnMarkerClickListener() {
    
                @Override
                public boolean onMarkerClick(Marker arg0) {
                    // TODO Auto-generated method stub
                    Toast.makeText(getApplicationContext(), "Marker被点击了!", Toast.LENGTH_SHORT).show();
                    return false;
                }
            });
        }
    

    很简单的代码,但是这里面有几个问题,第一个是这个标注不是定位,所以位置不会一成不变,可以随着移动而显示在不同位置,第二个是因为我们的位置是实时更新的,所以代码会调用很多次,标注也会打好多次,所以我们加了判断,在标注之前先去掉以前标注的。那么下面是演示结果。

    地图标注

    可以看到我们的标注已经显示在地图上了。
    这里还是给出zhh_happig文章里写的一些常用方法

    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里面的图片
    
    [作者:zhh_happig
    链接:http://www.jianshu.com/p/fdd1ba783495
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。]
    

    这个仅仅是简单的探索一下,更多的玩法在以后的文章可能会有

    定位图层

    定位图层指的是,我们在地图上点击定位按钮给我们显示的小圆点,具体的代码如下

       //在初始化方法里写开启
        private void initMap() {
            ···省略的代码
            // 开启定位图层
            baidumap.setMyLocationEnabled(true);
        }
    
    
     private void moveTo(BDLocation bdLocation) {
        if(····){
            ···省略的代码
    
          //创建LocationData对象
            MyLocationData locData = new MyLocationData.Builder()
             //设置精度半径,可以设置0,此时就不会显示外圈的圆   
                 .accuracy(bdLocation.getRadius())
                   //设置方向,不过一定要 设置option.setNeedDeviceDirect(true);
                  //通过这个方法获取的方式不是实时更新的,所以一般选择用手机
                //方向传感器来判断           
    .direction(bdLocation.getDirection()).latitude(bdLocation.getLatitude())
                    .longitude(bdLocation.getLongitude()).build();
        //设置显示
            baidumap.setMyLocationData(locData);
        }
    }
    

    把代码写在if判断里面更符合实际
    如果离开该活动记得取消定位图层释放资源(设置false)
    可以看到我们的定位图层还是在moveTo的代码里添加了一些东西,根据我们的经纬度,我们可以设置这个小圆点
    演示如图

    定位图层

    可以看到我们的定位图层是一个小蓝点。

    总结

    本篇文章主要实现了地图的显示,而不再是简单的数据,下一篇文章我们将继续探索百度地图的其他功能。

    参考

    《第一行代码 第二版》
    简书:zhh_happig
    百度地图开发文档

    相关文章

      网友评论

          本文标题:百度地图 SDK(2)----显示地图,标注位置

          本文链接:https://www.haomeiwen.com/subject/ysyrlxtx.html