Android 高德地图给指定坐标显示图片,以及聚合显示

原创 2017年09月21日 14:57:30

官网实例请点击:Android 高德地图聚合官网

下面是一个案例:
效果图:
这里写图片描述

MainActivity


public class MainActivity extends AppCompatActivity {


    public static final String TAG = MainActivity.class.getSimpleName();

    private MapView mapView;
    private AMap aMap;
    /**
     * 地图初始化比例尺,地图比例尺
     */
    public static float ORGZOON = 12;
    /**
     * 数据列表
     */
    private List<DotInfo> dotList = new ArrayList<>();
    /**
     * marker数据集合
     */
    public Map<String, Marker> markerMap = new ConcurrentHashMap<>();

    public static final int MARKER_NORMA = 1;
    public static final int MARKER_TOGE = 2;
    public static int markerStatus = MARKER_NORMA;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mapView = (MapView) findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);// 此方法必须重写
        init();
    }

    /**
     * 初始化AMap对象
     */
    private void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
            aMap.moveCamera(CameraUpdateFactory.zoomTo(ORGZOON));
        }

        aMap.setOnCameraChangeListener(onCameraChangeListener);
        dotList.clear();
        dotList = DotInfo.initData();
    }



    /**
     * 设置地图移动监听
     */
    private AMap.OnCameraChangeListener onCameraChangeListener = new AMap.OnCameraChangeListener() {
        @Override
        public void onCameraChange(CameraPosition cameraPosition) {
        }

        @Override
        public void onCameraChangeFinish(CameraPosition cameraPosition) {
            // 放大缩小完成后对聚合点进行重新计算
            updateMapMarkers();
        }
    };

    private synchronized void updateMapMarkers() {
        if (dotList != null && dotList.size() > 0) {
            Log.i(TAG, "地图级别:" + aMap.getCameraPosition().zoom);
            // 若当前地图级别小于初始化比例尺,则显示聚合网点
            if (aMap.getCameraPosition().zoom < 7) {
                markerStatus = MARKER_TOGE;
                updateTogMarkers();
            }
            // 显示普通marker
            else {
                if (markerStatus == MARKER_TOGE) {
                    markerStatus = MARKER_NORMA;
                    updateNormalMarkers();
                }
            }

            System.gc();
        }
    }


    /**
     * 更新普通网点数据
     */
    private void updateNormalMarkers() {
        // 判断上一次更新marker操作的操作类型,若上次显示的是聚合网点,则先清空地图,然后清空网点信息,在刷新地图marker
        aMap.clear();
        markerMap.clear();

        loadMarker(DotInfo.initData());
    }

    /**
     * 更新聚合网点
     */
    private void updateTogMarkers() {

        Log.i(TAG, "开始显示聚合网点,清空地图normal marker...");
        aMap.clear();
        // 更新聚合marker
        MapTogetherManager.getInstance(this, aMap).onMapLoadedUpdateMarker(markerMap);

        // 设置marker点击事件,若是聚合网点此时点击marker则放大地图显示正常网点
        aMap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                // 初始化地图按指定的比例尺移动到定位的坐标
                aMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(marker.getPosition(), ORGZOON, 3, 0)), 1000, null);
                return true;
            }
        });
    }


    private void updateGetMarkers() {
        Log.e(TAG, "");
        aMap.clear();
        MapTogetherManager.getInstance(this, aMap).onMapLoadedUpdateMarker(markerMap);


    }


    /**
     * 初始化marker数据
     */
    private void loadMarker(List<DotInfo> dotList) {
        if (dotList == null || dotList.size() == 0) {
            return;
        }

        for (int i = 0; i < dotList.size(); i++) {
            DotInfo dotInfo = dotList.get(i);

            MarkerOptions options = new MarkerOptions();
            options.anchor(0.5f, 1.0f);
            options.position(new LatLng(dotInfo.getDotLat(), dotInfo.getDotLon()));

            setIconToOptions(options);

            Marker marker = aMap.addMarker(options);
            marker.setObject(dotInfo);
            marker.setZIndex(ORGZOON);

            markerMap.put(dotInfo.getDotId(), marker);
        }
    }

    /**
     * 为marker的Options设置icon
     *
     * @param options
     */
    private void setIconToOptions(MarkerOptions options) {


        ImageView view = new ImageView(this);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(21, 27, 1);
        view.setImageResource(R.mipmap.blue_location);
        view.setLayoutParams(params);
        view.setScaleType(ImageView.ScaleType.FIT_XY);
        options.icon(BitmapDescriptorFactory.fromView(view));
    }





    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();

        updateNormalMarkers();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }


}

MapTogetherManager

public class MapTogetherManager {

    public static final String TAG = MapTogetherManager.class.getSimpleName();

    private int CLUSTER_SIZE = 100;// 地图上距离小于多少个像素点,则合并
    private int DRAWABLE_RADIUS = 80;// 聚合网点的显示大小,drawable的radius大小
    private static Map<String, TogDotInfo> togDotInfoMap;// 聚合网点列表
    private static Map<String, Marker> togMarkerMap;// 聚合网点marker
    private Activity mContext;
    private AMap aMap;


    public static MapTogetherManager instance = null;

    public static MapTogetherManager getInstance(Activity mContext, AMap aMap) {
        if (instance == null) {
            instance = new MapTogetherManager(mContext, aMap);
        }
        return instance;
    }

    private MapTogetherManager(Activity mContext, AMap aMap) {
        this.mContext = mContext;
        this.aMap = aMap;
        togDotInfoMap = new ConcurrentHashMap<String, TogDotInfo>();
        togMarkerMap = new ConcurrentHashMap<String, Marker>();
    }

    // ########### 设置当地图加载完成事件 start ######################

    Object lockObject = new Object();
    /**
     * 更新聚合网点
     */
    public void onMapLoadedUpdateMarker(final Map<String, Marker> markerMap) {
        // 清空内存聚合网点数据
        togDotInfoMap.clear();
        togMarkerMap.clear();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lockObject) {
                    Log.e(TAG, "开始循环遍历,执行网点聚合操作...");
                    Iterator<Map.Entry<String, Marker>> iterator = markerMap.entrySet().iterator();
                    // 循环遍历在已有的聚合基础上,对添加的单个元素进行聚合
                    while (iterator.hasNext()) {
                        assignSingleCluster(iterator.next().getValue());
                    }
                    Log.e(TAG, "开始执行将聚合网点展示在地图上...");
                    // 将聚合的网点现在在地图上
                    if (togDotInfoMap != null && togDotInfoMap.size() > 0) {
                        Iterator<Map.Entry<String, TogDotInfo>> cIterator = togDotInfoMap.entrySet().iterator();
                        while (cIterator.hasNext()) {
                            Map.Entry<String, TogDotInfo> togMap = cIterator.next();
                            addTogDotInfoToMap(togMap.getKey(), togMap.getValue());
                        }
                    }
                }
            }
        }).start();
    }

    /**
     * 在已有的聚合基础上,对添加的单个元素进行聚合
     */
    private void assignSingleCluster(Marker marker) {
        DotInfo dotInfo = (DotInfo) marker.getObject();
        LatLng latLng = new LatLng(dotInfo.getDotLat(), dotInfo.getDotLon());
        Point point = aMap.getProjection().toScreenLocation(latLng);
        TogDotInfo togDotInfo = getCluster(point);
        if (togDotInfo != null) {
            togDotInfo.addClusterItem(marker);
            // 更新聚合网点个数
            togDotInfo.setDotCount(togDotInfo.getDotCount() + 1);
        } else {
            togDotInfo = new TogDotInfo(point, latLng);
            // 更新聚合网点个数
            togDotInfo.setDotCount(1);
            togDotInfo.addClusterItem(marker);
            togDotInfoMap.put(dotInfo.getDotId() + SystemClock.currentThreadTimeMillis(), togDotInfo);
        }
    }


    /**
     * 将聚合网点添加至地图显示
     * @param togDotInfo 需要更新的聚合网点对象
     */
    private void addTogDotInfoToMap(String dotId, TogDotInfo togDotInfo) {
        LatLng latlng = togDotInfo.getCenterLatLng();
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.anchor(0.5f, 0.5f).icon(getBitmapDes(togDotInfo)).position(latlng);
        Marker marker = aMap.addMarker(markerOptions);
        togMarkerMap.put(dotId, marker);
    }


    /**
     * 获取每个聚合点的绘制样式
     **/
    private BitmapDescriptor getBitmapDes(final TogDotInfo togDotInfo) {
        TextView textView = new TextView(mContext);
        String tile = String.valueOf(togDotInfo.getDotCount());
        textView.setText(tile + "");
        textView.setGravity(Gravity.CENTER);

        textView.setTextColor(Color.BLACK);
        textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 15);
        textView.setBackgroundDrawable(getDrawAble(togDotInfo.getDotCount()));
        togDotInfo.setTextView(textView);
        return BitmapDescriptorFactory.fromView(textView);
    }

    /**
     * 根据一个点获取是否可以依附的聚合点,没有则返回null
     * @param point
     * @return
     */
    private TogDotInfo getCluster(Point point) {
        Iterator<Map.Entry<String, TogDotInfo>> cIterator = togDotInfoMap.entrySet().iterator();
        while (cIterator.hasNext()) {
            TogDotInfo togDotInfo = cIterator.next().getValue();
            Point poi = togDotInfo.getCenterPoint();
            double distance = getDistanceBetweenTwoPoints(point.x, point.y, poi.x, poi.y);
            if (distance < CLUSTER_SIZE) {
                return togDotInfo;
            }
        }

        return null;
    }

    /**
     * 计算地图上两个点之间的距离
     * @return
     */
    private double getDistanceBetweenTwoPoints(double x1, double y1, double x2,
                                               double y2) {
        double distance = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2)
                * (y1 - y2));
        return distance;
    }


    /**
     * 获取聚合网点显示的Drawable
     * @param clusterNum
     * @return
     */
    public Drawable getDrawAble(int clusterNum) {
        int radius = DisplayUtil.dip2px(mContext, DRAWABLE_RADIUS);
        // 根据不同的网点个数,显示不同的聚合网点drawable
        // if (clusterNum < 5) {
            BitmapDrawable drawable = new BitmapDrawable(drawCircle(radius,
                    Color.argb(159, 210, 154, 6)));
            return drawable;
        /*} else if (clusterNum < 10) {
            BitmapDrawable drawable = new BitmapDrawable(drawCircle(radius,
                    Color.argb(199, 217, 114, 0)));
            return drawable;
        } else {
            BitmapDrawable drawable = new BitmapDrawable(drawCircle(radius,
                    Color.argb(235, 215, 66, 2)));
            return drawable;
        }*/
    }

    /**
     * 获取聚合网点显示的圆框
     * @param radius
     * @param color
     * @return
     */
    private Bitmap drawCircle(int radius, int color) {
        Bitmap bitmap = Bitmap.createBitmap(radius * 2, radius * 2,
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        RectF rectF = new RectF(0, 0, radius * 2, radius * 2);
        paint.setColor(color);
        canvas.drawArc(rectF, 0, 360, true, paint);
        return bitmap;
    }
    // ########### 设置当地图加载完成事件 end ######################
}

TogDotInfo

**
 * 聚合网点信息列表用于保存聚合网点信息
 */
class TogDotInfo {
    private Point mPoint;// 中心网点
    private LatLng mLatLng;// 中心网点经纬度
    private List<Marker> mClusterItems;// 网点列表
    private int dotCount;// 网点个数
    private TextView textView;// 聚合网点显示


    TogDotInfo(Point point, LatLng latLng) {
        mPoint = point;
        mLatLng = latLng;
        mClusterItems = new ArrayList<>();
    }

    void addClusterItem(Marker clusterItem) {
        mClusterItems.add(clusterItem);
    }

    Point getCenterPoint() {
        return mPoint;
    }

    LatLng getCenterLatLng() {
        return mLatLng;
    }

    public int getDotCount() {
        return dotCount;
    }

    public void setDotCount(int dotCount) {
        this.dotCount = dotCount;
    }

    public List<Marker> getmClusterItems() {
        return mClusterItems;
    }

    public TextView getTextView() {
        return textView;
    }

    public void setTextView(TextView textView) {
        this.textView = textView;
    }
}

DotInfo


public class DotInfo {

    private String dotId;
    private double dotLat;
    private double dotLon;


    public String getDotId() {
        return dotId;
    }

    public void setDotId(String dotId) {
        this.dotId = dotId;
    }

    public double getDotLat() {
        return dotLat;
    }

    public void setDotLat(double dotLat) {
        this.dotLat = dotLat;
    }

    public double getDotLon() {
        return dotLon;
    }

    public void setDotLon(double dotLon) {
        this.dotLon = dotLon;
    }

    /**
     * 初始化数据
     * @return
     */
    public static List<DotInfo> initData() {
        List<DotInfo> dotInfoList = new ArrayList<>();

        DotInfo dotInfo1 = new DotInfo();
        dotInfo1.setDotLat(39.976318);
        dotInfo1.setDotLon(116.318988);
        dotInfo1.setDotId("dotInfo1");
        dotInfoList.add(dotInfo1);

        DotInfo dotInfo2 = new DotInfo();
        dotInfo2.setDotLat(40.045813);
        dotInfo2.setDotLon(116.304504);
        dotInfo2.setDotId("dotInfo2");
        dotInfoList.add(dotInfo2);

        DotInfo dotInfo3 = new DotInfo();
        dotInfo3.setDotLat(39.923347);
        dotInfo3.setDotLon(116.507537);
        dotInfo3.setDotId("dotInfo3");
        dotInfoList.add(dotInfo3);

        DotInfo dotInfo4 = new DotInfo();
        dotInfo4.setDotLat(39.91125);
        dotInfo4.setDotLon(116.477378);
        dotInfo4.setDotId("dotInfo4");
        dotInfoList.add(dotInfo4);

        DotInfo dotInfo5 = new DotInfo();
        dotInfo5.setDotLat(40.041337);
        dotInfo5.setDotLon(116.312181);
        dotInfo5.setDotId("dotInfo5");
        dotInfoList.add(dotInfo5);

        DotInfo dotInfo6 = new DotInfo();
        dotInfo6.setDotLat(39.971879);
        dotInfo6.setDotLon(116.306446);
        dotInfo6.setDotId("dotInfo6");
        dotInfoList.add(dotInfo6);

        DotInfo dotInfo7 = new DotInfo();
        dotInfo7.setDotLat(40.002434);
        dotInfo7.setDotLon(116.463232);
        dotInfo7.setDotId("dotInfo7");
        dotInfoList.add(dotInfo7);

        DotInfo dotInfo8 = new DotInfo();
        dotInfo8.setDotLat(39.980959);
        dotInfo8.setDotLon(116.331772);
        dotInfo8.setDotId("dotInfo8");
        dotInfoList.add(dotInfo8);

        DotInfo dotInfo9 = new DotInfo();
        dotInfo9.setDotLat(39.925659);
        dotInfo9.setDotLon(116.508567);
        dotInfo9.setDotId("dotInfo9");
        dotInfoList.add(dotInfo9);

        DotInfo dotInfo10 = new DotInfo();
        dotInfo10.setDotLat(39.88543);
        dotInfo10.setDotLon(116.461778);
        dotInfo10.setDotId("dotInfo10");
        dotInfoList.add(dotInfo10);

        DotInfo dotInfo11 = new DotInfo();
        dotInfo11.setDotLat(39.98343);
        dotInfo11.setDotLon(116.311843);
        dotInfo11.setDotId("dotInfo11");
        dotInfoList.add(dotInfo11);

        DotInfo dotInfo12 = new DotInfo();
        dotInfo12.setDotLat(40.029849);
        dotInfo12.setDotLon(116.313302);
        dotInfo12.setDotId("dotInfo12");
        dotInfoList.add(dotInfo12);

        return dotInfoList;
    }
}

DisplayUtil

public class DisplayUtil {

    public static int screenWidthPx; //屏幕宽 px
    public static int screenhightPx; //屏幕高 px
    public static float density;//屏幕密度
    public static int densityDPI;//屏幕密度
    public static float screenWidthDip;//  dp单位
    public static float screenHightDip;//  dp单位
    public static int statusBarHight;

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }


    /**
     * 将px值转换为sp值,保证文字大小不变
     *
     * @param pxValue (DisplayMetrics类中属性scaledDensity)
     * @return
     */
    public static int px2sp(Context context, float pxValue) {
        final float fontScale = context.getResources().getDisplayMetrics()
                .scaledDensity;
        return (int) (pxValue / fontScale + 0.5f);
    }

    /**
     * 将sp值转换为px值,保证文字大小不变
     *
     * @param spValue (DisplayMetrics类中属性scaledDensity)
     * @return
     */
    public static int sp2px(Context context, float spValue) {
        final float fontScale = context.getResources().getDisplayMetrics()
                .scaledDensity;
        return (int) (spValue * fontScale + 0.5f);
    }
}

xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.test_map_pio.MainActivity">

    <com.amap.api.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

一些基础配置这里就不在介绍,如有什么不足,请指出。

版权声明:本文为博主原创文章,未经博主允许不得转载。

基于高德地图API实现车辆轨迹回放并显示实时坐标

一、先上代码: html代码: js代码: var postData = {}; postData['rsearch'] = rsearch; postData['uid...

高德地图生成静态图片,显示指定经纬度的地图

最近接到一个地图需求,1.生成静态图片,2.显示指定经纬度的地图然后我结合需求sdkapi后,就确定了大概几个需求。本文只注明几个比较有用的地方,具体还得结合官方文档生成静态图片这个在android ...

【高德地图API】从零开始学高德JS API(三)覆盖物——标注|折线|多边形|信息窗口|聚合marker|麻点图|图片覆盖物

覆盖物,是一张地图的灵魂。有覆盖物的地图,才是完整的地图。在一张地图上,除了底层的底图(瓦片图,矢量图),控件(有功能可操作的工具),最重要最不可缺少的就是覆盖物了。覆盖物有多种,包括,标注、折线、多...

【Android】高德地图根据2个坐标智能缩放地图

需求: 在地图上给定2个坐标点,然后将2个坐标点通过缩放都能显示出来。 实现: 通过查阅高德地图接入文档和API能找到缩放的API高德地图文档,看到以下说明 限制地图的显示范围 从地图 SDK...
  • dqmj2
  • dqmj2
  • 2017年11月09日 09:41
  • 91

高德地图聚合Marker

  • 2016年12月17日 17:31
  • 34.59MB
  • 下载

高德地图点聚合效果

  • 2017年08月16日 09:56
  • 72.55MB
  • 下载

iOS高德地图 多个大头针显示图片 点击效果

高德地图 添加多个大头针(标注) 显示不同图片 与点击方法的解决方案
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android 高德地图给指定坐标显示图片,以及聚合显示
举报原因:
原因补充:

(最多只允许输入30个字)