iOS使用百度地图绘制轨迹遇到的坑

路线绘制完毕的时候,想要截图,但是死活不能截取到完整的“起点”+“终点”图片,即使在截图之前将地图的centerCoordinate设置成中点,然后设置2s延时后再截图,也还是只能截取到以终点为中点的图片。并不是设置center无效,地图会闪一下中点的位置,然后还是回归到终点的位置,然后截图。但是!但是!当地图加载后,我人为地拉动一下地图,那么在截图的时候,竟然可以设置中点成功,并截取到完整的图片。这个问题纠结了一个礼拜。(问题看不懂的:我搜索了一下如何上传视频,但是貌似简书的markdown不支持视频,但是我又不想用回富文本,所以,只能用文字描述了。)

灵光一闪

今天突然想到将这个设置成no:_mapView.showsUserLocation = NO; 这样的话,就需要自己实现定位图片的一些功能,譬如箭头图标;设备运动方向变化的时候,箭头要跟着指向前进的方向;还有就是随着定位的变化而变化位置。
我猜想的是,百度地图在我停止更新地点然后设置中点的时候,还会在某个回调中将当前位置设置成中点,但是拖动地图打断了它的这种回调。所以,我干脆就不让它来帮我showUserLocation,我自己来显示好了。这样子一改,确实解决了问题。但是在模拟器上开车跑的时候(看本文“收获”小节),结束定位来截图的时候,还有可能会定位到当前位置,导致截图不完整,但这个现象只出现了一次,然后无法重现,所以我暂时先不管了,毕竟我这个App是给用户绘制走路路线的。

关键代码

#pragma mark - update heading
-(void)BMKLocationManager:(BMKLocationManager *)manager didUpdateHeading:(CLHeading *)heading
{
    //magneticHeading: 距离磁北方向的角度
    //trueHeading: 真北
    //headingAccuracy: 如果是负数,代表当前设备朝向不可用
    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) {
            //角度,因为箭头图片向右方,所以逆时针转90度
            CLLocationDirection angle = heading.magneticHeading-90.f;
            //顺时针旋转图片(弧度)
            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;
        //构建分段颜色索引数组
        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 - 设置起点、终点和当前点样式
-(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需要设置成-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. 使用百度地图绘制路线,可以使用模拟器来进行模拟人的走动,或者车跑,或者自定义位置。
    打开模拟器,去到导航栏,点击Debug,如下图,


    模拟器模拟运动
  2. 我写了NSMutableArray *overlays和annotations来存储添加的层和线,原来mapview自己会保存,删除的时候使用这个就OK了。

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

感谢

https://www.jianshu.com/p/ae94bfd7da3a

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342