美文网首页
iOS地图结构体数组坐标构造

iOS地图结构体数组坐标构造

作者: 数字d | 来源:发表于2019-05-31 17:34 被阅读0次

    使用地图API开发前前后后也有三年了吧,从使用高德转战腾讯,对这个地图坐标构造数组总是不太熟悉,每次遇到了就查资料粘贴复制,耽误时间,这里记录一下,方便未来查找。

    1.腾讯地图3D配置方案https://lbs.qq.com/ios_v1/guide-3d.html

    常规流程,
    添加sdk,
    添加bundle资源文件(这里最好添加上,否则第一次加载地图资源会出现各种意想不到的问题)
    -ObjC,
    添加各种依赖

    2.0设置起点和终点的位置

        QPointAnnotation * startAnnotation;
        QPointAnnotation * endAnnotation;
    
        NSString * startLat = @"19.967205";
        NSString * startLon = @"110.410133";
        
        NSString * endLat = @"20.040722";
        NSString * endLon = @"110.231647";
    
        self.annotations = [NSMutableArray array];
        
        startAnnotation = [[QPointAnnotation alloc] init];
        startAnnotation.coordinate = CLLocationCoordinate2DMake([startLat doubleValue],[startLon doubleValue]);
        [self.annotations addObject:startAnnotation];
        
        endAnnotation = [[QPointAnnotation alloc] init];
        endAnnotation.coordinate = CLLocationCoordinate2DMake([endLat doubleValue],[endLon doubleValue]);
        [self.annotations addObject:endAnnotation];
        [self.mapView addAnnotations:self.annotations];
    
    

    2.1设置起点和终点的UI

    自定义一个CustomAnnotationView类

    @interface CustomAnnotationView : QAnnotationView
    

    自定义遮盖物子类基本代码实现

    - (instancetype)initWithAnnotation:(id<QAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
    {
        if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier])
        {
            
            self.bounds = CGRectMake(0, 0, 24, 38);
            [self setupLabelAndImage];
            self.centerOffset = CGPointMake(0, 0);
            self.backgroundColor = [UIColor clearColor];
        }
        
        return self;
    }
    
    -(void)setIconImageStr:(NSString *)iconImageStr
    {
        _iconImageStr = iconImageStr;
        UIImage * image = [UIImage imageNamed:_iconImageStr];
        self.imageView = [[UIImageView alloc] initWithImage:image];
        self.imageView.frame = CGRectMake(0, 0, 24, 38);
        [self addSubview:self.imageView];
    }
    
    

    2.2地图添加遮盖物代理

    - (QAnnotationView *)mapView:(QMapView *)mapView viewForAnnotation:(id<QAnnotation>)annotation
    {
        if ([annotation isKindOfClass:[QPointAnnotation class]])
        {
            static NSString *pointReuseIndetifier = @"pointReuseIndetifier";
            CustomAnnotationView *annotationView = (CustomAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndetifier];
            
            if (annotationView == nil)
            {
                annotationView = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndetifier];
            }
            annotationView.canShowCallout   = NO;
            
            if (annotation == startAnnotation) {
                annotationView.iconImageStr = @"map_icon_origin";
            }else if(annotation == endAnnotation)
            {
                annotationView.iconImageStr = @"map_icon_destination";
            }else
            {
                annotationView.iconImageStr = @"order_icon_finish";
            }
            return annotationView;
        }
        return nil;
        
        
    }
    
    

    3.路线规划服务 https://lbs.qq.com/webservice_v1/guide-road.html

    腾讯地图webserviceAPI提供的算路接口,通过get请求传入起点和终点坐标,可以规划出一条路线。返回的规划数据中,坐标点集polyline会有压缩。

    4.0坐标解压服务

    https://lbs.qq.com/webservice_v1/guide-road.html#link-seven
    腾讯地图解压缩示例

    var coors=[127.496637,50.243916,-345,-1828,19867,-26154];
    for (var i = 2; i < coors.length ; I++)
    {coors[i] = coors[i-2] + coors[i]/1000000}
    

    iOS中解压缩的简单实现方案

    self.arr = @[@"127.496637",@"50.243916",@"-345",@"-1828",@"19867",@"-26154"];
        NSUInteger count = self.arr.count;
        NSMutableArray * arra = [NSMutableArray arrayWithArray:self.arr];
    
    //    解压缩坐标实现
            for (int i = 2 ; i < arra.count; i ++) {
                double v0 = [arra[i - 2] doubleValue];
                double v1 = [arra[i] doubleValue] / 1000000;
                double vTotal = v0 + v1;
                NSNumber * number = [NSNumber numberWithDouble:vTotal];
                NSMutableArray *newArray = [arra mutableCopy];
                [newArray replaceObjectAtIndex:i withObject:number];
                arra = newArray;
            }
        NSLog(@"%@",arra);
    
    

    \color{red}{5.0构造坐标点串并展示}

    https://lbs.qq.com/ios_v1/guide-3d.html

    //    构造结构体数组实现并且赋值
        int vCount = (int)count / 2;
        CLLocationCoordinate2D coordinateArry[vCount];
            for (int i = 0; i < count ;i += 2) {
                double vLat = [arra[i] doubleValue];
                double vLon = [arra[i + 1] doubleValue];
                int v = i / 2;
                coordinateArry[v].latitude = vLat;
                coordinateArry[v].longitude = vLon;
            }
    //    展示折线到地图上
            QPolyline *walkPolyline = [QPolyline polylineWithCoordinates:coordinateArry count:vCount];
            [self.mapView addOverlay:walkPolyline];
    
    

    5.1地图覆盖物代理

    - (QOverlayView *)mapView:(QMapView *)mapView viewForOverlay:(id<QOverlay>)overlay
    {
        QPolylineView *polylineView = [[QPolylineView alloc] initWithPolyline:overlay];
        polylineView.lineWidth = 8;
        polylineView.lineDashPattern = nil;
        polylineView.strokeColor = [UIColor greenColor];
        return polylineView;
    }
    
    

    6.效果图示:

    Simulator Screen Shot - iPhone 7 - 2019-05-31 at 15.59.09.png

    7.代码地址https://github.com/xgkp/TencentMapDrawLine.git

    备注:由于腾讯地图的sdk大于100M,所以上传代码时候我将有一个文件目录/Vender添加到了gitignore文件里去了,如果要运行代码,请自行添加。目录图示:

    zz.png

    8.一点思考和艰辛的曲折

    如图:
    图示:


    zzz.png zc.png

    腾讯地图有一个

    + (QPolyline *)polylineWithCoordinates:
    (CLLocationCoordinate2D *)coords count:(NSUInteger)count;
    

    方法,这个方法实际的效果是将所有的点集合进行展示。

    中间的CLLocationCoordinate2D参数,这个参数从最后一张图看起来是一个C的结构体,但奇怪的是,后面又跟了一个count参数,这个不是表示数组长度的么,嗯?

    既然coords存储的是一个数组类型的参数,那就和CLLocationCoordinate2D这个类型是结构体相互矛盾。

    这个就造成了我的困惑,饶了一大个弯路。

    我一看是数组呀,好办,就写一个for 循环,用坐标来遍历坐标数组,构造CLLocationCoordinate2D类型的数据,放到一个最终的数组中,在向iOS数组中添加这个CLLocationCoordinate2D类型的对象时候,报错, zcc.png

    我一看,这个貌似是OC中的数组不能存储这个结构体类型,需要转成其他类型才能存吧。
    这里,又赶快去找了OC下可以存结构体的方法:

     NSValue包装对象指针,CGRect结构体等
     一个NSValue对象是用来存储一个C或者Objective-C
    数据的简单容器,它可以保存任意类型的数据.
    比如int , float , char ,当然也可以是指pointers,structures, 
    and object ids .
    NSValue类的目标就是允许以上数据类型的数据结构能够被添加到集合里,
    例如那些需要其元素是对象的数据结构,
    如NSArray 或者NSSet的实例.
    需要注意的是NSValue对象一直是不可枚举的
    

    直接上代码

    
        NSMutableArray * arraaa = [NSMutableArray arrayWithCapacity:0];
        CLLocationCoordinate2D coor = CLLocationCoordinate2DMake(19.000000, 110.000000);
    //    [arraaa addObject:coor];
        NSValue *va = [NSValue valueWithBytes:&coor objCType: @encode(CLLocationCoordinate2D)];
        [arraaa addObject:va];
    
        }
    

    这样写居然不报错,我猜,这个应该搞定了吧。

    接着下一步emm


    z2.png

    点击Fix,哇塞,居然不报错了,看到曙光了

       for (int i = 0; i < arra.count; i += 2) {
            double vLat = [arra[i] doubleValue];
            double vLng = [arra[i + 1] doubleValue];
            CLLocationCoordinate2D coor = CLLocationCoordinate2DMake(vLat, vLng);
            NSValue *va = [NSValue valueWithBytes:&coor objCType: @encode(CLLocationCoordinate2D)];
              [arraaa addObject:va];
        }
        
        
        QPolyline *Polyline1 = [QPolyline polylineWithCoordinates:(__bridge CLLocationCoordinate2D *)(arraaa) count:vCount];
        [self.mapView addOverlay:Polyline1];
    
    

    运行一下,emm没显示,空白一片。到此感觉到了应该是用bridge将OC数组直接强转成坐标格式的结构体数组还是有问题的,到现在也没明白。

    于是转换思路,既然要的是结构体,那只能从一开始就创建成结构体数组该有的样子才行。

        CLLocationCoordinate2D coordinateArry[vCount];
    

    这个创建好了,但是没有set方法,没有addObject方法,又卡住了!!!emmm,尴尬也不知道哪里来了印象,貌似是用下标来赋值的,尝试赋值。


    z22.png

    下标值不是数组,指针,向量,难道结构体不是这样来取的吗,居然没我想要的struct。哼~快没辙了。
    下班回家,不想了~~

    最近一到下班时候就雷雨,不过每天有彩虹看~~~

    zzzz.jpeg zzzzzz.png

    回去还是不甘心,就翻开腾讯地图的iOS3D地图的api介绍,突然想到貌似demo中有写多边形和折线的画法,看下那个数据是怎么构造的,或许有解决办法。

    最后居然看到了令我惊奇的一幕~~~


    z1.png

    真想给自己一嘴巴子,耽误那么久,居然这里有现成的!!!
    总是想着用下标来取,却没注意结构体是要直接调出属性一样的来赋值....

    跌宕起伏~~~~~~~

    相关文章

      网友评论

          本文标题:iOS地图结构体数组坐标构造

          本文链接:https://www.haomeiwen.com/subject/ihhwtctx.html