需求: 把点亮的城市全部显示 并且显示区域在屏幕的四分之三区域 因为底部有四分之一的区域被遮挡
1.首先我们在点亮 /市级/ 区域时,获取到了市级每个行政区划的边界点,并且还获取到了市级的中心点,我们从中心点开始动手
1.1 我们有一个需要点亮城市的名字集合
private val searchQueue = LinkedList<String>() // 用于存储待搜索的城市列表
1.2 处理城市搜索队列 获取城市的中心点和市级每个行政区划的边界点(具体可以)
// 处理搜索队列
private fun processSearchQueue() {
if (searchQueue.isNotEmpty()) {
val city = searchQueue.poll() // 取出队列中的第一个城市
performSearchForCity(city)
} else {
// 如果队列为空,并且已经处理了所有城市,可以执行一些后续操作
if (processedCities == cityCount) {
// 所有城市都已处理完毕
moveMapCenter()
}
}
}
1.3 获取到城市的中心点 并且保存到一个集合中
private fun performSearchForCity(city: String) {
val search = DistrictSearch(context)
val query = DistrictSearchQuery()
query.keywords = city // 使用当前遍历到的城市作为关键字
query.isShowBoundary = true // 是否返回边界值
query.isShowChild = false
search.query = query
// 由于搜索是异步的,我们需要为每个城市设置一个监听器来处理结果
search.setOnDistrictSearchListener { districtResult ->
if (districtResult != null && districtResult.aMapException.errorCode == 1000) {
// 成功获取到行政区划信息
val districtItems: List<DistrictItem>? = districtResult.district
val districtItem = districtItems?.firstOrNull()
val center = districtItem?.center
center?.let {
if (center.longitude > 0) {
mapLatLngList.add(LatLng(center.latitude, center.longitude))
}
}
processedCities++
// 记录日志
YzLog.e("IMineRunFootPrintImpl-》districtItems for $city: ${districtItems.toString()}")
// 绘制省份和标记
drawMap(districtItems)
} else {
// 处理查询失败的情况
YzLog.e("IMineRunFootPrintImpl-》DistrictSearch failed for $city: ${districtResult?.aMapException?.errorMessage}")
}
// 完成当前搜索后,继续处理队列中的下一个城市
processSearchQueue()
}
// 执行异步搜索
search.searchDistrictAsyn()
// 保存当前搜索实例,以便在需要时可以取消或重新配置
currentSearch = search
}
2 获取到了城市的中心点 并把所有点亮城市区域显示出来
2.1 高德地图 LatLngBounds.Builder().include(latlng) 可以让所有点 都显示在地图区域上 并且获取到边界的四个点
//通过城市中心点集合 计算最小外接矩形
val builder = LatLngBounds.Builder()
for (latlng in points) {
builder.include(latlng)
}
val originalLatLngBounds = builder.build()
// 2. 获取原始矩形的四个角点
val southwest = originalLatLngBounds.southwest
val northeast = originalLatLngBounds.northeast
val newBounds = LatLngBounds(southwest, northeast)
getCurMap()?.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(newBounds, 0,0,0,paddingBottom))
// 3. 创建多边形对象
val polygonOptions = PolygonOptions()
.add(southwest)
.add(northwest)
.add(northeast)
.add(southeast)
.strokeColor(Color.parseColor("#00ff0000")) // 设置边框颜色为暗红色
.fillColor(Color.argb(128, 139, 0, 0)) // 设置填充颜色为半透明的暗红色
.strokeWidth(5f) // 设置边框宽度
// 4. 获取地图实例并添加多边形
val aMap = getCurMap() // 假设这是您获取地图实例的方法
aMap?.addPolygon(polygonOptions)
2.2 因为底部有四分之一的区域遮挡住了 如果底下有地图,就显示不出来 我们先把地图缩小 看看绘制出获取到边界的四个点是否正确
2.3 因为我们是以中心点来绘制的 所以我城市的其他区域会显示不全 这边的想法是放大地图显示区域的倍数 因为我们知道了地理坐标(经纬度) 可以通过经纬度来实现放大或缩小
// 3. 计算矩形的宽度(纬度差值)和高度(经度差值)
val latDiff = northeast.latitude - southwest.latitude
val lngDiff = northeast.longitude - southwest.longitude
// 4. 根据指定的比例分别放大宽度和高度
val newLatDiff = latDiff * 1.25 // 宽度(纬度差值)放大1.5倍
val newLngDiff = lngDiff * 1.5 // 高度(经度差值)放大1.25倍
// 5. 计算新的西南角点(此角点将作为新矩形的起点)
// 注意:新西南角点的计算需考虑原始矩形中心与新矩形中心的相对位置
val centerLat = southwest.latitude + latDiff / 2
val centerLng = southwest.longitude + lngDiff / 2
// 6. 根据新的西南角点和放大后的宽度、高度,计算其他三个角点
val newSouthwest = LatLng(centerLat - newLatDiff / 2, centerLng - newLngDiff / 2)
val newNorthwest = LatLng(newSouthwest.latitude + newLatDiff, newSouthwest.longitude)
val newNortheast =
LatLng(newSouthwest.latitude + newLatDiff, newSouthwest.longitude + newLngDiff)
val newSoutheast = LatLng(newSouthwest.latitude, newSouthwest.longitude + newLngDiff)
val newBounds = LatLngBounds(newSouthwest, newNortheast
2.4 这样一来 区域是全屏 但是城市的区域 都显示出来了 但是还是会有遮挡 然后我们通过加padding 来实现显示区域为全屏的四分之三 并且给中心点 绘制标志
val screenHeight =DensityUtils.getScreenHeight(context)
val paddingBottom = screenHeight / 4
getCurMap()?.moveCamera(CameraUpdateFactory.newLatLngBoundsRect(newBounds, 0,0,0,paddingBottom))
// 计算中心点的纬度和经度
val centerLatitude = (newSouthwest.latitude + newNortheast.latitude) / 2.0
val centerLongitude = (newSouthwest.longitude + newNortheast.longitude) / 2.0
curLocation = LatLng(centerLatitude, centerLongitude)
addMarker(centerLatitude, centerLongitude, "中心点")
2.5 最终效果图