最近做的一个共享出行的项目中,有一个行程详情的界面,就是把自己的行程轨迹显示在地图上,需要用到地图的标注,画线,和缩放级别自适应的功能.其中缩放级别自适应我是找了好久才实现的,在此记录一下,希望能让别人少走些弯路.
- 地图标注.
地图标注需要实现MapView的MAMapViewDelegate
的mapView viewFor annotation:
代理方法,此方法返回一个MAAnnotationView
对象,你可以根据自己的需求设置自己的标注,我的项目需求是标识起点和终点,所以我通过经纬度判断出这两点后,分别设置对应的图像:
//起点
if annotation.coordinate.latitude == self.startPointAnimation.coordinate.latitude && annotation.coordinate.longitude == self.startPointAnimation.coordinate.longitude {
annotationView?.image = UIImage.init(named: "startPoint")
}
//终点
if annotation.coordinate.latitude == self.endPointAnimation.coordinate.latitude && annotation.coordinate.longitude == self.endPointAnimation.coordinate.longitude{
annotationView?.image = UIImage.init(named: "endPoint")
}
需要注意的是,此代理方法需要调用MapView的addAnnotations
方法触发.
- 划线
划线需要实现MapView的mapView rendererFor overlay:
代理,返回MAOverlayRenderer
对象,直接在此方法中设置折线的样式即可:
//绘制路线
func mapView(_ mapView: MAMapView!, rendererFor overlay: MAOverlay!) -> MAOverlayRenderer! {
if overlay.isKind(of: MAPolyline.self) {
let polylineRender = MAPolylineRenderer.init(overlay: overlay)
polylineRender?.lineWidth = 3
polylineRender?.strokeColor = KgreenColor()
polylineRender?.fillColor = KgreenColor()
polylineRender?.lineJoinType = kMALineJoinRound
return polylineRender
}
return nil
}
需要注意的是:此代理方法需要实现MapView的addOverlay
方法触发
- 逆地理编码
逆地理编码需要实现MapView的AMapSearchDelegate
代理中的onReGeocodeSearchDone response:
方法,判断出起点和终点的坐标后,调用response.regeocode.formattedAddress
获取格式化后的地址
func onReGeocodeSearchDone(_ request: AMapReGeocodeSearchRequest!, response: AMapReGeocodeSearchResponse!) {
if response.regeocode == nil {
return
}
//起点
if request.location.latitude == CGFloat(self.startPointAnimation.coordinate.latitude) && request.location.longitude == CGFloat(self.startPointAnimation.coordinate.longitude){
startAddressLabel.text = response.regeocode.formattedAddress
}
//终点
if request.location.latitude == CGFloat(self.endPointAnimation.coordinate.latitude) && request.location.longitude == CGFloat(self.endPointAnimation.coordinate.longitude){
endAddressLabel.text = response.regeocode.formattedAddress
}
}
逆地理编码需要传入需要转码的位置坐标,然后发起逆地理编码的请求:
//发起逆地理编码请求
let request = AMapReGeocodeSearchRequest()
request.location = AMapGeoPoint.location(withLatitude: CGFloat(self.startPointAnimation.coordinate.latitude), longitude: CGFloat(self.startPointAnimation.coordinate.longitude))
request.requireExtension = true
self.search.aMapReGoecodeSearch(request)
- 最后就是缩放级别的自适应,因为行程有长有短,不可能设置一个固定的缩放级别,需要根据行程的坐标数组自动适应,就像摩拜单车,小蓝单车中的行程详情页一样,不管骑行多远或者多近,都能以适当的缩放比例展示,高德提供了一个很简单的方法实现这一需求,然而我之前找了两天才找到,唉...
实现起来很简单,在你调用划线的方法后面加上下面一句代码就可以了:
self.mapView.add(self.pointLine)
//调用划线后,调用下面方法,设置地图可视矩形的范围
self.mapView.setVisibleMapRect(self.pointLine.boundingMapRect, edgePadding: UIEdgeInsetsMake(40, 40, 40, 40), animated: true)
先看一下行程特别短的显示效果:
再看一下行程特别长的显示效果:
不管轨迹什么样,缩放级别都能自动适应了.