最近做的一個共享出行的項目中,有一個行程詳情的界面,就是把自己的行程軌跡顯示在地圖上,需要用到地圖的標注,畫線,和縮放級別自適應的功能.其中縮放級別自適應我是找了好久才實現(xiàn)的,在此記錄一下,希望能讓別人少走些彎路.
- 地圖標注.
地圖標注需要實現(xiàn)MapView的MAMapViewDelegate
的mapView viewFor annotation:
代理方法,此方法返回一個MAAnnotationView
對象,你可以根據(jù)自己的需求設置自己的標注,我的項目需求是標識起點和終點,所以我通過經緯度判斷出這兩點后,分別設置對應的圖像:
//起點
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
方法觸發(fā).
- 劃線
劃線需要實現(xiàn)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
}
需要注意的是:此代理方法需要實現(xiàn)MapView的addOverlay
方法觸發(fā)
- 逆地理編碼
逆地理編碼需要實現(xiàn)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
}
}
逆地理編碼需要傳入需要轉碼的位置坐標,然后發(fā)起逆地理編碼的請求:
//發(fā)起逆地理編碼請求
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)
- 最后就是縮放級別的自適應,因為行程有長有短,不可能設置一個固定的縮放級別,需要根據(jù)行程的坐標數(shù)組自動適應,就像摩拜單車,小藍單車中的行程詳情頁一樣,不管騎行多遠或者多近,都能以適當?shù)目s放比例展示,高德提供了一個很簡單的方法實現(xiàn)這一需求,然而我之前找了兩天才找到,唉...
實現(xiàn)起來很簡單,在你調用劃線的方法后面加上下面一句代碼就可以了:
self.mapView.add(self.pointLine)
//調用劃線后,調用下面方法,設置地圖可視矩形的范圍
self.mapView.setVisibleMapRect(self.pointLine.boundingMapRect, edgePadding: UIEdgeInsetsMake(40, 40, 40, 40), animated: true)
先看一下行程特別短的顯示效果:
再看一下行程特別長的顯示效果:
不管軌跡什么樣,縮放級別都能自動適應了.