Arcgis For Ios和Mapbox For Ios 吐槽

3 篇文章 0 订阅
2 篇文章 0 订阅

公司为了节约成本开始换成了Mapbox 开源免费,最初用的Arcgis ,Arcgis买的时候70多个W,Arcgis手机端支持非常差劲,打电话没有人能给你提供服务,必须邮件,而且他们Ios开发不怎么负责,我们70w买的Arcgis你就这态度?问你个报警动态怎么能实现,原本是没有接口实现,你直接跟我说实现不了就行了,Ios开发给我发了段代码,给个定时器->去修改点的阿尔法,模拟闪光。。。。我地图上几百个点甚至上千个点,你让我这么做?

槽点:
1.文档:
(1).mapbox详细,非常详细,手把手教你了,swift OC都有很全。
(2).Arcgis 挺烂,swift转OC基本上挂羊头卖狗肉,因为项目OC的,swift转OC遇到了很多坑。

2020.12.16====
(3).Arcgis代码封装性比较好,举个例子,arcgis图层加载直接放url就行,mapbox需要先用get请求请求下数据,然后对数据进行处理,需要自己绘制线,相比arcgis,arcgis就方便很多直接使用图层url就可以不需要区分点和线图层。
(4).关于点击方法,mapbox自己加点击方法,arcgis 是自带的tap点击方法,arcgis获取点击图层属性稍微麻烦点,mapbox能直接点出来。

2020.12.22====
(5).mapbox对ios支持不是很好啊,对了下发现没有安卓功能多,先更新下其中一个功能,画区域去获取图层要素:

思路:屏幕中间有个框 放在self.view上,点击方法拿到point,用这个方法去读数据

//把你要获取的图层的IDF标识符写上,因为mapbox创建图层都需要标识符,我建议是把标识符写在pch文件里,因为我的项目的图层是通过geoserver发布的,而且在三个vc里频繁使用
NSSet *idfSet = [NSSet setWithArray:@[Line_1,Line_2,Line_3,Line_4,Line_5,Line_6,Line_7,Line_8,Line_9]];
// 获取图层
NSArray *featureArr = [self.mapBoxmapView visibleFeaturesInRect:self.view.frame inStyleLayersWithIdentifiers:idfSet];
//遍历图层获取所有要素
[featureArr enumerateObjectsUsingBlock:^(MGLPolygonFeature *obj, NSUInteger idx, BOOL * _Nonnull stop) {
//obj.attributes;
//这里建议字典转模型
 XXXPipeNetWorkDataModel *model = [XXXPipeNetWorkDataModel yy_modelWithDictionary:obj.attributes];
}]

6.关于mapbox 的测量距离和测量面积里面没有实现方法,我说下实现思路,arcgis和mapbox一起用才行,主要用到arcgis的测量距离和面积的方法,用贝塞尔曲线画图层,然后专程arcgis对象,用arcgis方法来实现,我下面直接贴代码.

#pragma  mark ---------- 贝塞尔曲线
//我先说下我的需求,这段代码直接复制不能用,需要改东西,只能提供关键代码和思路
//我是面积和距离通过一个标识符来分辨的indexpath 如果是1就是测面 2就是测距
//这个sport就是你添加了点击方法 拿到的那个sport
- (void)beginDrawBezierPathWithPoint:(CGPoint)sport{
    //首先只要点击屏幕就记录点 这边有几个关键的地方需要注意下
    //面积是3个点 距离是2个点 
    [self.savePointArr addObject:@(sport)];
    //   创建一个路径对象
    //  起点
    if (self.savePointArr.count >= 2) {
        //这块是距离 当只有数组里面大于等于2个点才开始链接
        if (self.savePointArr.count == 2) {
            //一共就俩点直接取也行 我习惯了遍历下
            for (int i = 0; i < 2; i++) {
                //取出点坐标
                NSNumber *pointNum = self.savePointArr[i];
                
                CGPoint selectedPoint = [pointNum CGPointValue];
                
                if (i == 0) {
                    //这里是起点
                    [self.mainBezier moveToPoint:selectedPoint];
                }else{
                    //连成一条线
                    [self.mainBezier addLineToPoint:selectedPoint];
                }
            }
           //拿到数组里的点的结构体 
            CGPoint p1 = [self.savePointArr[0] CGPointValue];
            CGPoint p2 = [self.savePointArr[1] CGPointValue];
            //mapbox方法 将点转成Arcgis能用的CLLocationCoordinate2D
            CLLocationCoordinate2D p1_2D = [self.mapBoxmapView convertPoint:p1 toCoordinateFromView:nil];
            CLLocationCoordinate2D p2_2D = [self.mapBoxmapView convertPoint:p2 toCoordinateFromView:nil];
            //转成Arcgis的点
            AGSPoint *agsP1 = [AGSPoint pointWithCLLocationCoordinate2D:p1_2D];
            AGSPoint *agsP2 = [AGSPoint pointWithCLLocationCoordinate2D:p2_2D];
            //Arcgis专门计算距离的方法 你其实不用也可以 百度上能找到 但是我没用过应为我要
            //做面积,后面可以直接拿来用
            double mapArea = [AGSGeometryEngine distanceBetweenGeometry1:agsP1 geometry2:agsP2];
            //距离需要累加 一个全局数组进行存储
            [self.saveLengthArr addObject:@(mapArea)];
            
            NSString *mapAreaStr = [NSString stringWithFormat:@"距离:%fm",mapArea];
          //自己做交互操作
          
        }else{
            //这块就是大于三个点之后的操作要连接前一个点然后算距离
            NSNumber *pointNum = self.savePointArr.lastObject;
            
            CGPoint selectedPoint = [pointNum CGPointValue];
            
            [self.mainBezier addLineToPoint:selectedPoint];
            
            CGPoint p1 = [self.savePointArr[self.savePointArr.count - 1] CGPointValue];
            CGPoint p2 = [self.savePointArr[self.savePointArr.count - 2] CGPointValue];
            
            CLLocationCoordinate2D p1_2D = [self.mapBoxmapView convertPoint:p1 toCoordinateFromView:nil];
            CLLocationCoordinate2D p2_2D = [self.mapBoxmapView convertPoint:p2 toCoordinateFromView:nil];
            
            AGSPoint *agsP1 = [AGSPoint pointWithCLLocationCoordinate2D:p1_2D];
            AGSPoint *agsP2 = [AGSPoint pointWithCLLocationCoordinate2D:p2_2D];
            
            double mapArea = [AGSGeometryEngine distanceBetweenGeometry1:agsP1 geometry2:agsP2];
            
            double allLength = mapArea;
            
            for (NSNumber *lengthNum in self.saveLengthArr) {
                
                allLength = [lengthNum doubleValue] + allLength;
            }
            //这块是我要画出面来算面积了
            if (self.selectedRightItemIndexRow == 1) {
                //三个点成为一个面 
                if (self.savePointArr.count == 3) {
                    //这个是记录贝塞尔曲线是否闭合的一个参数,如果闭合说明继续点击要将闭合的贝塞尔曲线重新打开,然后把线重新连接闭合
                    self.bezierPathIsClose = YES;
                    
                    [self.mainBezier closePath];
                }
            }
          //这里是周长大于2个点之后的显示
            if (self.selectedRightItemIndexRow == 2) {
                
                NSString *mapAreaStr = [NSString stringWithFormat:@"周长:%fm",allLength];
                    
                [self lineAndPiceBtnShow:mapAreaStr];
            }
        }
       // >
        //  设置路径画
        //这块是画面+算面积 前面这个判断就是为了保证唯一性,只有画多边形的时候才进入
        if (self.selectedRightItemIndexRow == 1 && self.bezierPathIsClose == YES && self.savePointArr.count > 3) {
            //首先删除贝塞尔里面所有的点
            [self.mainBezier removeAllPoints];
           
            for (CAShapeLayer *shapeLayer in self.saveAllLayerArr) {
                
                [shapeLayer removeFromSuperlayer];
            }
            
        //    [self.view setNeedsDisplay];
           // 这块就是直接重新画点进行闭合 生成新的面
            for (int i = 0; i < self.savePointArr.count;  i++) {
                
                NSNumber *pointNum = self.savePointArr[i];
                
                CGPoint selectedPoint = [pointNum CGPointValue];
                
                if (i == 0) {
                    
                    [self.mainBezier moveToPoint:selectedPoint];
                }else{
                    
                    [self.mainBezier addLineToPoint:selectedPoint];
                }
            }
            
            [self.mainBezier closePath];
        }
        
        if (self.selectedRightItemIndexRow == 1 && self.savePointArr.count >= 3) {
            //这块是算面积 用Arcgis
            NSMutableArray <AGSPoint *>*newMarr = [NSMutableArray array];
            
            for (NSNumber *numPoint in self.savePointArr) {
                
                CGPoint p = [numPoint CGPointValue];
                
                CLLocationCoordinate2D p1_2D = [self.mapBoxmapView convertPoint:p toCoordinateFromView:nil];
                
                AGSPoint *agsP1 = [AGSPoint pointWithCLLocationCoordinate2D:p1_2D];
                
                [newMarr addObject:agsP1];
            }
           
            AGSPolygon *polygon = [AGSPolygon polygonWithPoints:newMarr];
            
            double mapArea = [AGSGeometryEngine geodeticAreaOfGeometry:polygon areaUnit:[AGSAreaUnit squareMeters] curveType:AGSGeodeticCurveTypeGeodesic];
            
            NSString *mapAreaStr = [NSString stringWithFormat:@"面积:%fm",mapArea];
                
            [self lineAndPiceBtnShow:mapAreaStr];
        }
        
        CAShapeLayer *lineLayer = [CAShapeLayer layer];
        lineLayer.bounds = self.view.bounds;
        lineLayer.position = self.view.layer.position;
        lineLayer.lineWidth = 2.0;
        lineLayer.strokeColor = [UIColor orangeColor].CGColor; //   边线颜色
       // >
        lineLayer.path = self.mainBezier.CGPath;
        
        if (self.selectedRightItemIndexRow == 1) {
            
            lineLayer.fillColor = [[UIColor orangeColor] colorWithAlphaComponent:0.6].CGColor;
        }else{
            
            lineLayer.fillColor = nil;
        }//  默认是black
        
        [self.view.layer addSublayer:lineLayer];
        
        [self.saveAllLayerArr addObject:lineLayer];
    }
}

(6).关于mapbox的表达式,我就搞懂一种.

// CAST 固定写法 building_name是我geojson里面的某个字段 nsstring是类型
//主要是用来显示名字的
NSExpression *ex1 = [NSExpression expressionWithFormat:@"CAST(Building_Name,'NSString')"];
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值