使用高德地图2D/3D SDK添加海量描点Marker以及视图中显示所有描点、我的定位添加呼吸动画

一、添加海量描点

1、高德2D SDK添加实现

由MarkerOverlay管理显示描点

1)初始化MarkerOverlay

//添加Marker Onerlay
    fun initOverlay(mOverlay: MarkerOverlay?, location: AMapLocation?) {
        if (mOverlay != null) {
            markerOverlay = mOverlay
            markerOverlay?.initData(selectBitmap, normalBitmap, mOffset)
            location?.let {
                animalLocation(location)
            }
        }
    }

2)设置海量描点数据

	/**
     *  真实接口数据
     *  select 选中的数据
     */
    fun setPointList(list: MutableList<StoresBean>?, select: Int?) {
        if (list != pointList) {
            pointList.clear()
            if (list != null && list.isNotEmpty()) {
                pointList.addAll(list)
            }
            markerOverlay?.setPointList(pointList, select)
            markerOverlay?.setCenterPoint(centerPoint)
            if (select != null && select > -1) {
                //获取选中的
                currentMarker = markerOverlay?.getCurrentMarker()
            }
            zoomToSpan()
        }
    }

    //测试数据
    fun getPointList(): MutableList<StoresBean>? {
        val pointList: MutableList<StoresBean> = ArrayList()
        pointList.add(StoresBean("", "22.583755", "113.929306", "深圳市深圳市深圳市", "深圳市", "名字1"))
        pointList.add(StoresBean("", "22.572589", "113.910079", "深圳市深圳市深圳市", "深圳市", "名字11"))
        pointList.add(StoresBean("", "22.573946", "113.928987", "深圳市深圳市深圳市", "深圳市", "名字12"))
        pointList.add(StoresBean("", "22.570466", "113.924343", "深圳市深圳市深圳市", "深圳市", "名字13"))
        pointList.add(StoresBean("", "22.563222", "113.924882", "深圳市深圳市深圳市", "深圳市", "名字14"))
        return pointList
    }

4)Marker点击监听

		//点击marker监听
        map.setOnMarkerClickListener {
            // 我的位置不需要选中
            if (locMarker != it) {
                //更换默认/选中图标
                if (currentMarker != it) {
                    if (showSelect) {
                        it.setIcon(selectBitmap)
                        currentMarker?.let { current ->
                            current.setIcon(normalBitmap)
                        }
                    }
                    currentMarker = it
                }
                clickMarkerListener?.invoke((it.`object`) as StoresBean)
            }
            //true 选中点不会跳到屏幕中间,false 跳到屏幕中间
            true
        }

5)MarkerOverlay主要方法

	//初始化list
    fun setPointList(points: List<StoresBean>?, select: Int?) {
        if (points != pointList) {
            pointList.clear()
            if (points != null && points.isNotEmpty()) {
                pointList.addAll(points)
            }
            removeFromMap()
            addOverMarker(select)
        }
    }
	/**
     * 添加Marker到地图中。
     * select 选中
     * mMarkers 所有的marker列表
     */
    private fun addOverMarker(select: Int?) {
        try {
            if (pointList.isNotEmpty()) {
                for (b in pointList) {
                    val selectBean = select != null && pointList.indexOf(b) == select
                    val lat: Double = b.latitude?.toDouble() as Double
                    val lon: Double = b.longitude?.toDouble() as Double
                    val marker: Marker = aMap!!.addMarker(
                        MarkerOptions()
                            .position(LatLng(lat, lon))
                            .icon(if (selectBean) selectBitmap else normalBit)
                    )
                    marker.setObject(b) //获取Marker覆盖物的附加信息对象,即自定义的Marker的属性,可在marker点击监听中获取
                    if (!mMarkers.contains(marker)) {
                        mMarkers.add(marker)
                    }
                    if (selectBean) {
                        currentMarker = marker
                    }
                }
            }
        } catch (e: Throwable) {
            e.printStackTrace()
        }
    }

	/**
     * 去掉MarkerOverlay上所有的Marker。
     */
    fun removeFromMap() {
        for (mark in mMarkers) {
            mark.remove()
        }
        mMarkers.clear()
        centerMarker?.remove()
    }

2、高德3D SDK添加实现

高德3D SDK 封装了海量描点的方法,直接使用官方方法即可

val overlayOptions = MultiPointOverlayOptions()
        overlayOptions.icon(normalBitmap) //设置图标
        overlayOptions.anchor(0.5f, 0.5f) //设置锚点
        val multiPointOverlay: MultiPointOverlay = aMap.addMultiPointOverlay(overlayOptions)
        val list: MutableList<MultiPointItem> = ArrayList<MultiPointItem>()
        multiPointOverlay.setItems(list);//将规范化的点集交给海量点管理对象设置,待加载完毕即可看到海量点信息
        // 定义海量点点击事件
        val multiPointClickListener: AMap.OnMultiPointClickListener = object : OnMultiPointClickListener() {
            // 海量点中某一点被点击时回调的接口
            // 返回 true 则表示接口已响应事件,否则返回false
            fun onPointClick(pointItem: MultiPointItem?): Boolean {
                //点击具体处理
                return false
            }
        }
        // 绑定海量点点击事件
        aMap.setOnMultiPointClickListener(multiPointClickListener)

二、视图显示所有描点

高德所有SDK可使用

1、根据中心点显示所有描点

/**
     * 缩放移动地图,保证所有自定义marker在可视范围中,且地图中心点不变。
     */
    fun zoomToSpanWithCenter() {
        if (pointList.isNotEmpty()) {
            if (aMap == null) return
            centerMarker?.isVisible = false
//            centerMarker?.showInfoWindow()
            val bounds = getLatLngBounds(centerPoint, pointList)
            //边距数值来控制插入区域与view的边框之间的空白距离。
            aMap?.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, mPadding))
        }
    }

    //根据中心点和自定义内容获取缩放bounds
    private fun getLatLngBounds(centerpoint: LatLng?, pointList: List<StoresBean>): LatLngBounds {
        val bean = LatLngBounds.builder()
        for (b in pointList) {
            val lat: Double = b.latitude?.toDouble() as Double
            val lon: Double = b.longitude?.toDouble() as Double
            val p = LatLng(lat, lon)
            val p0 = LatLng(p.latitude - mOffset, p.longitude)  //屏幕中心偏移
            bean.include(p0)
            if (centerpoint != null) {
                val p1 = LatLng(centerpoint.latitude * 2 - p.latitude, centerpoint.longitude * 2 - p.longitude)
//                bean.include(p)
                bean.include(p1)
            }
        }
        return bean.build()
    }

2、显示所有描点(没有自定义中心点)

/**
     * 缩放移动地图,保证所有自定义marker在可视范围中。
     */
    fun zoomToSpan() {
        if (pointList.isNotEmpty()) {
            if (aMap == null) return
//            centerMarker?.isVisible = false
            val bounds = getLatLngBounds(pointList)
            aMap?.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, mPadding))
        }
    }

    /**
     * 根据自定义内容获取缩放bounds
     */
    private fun getLatLngBounds(pointList: List<StoresBean>): LatLngBounds {
        val bean = LatLngBounds.builder()
        for (b in pointList) {
            val lat: Double = b.latitude?.toDouble() as Double
            val lon: Double = b.longitude?.toDouble() as Double
            val p = LatLng(lat, lon)
            val p1 = LatLng(p.latitude - mOffset, p.longitude)  //屏幕中心偏移
            bean.include(p1)
        }
        return bean.build()
    }

三、添加呼吸动画

1、高德2D SDK添加实现

1)设置序列帧图片的方式

2D SDK 只开放这种方式;
参数说明: period 1频数最快、默认20;2d的最快也不是很快。图片帧数越多,动画的完成时间越久。

//设置呼吸动画帧列表
    private fun addMarker(point: LatLng): Marker? {
        return map.addMarker(
            MarkerOptions().position(point).icons(getIconList()).period(1)
                .anchor(0.5f, 0.5f)
        )
    }
    
/**
 * 我的定位蓝点动效
 */
fun getIconList(): ArrayList<BitmapDescriptor> {
    val iconList: ArrayList<BitmapDescriptor> = ArrayList()
    iconList.add(BitmapDescriptorFactory.fromResource(R.drawable.ic_loc_animation_000))
    iconList.add(BitmapDescriptorFactory.fromResource(R.drawable.ic_loc_animation_001))
    ...
    return iconList
}

2、高德3D SDK添加实现

1)设置序列帧图片的方式

3D SDK也可使用2D的方式
特别说明: 参数 period(1) 1频数最快、默认20;相比较2d的快很多

2)使用setAnimation()的方式

            // 动画执行完成后,默认会保持到最后一帧的状态
            val animationSet = AnimationSet(true)
            val alphaAnimation = AlphaAnimation(1f, 0f)
            alphaAnimation.setDuration(2000)
            // 设置不断重复
            alphaAnimation.setRepeatCount(Animation.INFINITE)
            val scaleAnimation = ScaleAnimation(1f, 3.5f, 1f, 3.5f)
            scaleAnimation.setDuration(2000)
            // 设置不断重复
            scaleAnimation.setRepeatCount(Animation.INFINITE)
            animationSet.addAnimation(alphaAnimation)
            animationSet.addAnimation(scaleAnimation)
            animationSet.setInterpolator(LinearInterpolator())
            locMarker?.setAnimation(animationSet)
            locMarker?.startAnimation()

四、高德SDK 2D/3D比较

1、体验方面

很明显的是地图加载显示方面,2D瓦片加载方式,瓦片的出现,缩放地图时显得加载缓慢,不顺滑;3D SDK在缩放加载的流畅度方面很好,且画质立体感方面也特别好。

2、API方面

3D SDK 提供的SDK比2D SDK多很多,例如动画和海量描点方案

3、工程配置方面

特别提醒

  1. 不要再一个项目中同时使用2D和3D SDK
  2. 2D SDK 需要而外引入地位SDK,而3D SDK以包含定位的SDK。
  3. navi导航SDK5.0.0以后版本包含了3D地图SDK,所以请不要同时引入 map3d 和 navi SDK。
//3D
compile 'com.amap.api:3dmap:latest.integration'
//2D
compile 'com.amap.api:map2d:latest.integration'
compile 'com.amap.api:map2d:latest.integration'

4、结论

如果没有自定义瓦片加载地图的需求,使用3D SDK

写在最后

此文章为个人开发时记录,有时时间有限,无法深入研究,若看到此文章后有其他见解或解决方式,欢迎留言交流👇👇👇

————————————————
版权声明:转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/weixin_44158429/article/details/126370328

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值