高德地图SDK Android版开发 9 覆盖物示例3批量点、海量点

前言

前文介绍了如何在地图上添加一个Marker,本文重点介绍如何批量添加和删除海量点的功能。

  • 批量操作:一次性向地图上大批量添加Marker的接口。
  • 海量点:应用于移动端的海量点图层用于批量展现具有相似属性的坐标点数据。海量点图层支持处理的点数量级跨度较大,从几十个点至十万个点(建议不超过100000个点数据)都可以应用海量点图层进行处理。该功能自 Android 地图 SDK 5.1.0版本起支持。

相关的类和接口

批量添加

高德地图SDKBaiduMap地图类除了提供添加一个Marker的接口外,还提供了批量添加的接口:

  • addMarker接口可以在地图上添一个图片标记对象。
  • addMarkers接口可以在地图上添一组图片标记对象。
  • setOnMarkerClickListenerremoveMarkerClickListener接口可以添加和移除Marker单击事件。
类型方法说明
MarkeraddMarker(MarkerOptions options)在地图上添一个图片标记(marker)对象。
ArrayList< Marker >addMarkers(ArrayList< MarkerOptions > options, boolean moveToCenter)在地图上添一组图片标记(marker)对象,并设置是否改变地图状态以至于所有的marker对象都在当前地图可视区域范围内显示。
voidsetOnMarkerClickListener(AMap.OnMarkerClickListener listener)设置marker点击事件监听接口。

海量点

MultiPointOverlay海量点管理对象,可以将大量点展示在地图上,通过MultiPointOverlayOptions类来设置海量点的选项。

  • 部分覆盖物类关系图:
Marker
Text
BasePointOverlay
BaseOverlay
MultiPointOverlay
Polyline
Polygon
Arc
Circle
  • 部分覆盖物选项类关系图:
TextOptions
MarkerOptions
BaseOptions
MultiPointOverlayOptions
PolylineOptions
PolygonOptions
ArcOptions
CircleOptions

AMap类

高德地图AMap地图类与海量点相关的接口:

  • addMultiPointOverlay接口可以在地图上添加一个海量点覆盖物(MultiPointOverlay)对象。

  • setOnMultiPointClickListener接口设置海量点单击事件监听。

类型方法说明
MultiPointOverlayaddMultiPointOverlay(MultiPointOverlayOptions options)在地图上添加一个海量点覆盖物(MultiPointOverlay)对象
voidsetOnMultiPointClickListener(AMap.OnMultiPointClickListener listener)设置海量点单击事件监听

AMap.OnMultiPointClickListener接口

// 海量点中某一点被点击时的回调
public interface OnMultiPointClickListener {
    /**
     * 海量点中某一点被点击时回调此方法。
     * @param item 包含海量点中其中某一点的信息。
     * @return 返回true表示该点击事件已被处理,不再往下传递(如底图点击不会被触发),返回false则继续往下传递。
     */
    boolean onPointClick(MultiPointItem item);
}

MultiPointOverlayOptions 海量点选项

类型方法说明
MultiPointOverlayOptionsicon(BitmapDescriptor bitmapDescriptor)设置海量点的显示图标
MultiPointOverlayOptionsanchor(float u, float v)设置海量点的锚点比例。
floatgetAnchorU()获取海量点锚点在水平范围的比例。
floatgetAnchorV()获取海量点锚点垂直范围的比例。
BitmapDescriptorgetIcon()获取海量点的显示图标

MultiPointOverlay

类型方法说明
voidsetItems(List< MultiPointItem > items)设置海量点,初始化或者更新海量点时可以调用此方法。
同步方法,如果点很多时,会消耗一定的时间,建议放在子线程中处理。
voidsetAnchor(float anchorX, float anchorY)统一设置海量点图标锚点比例。
voidsetEnable(boolean enable)设置海量点是否显示,默认为显示
List< MultiPointItem >getItems()获取海量点,初始化或者更新海量点时可以调用此方法
voidremove()从地图上移除海量点图层
voiddestroy()海量点图层销毁

MultiPointItem 海量点中单个点的属性

  • getter
类型方法说明
StringgetCustomerId()
LatLnggetLatLng()
ObjectgetObject()
StringgetSnippet()
StringgetTitle()
  • setter
类型方法说明
voidsetLatLng(LatLng latLng)
voidsetCustomerId(String customerId)为海量点设置一个唯一标识,可以用来判断,默认为null
voidsetObject(Object object)设置附加信息对象。
voidsetSnippet(String snippet)
voidsetTitle(String title)

示例

界面布局

在这里插入图片描述

  • 布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MapMarkersActivity">

    <com.amap.api.maps.MapView
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@id/bottomView"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.appcompat.widget.LinearLayoutCompat
        android:id="@+id/bottomView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/map">

        <RadioGroup
            android:id="@+id/RadioGroup"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/background_dark"
            android:gravity="center_horizontal"
            android:orientation="horizontal"
            android:paddingHorizontal="10dp">

            <RadioButton
                android:id="@+id/bulk"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:checked="true"
                android:onClick="setMarkerFlag"
                android:text="批量点"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/multiPoint"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setMarkerFlag"
                android:text="海量点"
                android:textColor="@color/white"
                android:textStyle="bold" />

            <RadioButton
                android:id="@+id/clear"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:onClick="setMarkerFlag"
                android:text="清除"
                android:textColor="@color/white"
                android:textStyle="bold" />
        </RadioGroup>

    </androidx.appcompat.widget.LinearLayoutCompat>
</androidx.constraintlayout.widget.ConstraintLayout>

MapMarks类

  • 以下是MapMarks部分代码。

常量

public static final String BULK = "Bulk"; // 批量点
public static final String MULTI_POINT = "MultiPoint"; // 海量点

成员变量

// 覆盖物列表
List<BaseOverlay> overlays = new ArrayList<>();
// 海量点选中高亮
Marker selectedMarker;

// 选中的状态
List<String> selectedFlags = new ArrayList<>();

// 气泡图标
ArrayList<BitmapDescriptor> bitmaps = new ArrayList<>();
// 点图标
BitmapDescriptor dotBitmap;

// Marker点击事件
AMap.OnMarkerClickListener bulkMarkerClickListener;
// 海量点点击事件
AMap.OnMultiPointClickListener multiPointClickListener;

初始化

selectedFlags.add(BULK);

int[] drawableIds = BubbleIcons.Number;
for (int drawableId : drawableIds) {
    BitmapDescriptor bitmap = BitmapDescriptorFactory.fromResource(drawableId);
    bitmaps.add(bitmap);
}
dotBitmap = BitmapDescriptorFactory.fromResource(CircleIcons.BLueDot[0]);

创建覆盖物

public void addMarkers() {
    if (selectedFlags.isEmpty())
        return;

    for (String flag : selectedFlags) {
        switch (flag) {
        case BULK:
            addBulk();
            break;
        case MULTI_POINT:
            // 读取数据并通过海量点管理对象设置(参考官网示例Demo)
            loadLocations(new LoadCallBack() {
                @Override
                public void onLoaded(List<MultiPointItem> points) {
                    addMultiPoint(points);
                }
            });
            break;
        }
    }
}
批量点
  • 创建MarkerOptions的集合
  • 在地图上批量添加覆盖物
  • 设置Marker单击事件
private void addBulk() {
    // 构造大量坐标数据
    List<LatLng> points = new ArrayList<>();
    points.add(new LatLng(39.97923, 116.357428));
    points.add(new LatLng(39.94923, 116.397428));
    points.add(new LatLng(39.97923, 116.437428));
    points.add(new LatLng(39.92353, 116.490705));
    points.add(new LatLng(40.023537, 116.289429));
    points.add(new LatLng(40.022211, 116.406137));

    // 创建OverlayOptions的集合
    ArrayList<MarkerOptions> optionsList = new ArrayList<>();
    for (int i = 0; i < points.size(); ++i) {
        // 创建OverlayOptions属性
        MarkerOptions option = new MarkerOptions()
                .position(points.get(i))
                .icon(bitmaps.get(i));
        // 将OverlayOptions添加到list
        optionsList.add(option);
    }

    boolean moveToCenter = true;
    // 在地图上添一组图片标记(marker)对象,
    // 并设置是否改变地图状态以至于所有的marker对象都在当前地图可视区域范围内显示。
    ArrayList<Marker> newOverlays = map.addMarkers(optionsList, moveToCenter);
    overlays.addAll(newOverlays);

    // 点击事件
    if (bulkMarkerClickListener == null) {
        bulkMarkerClickListener = new AMap.OnMarkerClickListener() {
            // marker被点击时回调的方法
            // 若响应点击事件,返回true,否则返回false
            // 默认返回false
            @Override
            public boolean onMarkerClick(Marker marker) {
                showToast("点击 marker");
                return true;
            }
        };
        map.setOnMarkerClickListener(bulkMarkerClickListener);
    }
}
海量点
  • 设置海量点属性
  • 添加海量点覆盖物
  • 设置海量点单击事件
private void addMultiPoint() {
    // 设置海量点属性
    MultiPointOverlayOptions overlayOptions = new MultiPointOverlayOptions()
            .icon(dotBitmap) // 设置图标
            .anchor(0.5f, 0.5f); // 设置锚点

    // 添加海量点获取管理对象
    MultiPointOverlay multiPointOverlay = map.addMultiPointOverlay(overlayOptions);
    // 将规范化的点集交给海量点管理对象设置,待加载完毕即可看到海量点信息
    overlays.add(multiPointOverlay);

    if (multiPointClickListener == null) {
        // 海量点点击事件
        multiPointClickListener = new AMap.OnMultiPointClickListener() {
            // 海量点中某一点被点击时回调的接口
            // 返回 true 则表示接口已响应事件,否则返回false
            @Override
            public boolean onPointClick(MultiPointItem item) {
                if (selectedMarker != null)
                    selectedMarker.remove();

                MarkerOptions markerOptions = new MarkerOptions();
                markerOptions.position(item.getLatLng());
                markerOptions.icon(bitmaps.get(0));
                selectedMarker = (Marker) map.addMarker(markerOptions);
                return true;
            }
        };
        map.setOnMultiPointClickListener(multiPointClickListener);
    }
}

加载大量点数据(参考自官网示例Demo)

// 读取数据并通过海量点管理对象设置(参考官网示例Demo)
List<MultiPointItem> multiPointItems = new ArrayList<>();
while(...) {
    // 创建MultiPointItem存放,海量点中某单个点的位置及其他信息
    MultiPointItem multiPointItem = new MultiPointItem(latLng);
    multiPointItems.add(multiPointItem);
}
//将规范化的点集交给海量点管理对象设置,待加载完毕即可看到海量点信息
multiPointOverlay.setItems(multiPointItems);

移除覆盖物

public void removeOverlay() {
    // 从地图上删除所有的覆盖物(marker,circle,polyline 等对象),
    // 但myLocationOverlay(内置定位覆盖物)除外。
//    boolean isKeepMyLocationOverlay = true;
//    map.clear(isKeepMyLocationOverlay);

    for (BaseOverlay overlay : overlays) {
        if (overlay instanceof Marker) {
            Marker marker = (Marker) overlay;
            marker.remove();
        } else if (overlay instanceof MultiPointOverlay) {
            MultiPointOverlay multiPointOverlay = (MultiPointOverlay) overlay;
            multiPointOverlay.remove();
        }
    }
    overlays.clear();

    if (selectedMarker != null)
        selectedMarker.remove();
    selectedMarker = null;
}

设置属性

public void setFlags(String flag) {
    selectedFlags.clear();
    if (flag != null)
        selectedFlags.add(flag);

    removeOverlay();
    addMarkers();
}

加载地图和移除地图

public void onMapLoaded() {
    addMarkers();
}

public void onMapDestroy() {
    isDestroy = true;

    removeOverlay();

    for (BitmapDescriptor bitmap : bitmaps) {
        bitmap.recycle();
    }
    bitmaps = null;

    if (dotBitmap != null)
        dotBitmap.recycle();
}

MapMarkersActivity类

  • 以下是MapMarkersActivity类部分代码

控件响应事件

public void setMarkerFlag(View view) {
    boolean checked = ((RadioButton) view).isChecked();
    if (!checked)
        return;

    int id = view.getId();
    String flag;
    if (id == R.id.bulk)
        flag = MapMarkers.BULK;
    else if (id == R.id.multiPoint)
        flag = MapMarkers.MULTI_POINT;
    else if (id == R.id.clear)
        flag = null;
    else
        return;

    mapMarkers.setFlags(flag);
}

运行效果图

批量点海量点
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值