美文网首页ArcGIS学习
ArcGIS for IOS 使用和集成(二)

ArcGIS for IOS 使用和集成(二)

作者: 多喝热开水 | 来源:发表于2020-03-31 10:58 被阅读0次

    加载底图图层与信息图层

    在第一章中讲述了如果集成ArcGIS ,本章我们来讲如何使用ArcGIS 如何加载底图,在底图上加载定位图层等等

    初始化 AGSMapView 加载底图图层

    为了让AGSMapView的业务逻辑更加清晰 我们选择新建一个ArcGISMapView 继承 AGSMapView ,将所有的关于Layer方面的操作都写在 ArcGISMapView 中,以减轻VC的业务压力。

    先看下项目目录:

    FB04C7F0-1761-443D-ABF9-C81B3C5E3E33.png

    在ArcGISMapView.h文件中:

    @interface ArcGISMapView : AGSMapView
    /// 基础图层
    @property (nonatomic, strong) AGSTiledMapServiceLayer *baseMapLayer;
    
    /// 初始化页面
    /// @param baseURL 底图地址
    - (instancetype)initWithFrame:(CGRect)frame BaseURL:(NSString *)baseURL;
    
    /// 设置基础底图图层
    /// @param baseURL 底图地址
    - (void) setupMapBaseLayerWithURL:(NSString *)baseURL;
    
    @end
    

    在ArcGISMapView.m文件中:

     @implementation ArcGISMapView
    
    - (instancetype)initWithFrame:(CGRect)frame BaseURL:(NSString *)baseURL
    {
        self = [super initWithFrame:frame];
        
        if (self) {
            [self setupMapBaseLayerWithURL:baseURL];
        }
        return self;
    }
    
    - (void) setupMapBaseLayerWithURL:(NSString *)baseURL
    {
        NSURL *baseMapURL = [NSURL URLWithString:baseURL];
        AGSTiledMapServiceLayer *baseMapLayer = [AGSTiledMapServiceLayer tiledMapServiceLayerWithURL:baseMapURL];
        self.baseMapLayer = baseMapLayer;
        
        // 插入底图
        [self insertMapLayer:baseMapLayer withName:MAP_BASE_NAME atIndex:0];
    }
    
    

    新建VC ArcGISMapViewController ,在VC中我们将mapView初始化

    @interface ArcGISMapViewController ()<AGSMapViewLayerDelegate>
    
    @property (nonatomic, strong) ArcGISMapView *mapView;
    
    @end
    
    
    @implementation ArcGISMapViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
        
        self.view.backgroundColor = [UIColor whiteColor];
        
        [self.view addSubview:self.mapView];
    }
    
    #pragma mark - AGSMapViewLayerDelegate
    
    - (void)mapViewDidLoad:(AGSMapView *)mapView
    {
        NSLog(@"mapView did load");
        
    }
    
    #pragma mark - init function
    
    - (ArcGISMapView *)mapView
    {
        if (!_mapView) {
            _mapView = [[ArcGISMapView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, kScreenHeight) BaseURL:@"输入你的底图地址"];
            _mapView.layerDelegate = self;
        }
        return _mapView;
    }
    
    @end
    
    

    通过上面的代码即能看到底图被正常的加载到了页面中:


    IMG_6129.PNG

    开启地图自动定位到当前位置并显示周边

    具体效果如如所示


    IMG_6130.PNG

    ArcGIS 与百度地图API还是有很多的不同的,在百度地图里你可能只需要使用BMKUserLocation 这个类就可以轻松展示定位,在ArcGIS中,你需要对AGSMapView 添加指定的图层(Layer) 才可以展示这种定位效果。

    我们新创建类 ArcGISLocationLayer 继承 AGSGraphicsLayer , 需要在这个图层上绘制我们需要的定位效果
    在 ArcGISLocationLayer.h文件中:

    @interface ArcGISLocationLayer : AGSGraphicsLayer
    /// 初始化定位图层
    - (instancetype) initLocationLayer;
    
    /// 更新定位
    /// @param lat 纬度
    /// @param lon 经度
    /// @param radius 区域范围 (米)
    - (void) updateLocationWithLat:(double)lat Lon:(double)lon radius:(double) radius;
    
    @end
    

    在 ArcGISLocationLayer.m文件中:

    @interface ArcGISLocationLayer()
    
    @property (strong, nonatomic )AGSGraphic *locationGraphic;
    
    @property (strong, nonatomic )AGSGraphic *locationCircleGraphic;
    
    @end
    
    @implementation ArcGISLocationLayer
    
    - (instancetype) initLocationLayer
    {
        self = [ArcGISLocationLayer graphicsLayer];
        
        if (self ) {
            
            // 增加定位区域
            [self addGraphic:self.locationGraphic];
            // 添加环形显示区域
            [self addGraphic:self.locationCircleGraphic];
        }
        
        return self;
    }
    
    - (void) updateLocationWithLat:(double)lat Lon:(double)lon radius:(double) radius
    {
       // 当需要展示定位时,让其正常在地图中展示
        self.locationCircleGraphic.visible = YES;
        self.locationGraphic.visible = YES;
        
        AGSPoint *point=[AGSPoint pointWithX:lon y:lat spatialReference:self.mapView.spatialReference];
        
        AGSGeometryEngine *geoEng=[AGSGeometryEngine defaultGeometryEngine];
        AGSPolygon *geBuffer = [geoEng bufferGeometry:point byDistance:[ArcGISCommonToolKit getLocationRadius:radius Lon:point.x Lat:point.y]];
        
        self.locationCircleGraphic.geometry = geBuffer;
        self.locationGraphic.geometry = point;
        
        [self refresh];
    }
    
    #pragma mark - init function
    - (AGSGraphic *)locationGraphic
    {
        if (!_locationGraphic) {
            // 初始化一个(0,0)
            AGSPoint *point=[AGSPoint pointWithX:0 y:0 spatialReference:self.mapView.spatialReference];
            
            // 设置定位到当前的icon样式
            AGSPictureMarkerSymbol *markerSymbol = [[AGSPictureMarkerSymbol alloc] initWithImageNamed:@"gis_location_marker"];
            _locationGraphic = [[AGSGraphic alloc] initWithGeometry:point symbol:markerSymbol attributes:nil];
            
            // 暂时隐藏起来
            _locationGraphic.visible = NO;
        }
        return _locationGraphic;
    }
    
    - (AGSGraphic *)locationCircleGraphic
    {
        if (!_locationCircleGraphic) {
            
            // 初始化一个(0,0)
            AGSPoint *point = [AGSPoint pointWithX:0 y:0 spatialReference:self.mapView.spatialReference];
            
            AGSGeometryEngine *geoEng = [AGSGeometryEngine defaultGeometryEngine];
            
            // 设置定位环周边的距离与颜色 
            AGSPolygon *geBuffer = [geoEng bufferGeometry:point byDistance:[ArcGISCommonToolKit getLocationRadius:200 Lon:point.x Lat:point.y]];
    
            AGSSimpleFillSymbol *outerSymbol = [AGSSimpleFillSymbol simpleFillSymbol];
            outerSymbol.color = [[UIColor blueColor] colorWithAlphaComponent:0.1];
            outerSymbol.outline.color = [[UIColor blueColor] colorWithAlphaComponent:0.5];
            _locationCircleGraphic = [[AGSGraphic alloc] initWithGeometry:geBuffer symbol:outerSymbol attributes:nil];
            
            // 暂时隐藏起来
            _locationCircleGraphic.visible = NO;
        }
        return _locationCircleGraphic;
    }
    
    @end
    

    绘制的图层中有两层 Graphic :
    locationGraphic 展示当前位置icon
    locationCircleGraphic 展示周边区域范围圈
    需要注意的是展示区域里的Distance(-(AGSMutablePolygon)bufferGeometry:(AGSGeometry)geometry byDistance:(double)distance; 这个方法)是根据当前的底图的 geometry's spatial reference 来判断的距离的,所以有 在墨卡托(Mercator)坐标系下,直接可以输入米,但是在经纬度制下需要我们做下转换,我们在这里简单转换一下就可以了,后面我们会详细讲解坐标值的转换问题。
    定义一个新类:ArcGISCommonToolKit 继承NSObject,

    +(double)getLocationRadius:(double)radius Lon:(double)lon Lat:(double)lat
    {
        return fabs(radius/111000*cos(lat));
    }
    

    在ArcGISMapView中我们简单调用下locationLayer里的方法就可以了,记得初始化一下ArcGISLocationLayer,并把该Layer添加到地图中,直接通过:addMapLayer: 方法就可以了

    在ArcGISMapViewController 中我们使用系统的CLLocationManager 来获取到当前的位置,传给 ArcGISMapView (我们定义的mapView)直接使用就可以了:

    #pragma mark 定位成功后则执行此代理方法
    -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    {
        [self.locationmanager stopUpdatingHeading];
        //旧址
        CLLocation *currentLocation = [locations lastObject];
        CLGeocoder *geoCoder = [[CLGeocoder alloc]init];
        //打印当前的经度与纬度
        NSLog(@"%f,%f",currentLocation.coordinate.latitude,currentLocation.coordinate.longitude);
        
        double log = 106.66141382;
        double lat = 29.87969803;
        
        [self.mapView updateLocationWithLat:lat Lon:log radius:300 isZoomMap:YES];
    }
    

    相关文章

      网友评论

        本文标题:ArcGIS for IOS 使用和集成(二)

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