Android中百度地图的使用(三)

前面两篇博客讲解了百度地图的使用、模式的切换以及定位,我们这篇博客来讲解一下百度地图覆盖物的添加。

地图 SDK 提供的点标记功能包含两大部分,一部分是点(俗称 Marker)、另一部分是浮于点上方的信息窗体(俗称 InfoWindow)。同时,SDK 对 Marker 和 InfoWindow 封装了大量的触发事件,例如点击事件、长按事件、拖拽事件。

效果图

要给地图添加覆盖物,首先需要覆盖物的经纬度,如果还要实现点击事件,显示详细的信息,还需要覆盖物的描述信息(如图片,位置名称等),所以先新建一个实体类,来存放这些信息。

实体类信息

public class Info implements Serializable {
    private double latitude;
    private double longtitude;
    private int imgId;
    private  String name;
    private String distance;
    private int zan;

    public  static List<Info> infos=new ArrayList<>();
    static
    {
        //添加几条markerinfo数据,用来显示marker
        infos.add(new Info(34.242652, 108.971171, R.drawable.a01, "英伦贵族小旅馆",
                "距离209米", 1456));
        infos.add(new Info(34.242952, 108.972171, R.drawable.a02, "沙井国际洗浴会所",
                "距离897米", 456));
        infos.add(new Info(34.242852, 108.973171, R.drawable.a03, "五环服装城",
                "距离249米", 1456));
        infos.add(new Info(34.242152, 108.971971, R.drawable.a04, "老米家泡馍小炒",
                "距离679米", 1456));
    }

    public Info(double latitude, double longtitude, int imgId, String name, String distance, int zan) {
        this.latitude = latitude;
        this.longtitude = longtitude;
        this.imgId = imgId;
        this.name = name;
        this.distance = distance;
        this.zan = zan;
    }

    public double getLatitude() {
        return latitude;
    }

    public void setLatitude(double latitude) {
        this.latitude = latitude;
    }

    public double getLongtitude() {
        return longtitude;
    }

    public void setLongtitude(double longtitude) {
        this.longtitude = longtitude;
    }

    public int getImgId() {
        return imgId;
    }

    public void setImgId(int imgId) {
        this.imgId = imgId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDistance() {
        return distance;
    }

    public void setDistance(String distance) {
        this.distance = distance;
    }

    public int getZan() {
        return zan;
    }

    public void setZan(int zan) {
        this.zan = zan;
    }
}

添加Marker

具体实现代码如下:

//定义Maker坐标点  
LatLng point = new LatLng(50.253647, 130.456321);  
//构建Marker图标  
BitmapDescriptor bitmap = BitmapDescriptorFactory  
    .fromResource(R.drawable.maker);  
//构建MarkerOption,用于在地图上添加Marker  
OverlayOptions option = new MarkerOptions()  
    .position(point)  
    .icon(bitmap);  
//在地图上添加Marker,并显示  
mBaiduMap.addOverlay(option);

添加文字和信息窗

文字(Text)和弹窗覆盖物(InfoWindow),在地图中也是一种覆盖物,可以使用showInfoWindow方法展示出来

具体代码实现方式如下:

 TextView tv = new TextView(mContext);
                tv.setBackgroundResource(R.drawable.location_tips);
                tv.setPadding(30, 20, 30, 50);
                tv.setText(info.getName());
                tv.setTextColor(Color.parseColor("#ffffff"));
                //定义用于显示该InfoWindow的坐标点
                final LatLng latLng = marker.getPosition();
                Point p = mBaiduMap.getProjection().toScreenLocation(latLng);
                p.y -= 47;
                LatLng ll = mBaiduMap.getProjection().fromScreenLocation(p);
                infoWindow = new InfoWindow(tv, ll, -47);
                mBaiduMap.showInfoWindow(infoWindow);

点击覆盖物显示详细信息

我们可以通过setOnMarkerClickListener点击事件获取到覆盖物的详细信息,具体实现代码如下:

 mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                Bundle extraInfo = marker.getExtraInfo();
                Info info = (Info) extraInfo.getSerializable("info");
                ImageView mIvPhoto= (ImageView) mMarkerLy.findViewById(R.id.iv_photo);
                TextView mTvName= (TextView)  mMarkerLy.findViewById(R.id.tv_name);
                TextView mTvDistance= (TextView)  mMarkerLy.findViewById(R.id.tv_distance);
                TextView mTvZan= (TextView) mMarkerLy. findViewById(R.id.tv_zan);
                mIvPhoto.setImageResource(info.getImgId());
                mTvName.setText(info.getName());
                mTvDistance.setText(info.getDistance());
                mTvZan.setText(info.getZan()+"");
                InfoWindow infoWindow;
                TextView tv = new TextView(mContext);
                tv.setBackgroundResource(R.drawable.location_tips);
                tv.setPadding(30, 20, 30, 50);
                tv.setText(info.getName());
                tv.setTextColor(Color.parseColor("#ffffff"));
                //定义用于显示该InfoWindow的坐标点
                final LatLng latLng = marker.getPosition();
                Point p = mBaiduMap.getProjection().toScreenLocation(latLng);
                p.y -= 47;
                LatLng ll = mBaiduMap.getProjection().fromScreenLocation(p);
                infoWindow = new InfoWindow(tv, ll, -47);
                mBaiduMap.showInfoWindow(infoWindow);
                mMarkerLy.setVisibility(View.VISIBLE);
                return true;
            }
        });

主界面代码

下面总结一下MainActivity代码,包含地图模式控制,地图定位,带方向的定位,显示覆盖物,显示覆盖物点击事件等,希望大家多多指正。


public class MainActivity extends AppCompatActivity {

    private MapView mMapView;
    private BaiduMap mBaiduMap;
    private MyLocationConfiguration.LocationMode mCurrentMode;
    public LocationClient mLocationClient = null;
    private MyLocationListener myListener ;
    public static final int Location_Permission = 0x01;
    boolean isFirstIn=true;
    private double mLatitude;
    private double mLongitude;
    private BitmapDescriptor mIcon;
    private Context mContext;
    private MyOrientationListener mMMyOrientationListener;
    private float mCurrentX;
    //覆盖物相关
    private BitmapDescriptor mMarkerBitmap;
    private RelativeLayout mMarkerLy;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        this.mContext=this;
        //声明LocationClient类
        mLocationClient = new LocationClient(getApplicationContext());
        myListener = new MyLocationListener();
        //注册监听函数
        mLocationClient.registerLocationListener(myListener);
        mMMyOrientationListener=new MyOrientationListener(mContext);
        initView();
        if (Build.VERSION.SDK_INT >= 23){
            requestLocalPermission();
        }else{
            initLocal();
        }
        initMarker();
        mBaiduMap.setOnMarkerClickListener(new BaiduMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                Bundle extraInfo = marker.getExtraInfo();
                Info info = (Info) extraInfo.getSerializable("info");
                ImageView mIvPhoto= (ImageView) mMarkerLy.findViewById(R.id.iv_photo);
                TextView mTvName= (TextView)  mMarkerLy.findViewById(R.id.tv_name);
                TextView mTvDistance= (TextView)  mMarkerLy.findViewById(R.id.tv_distance);
                TextView mTvZan= (TextView) mMarkerLy. findViewById(R.id.tv_zan);
                mIvPhoto.setImageResource(info.getImgId());
                mTvName.setText(info.getName());
                mTvDistance.setText(info.getDistance());
                mTvZan.setText(info.getZan()+"");
                InfoWindow infoWindow;
                TextView tv = new TextView(mContext);
                tv.setBackgroundResource(R.drawable.location_tips);
                tv.setPadding(30, 20, 30, 50);
                tv.setText(info.getName());
                tv.setTextColor(Color.parseColor("#ffffff"));
                //定义用于显示该InfoWindow的坐标点
                final LatLng latLng = marker.getPosition();
                Point p = mBaiduMap.getProjection().toScreenLocation(latLng);
                p.y -= 47;
                LatLng ll = mBaiduMap.getProjection().fromScreenLocation(p);
                infoWindow = new InfoWindow(tv, ll, -47);
                mBaiduMap.showInfoWindow(infoWindow);
                mMarkerLy.setVisibility(View.VISIBLE);
                return true;
            }
        });
        mBaiduMap.setOnMapClickListener(new BaiduMap.OnMapClickListener()
        {

            @Override
            public boolean onMapPoiClick(MapPoi arg0)
            {
                return false;
            }

            @Override
            public void onMapClick(LatLng arg0)
            {
                mMarkerLy.setVisibility(View.GONE);
                mBaiduMap.hideInfoWindow();
            }
        });
    }

    /**
     * 初始化覆盖物
     */
    private void initMarker() {
        mMarkerBitmap=BitmapDescriptorFactory.fromResource(R.drawable.maker);
        mMarkerLy = (RelativeLayout) findViewById(R.id.rl_marker);
    }

    /**
     * 定位到我的位置
     */
    private  void aboutLocal(){
        MapStatusUpdate mapLatlng = MapStatusUpdateFactory.
                newLatLng(new LatLng(mLatitude,mLongitude));
        mBaiduMap.animateMapStatus(mapLatlng);
    }
    /**
     * 初始化定位
     */
    private void initLocal() {
        LocationClientOption option = new LocationClientOption();
        //可选,设置定位模式,默认高精度
        //LocationMode.Hight_Accuracy:高精度;
        //LocationMode. Battery_Saving:低功耗;
        //LocationMode. Device_Sensors:仅使用设备;
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,设置返回经纬度坐标类型,默认gcj02
        //gcj02:国测局坐标;
        //bd09ll:百度经纬度坐标;
        //bd09:百度墨卡托坐标;
        //海外地区定位,无需设置坐标类型,统一返回wgs84类型坐标
        option.setCoorType("bd09ll");
        //可选,设置发起定位请求的间隔,int类型,单位ms
        //如果设置为0,则代表单次定位,即仅定位一次,默认为0
        //如果设置非0,需设置1000ms以上才有效
        option.setScanSpan(1000);
        //可选,设置是否使用gps,默认false
        //使用高精度和仅用设备两种定位模式的,参数必须设置为true
        option.setOpenGps(true);
        //可选,设置是否当GPS有效时按照1S/1次频率输出GPS结果,默认false
        option.setLocationNotify(true);
        //可选,定位SDK内部是一个service,并放到了独立进程。
        //设置是否在stop的时候杀死这个进程,默认(建议)不杀死,即setIgnoreKillProcess(true)
        option.setIgnoreKillProcess(false);
        //可选,设置是否收集Crash信息,默认收集,即参数为false
        option.SetIgnoreCacheException(false);
        //可选,7.2版本新增能力
        //如果设置了该接口,首次启动定位时,会先判断当前WiFi是否超出有效期,若超出有效期,会先重新扫描WiFi,然后定位
        option.setWifiCacheTimeOut(5*60*1000);
        //可选,设置是否需要过滤GPS仿真结果,默认需要,即参数为false
        option.setEnableSimulateGps(false);
        //mLocationClient为第二步初始化过的LocationClient对象
        //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
        //更多LocationClientOption的配置,请参照类参考中LocationClientOption类的详细说明
        option.setIsNeedAddress(true);
        //自定义图标
        mIcon=BitmapDescriptorFactory.fromResource(R.drawable.navi_map_gps_locked);
        mLocationClient.setLocOption(option);
        mMMyOrientationListener.setOnOrientationListener(new MyOrientationListener.OnOrientationListener() {
            @Override
            public void onOrientationChanged(float x) {
                mCurrentX=x;
            }
        });
//        mBaiduMap.setMyLocationEnabled(true);
//        if (!mLocationClient.isStarted()){
//            mLocationClient.start();
//        }
//        //开始方向传感器
//        mMMyOrientationListener.start();
    }

    private void initView() {
        mMapView = (MapView) findViewById(R.id.mv_map);
        mBaiduMap = mMapView.getMap();
        //放大地图的倍数
        MapStatusUpdate msu = MapStatusUpdateFactory.zoomTo(15.0f);
        mBaiduMap.setMapStatus(msu);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.id_map_common: //普通地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
                break;
            case R.id.id_map_site: //卫星地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);
                break;
            case R.id.id_map_none: //空白地图
                mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NONE);
                break;
            case R.id.id_map_traffic: //实时交通(off)
                if (mBaiduMap.isTrafficEnabled())
                {
                    mBaiduMap.setTrafficEnabled(false);
                    item.setTitle("实时交通(off)");
                } else
                {
                    mBaiduMap.setTrafficEnabled(true);
                    item.setTitle("实时交通(on)");
                }
                break;
            case R.id.id_map_location: //我的位置
                aboutLocal();
                break;
            case R.id.id_map_mode_common: //普通模式
                mCurrentMode = MyLocationConfiguration.LocationMode.NORMAL;   //默认为 LocationMode.NORMAL 普通态
                break;
            case R.id.id_map_mode_following: //跟随模式
                mCurrentMode = MyLocationConfiguration.LocationMode.FOLLOWING;//定位跟随态
                break;
            case R.id.id_map_mode_compass: //罗盘模式
                mCurrentMode = MyLocationConfiguration.LocationMode.COMPASS;  //定位罗盘态
                break;
            case R.id.id_add_overlay: //添加覆盖物
                addOverlays(Info.infos);
                break;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * 添加覆盖物
     * @param infos
     */
    private void addOverlays(List<Info> infos) {
        mBaiduMap.clear();
        LatLng latLng=null;
        Marker marker=null;
        OverlayOptions options;
        for (Info info:infos){
            //经纬度
            latLng=new LatLng(info.getLatitude(),info.getLongtitude());
            //图标
            options=new MarkerOptions().position(latLng).icon(mMarkerBitmap).zIndex(5);
            marker= (Marker) mBaiduMap.addOverlay(options);
            Bundle bundle=new Bundle();
            bundle.putSerializable("info",info);
            marker.setExtraInfo(bundle);
        }
        MapStatusUpdate msu=MapStatusUpdateFactory.newLatLng(latLng);
        mBaiduMap.animateMapStatus(msu);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mMapView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mMapView.onPause();
    }

    @Override
    protected void onStart() {
        super.onStart();
        mBaiduMap.setMyLocationEnabled(true);
        if (!mLocationClient.isStarted()){
            mLocationClient.start();
        }
        //开始方向传感器
        mMMyOrientationListener.start();

    }

    @Override
    protected void onStop() {
        super.onStop();
        mBaiduMap.setMyLocationEnabled(false);
        mLocationClient.stop();
        //停止方向传感器
        mMMyOrientationListener.stop();
    }

    class MyLocationListener extends BDAbstractLocationListener {

        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            //此处的BDLocation为定位结果信息类,通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关(常用)的结果信息
            //更多结果信息获取说明,请参照类参考中BDLocation类中的说明

            double latitude = bdLocation.getLatitude();    //获取纬度信息
            double longitude = bdLocation.getLongitude();    //获取经度信息
            float radius = bdLocation.getRadius();    //获取定位精度,默认值为0.0f
//            String coorType = bdLocation.getCoorType();
//            MapStatusUpdate mapUpdate = MapStatusUpdateFactory.zoomTo(radius);
//            mBaiduMap.setMapStatus(mapUpdate);

            MyLocationData data = new MyLocationData.Builder()//
                    .direction(mCurrentX)//
                    .accuracy(radius)//
                    .latitude(latitude)//
                    .longitude(longitude)//
                    .build();
            mBaiduMap.setMyLocationData(data);
            //设置自定义图标
            mBaiduMap.setMyLocationConfiguration(new MyLocationConfiguration(
                    mCurrentMode, true, mIcon));
            //更新经纬度
            mLatitude=   bdLocation.getLatitude();
            mLongitude=bdLocation.getLongitude();
            LatLng  point=  new LatLng(latitude,longitude);
            if (isFirstIn){
                //开始移动
                MapStatusUpdate mapLatlng = MapStatusUpdateFactory.
                        newLatLng(point);
                mBaiduMap.animateMapStatus(mapLatlng);
                Toast.makeText(mContext,bdLocation.getAddrStr(), Toast.LENGTH_SHORT).show();
                isFirstIn=false;
             }
//            //绘制图层
//            //定义Maker坐标点
//            LatLng point = new LatLng(latitude,longitude);
//            //构建Marker图标
//            BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(R.drawable.icon_gcoding);
//            //构建MarkerOption,用于在地图上添加Marker
//            OverlayOptions option = new MarkerOptions().position(point).icon(bitmap);
//            //在地图上添加Marker,并显示
//            mBaiduMap.addOverlay(option);
        }
    }
    private void requestLocalPermission() {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            //若权限没有开启,则请求权限
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, Location_Permission);
        }else{
           initLocal();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode==Location_Permission){
            if (grantResults[0]==PackageManager.PERMISSION_GRANTED){
                 initLocal();
            }else{
                Toast.makeText(this, "权限被拒绝", Toast.LENGTH_SHORT).show();

            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

到这里覆盖物的添加就已经讲解就基本完了,代码是根据鸿洋大神的视频修改的,有需要的话可以去我的资源里面进行下载。关于百度地图的基本使用到此就结束了,有说的不好的地方请大家多多指正。

Demo

https://download.csdn.net/download/wen_haha/10561227

猜你喜欢

转载自blog.csdn.net/wen_haha/article/details/81187280