高德地图 聚合

项目里 刚好用到了 高德聚合 开始找了个官方的demo 发现 android 和ios的效果 差很多 ,但还是要做成一致的 。。oedoukei 当然 这难不倒wuli 戴老师 ,几个小时 就帮我改编了一版。。。

这是最终的效果.jpg

高德聚合的demo地址:

(https://github.com/amap-demo/android-cluster-marker)

那下面 我就贴一个工具类 哦:




public class AggregationUtils implements AMap.OnCameraChangeListener,
        AMap.InfoWindowAdapter, AMap.OnMarkerClickListener,AMap.OnMapClickListener {

    private ArrayList<Cluster> mClusters = new ArrayList<>();   //聚合点

    private List<Marker> allMarker = new ArrayList<>(); //所有的marker

    private Marker clickMarker; //当前点击的marker

    private float zoom;   //当前放大缩小程度

    private int aggregationRadius=100;//聚合半径

    private double mClusterDistance;    //聚合范围

    private List<ClusterItem> allPoints = new ArrayList<ClusterItem>(); //所有的点

    private Context context;

    private AMap aMap;

    public void setContext(Context context) {
        this.context = context;
    }

    /**
     * 设置所有的点
     * @param allPoints
     */
    public void setAllPoints(List<ClusterItem> allPoints) {
        this.allPoints = allPoints;
    }

    /**
     * 设置map
     * @param aMap
     */
    public void setaMap(AMap aMap) {
        this.aMap = aMap;
        zoom = aMap.getCameraPosition().zoom;
        aMap.setInfoWindowAdapter(this);
        aMap.setOnCameraChangeListener(this);
        aMap.setOnMarkerClickListener(this);
        aMap.setOnMapClickListener(this);
    }

    /**
     * 显示所有的点
     */
    private void showPoint(){
        assignClusters();

        //画圆
        for (int i=0;i<mClusters.size();i++){
           Cluster cluster = mClusters.get(i);

            if(clickMarker!=null){
                if(clickMarker.getPosition().latitude==cluster.getCenterLatLng().latitude&&clickMarker.getPosition().longitude==cluster.getCenterLatLng().longitude){
                    allMarker.add(clickMarker);
                    continue;
                }
            }
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.anchor(0.5f, 0.5f).icon(getBitmapDes(cluster.mClusterItems.size())).position(cluster.mLatLng).title("...");

            Marker marker = aMap.addMarker(markerOptions);
            marker.setInfoWindowEnable(true);
            marker.setObject(cluster);
            allMarker.add(marker);
        }
    }

    /**
     * 对点进行聚合
     */
    private void assignClusters() {
        //算出聚合点
        mClusterDistance = aMap.getScalePerPixel()*aggregationRadius;

        //屏幕范围
        LatLngBounds visibleBounds = aMap.getProjection().getVisibleRegion().latLngBounds;

        //循环所有点
        for (int i=0;i<allPoints.size();i++) {
            LatLng latlng = allPoints.get(i).latLng;

            //判断当前点是否在可视范围内
            if (visibleBounds.contains(latlng)) {
                //获取聚合点
                Cluster cluster = getCluster(latlng,mClusters);

                //判断聚合点是否为空
                if (cluster != null) {
                    //不为空则直接加入到聚合点内
                    cluster.addClusterItem(latlng,allPoints.get(i).address,allPoints.get(i).id);
                } else {
                    //为空则创建聚合点
                    cluster = new Cluster(latlng);
                    mClusters.add(cluster);
                    cluster.addClusterItem(latlng,allPoints.get(i).address,allPoints.get(i).id);
                }

            }
        }
    }

    /**
     * 判断当前点附近是否有聚合点
     *
     * @param latLng
     * @return
     */
    private Cluster getCluster(LatLng latLng, List<Cluster> clusters) {
        //循环所有的聚合点
        for (Cluster cluster : clusters) {
            LatLng clusterCenterPoint = cluster.getCenterLatLng();
            //计算当前点和聚合点之间的距离
            double distance = AMapUtils.calculateLineDistance(latLng, clusterCenterPoint);

            //如果距离在规定点范围内,则说明有聚合点
            if (distance < mClusterDistance) {
                return cluster;
            }
        }
        return null;
    }

    /**
     * 获取每个聚合点的绘制样式
     */
    private BitmapDescriptor getBitmapDes(int num) {
        TextView textView = new TextView(context);
        textView.setText(String.valueOf(num));
        textView.setGravity(Gravity.CENTER);
        textView.setTextColor(Color.WHITE);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
        textView.setBackground(getDrawAble());

        return BitmapDescriptorFactory.fromView(textView);
    }


    private Drawable getDrawAble() {
        int radius = DensityUtils.dp2px(context, 50);
        Drawable bitmapDrawable = new BitmapDrawable(null, drawCircle(radius));
        return bitmapDrawable;
    }


    private Bitmap drawCircle(int radius) {
        Bitmap bitmap = Bitmap.createBitmap(radius * 2, radius * 2,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint1 = new Paint();

        paint1.setColor(Color.parseColor("#2dbdff"));
        paint1.setAlpha(160);
        canvas.drawCircle(radius,radius,radius-10,paint1);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setColor(Color.parseColor("#0386ba"));                          //设置画笔颜色
        paint.setStyle(Paint.Style.STROKE);                       //设置画笔为空心
        paint.setStrokeWidth( DensityUtils.dp2px(context, 4));             //设置线宽
        canvas.drawCircle(radius,radius,radius-10,paint);

        return bitmap;
    }

    /**
     * 点击地图
     * @param latLng
     */
    @Override
    public void onMapClick(LatLng latLng) {
        clickMarker.hideInfoWindow();
    }

    /**
     * 地图移动
     * @param cameraPosition
     */
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        if(zoom!=cameraPosition.zoom){
            clickMarker = null;
            zoom = cameraPosition.zoom;
        }
    }
    /**
     * 地图移动完成
     * @param cameraPosition
     */
    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        for (Marker marker:allMarker){
            if(clickMarker!=null&&clickMarker.getPosition().longitude==marker.getPosition().longitude&&clickMarker.getPosition().latitude==marker.getPosition().latitude){
                continue;
            }

            marker.hideInfoWindow();
            marker.remove();
        }

        allMarker = new ArrayList<Marker>();
        mClusters = new ArrayList<Cluster>();
        mClusterDistance = aMap.getScalePerPixel()*aggregationRadius;//聚合的范围半径
        showPoint();

        //如果点击的marker 不再可是范围内
        LatLngBounds visibleBounds = aMap.getProjection().getVisibleRegion().latLngBounds;
        if(!visibleBounds.contains(clickMarker.getPosition())){
            clickMarker.hideInfoWindow();
            clickMarker.remove();
            clickMarker=null;
        }
    }
    /**
     * marker 点击
     * @param
     */
    @Override
    public boolean onMarkerClick(Marker marker) {
        clickMarker = marker;
        marker.showInfoWindow();

        //返回:true 表示点击marker 后marker 不会移动到地图中心;返回false 表示点击marker 后marker 会自动移动到地图中心
        return true;
    }

    /**
     * 自定义弹框
     * @param marker
     * @return
     */
    @Override
    public View getInfoWindow(Marker marker) {
        View infoContent = LayoutInflater.from(context).inflate(R.layout.dialog_behavior, null);
        render(infoContent,marker);
        return infoContent;
    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }


    /**
     * 自定义infowinfow窗口
     * @param
     * @param view
     */
    public void render(View view,Marker marker) {
        final Cluster cluster = (Cluster)marker.getObject();

        ListView recyclerView = (ListView) view.findViewById(R.id.listView);
        recyclerView.setAdapter(new BaseAdapter() {
            @Override
            public int getCount() {
                return cluster.mClusterItems.size();
            }

            @Override
            public Object getItem(int position) {
                return null;
            }

            @Override
            public long getItemId(int position) {
                return 0;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View view = LayoutInflater.from(context).inflate(R.layout.item_behavior, parent,false);
                TextView tv = (TextView) view.findViewById(R.id.text_item);
                tv.setText(cluster.mClusterItems.get(position).address);
                return view;
            }
        });
        setListViewHeightBasedOnChildren(recyclerView);

    }

    /**
     * 切换页面的时候调用
     */
    public void resetData(){
        if(clickMarker!=null){
            clickMarker.hideInfoWindow();
        }
        allPoints.clear();
    }

    /**
     * 动态设置listview 的高度
     * @param listView
     */
    public void setListViewHeightBasedOnChildren(ListView listView) {

        //获取listview的适配器
        ListAdapter listAdapter = listView.getAdapter(); //item的高度

        if (listAdapter == null) {
            return;
        }
        int totalHeight = 0;

        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);

            listItem.measure(0, 0); //计算子项View 的宽高 //统计所有子项的总高度
            totalHeight += listItem.getMeasuredHeight()+listView.getDividerHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        int maxHeight=DensityUtils.dp2px(context,100);
        if(totalHeight>maxHeight){
            params.height=maxHeight;
        }else{
            params.height = totalHeight;
        }

        listView.setLayoutParams(params);
    }

    /**
     *
     * 聚合点
     */
    public class Cluster {
        //聚合点位置
        private LatLng mLatLng;

        //聚合点中列表
        private List<ClusterItem> mClusterItems = new ArrayList<ClusterItem>();

        Cluster( LatLng latLng) {
            mLatLng = latLng;
        }

        LatLng getCenterLatLng() {
            return mLatLng;
        }

        void addClusterItem(LatLng latLng ,String address,String id) {
            ClusterItem clusterItem=new ClusterItem();
            clusterItem.latLng=latLng;
            clusterItem.address=address;
            clusterItem.id=id;
            mClusterItems.add(clusterItem);
        }
    }

    static class ClusterItem{
        public LatLng latLng;
        public  String address;
        public String id;
    }
}
  • 初始化调用
 aggregationutils=new AggregationUtils();
            aggregationutils.setaMap(aMap);
            aggregationutils.setContext(getActivity());
  • set数据点
aggregationutils.setAllPoints(allPoints);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,651评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,468评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,931评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,218评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,234评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,198评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,084评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,926评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,341评论 1 311
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,563评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,731评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,430评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,036评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,676评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,829评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,743评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,629评论 2 354

推荐阅读更多精彩内容