加载底图图层与信息图层
在第一章中讲述了如果集成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];
}
网友评论