Android 百度地图(二)——地图切换、定位、添加覆盖物、搜索位置、连线

来源:互联网 发布:网络正常守望先锋卡 编辑:程序博客网 时间:2024/06/08 10:45

  在 Android 百度地图(一)——简单使用 博客中简单介绍了它的使用,基本上都是按照百度API所给的介绍进行操作的,只是初步地让百度地图显示在应用中,并没有具体的使用或是操作它,我们平时所看到的地图都是可以定位、查询的,那么怎样实现地图的切换、定位、与连线呢?

一、地图切换  

  先来看下上次的代码,没错上次的代码就是跟百度API中写的一模一样,其实使用第三方的开源控件就是这样的,就是查看它的开发指南和Demo学习并使用。
上次代码

public class MainActivity extends Activity {      MapView mMapView = null;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);           //在使用SDK各组件之前初始化context信息,传入ApplicationContext          //注意该方法要再setContentView方法之前实现          SDKInitializer.initialize(getApplicationContext());          setContentView(R.layout.activity_main);          //获取地图控件引用          mMapView = (MapView) findViewById(R.id.bmapView);      }      @Override      protected void onDestroy() {          super.onDestroy();          //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理          mMapView.onDestroy();      }      @Override      protected void onResume() {          super.onResume();          //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理          mMapView.onResume();          }      @Override      protected void onPause() {          super.onPause();          //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理          mMapView.onPause();          }      }

  我们的地图有三种:普通地图、卫星地图、交通地图;现在为了实现地图的切换
  1、在菜单项中添加三个item。
这里写图片描述

<item        android:id="@+id/menu_normal"        android:orderInCategory="100"        android:showAsAction="never"        android:title="普通模式"/><item        android:id="@+id/menu_site"        android:orderInCategory="100"        android:showAsAction="never"        android:title="卫星图"/><item        android:id="@+id/menu_traffic"        android:orderInCategory="100"        android:showAsAction="never"        android:title="实时交通(off)"/>

2、在MainActivity中获得一个Baidumap,mBaiduMap = mapview.getMap();,通过Baidumap切换地图类型。

    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) {        case R.id.menu_normal:            //普通地图模式            mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);            break;        case R.id.menu_site:            //卫星地图模式            mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);            break;        case R.id.menu_traffic:        //实时交通            if (mBaiduMap.isTrafficEnabled()) {                mBaiduMap.setTrafficEnabled(false);                item.setTitle("实时交通(off)");            } else {                mBaiduMap.setTrafficEnabled(true);                item.setTitle("实时交通(on)");            }            break;        default:            break;        }        return super.onOptionsItemSelected(item);    }

卫星地图(第一张图)与交通地图(第二张图)
卫星地图
交通地图
备注:可以看出卫星地图与交通地图的不同,交通地图会有许多的绿色的交通线。

二、定位功能

  想要实现定位功能首先要去百度LBS的官网下载相关jar包和so文件,Java的jar包放置在libs文件夹下,另一个类.so库是c语言写的一些逻辑,不需要关注,调用的时候需要用到一种机制:JNI java native interface.这些库如果是ecplise 就直接拷贝到libs下面,Android studio的话就需要放置到jnilibs文件夹下面。jniLibs文件夹位置在src/main/jnilibs,参考开发指南配置权限,服务等等。 
  具体实现方面,百度地图定位功能的实现是通过一个LocationClient客户端 和BDLocationListener监听接口,由于定位是一个异步加载的过程,需要通过LocationClient对BDLocationListener进行注册与注销。

LocationClient locationclient=LocationClient(getApplicationContext());//这里有写一个class实现了BDLocationListener 接口 BDLocationListener myListener = new MyLocationListener();        // 注册要写在setContentView上面        locationclient.registerLocationListener(myListener);

接口的实现:

class MyLocationListener implements BDLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {//这里可以对location.getaddress.address进行打印,或者是其他操作              }    }

除了上面介绍的,定位方面还有许多的设置需要我们去实现。
下面代码拷贝的百度API Demo,具体可以参看开发指南。在oncreate方法中调用ini()方法即可。

    private void ini() {        //对locationclient进行必要的配置        LocationClientOption option = new LocationClientOption();// 可选,默认高精度,设置定位模式,高精度,低功耗,仅设备option.setLocationMode(LocationMode.Hight_Accuracy);// 可选,默认gcj02,设置返回的定位结果坐标系        option.setCoorType("bd09ll");        int span = 1000;        // 可选,默认0,即仅定位一次,        //设置发起定位请求的间隔需要大于等于1000ms才是有效的        option.setScanSpan(span);        // 可选,设置是否需要地址信息,默认不需要        option.setIsNeedAddress(true);        // 可选,默认false,设置是否使用gps        option.setOpenGps(true);        // 可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果        option.setLocationNotify(true);// 可选,默认false,设置是否需要位置语义化结果,可以在option.setIsNeedLocationDescribe(true);//BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”// 可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到   option.setIsNeedLocationPoiList(true);// 可选,默认false,定位SDK内部是一个SERVICE,//并放到了独立进程,设置是否在stop的时候杀死这个进程,默认杀死        option.setIgnoreKillProcess(false);    // 可选,默认false,设置是否收集CRASH信息,默认收集        option.SetIgnoreCacheException(false);    // 可选,默认false,设置是否需要过滤gps仿真结果,默认需要        option.setEnableSimulateGps(false);        //对locationclient设置        locationclient.setLocOption(option);        //开启locationclient定位        locationclient.start();    }

在实际开发中如果不是为汽车导航的那种软件不需要像上面那样设置那么多,设置的过多反而会很耗电,十分不合理。
补充:
定位的方式有三种:流量(根据三个基站,计算出你的中心位置,误差大,多的时候能达到4、5百米)+网络定位(wifi(本身不能实现定位功能,也是通过类似于基站的方式)与GPS定位(误差十米以内)

三、添加覆盖物

  在定位的基础上为了显示我们的定位位置,我们在MyLocationListeneronReceiveLocation方法中,为我们的当前位置添加覆盖物,使用BaiduMap的addOverlay和setMapStatus方法。

    class MyLocationListener implements BDLocationListener {        @Override        public void onReceiveLocation(BDLocation location) {        //判断使用的定位类型,不进行判断会定位错误            if (location.getLocType() == BDLocation.TypeGpsLocation                    || location.getLocType() == BDLocation.TypeNetWorkLocation) {            //LatLng是用于同时获得经纬度的                mlatlng = new LatLng(location.getLatitude(),location.getLongitude());    //为地图当前定位位置添加覆盖物,设置图片,设置经纬度                mBaiduMap.addOverlay(new MarkerOptions().position(mlatlng)                        .icon(BitmapDescriptorFactory                                .fromResource(R.drawable.ic_launcher)));                mBaiduMap.setMapStatus(MapStatusUpdateFactory                        .newLatLng(mlatlng));           //将当前位置添加到要链接的点集合中去        points.add(mlatlng);            }//停止定位,表示只定位一次            locationclient.stop();        }    }

看下效果
这里写图片描述

四、搜索位置

   关于搜索位置需要用到GeoCoder ,同样搜索是一个耗时的过程需要调用它的监听器,进行监听并进行相应。

    // 初始化搜索模块,注册事件监听     GeoCoder mSearch = GeoCoder.newInstance();        mSearch.setOnGetGeoCodeResultListener(this);

在Button按钮的点击事件里面开启搜索

mbtn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                mSearch.geocode(new GeoCodeOption().city("烟台").address(                        "莱州市平里店镇"));            }        });

监听结果

@Override    public void onGetGeoCodeResult(GeoCodeResult result) {        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {            Toast.makeText(MainActivity.this, "抱歉,未能找到结果", Toast.LENGTH_LONG)                    .show();            return;        }        // mBaiduMap.clear();        //如果找到了就添加覆盖物        mBaiduMap.addOverlay(new MarkerOptions().position(result.getLocation())                .icon(BitmapDescriptorFactory                        .fromResource(R.drawable.ic_launcher)));        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(result                .getLocation()));        String strInfo = String.format("纬度:%f 经度:%f",                result.getLocation().latitude, result.getLocation().longitude);        mlatlngnow = new LatLng(result.getLocation().latitude,                result.getLocation().longitude);            //添加经纬度,用于后面的连线        points.add(mlatlngnow);        mtextview.setText(strInfo);    }    @Override    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {        if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {            Toast.makeText(MainActivity.this, "抱歉,未能找到结果", Toast.LENGTH_LONG)                    .show();            return;        }        // mBaiduMap.clear();        mBaiduMap.addOverlay(new MarkerOptions().position(result.getLocation())                .icon(BitmapDescriptorFactory                        .fromResource(R.drawable.ic_launcher)));        mBaiduMap.setMapStatus(MapStatusUpdateFactory.newLatLng(result                .getLocation()));    }

备注:
onGetGeoCodeResult与onGetReverseGeoCodeResult的区别是前者是经纬度转换为位置,后者是位置转换为经纬度。

五、连线

  百度API Demo中为我们提供了多种方式绘制地图上的连线,让我们先来看下百度API是怎样实现划线的。
下面的绘制中我们只需要在oncreate方法中调用addCustomElementsDemo()方法就可以在地图上进行绘制了。

/**百度API代码     * 添加点、线、多边形、圆、文字     */    public void addCustomElementsDemo() {        // 添加折线        LatLng p1 = new LatLng(39.97923, 116.357428);        LatLng p2 = new LatLng(39.94923, 116.397428);        LatLng p3 = new LatLng(39.97923, 116.437428);        List<LatLng> points = new ArrayList<LatLng>();        points.add(p1);        points.add(p2);        points.add(p3);        OverlayOptions ooPolyline = new PolylineOptions().width(10)                .color(0xAAFF0000).points(points);        mBaiduMap.addOverlay(ooPolyline);        // 添加弧线        OverlayOptions ooArc = new ArcOptions().color(0xAA00FF00).width(4)                .points(p1, p2, p3);        mBaiduMap.addOverlay(ooArc);        // 添加圆        LatLng llCircle = new LatLng(39.90923, 116.447428);        OverlayOptions ooCircle = new CircleOptions().fillColor(0x000000FF)                .center(llCircle).stroke(new Stroke(5, 0xAA000000))                .radius(1400);        mBaiduMap.addOverlay(ooCircle);        LatLng llDot = new LatLng(39.98923, 116.397428);        OverlayOptions ooDot = new DotOptions().center(llDot).radius(6)                .color(0xFF0000FF);        mBaiduMap.addOverlay(ooDot);        // 添加多边形        LatLng pt1 = new LatLng(39.93923, 116.357428);        LatLng pt2 = new LatLng(39.91923, 116.327428);        LatLng pt3 = new LatLng(39.89923, 116.347428);        LatLng pt4 = new LatLng(39.89923, 116.367428);        LatLng pt5 = new LatLng(39.91923, 116.387428);        List<LatLng> pts = new ArrayList<LatLng>();        pts.add(pt1);        pts.add(pt2);        pts.add(pt3);        pts.add(pt4);        pts.add(pt5);        OverlayOptions ooPolygon = new PolygonOptions().points(pts)                .stroke(new Stroke(5, 0xAA00FF00)).fillColor(0xAAFFFF00);        mBaiduMap.addOverlay(ooPolygon);        // 添加文字        LatLng llText = new LatLng(39.86923, 116.397428);        OverlayOptions ooText = new TextOptions().bgColor(0xAAFFFF00)                .fontSize(24).fontColor(0xFFFF00FF).text("百度地图SDK").rotate(-30)                .position(llText);        mBaiduMap.addOverlay(ooText);    }

  这里我们可以通过上面定位确定的点与搜索的位置添加到points中,进行绘制连线。
  这里写图片描述
 

0 0
原创粉丝点击