0%

地图导航和百度鹰眼轨迹播放

前言

选择导航和百度鹰眼轨迹使用方法。

导航选择

先在 info.plist 中添加 schemes

1
2
3
4
5
<key>LSApplicationQueriesSchemes</key>
<array>
<string>iosamap</string>
<string>baidumap</string>
</array>

Swift 4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
        var start: CLLocationCoordinate2D!
var end: CLLocationCoordinate2D!

CLGeocoder().geocodeAddressString(order.startAddress) { (placemarks, error) in
if let placemark = placemarks?.first {
if let location = placemark.location {
start = location.coordinate
// start = CLLocationCoordinate2D.init(latitude: 39.9042, longitude: 116.4074)
}
}
}

CLGeocoder().geocodeAddressString(order.startAddress) { (placemarks, error) in
if let placemark = placemarks?.first {
if let location = placemark.location {
end = location.coordinate
// end = CLLocationCoordinate2D.init(latitude: 39.3434, longitude: 117.3616)

}
}
}

let alert = UIAlertController.init(title: "请选择导航", message: nil, preferredStyle: .actionSheet)

alert.addAction(UIAlertAction.init(title: "苹果地图", style: .default, handler: { (_) in
if start != nil && end != nil {
let s = MKMapItem.init(placemark: MKPlacemark.init(coordinate: start, addressDictionary: nil))
let e = MKMapItem.init(placemark: MKPlacemark.init(coordinate: end, addressDictionary: nil))
MKMapItem.openMaps(with: [s, e], launchOptions: [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving])
}
}))

if UIApplication.shared.canOpenURL(URL.init(string: "iosamap://")!) {
alert.addAction(UIAlertAction.init(title: "高德地图", style: .default, handler: { (_) in
if start != nil && end != nil {
let string = String(format: "iosamap://navi?sourceApplication=zhiyuncar&backScheme=zhiyuncar&lat=%f&lon=%f&dev=0&style=2",end.latitude,end.longitude)
if let url = URL.init(string: string) {
UIApplication.shared.openURL(url)
}
}
}))
}

if UIApplication.shared.canOpenURL(URL.init(string: "baidumap://")!) {
alert.addAction(UIAlertAction.init(title: "百度地图", style: .default, handler: { (_) in
if start != nil && end != nil {
let string = String(format: "baidumap://map/direction?origin=%f,%f&destination=%f,%f&mode=driving&coord_type=gcj02",start.latitude, start.longitude,end.latitude, end.longitude)
if let url = URL.init(string: string) {
UIApplication.shared.openURL(url)
}
}
}))
}

alert.addAction(UIAlertAction.init(title: "取消", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)

百度鹰眼

  1. AppDelegate 中启用百度地图

    1
    2
    mapManager = BMKMapManager()
    mapManager?.start(BAIDU_AK, generalDelegate: self)
  2. 添加地图,实现 protocol BMKMapViewDelegate

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    func mapView(_ mapView: BMKMapView!, viewFor overlay: BMKOverlay!) -> BMKOverlayView! {
    if overlay is BMKPolyline {
    let line = BMKPolylineView.init(overlay: overlay)
    line?.strokeColor = UIColor.init(red: 23/255.0, green: 161/255.0, blue: 95/255.0, alpha: 1)
    line?.lineWidth = 5
    line?.colors = [UIColor.init(red: 23/255.0, green: 161/255.0, blue: 95/255.0, alpha: 1)]
    return line
    }
    return nil
    }

    func mapView(_ mapView: BMKMapView!, viewFor annotation: BMKAnnotation!) -> BMKAnnotationView! {
    let view = BMKPinAnnotationView.init(annotation: annotation, reuseIdentifier: "myAnnotation")
    view?.pinColor = 3
    view?.animatesDrop = false
    view?.annotation = annotation

    if locationString == "终点" {
    view?.image = UIImage.init(named: "track_end")
    locationString = ""
    } else if locationString == "起点" {
    view?.image = UIImage.init(named: "track_start")
    locationString = ""
    } else if locationString == "车" {
    view?.image = UIImage.init(named: "track_car")
    locationString = ""
    }

    return view
    }
  3. 获取鹰眼数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    func yingYan() {
    let entityName = String(format: "%@%d", User.sharedInstance.baiduEentityPrefix, sendCarOrder.vehicleId)
    let sop = BTKServiceOption.init(ak: BAIDU_AK, mcode: BAIDU_MODE, serviceID: UInt(BAIDU_SERVICE_ID), keepAlive: false)
    BTKAction.sharedInstance().initInfo(sop)
    //转化成时间戳
    print(chooseDateButton.titleLabel!.text!)
    let start = String(format: "%@ 00:00:00", chooseDateButton.titleLabel!.text!)
    let end = String(format: "%@ 23:59:59", chooseDateButton.titleLabel!.text!)
    let startTime = ZyDateFormatter.baiduDateFormatter.date(from: start)?.timeIntervalSince1970
    let endTime = ZyDateFormatter.baiduDateFormatter.date(from: end)?.timeIntervalSince1970

    DispatchQueue.global().async {
    let option = BTKQueryTrackProcessOption()
    option.denoise = true
    option.vacuate = true
    option.mapMatch = true
    option.radiusThreshold = 100

    let request = BTKQueryHistoryTrackRequest.init(entityName: entityName, startTime: UInt(startTime!), endTime: UInt(endTime!), isProcessed: true, processOption: option, supplementMode: BTKTrackProcessOptionSupplementMode(rawValue: 3)!, outputCoordType: BTKCoordType(rawValue: 3)!, sortType: BTKTrackSortType(rawValue: 1)!, pageIndex: 1, pageSize: 100, serviceID: UInt(BAIDU_SERVICE_ID), tag: 13)

    BTKTrackAction.sharedInstance().queryHistoryTrack(with: request, delegate: self)
    }

    }
  4. BTKTrackDelegate 代理方法中获得数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    func onQueryHistoryTrack(_ response: Data!) {
    let json = JSON(response)

    if json["status"].int == 0 {
    let startTime = json["start_point"]["loc_time"].int!
    let endTime = json["end_point"]["loc_time"].int!

    let duration = endTime - startTime

    totalTime = duration
    self.endTime = endTime

    let minute = duration/60
    let second = duration%60

    DispatchQueue.main.async {
    self.durationLabel.text = String(format:"%02d:%02d",minute, second)
    }

    //去掉经纬度为0的点
    var pointsWithoutZero = [JSON]()
    for point in json["points"].arrayValue {
    let lat = point["latitude"].doubleValue
    let lon = point["longitude"].doubleValue

    if fabs(lat - 0) < 0.001 && fabs(lon - 0) < 0.001 {
    continue
    }
    pointsWithoutZero.append(point)
    }

    self.points = pointsWithoutZero

    var locations = [CLLocationCoordinate2D]()
    var minLat: CLLocationDegrees = 90.0
    var maxLat: CLLocationDegrees = -90.0
    var minLon: CLLocationDegrees = 180.0
    var maxLon: CLLocationDegrees = -180.0

    for point in pointsWithoutZero {
    let lat = point["latitude"].doubleValue
    let lon = point["longitude"].doubleValue

    minLat = min(minLat, lat)
    maxLat = max(maxLat, lat)
    minLon = min(minLon, lon)
    maxLon = max(maxLon, lon)

    locations.append(CLLocationCoordinate2D.init(latitude: lat, longitude: lon))
    }

    //生成轨迹线
    let polyline = BMKPolyline.init(coordinates: &locations, count: UInt(locations.count))

    // 获取轨迹的中心点和经纬度范围,确定轨迹的经纬度区域
    let centerCoor = CLLocationCoordinate2DMake((minLat + maxLat) * 0.5, (minLon + maxLon) * 0.5)
    // 经纬度范围乘以一个大于1的系数,以在绘制轨迹时留出边缘部分
    var viewSapn = BMKCoordinateSpan()
    viewSapn.latitudeDelta = (maxLat - minLat) * 1.2
    viewSapn.longitudeDelta = (maxLon - minLon) * 1.2

    var viewRegion = BMKCoordinateRegion()
    viewRegion.center = centerCoor
    viewRegion.span = viewSapn

    //回主线程绘制轨迹线
    DispatchQueue.main.async {
    if pointsWithoutZero.count > 1 {
    // 设定当前地图的显示范围
    self.mapView.setRegion(viewRegion, animated: true)

    // 向地图窗口添加Overlay,需要实现BMKMapViewDelegate的-mapView:viewForOverlay:方法来生成标注对应的View
    //循环添加用户的起,终坐标
    for index in [0,1] {
    var item = BMKPointAnnotation()

    if index == 0 {
    let coor = CLLocationCoordinate2DMake(pointsWithoutZero[0]["latitude"].doubleValue, pointsWithoutZero[0]["longitude"].doubleValue)
    item.coordinate = coor
    self.mapView.centerCoordinate = coor
    self.locationString = "起点"
    } else {
    let coor = CLLocationCoordinate2DMake(pointsWithoutZero.last!["latitude"].doubleValue, pointsWithoutZero.last!["longitude"].doubleValue)
    item.coordinate = coor
    self.mapView.centerCoordinate = coor
    self.locationString = "终点"
    }

    self.mapView.addAnnotation(item)

    }

    self.mapView.addOverlays([polyline!])


    } else {
    let alert = UIAlertController.init(title: "提示", message: "指定轨迹的轨迹点少于两个,无法绘制", preferredStyle: .alert)
    alert.addAction(UIAlertAction.init(title: "取消", style: .cancel, handler: nil))

    self.present(alert, animated: true, completion: nil)
    }
    }

    }

    }
  5. timer 绘制轨迹

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    @objc func refreshMap() {
    if self.point == points.count {
    timer?.invalidate()
    } else {
    let annotation = BMKPointAnnotation()
    self.mapView.removeAnnotations(self.mapView.annotations)

    var coor = CLLocationCoordinate2D()
    coor.latitude = points[point]["latitude"].doubleValue
    coor.longitude = points[point]["longitude"].doubleValue
    annotation.coordinate = coor
    mapView.centerCoordinate = coor

    if point == 0 {
    locationString = "起点"
    } else if point == points.count - 1{
    locationString = "终点"
    } else {
    locationString = "车"
    }

    let time = points[point]["loc_time"].intValue
    let leftTime = endTime - time

    self.durationLabel.text = String(format:"%02d:%02d",leftTime/60, leftTime%60)

    progressView.progress = Float(point) / Float(points.count - 1)

    mapView.addAnnotation(annotation)
    mapView.selectAnnotation(annotation, animated: true)
    mapView.showsUserLocation = true
    }
    point += 1
    }