高德地圖 聚合

項(xiàng)目里 剛好用到了 高德聚合 開(kāi)始找了個(gè)官方的demo 發(fā)現(xiàn) android 和ios的效果 差很多 绸罗,但還是要做成一致的 。珊蟀。oedoukei 當(dāng)然 這難不倒wuli 戴老師 ,幾個(gè)小時(shí) 就幫我改編了一版腻窒。磅崭。。

這是最終的效果.jpg

高德聚合的demo地址:

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

那下面 我就貼一個(gè)工具類(lèi) 哦:




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

    private ArrayList<Cluster> mClusters = new ArrayList<>();   //聚合點(diǎn)

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

    private Marker clickMarker; //當(dāng)前點(diǎn)擊的marker

    private float zoom;   //當(dāng)前放大縮小程度

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

    private double mClusterDistance;    //聚合范圍

    private List<ClusterItem> allPoints = new ArrayList<ClusterItem>(); //所有的點(diǎn)

    private Context context;

    private AMap aMap;

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

    /**
     * 設(shè)置所有的點(diǎn)
     * @param allPoints
     */
    public void setAllPoints(List<ClusterItem> allPoints) {
        this.allPoints = allPoints;
    }

    /**
     * 設(shè)置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);
    }

    /**
     * 顯示所有的點(diǎn)
     */
    private void showPoint(){
        assignClusters();

        //畫(huà)圓
        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);
        }
    }

    /**
     * 對(duì)點(diǎn)進(jìn)行聚合
     */
    private void assignClusters() {
        //算出聚合點(diǎn)
        mClusterDistance = aMap.getScalePerPixel()*aggregationRadius;

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

        //循環(huán)所有點(diǎn)
        for (int i=0;i<allPoints.size();i++) {
            LatLng latlng = allPoints.get(i).latLng;

            //判斷當(dāng)前點(diǎn)是否在可視范圍內(nèi)
            if (visibleBounds.contains(latlng)) {
                //獲取聚合點(diǎn)
                Cluster cluster = getCluster(latlng,mClusters);

                //判斷聚合點(diǎn)是否為空
                if (cluster != null) {
                    //不為空則直接加入到聚合點(diǎn)內(nèi)
                    cluster.addClusterItem(latlng,allPoints.get(i).address,allPoints.get(i).id);
                } else {
                    //為空則創(chuàng)建聚合點(diǎn)
                    cluster = new Cluster(latlng);
                    mClusters.add(cluster);
                    cluster.addClusterItem(latlng,allPoints.get(i).address,allPoints.get(i).id);
                }

            }
        }
    }

    /**
     * 判斷當(dāng)前點(diǎn)附近是否有聚合點(diǎn)
     *
     * @param latLng
     * @return
     */
    private Cluster getCluster(LatLng latLng, List<Cluster> clusters) {
        //循環(huán)所有的聚合點(diǎn)
        for (Cluster cluster : clusters) {
            LatLng clusterCenterPoint = cluster.getCenterLatLng();
            //計(jì)算當(dāng)前點(diǎn)和聚合點(diǎn)之間的距離
            double distance = AMapUtils.calculateLineDistance(latLng, clusterCenterPoint);

            //如果距離在規(guī)定點(diǎn)范圍內(nèi)愉适,則說(shuō)明有聚合點(diǎn)
            if (distance < mClusterDistance) {
                return cluster;
            }
        }
        return null;
    }

    /**
     * 獲取每個(gè)聚合點(diǎn)的繪制樣式
     */
    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"));                          //設(shè)置畫(huà)筆顏色
        paint.setStyle(Paint.Style.STROKE);                       //設(shè)置畫(huà)筆為空心
        paint.setStrokeWidth( DensityUtils.dp2px(context, 4));             //設(shè)置線(xiàn)寬
        canvas.drawCircle(radius,radius,radius-10,paint);

        return bitmap;
    }

    /**
     * 點(diǎn)擊地圖
     * @param latLng
     */
    @Override
    public void onMapClick(LatLng latLng) {
        clickMarker.hideInfoWindow();
    }

    /**
     * 地圖移動(dòng)
     * @param cameraPosition
     */
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {
        if(zoom!=cameraPosition.zoom){
            clickMarker = null;
            zoom = cameraPosition.zoom;
        }
    }
    /**
     * 地圖移動(dòng)完成
     * @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();

        //如果點(diǎn)擊的marker 不再可是范圍內(nèi)
        LatLngBounds visibleBounds = aMap.getProjection().getVisibleRegion().latLngBounds;
        if(!visibleBounds.contains(clickMarker.getPosition())){
            clickMarker.hideInfoWindow();
            clickMarker.remove();
            clickMarker=null;
        }
    }
    /**
     * marker 點(diǎn)擊
     * @param
     */
    @Override
    public boolean onMarkerClick(Marker marker) {
        clickMarker = marker;
        marker.showInfoWindow();

        //返回:true 表示點(diǎn)擊marker 后marker 不會(huì)移動(dòng)到地圖中心;返回false 表示點(diǎn)擊marker 后marker 會(huì)自動(dòng)移動(dòng)到地圖中心
        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);

    }

    /**
     * 切換頁(yè)面的時(shí)候調(diào)用
     */
    public void resetData(){
        if(clickMarker!=null){
            clickMarker.hideInfoWindow();
        }
        allPoints.clear();
    }

    /**
     * 動(dòng)態(tài)設(shè)置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); //計(jì)算子項(xiàng)View 的寬高 //統(tǒng)計(jì)所有子項(xiàng)的總高度
            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);
    }

    /**
     *
     * 聚合點(diǎn)
     */
    public class Cluster {
        //聚合點(diǎn)位置
        private LatLng mLatLng;

        //聚合點(diǎn)中列表
        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;
    }
}
  • 初始化調(diào)用
 aggregationutils=new AggregationUtils();
            aggregationutils.setaMap(aMap);
            aggregationutils.setContext(getActivity());
  • set數(shù)據(jù)點(diǎn)
aggregationutils.setAllPoints(allPoints);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疆股,一起剝皮案震驚了整個(gè)濱河市旬痹,隨后出現(xiàn)的幾起案子讨越,更是在濱河造成了極大的恐慌,老刑警劉巖把跨,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件着逐,死亡現(xiàn)場(chǎng)離奇詭異意蛀,居然都是意外死亡健芭,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)若贮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)谴麦,“玉大人伸头,你說(shuō)我怎么就攤上這事⌒芏В” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵精绎,是天一觀的道長(zhǎng)锌妻。 經(jīng)常有香客問(wèn)我,道長(zhǎng)仿粹,這世上最難降的妖魔是什么吭历? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮摩骨,結(jié)果婚禮上朗若,老公的妹妹穿的比我還像新娘。我一直安慰自己灾馒,他們只是感情好遣总,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布轨功。 她就那樣靜靜地躺著傅物,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蒿褂。 梳的紋絲不亂的頭發(fā)上卒暂,一...
    開(kāi)封第一講書(shū)人閱讀 51,208評(píng)論 1 299
  • 那天也祠,我揣著相機(jī)與錄音,去河邊找鬼诈嘿。 笑死,一個(gè)胖子當(dāng)著我的面吹牛淳梦,可吹牛的內(nèi)容都是我干的昔字。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼陨囊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼蜘醋!你這毒婦竟也來(lái)了咏尝?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎伺糠,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體累驮,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谤专,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了映之。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜡坊。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蠢甲,靈堂內(nèi)的尸體忽然破棺而出据忘,到底是詐尸還是另有隱情,我是刑警寧澤曼追,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布萧福,位于F島的核電站,受9級(jí)特大地震影響膏燕,放射性物質(zhì)發(fā)生泄漏悟民。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一近忙、第九天 我趴在偏房一處隱蔽的房頂上張望智润。 院中可真熱鬧,春花似錦锯玛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至病曾,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間捷兰,已是汗流浹背负敏。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留顶考,地道東北人妖泄。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓蹈胡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親罚渐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容