ArcGIS Runtime SDK for iOS 开发之地图范围(map extent)

       注:本篇文章翻译自:https://developers.arcgis.com/ios/objective-c/guide/iphonesdk-mapnavigation.htm

       地图视图包含了地图范围被定义和改变的选项。值得注意的是,底图(加载到地图中的第一层图层)定义了下列地图属性:

       初始化范围

       全部范围

       空间参考系

       其中,初始范围可以被改变,而空间参考不可以改变。

       本篇文章主要讨论针对开发者和最终用户的地图范围解决方案。

        设置地图范围

       可以使用zoomToEnvelope:animated:的方法,通过传递一个表示你想要缩放到区域的envelope几何体来设置地图范围。

<span style="font-size:14px;">-(void)viewDidLoad{
  [super viewDidLoad];

 //add a layer to the map
 AGSTiledMapServiceLayer*tiledLayer=[AGSTiledMapServiceLayer tiledMapServiceLayerWithURL:[NSURLURLWithString:@"http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"]];
[self.mapViewaddMapLayer:tiledLayerwithName:@"Tiled Layer"];

  //zoom to an area
 AGSEnvelope *envelope = [AGSEnvelope envelopeWithXmin:-124.83145667 ymin:30.49849464 xmax:-113.91375495  ymax:44.69150688  spatialReference:mapView.spatialReference];
 [self.mapView zoomToEnvelope:envelope animated:NO];
}</span>

      获取地图范围

      在地图被加载前你可能不知道它的范围,但是你可以利用地图视图的visibleArea属性来获取地图的范围。

<span style="font-size:14px;">AGSPolygon* mapExtent = self.mapView.visibleArea;</span>
       其中visibleArea属性返回一个四边形,四个包含坐标的角为地图的四个角,以左上角为起点,以顺时针方向围绕而成。

       如果地图没有做任何旋转,那么由visibleArea四边形所表示的的面积和四边形的面积是一致的。那么你就可以用visibleArea四边形或是它的envelope作为地图的范围。

       然而,不过如果地图发生转动后,那么visibleArea四边形和四边形的外包是不同的。外包(envelope)的面积比多边形的面积稍大,使得它完全包含多边形。在这种情况下,使用visibleArea多边形来获取地图的范围。

       追踪平移和缩放

       地图视图为地图范围的变化提供了两个通知(notifications),AGSMapViewDidEbdPanningNotification和AGSMapViewDidEndZoomingNotification。当地图被平移或是缩放后,这些通知各自被通知。下面的这些代码就是当用户平移或是缩放地图时如何监听这些通知的例子。例子展示了从地图视图的envelope的属性获得的一个新的地图范围提醒。

<span style="font-size:14px;">- (void)mapViewDidLoad:(AGSMapView *)mapView  {

  // register for pan notifications
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToEnvChange:)
    name:AGSMapViewDidEndPanningNotification object:nil];

  // register for zoom notifications
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToEnvChange:) 
    name:AGSMapViewDidEndZoomingNotification object:nil];

  ...
}

// The method that should be called when the notification arises
- (void)respondToEnvChange: (NSNotification*) notification {

  //create the string containing the new map extent NSString*
  NSString* theString = [[NSString alloc] initWithFormat:@"xmin = %f,\nymin =
    %f,\nxmax = %f,\nymax = %f", mapView.envelope.xmin,
    mapView.envelope.ymin, mapView.envelope.xmax,
    mapView.envelope.ymax];

  //display the new map extent in a simple alert
  UIAlertView* alertView = [[UIAlertView alloc]	initWithTitle:@"Finished Panning" 
    message:theString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
  [alertView show];

}</span>
       改变地图范围

       正如前面所述,你可以利用zoomToEnvelop: animated 方法来设定地图范围。你也可以利用centerAtPoint:animated的方法将地图范围设置为以给定的一个点为中心。

<span style="font-size:14px;">AGSPoint *newPoint = [AGSPoint pointWithX:-93.032201 y:49.636213 spatialReference:self.mapView.spatialReference];
[self.mapView centerAtPoint:newPoint animated:NO];</span>

       用户手势

       用户可以在程序运行时执行多种手势操作来改变地图的范围。所有的这些操作都会触发MapDidEndPanning和MapDidEndZooming的通知。  

用户操作地图操作通知
捏住往里缩小地图AGSMapViewDidEndZoomingNotification
捏住往外放大地图AGSMapViewDidEndZoomingNotification
双击放大地图AGSMapViewDidEndZoomingNotification
两只指头单击缩小地图AGSMapViewDidEndZoomingNotification
滑动(任何方向)朝滑动的方向移动地图AGSMapViewDidPanningNotification
两个指头扭转旋转地图 

注:启用AGSMapView中的allowRotationByPinching属性才可以启用两个指头一起扭转的手势。

       启用Wrap around

       世界是圆的,它并不会在日期线终止。然而,许多关于地球的扁平的描述仅是将其延伸至东、西经180度。这使得很难看到跨越日期线的区域或是穿越太平洋的路线。

       但是有了wrap around的支持,就可以看到超越了日期线的无缝扩展的世界地图。东、西半球彼此环绕形成一副连续的地图,从而给人一种地图是无止境的感觉。同时平移地图也变的类似于去旋转地球仪了。

       要启用Wrap around,只要调用AGSMapView的enableWrapAround 方法即可。

<span style="font-size:14px;">//enable wrap around
[self.mapView enableWrapAround];</span>
       约束

      在启用wrap around之前,下面的这些要求必须要满足:

      1)地图的全部外包必须覆盖整个世界。

      2)地图的空间参考系必须是WGS84坐标系(WKID = 4326)或者Web墨卡托(WKID = 102113、102100、3857) 。这就意味着地图中所有的平铺层的参考系必须属于这些参考系中的一个。另一方面,动态层可以是任何一种空间参考,因为它能够重新投影数据。

      3)动态图层必须基于来自于ArcGIS Server10.0或是更高版本中的地图服务。这是因为早期版本的REST API不支持WKT(well-known text)格式的空间参考值,而这在制作支持wrap around的地图服务中又是必须的。
      4)如果这些要求没有得到满足而你又要试图启用wrap around时,那么AGSMapView中的wrapAroundStatus属性就会提示wrap around不支持。

<span style="font-size:14px;">[self.mapView enableWrapAround];
if(self.mapView.wrapAroundStatus == AGSMapViewWrapAroundStatusUnsupported){
  NSLog(@"Wrap around is not supported");
}</span>
       标准化几何体

       为了更好的理解wrap around,我们可以将地图看作是由框架组成的。在经度-180度和+180度之间的部分看作是框架0,这个部分在wrap around未启用时,通常是可见的。与该框架挨着的东面部分看作是框架1,假设延伸在经度+180度和+540度之间。和框架0挨着的西面是框架-1,假设延伸在经度-180度和-540度之间。    

       依据被展示的框架,被地图报告的经度值是真实的(在-180度和+180度之间) 或是假设的(超过-180度和+180度)。这里是一些可能包含假设坐标的几何体的例子:

        1)地图的外包(envelope)

        2)被地图代理报告的触摸坐标

        3)被草图层(sketch layer)数字化的几何体

        当几何体包含假设坐标时,那么在利用它们来进行空间查询或将它们存储进地理数据库前要进行标准化处理。而标准化的过程就是将几何体的坐标从其他框架转化到框架0中来。在程序运行时要检查出几何体是否包含假设坐标以及是否需要进行标准化是困难的,所以在wrap around启用时经常标准化几何体是一种很安全的做法。

        你可以利用AGSGeometryEngine的方法normalizeCentralMeridianOfGeometry:来标准化几何体。

AGSGeometry* geo = ...;

if(self.mapView.wrapAroundStatus == AGSMapViewWrapAroundStatusEnabled){
 geo = [[AGSGeometryEngine defaultGeometryEngine] normalizeCentralMeridianOfGeometry: geo]; 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值