高德地圖 聚合

項目里 剛好用到了 高德聚合 開始找了個官方的demo 發(fā)現(xiàn) android 和ios的效果 差很多 ,但還是要做成一致的 。。oedoukei 當(dāng)然 這難不倒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; //當(dāng)前點擊的marker

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

    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;
    }

    /**
     * 設(shè)置所有的點
     * @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);
    }

    /**
     * 顯示所有的點
     */
    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;

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

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

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

            }
        }
    }

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

            //如果距離在規(guī)定點范圍內(nèi),則說明有聚合點
            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"));                          //設(shè)置畫筆顏色
        paint.setStyle(Paint.Style.STROKE);                       //設(shè)置畫筆為空心
        paint.setStrokeWidth( DensityUtils.dp2px(context, 4));             //設(shè)置線寬
        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 不再可是范圍內(nèi)
        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);

    }

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

    /**
     * 動態(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); //計算子項View 的寬高 //統(tǒ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);
    }

    /**
     *
     * 聚合點
     */
    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;
    }
}
  • 初始化調(diào)用
 aggregationutils=new AggregationUtils();
            aggregationutils.setaMap(aMap);
            aggregationutils.setContext(getActivity());
  • set數(shù)據(jù)點
aggregationutils.setAllPoints(allPoints);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容