android开发百度地图点聚合功能

版权声明:本文为博主原创文章,未经博主允许不得转载! https://blog.csdn.net/bojinyanfeng/article/details/82801437

android开发百度地图点聚合功能

第一次写博客。。。也不知道怎么写呢。就按照我实现功能的步骤来写吧!

首先,我们得去准备一些东西。

  1. 百度地图demo ,地址:http://lbsyun.baidu.com/index.php?title=sdk/download&action#selected=mapsdk_basicmap,mapsdk_searchfunction,mapsdk_lbscloudsearch,mapsdk_calculationtool,mapsdk_radar;
  2. 申请百度地图key ,可以根据教程来申请:http://lbsyun.baidu.com/index.php?title=android-locsdk/guide/key;
  3. 一个android项目 ,这我就不多说;

步骤(这是我的步骤)

打开下载demo地址,选择要下载的功能资源,然后点击下载实例代码。具体如下图:
在这里插入图片描述

下载下来的压缩包里,解压如下图的压缩包:
在这里插入图片描述

百度的点聚合是对外开放源码的。我们需要在百度提供的demo中把clusterutil整个目录拷贝到自己的工程里面。
具体的路径在:你的解压路径\BaiduMap_AndroidSDK_v5.2.0_Sample\BaiduMapsApiDemo\src\com\baidu\mapapi\clusterutil
除了clusterutil包里的代码外,还需要以下东西:
layout文件夹的text_bubble.xml
styles.xml文件中的相关部分

参考百度地图demo点聚合功能代码

代码在:你的解压路径\BaiduMap_AndroidSDK_v5.2.0_Sample\BaiduMapsApiDemo\src\baidumapsdk\demo\map\MarkerClusterDemo.java

其中,我们用到的


 	private ClusterManager<MyItem> mClusterManager;
	// 定义点聚合管理类ClusterManager
        mClusterManager = new ClusterManager<MyItem>(this, mBaiduMap);
        // 添加Marker点,这里就使用自己添加点的方法了
        //addMarkers();
        // 设置地图监听,当地图状态发生改变时,进行点聚合运算
        mBaiduMap.setOnMapStatusChangeListener(mClusterManager);
        // 设置maker点击时的响应
        mBaiduMap.setOnMarkerClickListener(mClusterManager);

        mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MyItem>() {
            @Override
            public boolean onClusterClick(Cluster<MyItem> cluster) {
                Toast.makeText(MarkerClusterDemo.this,
                        "有" + cluster.getSize() + "个点", Toast.LENGTH_SHORT).show();

                return false;
            }
        });
        mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {
            @Override
            public boolean onClusterItemClick(MyItem item) {
                Toast.makeText(MarkerClusterDemo.this,
                        "点击单个Item", Toast.LENGTH_SHORT).show();

                return false;
            }
        });
     /**
     * 每个Marker点,包含Marker点坐标以及图标
     */
    public class MyItem implements ClusterItem {
        private final LatLng mPosition;

        public MyItem(LatLng latLng) {
            mPosition = latLng;
        }

        @Override
        public LatLng getPosition() {
            return mPosition;
        }

        @Override
        public BitmapDescriptor getBitmapDescriptor() {
            return BitmapDescriptorFactory
                    .fromResource(R.drawable.icon_gcoding);
        }
    }

按照demo的方法基本上是可以完成点聚合的功能的。但是,现在项目要求点击Marker点时需要弹出气泡信息,也就是说需要传递参数进Marker点里。所以MyItem 方法需要加入额外信息Bundle。参考https://blog.csdn.net/fangjingjingll/article/details/51984257

1、修改MyItem ,加入额外信息Bundle

// An highlighted block
/**
     * 每个Marker点,包含Marker点坐标、图标以及额外信息
     */
    public class MyItem implements ClusterItem {
        private final LatLng mPosition;//点
        private Bundle buns;//额外信息
        public MyItem(LatLng latLng) {
            mPosition = latLng;
        }
        public MyItem(LatLng latLng,Bundle bun) {
            mPosition = latLng;
            buns=bun;
        }
        @Override
        public LatLng getPosition() {
            return mPosition;
        }
        @Override
        public Bundle getExtraInfo() {
            return buns;
        }
        @Override
        public BitmapDescriptor getBitmapDescriptor() {//点图标
            return BitmapDescriptorFactory.fromResource(R.drawable.ic_red_maps_equ);
        }
    }

2、ClusterItem 接口添加新的抽象方法
(package com.baidu.mapapi.clusterutil.clustering)

	public interface ClusterItem {

	    /**
	     * The position of this marker. This must always return the same value.
	     */
	    LatLng getPosition();
	
	    BitmapDescriptor getBitmapDescriptor();
	
	    Bundle getExtraInfo();//新添加的额外信息
	}

3、DefaultClusterRenderer类添加额外信息
(package com.baidu.mapapi.clusterutil.clustering.view)

     /**
     * Creates markerWithPosition(s) for a particular cluster, animating it if necessary.
     */
    private class CreateMarkerTask {
        private final Cluster<T> cluster;
        private final Set<MarkerWithPosition> newMarkers;
        private final LatLng animateFrom;

        /**
         * @param c            the cluster to render.
         * @param markersAdded a collection of markers to append any created markers.
         * @param animateFrom  the location to animate the markerWithPosition from, or null if no
         *                     animation is required.
         */
        public CreateMarkerTask(Cluster<T> c, Set<MarkerWithPosition> markersAdded, LatLng animateFrom) {
            this.cluster = c;
            this.newMarkers = markersAdded;
            this.animateFrom = animateFrom;
        }

        private void perform(MarkerModifier markerModifier) {
            // Don't show small clusters. Render the markers inside, instead.
            if (!shouldRenderAsCluster(cluster)) {
                for (T item : cluster.getItems()) {
                    Marker marker = mMarkerCache.get(item);
                    MarkerWithPosition markerWithPosition;
                    if (marker == null) {
                        MarkerOptions markerOptions = new MarkerOptions();
                        if (animateFrom != null) {
                            markerOptions.position(animateFrom);
                            markerOptions.icon(item.getBitmapDescriptor());
                            //添加额外信息
                            markerOptions.extraInfo(item.getExtraInfo());
                        } else {
                            markerOptions.position(item.getPosition());
                            markerOptions.icon(item.getBitmapDescriptor());
                             //添加额外信息
                            markerOptions.extraInfo(item.getExtraInfo());
                        }
                        onBeforeClusterItemRendered(item, markerOptions);
                        marker = mClusterManager.getMarkerCollection().addMarker(markerOptions);
                        markerWithPosition = new MarkerWithPosition(marker);
                        mMarkerCache.put(item, marker);
                        if (animateFrom != null) {
                            markerModifier.animate(markerWithPosition, animateFrom, item.getPosition());
                        }
                    } else {
                        markerWithPosition = new MarkerWithPosition(marker);
                    }
                    onClusterItemRendered(item, marker);
                    newMarkers.add(markerWithPosition);
                }
                return;
            }

            MarkerOptions markerOptions = new MarkerOptions()
                    .position(animateFrom == null ? cluster.getPosition() : animateFrom);

            onBeforeClusterRendered(cluster, markerOptions);

            Marker marker = mClusterManager.getClusterMarkerCollection().addMarker(markerOptions);
            mMarkerToCluster.put(marker, cluster);
            mClusterToMarker.put(cluster, marker);
            MarkerWithPosition markerWithPosition = new MarkerWithPosition(marker);
            if (animateFrom != null) {
                markerModifier.animate(markerWithPosition, animateFrom, cluster.getPosition());
            }
            onClusterRendered(cluster, marker);
            newMarkers.add(markerWithPosition);
        }
    }

4、添加点方法,从我的项目中提取的某部分

	List<MyItem> items = new ArrayList<MyItem>();
	for(int i=0;i<c;i++){
             JSONObject job = equList.getJSONObject(i);
              //获取经纬度添加地图标注
             String lo = job.has("longitude")?job.getString("longitude"):"";
             String la = job.has("latitude")?job.getString("latitude"):"";
              if(!TextUtils.isEmpty(lo)&&!TextUtils.isEmpty(la)){
                    LatLng point =  new LatLng(Double.valueOf(la), Double.valueOf(lo));
                    //添加额外信息
                    Bundle bundle = new Bundle();
                    bundle.putString("json",job.toString());
                    MyItem myItem = new MyItem(point,bundle);
                    items.add(myItem);
                      
              	}
     	 }
     	mClusterManager.addItems(items);//把点添加到聚合类里

5、点击聚合点和Marker 点方法,从我的项目中提取部分代码

	mClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MyItem>() {//点击聚合点触发
            @Override
            public boolean onClusterClick(Cluster<MyItem> cluster) {
                //Toast.makeText(getActivity(), "有" + cluster.getSize() + "个点", Toast.LENGTH_SHORT).show();
                List<MyItem> items = (List<MyItem>) cluster.getItems();
                LatLngBounds.Builder builder2 = new LatLngBounds.Builder();
                int i=0;
                for(MyItem myItem : items){
                    builder2 = builder2.include(myItem.getPosition());
                }
                LatLngBounds latlngBounds = builder2.build();
                MapStatusUpdate u = MapStatusUpdateFactory.newLatLngBounds(latlngBounds,mMapView.getWidth(),mMapView.getHeight());
                mBaidumap.animateMapStatus(u);
                return false;
            }
        });
        mClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MyItem>() {//点击单个Marker点触发
            @Override
            public boolean onClusterItemClick(MyItem item) {
                if(item!=null&&item.getExtraInfo().get("json")!=null){
                    String str = String.valueOf(item.getExtraInfo().get("json"));
                    //点击弹出气泡窗口,显示一些信息。点击窗口可以跳转到详情页面
                    try {
                        JSONObject job = new JSONObject(str);
                        View view = getLayoutInflater().inflate(R.layout.popu_marker, null);
                        TextView text_title = (TextView) view.findViewById(R.id.marker_title);
                        TextView text_text = (TextView) view.findViewById(R.id.marker_text);
                        TextView text_address = (TextView) view.findViewById(R.id.marker_address);
                        SpannableString titleText = new SpannableString("名称:"+(job.has("customerName")?job.getString("customerName"):"无"));
                        /*titleText.setSpan(new ForegroundColorSpan(R.color.generalColor), 0, titleText.length(), 0);*/
                        text_title.setText(titleText);
                        SpannableString texttext = new SpannableString("编号:"+(job.has("customerNum")?job.getString("customerNum"):"无"));
                        text_text.setText(texttext);
                        SpannableString address = new SpannableString("地址:"+(job.has("userAddr")?job.getString("userAddr"):"无"));
                        text_address.setText(address);
                        //点击进入详情页面
                        equipment = new Equipment();
                        ...
                        view.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                //使用json数据传递参数到详情页面。
                                Intent intent = new Intent(getActivity(),EquDetailsActivity.class);
                                Bundle bundle = new Bundle();
                                // Serializable传递对象
                                bundle.putSerializable("equipment", equipment);
                                intent.putExtras(bundle);
                                intent.putExtra("pageType","detail");//用于标别查看页面
                                startActivity(intent);
                            }
                        });
                        //定义用于显示该InfoWindow的坐标点
                        LatLng pt = new LatLng(job.getDouble("latitude"),job.getDouble("longitude"));
                        //创建InfoWindow , 传入 view, 地理坐标, y 轴偏移量
                        InfoWindow mInfoWindow = new InfoWindow(view, pt, -47);
                        //显示InfoWindow
                        mBaidumap.showInfoWindow(mInfoWindow);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
                return false;
            }
        });

6、修改聚合数
(通过修改DefaultClusterRenderer类里面的MIN_CLUSTER_SIZE参数来设置当几个点叠在一起时,要进行聚合,默认是4)

        //原demo中,要至少5个点才能聚合,而实际使用时,我可不能这样来实现,只要有两个点靠近了,也是要聚合的。
	private static final int MIN_CLUSTER_SIZE = 1;

最后贴一个气泡布局popu_marker.xml,上述点击单个点时弹出的气泡信息布局。custom_info_bubble2为安卓.9图。气泡基本情况如下功能实现部分截图。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/custom_info_bubble2"
    android:orientation="vertical" >


    <TextView
        android:textColor="@color/generalColor"
        android:id="@+id/marker_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:textColor="@color/generalColor"
        android:id="@+id/marker_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:textColor="@color/generalColor"
        android:id="@+id/marker_address"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

功能实现部分截图
在这里插入图片描述
在这里插入图片描述

有什么不懂都可以去找“百度”老师来帮忙解决。

猜你喜欢

转载自blog.csdn.net/bojinyanfeng/article/details/82801437