高德地图SDK添加海量描点、我的定位呼吸动画
一、添加海量描点
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、工程配置方面
特别提醒
- 不要再一个项目中同时使用2D和3D SDK
- 2D SDK 需要而外引入地位SDK,而3D SDK以包含定位的SDK。
- 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