iOS使用百度地圖繪制軌跡遇到的坑

路線繪制完畢的時候,想要截圖,但是死活不能截取到完整的“起點”+“終點”圖片,即使在截圖之前將地圖的centerCoordinate設(shè)置成中點,然后設(shè)置2s延時后再截圖,也還是只能截取到以終點為中點的圖片。并不是設(shè)置center無效,地圖會閃一下中點的位置,然后還是回歸到終點的位置,然后截圖。但是!但是!當?shù)貓D加載后,我人為地拉動一下地圖,那么在截圖的時候,竟然可以設(shè)置中點成功,并截取到完整的圖片。這個問題糾結(jié)了一個禮拜。(問題看不懂的:我搜索了一下如何上傳視頻,但是貌似簡書的markdown不支持視頻,但是我又不想用回富文本,所以,只能用文字描述了。)

靈光一閃

今天突然想到將這個設(shè)置成no:_mapView.showsUserLocation = NO; 這樣的話,就需要自己實現(xiàn)定位圖片的一些功能,譬如箭頭圖標;設(shè)備運動方向變化的時候,箭頭要跟著指向前進的方向;還有就是隨著定位的變化而變化位置。
我猜想的是,百度地圖在我停止更新地點然后設(shè)置中點的時候,還會在某個回調(diào)中將當前位置設(shè)置成中點,但是拖動地圖打斷了它的這種回調(diào)。所以,我干脆就不讓它來幫我showUserLocation,我自己來顯示好了。這樣子一改,確實解決了問題。但是在模擬器上開車跑的時候(看本文“收獲”小節(jié)),結(jié)束定位來截圖的時候,還有可能會定位到當前位置,導(dǎo)致截圖不完整,但這個現(xiàn)象只出現(xiàn)了一次,然后無法重現(xiàn),所以我暫時先不管了,畢竟我這個App是給用戶繪制走路路線的。

關(guān)鍵代碼

#pragma mark - update heading
-(void)BMKLocationManager:(BMKLocationManager *)manager didUpdateHeading:(CLHeading *)heading
{
    //magneticHeading: 距離磁北方向的角度
    //trueHeading: 真北
    //headingAccuracy: 如果是負數(shù),代表當前設(shè)備朝向不可用
    if (heading.headingAccuracy < 0) {
        return ;
    }

    if (!self.userLocation) {
        self.userLocation = [[BMKUserLocation alloc] init];
    }
    self.userLocation.heading = heading;
    [self.mapView updateLocationData:self.userLocation];
    for (UIView *subView in self.arrowView.subviews) {
        if ([subView isKindOfClass:[UIImageView class]] && subView.tag == 10000000) {
            //角度,因為箭頭圖片向右方,所以逆時針轉(zhuǎn)90度
            CLLocationDirection angle = heading.magneticHeading-90.f;
            //順時針旋轉(zhuǎn)圖片(弧度)
            subView.transform = CGAffineTransformMakeRotation(angle*M_PI/180.f);
        }
    }
}
#pragma mark - update location
-(void)BMKLocationManager:(BMKLocationManager *)manager didUpdateLocation:(BMKLocation *)location orError:(NSError *)error
{
    if (error) {
        NSLog(@"locError:{%ld - %@};", (long)error.code, error.localizedDescription);
    }
    if (!location) {
        return ;
    }
    if (!self.userLocation) {
        self.userLocation = [[BMKUserLocation alloc] init];
    }
    
    self.userLocation.location = location.location;
    [self.mapView updateLocationData:self.userLocation];
    //地圖放縮大小,4-21
    self.mapView.zoomLevel = 21;
    self.mapView.centerCoordinate = CLLocationCoordinate2DMake(self.userLocation.location.coordinate.latitude, self.userLocation.location.coordinate.longitude);
    
    if (self.arrow) {
        [self.mapView removeAnnotation:self.arrow];
    }
    
    BMKPointAnnotation *arrow = [[BMKPointAnnotation alloc] init];
    arrow.coordinate = CLLocationCoordinate2DMake(self.userLocation.location.coordinate.latitude, self.userLocation.location.coordinate.longitude);
    arrow.title = kArrowTitle;
    [self.mapView addAnnotation:arrow];
    self.arrow = arrow;
    
    if(self.isStartTrace)
    {
        CGFloat distance = [self.userLocation.location distanceFromLocation:self.firstLocation.location];
        if (distance < 10) {
            return ;
        }
        
        CLLocationCoordinate2D coords[2] = {0};
        coords[0].latitude = self.firstLocation.location.coordinate.latitude;
        coords[0].longitude = self.firstLocation.location.coordinate.longitude;
        coords[1].latitude = location.location.coordinate.latitude;
        coords[1].longitude = location.location.coordinate.longitude;
        //構(gòu)建分段顏色索引數(shù)組
        BMKPolyline *polyline = [BMKPolyline polylineWithCoordinates:coords count:2];
        [self.mapView addOverlay:polyline];
        [self.points addObject:location];
        
        self.firstLocation = [self.userLocation copy];
    }
}
#pragma mark - 繪制軌跡點
-(void)drawTrackWithPoints:(NSArray *)points
{
    NSLog(@"points: %@", points);
    
    CLLocationCoordinate2D coors[points.count];
    NSInteger cnt = 0;
    for (size_t i = 0; i < points.count; i++) {
        CLLocationCoordinate2D p = CLLocationCoordinate2DMake(((BMKLocation *)points[i]).location.coordinate.latitude, ((BMKLocation *)points[i]).location.coordinate.longitude);
        coors[i] = p;
        cnt++;
    }
    BMKPolyline *line = [BMKPolyline polylineWithCoordinates:coors count:cnt];
    //起點annotation
    BMKPointAnnotation *startAnnotation = [[BMKPointAnnotation alloc] init];
    startAnnotation.coordinate = coors[0];
    startAnnotation.title = kStartPositionTitle;
    //終點annotation
    BMKPointAnnotation *endAnnotation = [[BMKPointAnnotation alloc] init];
    endAnnotation.coordinate = coors[cnt-1];
    endAnnotation.title = kEndPositionTitle;

    dispatch_async(MAIN_QUEUE, ^{
        [self.mapView removeOverlays:self.mapView.overlays];
        [self.mapView removeAnnotations:self.mapView.annotations];
        [self mapViewFitForCoordinates:points];
        [self.mapView addOverlay:line];
        [self.mapView addAnnotation:startAnnotation];
        [self.mapView addAnnotation:endAnnotation];
    });
}
#pragma mark - 設(shè)置起點、終點和當前點樣式
-(BMKAnnotationView *)mapView:(BMKMapView *)mapView viewForAnnotation:(id<BMKAnnotation>)annotation
{
    BMKAnnotationView *view = nil;
    
    if ([annotation.title isEqualToString:kStartPositionTitle]) {
        static NSString *startViewID = @"startAnnotationID";
        view = [mapView dequeueReusableAnnotationViewWithIdentifier:startViewID];
        if (view == nil) {
            view = [[BMKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:startViewID];
            UILabel *lbl = [self createLabel:@"始"];
            [view addSubview:lbl];
        }
    }
    else if([annotation.title isEqualToString:kEndPositionTitle]){
        static NSString *endViewID = @"endAnnotationID";
        view = [mapView dequeueReusableAnnotationViewWithIdentifier:endViewID];
        if (view == nil) {
            view = [[BMKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:endViewID];
            UILabel *lbl = [self createLabel:@"終"];
            [view addSubview:lbl];
        }
    }
    else if([annotation.title isEqualToString:kArrowTitle]){
        static NSString *runningArrowID = @"runningArrowAnnotationID";
        view = [mapView dequeueReusableAnnotationViewWithIdentifier:runningArrowID];
        if (view == nil) {
            view = [[BMKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:runningArrowID];
            view.frame = CGRectMake(0, 0, 22, 22);
            view.draggable = NO;
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];
            imageView.transform = CGAffineTransformMakeRotation((self.firstLocation.heading.magneticHeading-90.f)*M_PI/180.f);
            imageView.image = [UIImage imageNamed:@"sportArrow.png"];
            imageView.tag = 10000000;
            [view addSubview:imageView];
        }
        self.arrowView = view;
    }
    return view;
}

-(UILabel *)createLabel:(NSString *)text
{
    //label的frame x, y需要設(shè)置成-15,不然“始”會有一截沒有連線的
    UILabel *lblStart = [[UILabel alloc] initWithFrame:CGRectMake(-15, -15, 30, 30)];
    lblStart.backgroundColor = CSecondaryColor;
    lblStart.font = [UIFont systemFontOfSize:14.0];
    lblStart.textAlignment = NSTextAlignmentCenter;
    lblStart.textColor = [UIColor whiteColor];
    lblStart.layer.cornerRadius = 15;
    lblStart.layer.borderWidth = 1;
    lblStart.layer.masksToBounds = YES;
    lblStart.layer.borderColor = [UIColor darkGrayColor].CGColor;
    lblStart.text = text;
    return lblStart;
}
-(void)mapViewFitForCoordinates:(NSArray *)points
{
    double minLat = 90.0;
    double maxLat = -90.0;
    double minLon = 180.0;
    double maxLon = -180.0;
    for (size_t i = 0; i < points.count; i++) {
        minLat = fmin(minLat, ((BMKLocation *)points[i]).location.coordinate.latitude);
        maxLat = fmax(maxLat, ((BMKLocation *)points[i]).location.coordinate.latitude);
        minLon = fmin(minLon, ((BMKLocation *)points[i]).location.coordinate.longitude);
        maxLon = fmax(maxLon, ((BMKLocation *)points[i]).location.coordinate.longitude);
    }
    CLLocationCoordinate2D center = CLLocationCoordinate2DMake((minLat+maxLat)*0.5, (minLon+maxLon)*0.5);
    BMKCoordinateSpan span;
    span.latitudeDelta = 1.2 * ((maxLat-minLat)+0.01);
    span.longitudeDelta = 1.2 * ((maxLon - minLon)+0.01);
    BMKCoordinateRegion region;
    region.center = center;
    region.span = span;
    [self.mapView setRegion:region animated:YES];
}

收獲

  1. 使用百度地圖繪制路線,可以使用模擬器來進行模擬人的走動,或者車跑,或者自定義位置。
    打開模擬器,去到導(dǎo)航欄,點擊Debug,如下圖,


    模擬器模擬運動
  2. 我寫了NSMutableArray *overlays和annotations來存儲添加的層和線,原來mapview自己會保存,刪除的時候使用這個就OK了。

        [self.mapView removeOverlays:self.mapView.overlays];
        [self.mapView removeAnnotations:self.mapView.annotations];

感謝

http://www.itdecent.cn/p/ae94bfd7da3a

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容