转载请注明!
前言
使用高德SDK实现定位及周边的搜索界面,先看效果图:
使用到了高德以下sdk:
com.amap.api:3dmap:latest.integration
com.amap.api:search:latest.integration
思路分析
本文不对高德sdk的集成做介绍,主要说说实现该页面的思路。
需求:
- 进入页面自动定位,并且展示周边
- 搜索地点,并且展示该地点周边
- 周边列表的点击,然后切换地图的定位蓝点
具体实现
首先需要注意权限的获取。
初始化高德相关的东西:
/**
* 初始化定位相关
*/
private fun initLocationAbout() {
val myLocationStyle = MyLocationStyle()
myLocationStyle.showMyLocation(true)
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW)
//设置默认定位按钮是否显示
mMap.uiSettings.isMyLocationButtonEnabled = false
//设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false
mMap.isMyLocationEnabled = true
mMap.myLocationStyle = myLocationStyle
//第一次定位
mMap.setOnMyLocationChangeListener {
val latLng = LatLng(it.latitude, it.longitude)
cameraMove(latLng)
}
mMap.setOnCameraChangeListener(object : AMap.OnCameraChangeListener {
override fun onCameraChangeFinish(p0: CameraPosition) {
cameraMarkers(p0.target)
//判断是否需要搜索周边
if (isSearchRound) {
poiSearch(p0.target)
}
isSearchRound = true
}
override fun onCameraChange(p0: CameraPosition) {
}
})
}
移动定位点的方法:
/**
* 移动地图
* @param latLng 坐标
*/
private fun cameraMove(latLng: LatLng) {
//其中的18f表示的是地图放大级别
val camera = CameraUpdateFactory.newCameraPosition(CameraPosition(latLng, 18f, 0f, 0f))
mMap.moveCamera(camera)
}
周边搜索的方法:
/**
* 周边搜索
*/
private fun poiSearch(latLng: LatLng) {
val point = LatLonPoint(latLng.latitude, latLng.longitude)
val geocodeSearch = GeocodeSearch(this)
val regeocodeQuery = RegeocodeQuery(point, 200f, GeocodeSearch.AMAP)
geocodeSearch.getFromLocationAsyn(regeocodeQuery)
geocodeSearch.setOnGeocodeSearchListener(object : GeocodeSearch.OnGeocodeSearchListener {
/**
* 逆地理编码
*/
override fun onRegeocodeSearched(p0: RegeocodeResult, p1: Int) {
if (p1 == AMapException.CODE_AMAP_SUCCESS) {
//创建当前位置的poi
val nowPoiltem = PoiItem(
"111",
p0.regeocodeQuery.point,
"地图位置",
p0.regeocodeAddress.formatAddress
)
nowPoiltem.adCode = p0.regeocodeAddress.adCode
nowPoiltem.provinceName = p0.regeocodeAddress.province
nowPoiltem.cityName = p0.regeocodeAddress.city
nowPoiltem.adName = p0.regeocodeAddress.district
val locationList = mutableListOf<PoiItem>()
//因为搜索的周边列表并不包含当前搜索的位置,所以需要把当前位置插进去
locationList.add(nowPoiltem)
locationList.addAll(p0.regeocodeAddress.pois)
//周边展示的Adapter
mAdapter.setCityAbout(
p0.regeocodeAddress.province,
p0.regeocodeAddress.city,
p0.regeocodeAddress.district
)
mAdapter.replaceData(locationList)
mAdapter.setEmptyView(mNoData)
} else {
mAdapter.setEmptyView(mErrorLoad)
}
}
/**
* 地理编码
*/
override fun onGeocodeSearched(p0: GeocodeResult?, p1: Int) {
hideLoading()
}
})
}
关键字搜索:
/**
* 搜索关键字
*/
private fun doSearchQuery(keyWord: String) {
val query = PoiSearch.Query(keyWord, "", mCity)
query.pageSize = 50
query.pageNum = 0
//搜索
val poiSearch = PoiSearch(this, query)
poiSearch.setOnPoiSearchListener(this)
poiSearch.searchPOIAsyn()
showLoading()
}
/**
* 可以在回调中解析result,获取POI信息
* result.getPois()可以获取到PoiItem列表,Poi详细信息可参考PoiItem类
* 返回结果成功或者失败的响应码。1000为成功,其他为失败(详细信息参见网站开发指南-实用工具-错误码对照表)
*/
override fun onPoiSearched(p0: PoiResult, p1: Int) {
hideLoading()
if (p1 == AMapException.CODE_AMAP_SUCCESS) {
mPopupLocation.replaceData(p0.pois)
//弹出框
mXPopup?.show()
} else {
App.mApplication.toast("搜索地址错误!")
}
}
周边列表的点击:
mAdapter.setOnItemClickListener { adapter, view, position ->
val data: PoiItem = adapter.data[position] as PoiItem
isSearchRound = false
mSelectLocation = position
mAdapter.selectLocation(position)
//移动点
val latLng = LatLng(data.latLonPoint.latitude, data.latLonPoint.longitude)
//创建
cameraMove(latLng)
}
页面功能通过以上方法就能实现,如果发现某些监听不会回调,先看看引入的sdk。在编写时,我一开始引用的高德的2dmap,发现地图移动的监听不会回调,然后换到3dmap就好了。
网友评论