ArcGIS Runtime SDK for iOS

ArcGIS Runtime SDK for iOS(以前被称为ArcGIS API for iOS),通过它可以在您的iOS应用程序中显示地图并执行GIS分析功能。该SDK包括:

1) 一个提供了方便灵活的类集合的Objective-C的API,使用通用的模型来简化自定义应用程序的开发过程。如果您对Esri的任意一种Web API有所了解,如Javascript,Flex或Sliverlight,或移动API如Android或Windows Phone,您就会发现这些API中许多概念都是相似的,这样您可以充分利用您现有的知识和技巧。

2) 提供概念式的帮助文档和API参考文档,来帮助您了解如何使用API。

3) 提供突出讲解API中重点功能的示例模版。

您可以使用API来做什么?

使用API您可以:

1) 显示和使用从ArcGIS Online和(或)ArcGIS Server聚合的服务。

2) 显示www.ArcGIS.com或ArcGIS 门户上的web地图。

3) 执行复杂的地理处理任务并显示返回结果。

4) 使用空间或SQL标准来进行搜索,查询和辨识要素。

5) 显示弹出式窗口要素的信息。

6) 通过地图绘制或使用设备的GPS感应器来采集位置。

7) 匹配地址的位置,反之亦然。

8) 执行几何操作和计算几何形状之间的关系。

API都包括什么?

API为您提供了可以用于iOS应用程序中的以下资源:

1) 地图和图层 – API支持动态地图和瓦片地图的显示。通过ArcGIS Runtime SDK for iOS,您可以在任何工程里显示地图。

2) 图形 – 您可以允许用户绘制,或当用户在图形要素上单击时弹出信息窗口,以此来提升您的应用程序的用户体验性能。

3) 任务 – 常用的GIS任务如要素的查询,搜索和辨识,地址查找,GP工具和采集等。

开始学习

安装

开始前您需要做什么

在使用ArcGIS Runtime SDK for iOS开发iOS应用程序前,您需要做如下一些事情:

开发环境要求

使用ArcGIS Runtime SDK for iOS开发应用程序需要一台运行雪豹(OS X 10.6.2 或更高版本)或狮子(OS X 10.7 或更高版本)的基于Intel内核的操作系统的Macintosh电脑。

苹果官方的iOS SDK

您首先需要完成注册才能成为正式的开发者,因为苹果官方要求必须通过注册后才可以下载IOS SDK。要完成这一步,请转到注册页面并完成注册过程。

当注册完成后,您可以转到iOS开发中心,登录之后下载iOS SDK到您的设备上。SDK包含了文档,框架,工具和一个用来帮助开发iOS应用程序的模拟器,也包含了 Xcode(iOS应用程序的开发者工具集),这样您就不需要购买任何的开发者工具集-因为这个已经包含在注册费里。

您需要使用IOS SDK4或更高版本来开发应用程序。在编写这个文档的时候,IOS SDK 5.1是目前最高的版本。

说明:

一般情况下不支持iOS SDK的测试版和GM种子,除非另有说明。

不管您用于开发的iOS SDK是什么版本的,通过配置 Xcode工程的IOS目标发布构建设置,您的应用程序仍然可以运行在较旧的iOS版本的设备上。

设备要求

使用ArcGIS Runtime SDK for iOS创建的应用程序可以运行在iPhone 3G, iPhone 3GS, iPhone 4, iPhone 4S, iPod touch, iPad, 和 iPad 2 设备上,这些设备必须安装的是IOS4或更高版本,我们强烈建议您在一台真机上来测试应用程序以确保它们可以如预想一样正常运行,单纯在模拟器中测试不能确保应用程序在真机上也能同样正常运行。

安装ArcGIS Runtime SDK for iOS

当您安装完iOS SDK后,您需要下载并安装ArcGIS Runtime SDK for iOS,这些可以在资源中心找到,通过安装向导把SDK组件安装到${HOME}/Library/SDKs/ArcGIS下。

API库文件,头文件和相关的资源(图片等等)都被做为一个名为ArcGIS.framework的框架来进行安装。

说明:

${HOME}/Library文件夹在狮子操作系统下默认是隐藏的,您可以在终端上发送命令来取消隐藏。

使用示例

ArcGIS Runtime SDK for iOS提供了一组示例应用,这些示例重点介绍了API和常用组件中一些可用的功能,以及一些使用API进行的练习操作。这些示例可以帮助您快速开发应用程序。

安装在磁盘上的示例

当您安装ArcGIS Runtime SDK for iOS SDK时,一个简单的示例,MapViewDemo,也同时安装到了磁盘上,这个示例位于${HOME}/Library/SDKs/ArcGIS/Samples/MapViewDemo路径下。这些示例是做为 Xcode工程来提供的,这样您可以通过简单的双击. Xcodeproj 文件来打开它们,当打开后,您可以通过单击工具条上的Build and Run按钮来在 Xcode中快速运行这些示例。

这个示例说明了您该怎么创建一个包含了地图视图,一个切片地图服务图层和一个动态地图服务图层的基本的应用程序。

通过运行示例,你可以很容易地检验SDK是否成功地安装到了您的电脑上,并且您的系统是否满足使用API的需要。

arcgis.com上的示例

在www.arcgis.com上的ArcGIS for iOS Developer Samples菜单下有很多可用的示例,这些示例是以zip文件的形式提供的,里面包含了整个 Xcode工程。您需要下载zip文件,解压然后双击 Xcodeproj来在 Xcode中打开示例,通过这些步骤您可以轻松创建并运行这些示例程序。

请定期检查这个菜单下的内容来及时获取更新的和新增的示例,您也可以发送反馈和建议到iOSDevTeam@esri.com邮箱中。

故障问题诊断

有些示例可能从开始就不能正常创建或运行,下面有一些方案可以帮助您诊断并解决这些问题。

相应的SDK

如前面提到的,每个示例都是做为一个包含了源代码,图形和 Xcode-specific工程文件的完整的 Xcode工程来提供的,这些工程文件存储了许多常用的设置如框架和组件库,使用的SDK,创建的目标文件等等。

通常当一个示例没有正确创建的时候,很可能是因为引用的您本机上的IOS SDK不可用。这是很常见的,例如,如果您安装的是一个最新版本的IOS SDK,而这个SDK版本比这个示例使用的SDK版本高,在这种情况下, Xcode的工具栏菜单的Overview上会显示一个Base SDK Missing的警告。

为了解决问题,您需要更新相应的SDK设置。您可以选择工程菜单下的Edit Active Target选项,这个将会弹出信息窗口,然后,在Build选项卡下,通过选择一个已经安装在您机器上的IOS SDK来更新相应的SDK设置。

在做任何改动之前都必须考虑一件事情,那就是确保您已经做了正确的配置和修改。默认有2个配置:Release 和Debug,分别用来创建Release 和Debug版本的应用程序,在许多设置中,例如相应的SDK,这两种配置通常是保持不变的。当您修改这些配置的时候,记得要对每个配置都做修改,您可以通过分别修改每个配置来完成这个操作,或者通过选择All Configurations option选项来同时修改这两项。

v/s模拟器

示例程序不能正常创建的另一个常见的原因是,看是否工程是配置为在设备上运行的。在这种情况下,您可能会遇到如下显示的错误:

避免这个错误最简单的方式是在模拟器中来运行示例,您可以通过在工具栏菜单中选择Simulator选项来运行。

如果您想在设备上运行实例,那么需要做如下几件事情:

1. 您需要从苹果官方获得一个有效的开发资格证明,这个证明需要安装在您的设备上,您可以从iOS Provisioning 门户(需要用您的苹果官方ID进行登录)上了解关于这个证明更详细的介绍。

2. 您还需要从iOS Provisioning 门户上创建一个开发配置文件并且把它安装到开发环境设备和每台您准备使用的IOS设备上。这个开发配置文件是用来对一个由开发者(由开发者资格证明来指定)创建的应用程序(由App ID来指定)进行授权的,从而使这个应用程序可以在设备上运行。您可以找到更多有关iOS开发指南中和iOS开发者计划用户指南中管理设备和数字身份认证环节的资料(需要用您的Apple ID进行登录)。

您还需要对工程做如下的改动:

1. 您需要修改示例程序的App ID,在工程菜单下,选择Edit Active Target选项,将打开一个信息窗口,然后在Properties选项卡下通过把开发配置文件中的App ID替换为"com.yourcompany"来修改Identifier属性。

2. 您需要对应用程序做数字签名认证,在工程菜单下,选择Edit Active Target选项,将弹出一个信息窗口,然后,在Build选项卡下,向下滚动到Code Signing Identify选项,然后选择您的开发配置文件来对应用程序做数字签名。

苹果官方的技术说明文档TN2250有更多关于代码签名过程的介绍。

当您完成了这些步骤之后,确保您的设备已经连接到开发环境所在的设备上,然后构建和运行工程,这个示例应用会安装在设备上然后自动启动。

配置一个 Xcode工程

Xcode是用于开发iOS应用程序的集成开发环境(IDE), Xcode可以单独下载或做为IOS SDK的一部分从Apple's iOS Dev Center下载。在编写这个文档的时候, Xcode4.3.1是当前最新的版本。

您可以使用一个内置的IOS工程模版来创建一个工程,然后配置它使其能够用ArcGIS Runtime SDK for iOS进行开发。

说明:

您们当中有些人可能会注意到,ArcGIS特定的 Xcode项目模板已经不能使用,这是因为第三方项目模版不受 Xcode的官方支持了。

添加ArcGIS的框架搜索路径

为了把ArcGIS的框架添加到您的工程中,要在左侧的导航面板中选择工程的节点,选择一个目标节点然后选择Build Settings选项卡。

在这个选项卡下,在搜索栏中输入“Framework Search Paths”来快速查找Framework Search Paths的设置,在目标列下面的空白处双击,然后使用加号按钮来添加如下的项:

$(HOME)/Library/SDKs/ArcGIS/**

添加依赖库

ArcGIS的框架依赖于以下需要被添加到您的项目设置中的框架和库。

  • CoreGraphics.framework
  • CoreLocation.framework
  • Foundation.framework
  • QuartzCore.framework
  • UIKit.framework
  • CoreText.framework (在v1.8版本中推出的)
  • libstdc++.dylib (在v1.8版本中推出的)
  • MediaPlayer.framework (在v2.0版本中推出的)
  • MobileCoreServices.framework (在v2.0版本中推出的)
  • libz.dylib (在v2.1版本中推出的)
  • Security.framework (在v2.1版本中推出的)

选择Build Phases选项卡,在Link Binary with Libraries选项的下面,单击+按钮,选择并添加每一个选项。

修改生成的标志

您需要添加一些生成的标志到工程中,以确保ArcGIS框架被正确载入。

说明:

如果没有这些标志,您的应用程序在调用ArcGIS API提供的类时可能会崩溃。

在Build Settings选项卡下,在搜索栏中输入“Other Linker Flags”来快速查找Other Linker Flags的设置,在目标列下面的空白处双击,然后使用加号按钮来添加如下的项:-all_load , -ObjC , -framework和ArcGIS,当完成后点击Done。

添加资源包

API资源例如Esri和Bing的logo图片,GPS位置等等都会合并为一个ArcGIS.bundle的文件,当您安装ArcGIS Runtime SDK for iOS时,如果选择了默认安装,那么这个资源包通常被安装到${HOME}/Library/SDKs/ArcGIS/ArcGIS.framework/Versions/Current/Resources目录下,您需要按照下面的方式来把这个包文件添加到工程中。

找到 Xcode应用程序的File菜单,选择Add Files to 选项,浏览位置

${HOME}/Library/SDKs/ArcGIS/ArcGIS.framework/Versions/Current/Resources, 选择ArcGIS.bundle文件夹,然后点击Add。

说明:

${HOME}/Library文件夹在狮子操作系统下默认是隐藏的,您可以在终端发送命令来取消隐藏,这样您能够使用Add Files to 对话框来浏览它。

为了使用自定义图片而不是这个包文件自带的图片,要确保添加到工程中的自定义图片有相同的名称,就象在包文件中那些图片一样,您工程中的这些图片将会优先于那些包文件中的图片。

现在您已经配置了一个 Xcode工程来开始使用ArcGIS Runtime SDK for iOS来进行开发了,下一步是在您的应用程序中创建并显示一个地图。

说明:

如上面所述配置一个新工程可能会有一点乏味,特别是当您还不得不重复做这些工作的时候。为了使您工作更方便,我们提供了一个预先配置好的工程,它使用了安装在${HOME}/Library/SDKs/ArcGIS/Samples/MapViewDemo路径下的SDK。这个示例工程是很小的,只包含了显示一幅全屏地图的代码。您可以很容易地拷贝这个工程的副本,然后重命名后就可以快速的进行一个新应用程序的开发了。

地图

显示一个地图

在应用程序中显示地理信息的主要方式是通过使用地图视图,地图视图允许您从不同的资源例如ArcGIS Server服务,Bing Map,街区地图等,或者从www.ArcGIS.com和自定义ArcGIS 门户中预先配置好的web map中搭配图层。

下面的步骤将引导您如何在应用程序中显示一个地图。如果您还没有做好准备工作,那么首先要配置好您的工程。下面部分假设您已经使用Single View Application Xcode模版创建了一个名为“MyFirstMapApp”的工程。

添加一个地图视图到用户界面中

在应用程序中显示地图的第一步是添加一个地图视图到应用程序的用户界面中,IOS应用程序的用户界面通常包含在一个nib文件(.xib extension)中,nib文件包含所有需要显示的UI组件,这些组件包括它们的样式,位置和布局等等。每个nib文件通常有一个绑定的视图控制器,这个控制器以UI组件来响应与用户的交互,并有选择地执行一些设置和移除任务等,视图和控制器对象是基于模型 - 视图 - 控制器的设计模式。

说明:

如果在您的工程中使用了Storyboard,这时就不会有任何的nib文件,相反会有一个storyboard文件。从概念上理解,这两个文件是类似的,因为它们都包含了UI,但是,一个storyboard文件包含了许多UI场景并定义了它们之间的转换或"segues",而nib文件只包含UI场景。虽然下面的步骤介绍的是在一个nib文件中怎么样添加一个地图视图到UI中,但您同样可以把这些相同的步骤应用到storyboard文件中。

假设我们要添加一个地图视图到一个包含在ViewController_iPhone.xib的nib文件的UI中。当您在左侧的Project Navigator面板中选择这个文件时,它的内容将显示在右侧的主显示区中,在Project Navigator和主显示区之间提供了一个当前nib文件中所有UI组件的列表,在 Xcode的最右侧是功能区,它包含了Inspector面板(上面)和Library面板(下面),Inspector面板可以使您检查和更改nib文件中的UI组件的属性,Library面板可以使您选择UI组件,多媒体,代码片断等等来添加到您的工程中。

为了添加一个地图视图,可以从库面板中选择一个通用的UIView对象,并把它拖拽到主显示区上。

UIView对象做为地图的一个占位符,它需要在应用程序中显示。为了实现这个目的,要重新设定UIView的大小,例如,使它完全覆盖下面的视图,这将确保我们的地图能全屏显示。

在这个UIView显示地图之前,我们需要把它转换为一个地图视图,我们通过在Inspector中指定AGSMapView为这个对象的类。

把mapview连接到视图控制器

现在我们已经添加了一个地图视图到UI中,我们需要把它连接到视图控制器这样我们可以用编程的方式在里面添加内容,并且能够与用户交互响应。为了做到这一点,首先我们需要使用Assistant Editor,这时视图控制器的头文件(ViewController.h)会显示在主显示区的旁边,然后我们能够在地图视图上右键单击,并把它拖拽到Assistant Editor中的头文件中。

之后, Xcode会自动提示我们输入一个名称,这样它可以创建一个从视图控制器到UI中的地图视图的“outlet”的连接,让我们称呼这个outlet为mapView。

如果我们尝试在这个阶段构建应用程序,将发现会有编译错误,这是因为我们的视图控制器包含了指向AGSMapView类的引用,但是这个类还没有被定义。为了修正这些错误,我们需要导入ArcGIS.h头文件到我们的视图控制器的头文件中。

向地图视图中添加内容

现在我们已经把一个地图视图添加到UI中,并且把它与视图控制器进行了连接,我们可以添加一些内容来在地图中显示,在导航栏中选择ViewController.m implementation文件并用源码编辑器打开它,定位到viewDidLoad方法,这个方法会在用户界面调用视图控制器添加行为时被执行,我们会创建一个使用了ArcGIS Online地图服务的切片图层,并把它添加到地图中:

如果我们现在运行应用程序,这个地图应该会显示来自ArcGIS Online地图服务中的内容。

响应地图动作

地图视图在地图发生一些必要的动作时会通知它的委托,例如,当一个图层加载时,或一个用户触摸地图的时候。这个委托是用来响应这些动作的,一个地图视图在执行一些必要的动作前也会告知它的委托,例如显示一个标注。这个委托用来执行地图要做的事,地图和它的委托之间的关系是建立在Delegation设计模型上的。

您可以设置一个地图视图的委托类,地图视图有三种类型的委托:

图层委托:

图层委托会被通知一些与图层相关的动作,例如当地图成功或失败加载一个图层。参考AGSMapViewLayerDelegate协议的API参考文档来了解更多图层委托之间的不同动作的介绍。

图层委托用来控制图层事件,如图层读取成功、失败,图层范围的变化等,例如下面的例子展示了一个图层控制器如何使用layerDelegate。

手势委托

手势委托用以控制手势事件,如点击或者长按地图等。

标注委托

标注委托用以控制标注关联的事件,如标注的样式以及触发标注后关联的操作。

分配一个标注委托的过程与上面的图层委托的方式是相似的。

地图导航

地图视图包含了定义和改变地图范围的选项,底图图层(第一个添加到地图中的图层)将为地图定义如下的属性:

1) 初始范围。

2) 整个范围。

3) 空间参考系。

初始范围是可以发生改变时,但空间参考系不能发生任何改变。这篇文档将介绍关于开发者和最终用户如何使用地图范围进行工作的相关方案。

设置地图范围

为了设置地图范围,可以在地图视图上使用zoomToEnvelope:animated方法来设定一块您想放大的几何范围。

另外,您也可以使用zoomToGeometry:withPadding:animated:方法在地图上放大到任意几何形状(例如一个村子或一条河的形状)。

说明:

您想要放大的地图范围的坐标系参数必须和地图的坐标系一致。

获得地图范围

除非地图已经加载完成,否则您可能不会知道地图的范围,您可以使用地图的visibleArea属性来获得地图的范围。

这个visibleArea属性返回一个多边形,这个多边形包含了地图四角的顶点,从左上角的角点开始,顺时针方向进行。

如果地图不包含任何旋转,那么由visibleArea多边形表示的区域将与多边形的范围完全一致,由此您可以使用visibleArea多边形的范围来做为地图的范围。

但是,如果地图旋转了,visibleArea多边形和这个多边形的范围将会是不同的,这需要一个比这个多边形更大的范围以致于它能够完全包含这个多边形。在这样的情况下,您将使用visibleArea多边形来获取地图范围。

跟踪平移和缩放

地图视图在范围改变时提供了两种通知,MapDidEndPanning 和 MapDidEndZooming,这两个通知会在地图被平移和缩放后分别发出。下面的代码介绍了当用户平移或缩放地图时如何监听这些通知,它会显示一个提示框,用来显示由地图视图的范围属性触发的新的地图范围。

当处理器处于空闲状态时,您应该注意要发出这些通知。当用户完成执行与通知被发出之间可能会有一点延迟,通知是在主线程中被传递的,您不应该通过执行大量的任务来锁定这个线程,否则您的应用程序将会出现停滞情况。

更改地图范围

如上面提到的,您可以在一个地图视图上使用zoomToEnvelope:animated:方法来设置范围,也可以使用地图视图的centerAtPoint:animated:方法来把地图居中到一个设定的点上。

用户手势

用户可以通过执行几个手势来在运行过程中更改地图视图的范围,所有这些操作都会触发MapDidEndPanning和MapDidEndZooming通知。

User Action Map Action Notification raised
Pinch-In Zoom out on map MapDidEndZooming
Pinch-Out Zoom in on map MapDidEndZooming
Double Tap om in on map MapDidEndZooming
Two finger Tap Zoom out on map MapDidEndZooming
Swipe (any direction) Pan map in direction of swipe MapDidEndPanning
Two finger Twist* Rotate the map

说明:

您必须在AGSMapView中启用allowRotationByPinching属性,以使两指扭转这个姿势变为可用。

在地图上定位

许多iOS设备如iPod Touch, iPad,和iPhone手机都提供了关于设备定位的功能,iOS包含了一个名为“CoreLocation”的框架来说明了定位是如何被触发的,是否通过无线,蜂窝网络或GPS,这个框架也为开发者提供了一个API来把定位功能整合到他们的应用程序中,同时根据自己的需求来进行配置。

地图组件AGSMapView使开发人员能够使用CoreLocation框架提供的复杂应用和简单应用两种方式来在地图上显示和跟踪设备的位置。AGSGPS对象与一个地图绑定,由此来为CoreLocation框架提供一个简单的外观,这极大地简化了服务定位的处理工作。

开始定位

为了在地图上显示设备位置,您需要调用AGSGPS对象中的start方法,在地图被加载完成后调用这个方法。例如,在mapViewDidLoad中:

默认情况下,地图使一个蓝色圆环的标志来显示设备位置,地图会一直尝试获取最准确的位置,这取决于信号强度,卫星位置和其他因素,返回的位置可能是一个最佳的近似值。地图会在位置周围显示一个蓝色的圆环来表示范围内的精度。

当设备移动时,地图会随之进行位置更新,并适当更新代表当前位置的篮色圆环标志。

自动平移模式

地图提供了一组预先设计好的设置,这些设置定义了在发生位置更新时地图是如何进行响应的。

离线

在这个模式下,这个标志可能因为位置更新而移出屏幕,此时地图不能被平移回来。

默认

在这种模式下,地图会一直尽量保持位置标志显示在屏幕范围内,它是通过在任意时候这个位置标志移出范围时都对标志进行重新居中操作来实现的,因此,这个位置标志可以在范围内随意移动,但是只要标志移出了范围之外,地图就会对标志进行重新居中。

您可以通过在AGSGPS中修改wanderExtentFactor指定一个wander extent。把wander extent这个值设为1是指定了地图的漂移程度等于它的可视范围,并且在地图重新居中之前它的位置标志可以向右移动到地图的边缘。把wander extent这个值设为0指定了地图在每次位置变更时都需要重新居中。默认情况下,飘移程度的大小是地图可视范围的一半。

如果用户在这个模式下平移地图,模式会自动切换到离线状态。

导航

这种模式最适合用于汽车导航,在这种模式下,位置标志被固定到屏幕上的一个点,然后总是指向设备的顶端。地图的平移和放置是基于位置更新和设备的移动方向的,因此,位置标志是固定出现的,同时出现在它下面的地图会进行移动和旋转。

位置标志的位置可以通过修改AGSGPS中的navigatonPointHeightFactor属性来进行修改。设定这个值为0指定的是地图底部,1是顶部。0到1之间的值指定了从底到顶部的这条线上的相应位置。

指南针导航

这种模式在用户旅行时是更好的选择,在导航模式下,位置会被固定到屏幕上的一点,它总是指向设备的顶端。但是,地图的旋转是基于用户相对于北磁极的位置的,不是基于设备的移动方向。在导航模式下,地图会反映出用户的位置。

位置标志的位置可以通过修改navigatonPointHeightFactor属性来修改。0值代表指向地图的底部,1值代表顶部。0到1之间的值指定了从底到顶部的这条线上的相应位置。

如果用户在这种模式下平移地图,模式会自动切换为离线状态。

说明:

如果您的应用程序允许改变设备界面的方向,您需要发送新的方向到AGSGPS对象中这样它能够重新定位。

停止定位

为了停止定位,您需要调用stop方法

自定义位置标志

SDK提供了3张图片,用来默认做为位置符号的。这些图片命名为"GpsDisplay.png" , "GpsDisplayHeading.png", 和"GpsDisplayCompass.png",它们包含在ArcGIS.bundle文件中。

GpsDisplay.png: Symbol showing location only GpsDisplayHeading.png: Symbol showing location and heading GpsDisplayCompass.png : Symbol showing location and compass bearing

这时将从默认图片中选择一个用做位置符号,这取决于正在使用的AutoPanMode和由位置更新提供的信息类型。

在离线,默认和导航模式下,只有当位置信息是可用时才会使用"GpsDisplay.png"图片,当位置和航向(旅行的方向)信息都可用时会使用"GpsDisplayHeading.png"图片。在离线和默认模式下,"GpsDisplayHeading.png"会适当的旋转,但是在导航模式下,旋转的会是地图。

说明:

航向信息只有当设备以一些非凡的速度移动时才会可用,这就是当旅行中设备在汽车内时地图为什么通常只显示"GpsDisplayHeading.png"图片代表的符号。

在指南针导航模式下,"GpsDisplayCompass.png"图片用来显示设备的位置和方位。

您可以通过使用自己的PNG图片来改变位置符号,您的图片必须和这些默认图片一样有相同的名称,并且做为您的 Xcode工程的一部分。您的 Xcode工程中的图片会优先于ArcGIS.bundle中提供的默认的图片,有一点要推荐的是您也可以在设备中使用高分辨率的图片。您应该把高分辨率的图片命名为"GpsDisplay@2x.png", "GpsDisplayHeading@2x.png", 和 GpsDisplayCompass@2x.png。

说明:

图片名称是区分大小写的。

显示在标注中的定位。

为了在用户点击位置符号时显示标注,您需要为地图的AGSGPS对象分配一个infoTemplateDelegate ,您可以通过使您工程中的其中一个类采用AGSGPSInfoTemplateDelegate协议来实现这个操作。

您的类实例必须也设置为AGSGPS对象的infoTemplateDelegate,这个将会使地图调用您类中的方法,然后在执行后再显示标注。

最后,您的类必须实现一个或多个方法,这些方法定义在一个协议中,这个协议指定什么内容需要在标注中显示。您可以为标注提供一个标题,详细信息或图片,或者您可以通过嵌入自定义视图来完全定义标注的外观。

说明:

如果您在标注中嵌入一个自定义视图,标题,详细信息,并且忽略图片的委托方法。要了解更多关于通过程序化的方式创建视图和使用界面构造器的详细信息,请参考苹果的View Programming Guide for iOS.您也会发现参考苹果的Resource Programming Guide是很有帮助的,它可以使您了解更多关于如何从一个nib文件中自动加载视图的操作方法。

访问位置信息

AGSGPS对象有两个属性用来提供设备的位置,currentLocation属性包含了由currentLocation相关框架提供的位置,基于WGS 84坐标系统的坐标总是以十进制来表示的。

currentPoint属性包含了相同的位置信息,但是它是投影到地图的空间参考系中的。

监听位置更新

AGSGPS中的currentLocation 和currentPoint属性兼容KVO(键-值)。您可以附加一个观察器到这两个属性的任意一个中,这样当它们更新时就会自动发出通知。

要了解更多关于KVO的信息,请参考Apple's Key-Value Observing Programming Guide。

也可以参考

GPS示例。

启用环绕

地球是圆的没有终点。但是,大部分地图坐标只能延展到东经180度和西经180度。这会使得区域可视化或穿越太平洋的路线很难进行。

从API的1.8版本开始,实现了使世界地图无限延展同时仍可以可视化。这只需要在地图上使用wrapAround属性,东部和西部半球相互环绕,形成一个连续的地图,给人的印象在地图上是无尽的,平移地图就变得类似于旋转地球仪一样。

约束

在环绕之前必须满足下面的要求:

GPS示例。

1) 地图的整个范围必须覆盖整个世界。

2) 地图的空间参考系必须是WGS 84 (WKID=4326) 或 Web Mercator (WKID=102113, 102100, 或 3857),它的意思是地图中的所有切片图层必须属于其中的一个空间参考系。动态图层,在另一方面,可以属于任何空间参考系,因为它们能够重构它们的数据。

3) 动态地图图层必须是基于ArcGIS Server10.0或更高版本的地图服务的,这是因为之前版本的REST API不支持空间参考系的WKT值,这个值是用来支持动态图层环绕的。

标准化几何形状

为了更好的理解环绕这个概念,需要理解清楚由可视化的帧组成的一个地图,这个是很有帮助的。-180经度,+180经度之间的映射的部分是“第0帧”,即使这个环绕是不可用的但这个帧也是可以显示的,在这帧西侧相邻的是“第1帧”,它假设在+180经度和+540经度之间延伸, 在“第0帧”东侧相邻的是“帧-1”,它假设-180经度和-540经度之间延伸。

因此,地图返回的经度值可能是真实的(在 -180 和 +180之间)或假设的(超出 -180 或 +180) ,这取决于正在显示的帧。这里是一些几何的示例,它们可以包含假设的坐标。

1) 一个地图的范围。

2) 由地图委托返回的触摸坐标。

3) 由草稿图层实现的几何形状数字化。

当几何包含假设的坐标时,您必须首先在使用它们执行空间查询或写入geodatabase之前对它们做标准化,要自动检查出是否几何形状需要做标准化是很困难的,因此,最好当环绕可用时就默认对几何形状做标准化。

您可以在AGSGeometryEngine中使用normalizeCentralMeridianOfGeometry方法来对几何形状做标准化。

地图图例

一个图例传送了在地图上使用的符号的含义,它把所代表的真实世界的实体与符号相关联 ,图例中的每一项通常由一个符号和说明文字来组成。

触发图例信息

从API1.8版本开始,您可以对如下图层类型触发图例信息:

1) 动态地图服务图层。

2) 切片地图服务图层。

3) 要素图层。

4) 图形图层。

ArcGIS 动态和切片地图服务图层

只有当图层使用一个ArcGIS Server v10 Service Pack 1或更高版本提供的服务时,ArcGIS 动态和切片地图服务图层的图例信息才会是可用的,这是因为v10 SP1版本之前的服务的REST API不能提供图例信息。

您可以通过在图层的AGSMapServiceInfo对象上调用retrieveLegendInfo方法来触发图例图片和文本,当图例信息被成功触发后,AGSMapServiceInfo的委托会被通知,或是当发生错误时也会通知。当成功时,AGSMapServiceLayerInfo 对象的legendImages 和 legendLabels属性会被填充。

ArcGIS要素和图形图层

对于一个ArcGIS要素图层来说,您通常会对图层中的每个要素类型或每个可用的要素模版显示一个图例项。对于一个图形图层来说,您会对图层使用的每个类型的符号显示一个图例项,渲染器通常用来决定要显示多少个图例点,因为一个渲染器会把不同的符号用逻辑分组上的图形来分别进行绑定。

要为ArcGIS 要素图层和图形图层创建图例项,您需要触发图层中使用的符号的图片。AGSRenderer 和 AGSSymbol都提供了方便的方法来返回符号的图片。

当您拥有这些图片后,您需要在图例中把它们与合适的文本绑定起来。

显示图例

当您拥有了每个图例项的图片和文本之后,您就可以使用一个UITableView或自定义视图来显示图例了。

也可以参考

Legend SampleTable of Contents (TOC) Sample

浏览时态数据

地理数据有时是一些时态数据,时态数据代表了一个特定时刻下,或者超越了一个时间段的整体的特性。例如, 飓风的推进过程,海洋温度的改变,野生动物栖息地的破坏,或者疾病的传播等等。通过在时间序列内观察和分析这些变化,您可以容易的识别趋势。

了解更多关于时态数据的知识

一个地图可以使您把时态数据可视化,并筛选出不属于一个特定时间段内的数据,当与时态渲染器结合使用时,您可以很容易地标志各种随时间变化发生的改变。

时间感知层

地图必须包含至少一个时间感知层来显示时态数据.下面图层的类型可以做为时间感知层: ArcGIS Server Dynamic Map Service Layer, ArcGIS Image Service Layer和 ArcGIS Feature Layer.如果一个图层使用的服务中使用了时态数据,那么它就是一个时间感知层。

了解关于更多时态数据

您可以通过使用ArcGIS服务目录来很轻松地说明是否一个服务包含了时态数据,如果Time Info属性被列出来了,它就代表数据是时态的

您也可以通过timeAware属性来自动检查是否图层是时间感知层。

时间范围

当在地图中有了至少一个时间感知层之后,您可以修改地图的时间范围来使时态数据可视化,时间范围定义了时间感知层显示数据的时间段。设置地图的时间范围与设置空间范围是很相似的,当空间范围指定了要显示的地理区域时,时间范围指定数据要显示的时间段,不管什么时候地图的时间范围发生改变,所有的时间感知层会自动更新以此来响应最新的范围,对于没有时间感应的图层上面所说的这些是不会有改变的。

查看一个时间段的数据

在地图上可以使您显示一个时间段内的数据,例如,在2001年12月3号和2002年3月17号发生的地震情况。为了完成这些,您需要创建一个AGSTimeExtent指定时间的开始点和结束点,然后您需要按如下方式来设置它成为地图的时间范围:

如果您想显示从一个特殊时间开始的数据,那么您可以指定开始时间并设置结束时间为0。下面的范围代表了一个从2002年3月17日开始的时间段:

相反,如果您想显示直到一个特殊时间为止的数据,您可以指定结束时间并设置开始时间为0.下面的范围内代表了一个直到2001年12月3日的时间段:

说明:

地图范围内的开始时间和结束时间是互相包含的。

在一个时间实例中查看数据

地图也可以显示属于一个特定时间实例的数据,例如,显示“卡特里娜”飓风在美国东部时间2005年8月25日上午6:30的位置,为了显示这个时间的数据,您可以使用相同的时间点和结束点来创建一个AGSTimeExtent,然后您需要按如下方式设置地图的时间范围:

图层时间选项

时间偏移

如果您在地图上有两个或更多的时间感知层,他们可以使用不同时区的数据,甚至完全不同时间段内的数据。例如,一个图层包含的用太平洋标准时间,纽约和其他东部标准时间表示的加州每小时内的交通数据。一个图层包含的2001年的北极冰盖的月度数据。甚至当您拥有这样的数据时,您可能想在地图上比较他们的趋势,例如,您可能想比较美国东部时间下午5时在加利福尼亚州和下午5点在纽约的上下班高峰期的交通情况,或者2001年6月和​​2011年6月的冰盖坐标。

要做到这一点,您可以指定一个偏移量来调整该层的一个时间选项。假设我们对2001年的冰盖层数据指定了+10年的偏移,这将会使图层认为它的数据是2011年,而不是2001年的,实际的数据是没有改变的,偏移一般应用于飞行模式。现在,当我们设置地图的时间范围为2011年6月,两个图层都将绘制它们的数据,2011年的数据的图层将正常绘制它6月的数据,但是2001年的数据的图层将首先对它的数据使用一个+10年的偏移量,然后绘制2001年6月的数据,因此,我们可以同时从两个层进行数据可视化,即使该数据属于完全不同的时间段。

累积时间

如之前提到过的,您可以使用一个只包含结束时间的时间范围来显示累积直到结束时间为止的时态数据。但是,可能在很多情况下在地图中有更多时间感知图层时,但您只想显示其中一部分图层的时态数据,在这种情况下,使用一个累积时间范围是不合理的,因为它会强制所有的时间感知层都显示累积的数据。

为了解决这种情况,您可以修改每个图层的时间选项来一直显示累积数据,这会使您合理的应用定义好的开始点和结束点的时间范围,但是选择的图层仍然会显示累积的数据。

禁用时间

您也可以通过禁用时间选项来从地图的时间范围内排除时间感知层,这些图层会看似没有收到时间提醒,只是简单显示数据

创建NSDate对象

当用时态数据查询时,您经常需要创建NSDate对象来指定时间范围,当您创建NSDate对象时,它们使用应用程序的默认时区。在设备上,时区可以是基于网络供应商提供的时间信息,也可以通过Settings手工设置的时间。应用程序使用的时区与正在使用的服务数据的时区可能是不同的,这可能会产生一些问题:

为了说明这样的问题,假设一个服务包含了以小时为单位的时态数据用来跟踪飓风的情况,同时也假设数据存储在GMT上,您要在一个特定的时间显示飓风的位置,比如2000年1月1日,上午12点,所以您要用相应的NSDate对象来创建一个AGSTimeExtent。

如果默认情况下应用程序使用了不同的时区,比如说太平洋标准时间,您会以一个NSDate 2000年1月1日,上午12AM PST来表示,而不是12 AM GMT。因此,该层会显示2000年1月1日上午12AM PST的飓风,相当于2000年1月1日 上午8AM GMT,即使我们原本设定显示的要素是12 AM GMT。

为了解决这样的问题,应该为您使用的时间值指定一个时区,IOS平台会自动校正时间值,如果有必要,会创建一个与使用您的应用程序默认的时区相同的NSDate对象。在如下的示例中,我们指定了一个上午12AM的值,但是也说明了这个值是属于GMT的。

也可以参考

Temporal queries using Query TaskTemporal RendererTemporal Sample

显示标注

有时必须显示地图中要素的更多信息。例如,用户可能想找到24小时营业的餐厅,或一处房子的出售价格。这些信息可以非常有效地使用标注来显示。

标注是标记在地图中的地理位置上的。当用户导航地图时,标注是固定在同一位置上的。标注可以以文本方式显示两部分内容:标题和详细信息。标注还有一个附加的按钮,这个附加的按钮可用于打开另一个视图显示更多的要素信息。从版本1.8开始,标注还可以在文本的左侧显示一个像素40x40的图像,您也可以通过嵌入自定义视图改变标注的布局。

这是一个AGS标注的实例,在任意时刻,地图上只有一个标注,它可以在AGSMapView显示标注的属性。

显示一个标注

无论何时用户点击一个图形,地图都要显示该标注,并提供给AGSGraphic对象一个有效的infoTemplateDelegate,该infoTemplateDelegate指定哪些内容需要显示标注。同样,当用户点击GPS定位符号时,地图也要显示标注,这时要提供给地图的AGSGPS对象一个有效的infoTemplateDelegate。

语法的观点看,您还可以使用AGSMapView方法显示一个标注。showCalloutAtPoint方法允许您在地图上的任何地理位置显示标注,showCalloutAtPoint:forGraphic:animated方法允许您对一个特定的图形显示标注。

在标注中显示内容

您有两种方式可以一个标注中显示信息:

1)通过在AGSCallout对象上直接修改属性。

2)使用一个infoTemplateDelegate。

直接修改标注的属性

当您在地图任意位置显示标注时,您通常只给AGSCallout属性分配值。当这样做时,您可以修改标题,细节,图像,和/或customView属性并显示这些内容。

使用一个infoTemplateDelegate

然而,在大多数情况下,标注显示的是与用户交互的响应。例如,当用户点击GPS位置符号时,或当用户在图形层点击一个图形时。在这种情况下,使用infoTemplateDelegate标注可以更方便的提供信息。

为了提供显示内容,需要执行一个委托协议。对于infoTemplateDelegate,指的是在标注中显示属性信息。对于使用infoTemplateDelegate进行GPS定位,指的是在标注中显示位置信息。

您还可以通过编程方式显示图形的标注,如果该图形有一个infoTemplateDelegate,那么它将被用来在标注中显示信息,否则,您需要指定信息来直接修改标注的属性,如在上一节中描述的。

不管如何显示标注,是通过编程的方式或自动的方式来响应用户交互,地图的calloutDelegate总是需要检查是否应显示一个图形或GPS定位符号的标注。因此,您可以控制在一个指定类中是否需要显示标注,如地图calloutDelegate类。每当显示标注时,相同的calloutDelegate都会被通知,这样就可以执行一些额外的操作。

图层

概述

一幅地图通常包含一个或多个图层,该API提供了接入多种类型地图的方法。

图层类型

我们通常使用的图层多数都是由GIS服务器管理的地图服务,例如 ArcGIS的地图服务,必应地图,Open Street地图等等。这些图层可以归结为两大类 - 动态图层和瓦片图层。

动态图层是指客户端发送请求给服务器端后,服务器端根据需求经过动态投影,返回给一幅符合客户端空间参考的图片。瓦片图层是指客户端发送请求给服务器端后,服务器端根据缓存策略从预先生成的瓦片缓存中提取相应的瓦片缓存,返回给客户端。瓦片图层因为是预先生成的,可以在用户请求时直接将相应的瓦片缓存传送到客户端,所以比直接动态生成地图图片的动态图层的显示效果更好。

Graphic Layer是指一种特殊的动态图层,它是将许多图形直接添加到图层中进行展示,不需要从地图服务中获取展示图片。

为地图添加图层

若您想为地图添加一个图层,您需要遵照以下操作来完成:

1) 初始化图层。如果图层的数据内容来自于地图服务,您就需要提供服务的网络地址。如果服务是安全服务,您还需要提供服务的相应证书。

2) 添加图层。您需要使用addMapLayer:withName:的方法将图层添加到地图上。图层的顺序是按自下而上的顺序排列,所以每次添加图层后,最新添加的图层会在最上面。这就意味着上面的图层会遮挡下面的图层。如果您想将图层插入到特殊的位置,您可以使用insertMapLayer:withName:atIndex:的方法为地图添加图层,例如设置atIndex:0,此时地图会放在最下面。添加图层的时候还有一点需要注意,您需要为图层提供一个独一无二的名称,因为您若想从地图中获取特定图层的需要提供图层的名称。

图层成功添加后,其数据内容会在打开地图的时候显示出来。

查看图层属性

如果图层的数据内容来自地图服务,当它初始化的时候默认就连接到相应的地图服务上。服务除了包含数据等内容之外,还包含了服务图层的许多默认属性。例如,AGSTiledMapServiceLayer访问ArcGIS Server发布的地图服务的时候,可以获得地图服务的范围、缓存策略等。初始化图层的时候,图层的属性也会被初始化。有时因为服务的响应速度、网络的传输速度等因素的影响,图层属性的初始化可能需要稍长一点的时间。

如果图层顺利初始化完成,它的loaded属性会变成可用状态。您可以通过查看这个属性,来确认图层属性的初始化是否完成。此外,每个图层还会发出LayerDidLoad 或者 LayerFailedToLoad的通知用告诉您图层是否被正确的加载了。您可以通过注册 observer(iOS开发中的观察员模式)来监听NSNotificationCenter中发回的通知。

验证加载图层信息

图层连接对应的地图服务的时候是在后台进行,不会阻塞当前线程。所以,您在使用addMapLayer:withName: 或者 insertMapLayer:withName:atIndex:方法添加图层的时候,不能假设图层已经顺利添加完成,而是需要进行验证。

当地图中某个图层添加成功或失败的时候,地图都会通知它的委托方法。此时您需要在您的类(管理地图的view controller)文件中,添加AGSMapViewLayerDelegate的协议,然后将您的这个类设置为地图的委托对象。

添加协议

设置地图的委托对象,使得作为委托对象的类可以接收地图的通知mapView.layerDelegate = self;

此时,作为委托对象的类需要实现协议中定义的一个或多个方法,用来指示程序在图层添加图层成功或失败的时候进行一些操作。例如,作为委托对象的类必须实现mapView:didLoadLayerForLayerView:方法来接收图层添加成功的通知。同样地,为了接收地图添加失败的通知,您需要实现mapView:failedLoadingLayerForLayerView:withError:方法

完成这些步骤之后,如果您收到图层添加成功的通知之后,就可以放心的查看和使用地图的属性了。

图层

在加入一个图层之后,地图会返回一个句柄用于View对象控制,这个View对象实现了AGSLayerView的协议并用于显示图层的内容。您可以用这个返回的句柄来控制View对象,比如控制图层的透明度。

建议您启用drawDuringZomming和drawDuringPanning来获得更好的交互体验,在开启这些设置之后MapView将会尝试在移动和缩放地图的时候对地图进行绘制,但是重绘地图可能会占用更多的CPU增大电量的消耗。因此,是否开启这些设置需要您自行权衡。

另外,图层的View对象有一个error属性,您可以使用KVO的方式来对此属性进行跟踪,这个属性将会在例如网络请求失败或者token验证失败的情况下变化。对于KVO编程,您可以参考苹果官方的Key-Value Observing Programming Guide。

地图空间参考

添加第一个图层之后它的坐标信息将作为这个AGSMapView的坐标信息,除动态图层会自适应坐标信息之外,任何与它不一致的坐标的图层将不会予以显示。

ArcGIS动态服务的图层

动态地图服务是从ArcGIS Server端动态添加的,并且没有进行过预缓存,如果它的坐标信息和MapView的不一致,将会进行动态适应。正因为动态地图服务是动态添加的,所以您可以控制它显示的内容。

ArcGIS Server的地图服务是基于mxd或者msd文件的。一个地图文档包含了要发布成服务的全部信息,要素是现实世界中地物的映射,要素在图层中控制。比如,一个国家公园的地图文档可能包含了不同的图层包括主道路、人行道等。地图文档还存储了地图的样式,如符号,可见度等。地图文档可以被用于发布到ArcGIS Server来创建地图服务。

ArcGIS Server有两种访问方式,分别为SOAP和REST,您可以在服务的页面的底部找到接口信息。

要实例化一个动态地图服务图层,您需要提供这个地图服务的REST URL信息,如:

如果您想经常改变动态服务图层的显示内容,则使用AGSMapServiceInfo来对它进行实例化,例如:

请注意AGSMapServiceInfo的创建是单线程的,这意味着创建的过程将会中断程序的其它操作,所以您可能希望在后台线程中对它进行调用。

在图层对象创建完之后,您就可以放心地调用到它的属性。

您可以将图层信息的改变弹窗显示,比如,您可以制定哪个图层可以显示并更改它的属性。

您还可以选择是否要显示这个图层的子图层。

ArcGIS切片服务的图层

ArcGIS的切片服务是通过预缓存的方式在iOS设备上显示地图,设备上显示的地图的参数是由服务决定的,在移动的时候Server会处理新的要显示的切片。

不像动态地图,切片地图的坐标信息要与地图一致,这是由于它是预缓存的所以不能适应新的坐标系统。

要实例化一个AGSTiledMapServiceLayer对象您需要提供一个URL指向服务器的REST服务地址,请注意一个没有做过切片的服务将不会返回信息。

在创建了一个Layer之后,您可以将其加入地图,当图层就绪后,您就可以放心的访问当中的属性了。

不像动态地图服务,您不可以动态改变切片地图服务中的内容,这个是因为切片地图服务是预缓存的而不是动态生成的。

图形

Graphics Layer允许您在地图上进行绘制,如在Graphics Layer在其上面绘制点、线、面。

如果您想将Graphics Layer加入到地图,您需要实例化一个AGSGraphicsLaeyer对象,实例化这个对象包括一些graphics和可选择的AGSRender,另有添加、删除、重绘的函数可供调用。请确保Graphics Layer在其它基本图层加载之后加载。

如何添加一个图形图层

如果您还没有创建您的程序,参照 Displaying A Map创建一个地图如下:

如果您想要获得Graphics Layer的句柄,则按如下方法创建:

这个返回的句柄可让您控制Graphics Layer的其它事件,如果您不需要返回句柄,可以通过以下方法加载:

请注意Graphics Layer的名字必须唯一。

添加Graphics到您的Graphics layer的方法在Managing Graphic features中讨论。

管理Graphic 要素

在您创建了Graphics layer后,您需要遵照以下步骤添加数据。在大部分的情况下,您需要用到的Graphics可能来自query的查询。

1) 创建或获得一个Graphics Layer以便于往上添加Graphic。

2) 创建或获得Graphic。

3) 如未设置,则设置Graphic的几何信息。

4) 为Graphic添置符号。

5) 将Graphic添加到Graphics Layer上。

从Map View 中获取 Graphics 图层的信息

您可以通过Graphic Layer的名称或者索引从地图中获取图层对象,您可以从 AGSMapView的mapLayerNames属性中通过名称查找,或者从mapLayerViews属性中通过索引查找。

mapLayerNames属性以数组方式存储着地图包含的全部图层。其中名称的顺序同地图中图层的顺序是一样的,例如,mapLayerNames中索引为0的名称对应着地图中最底层的地图。

如果您知道图层的索引号就可以直接获取图层的名称:

为了从地图获取Graphics layer(或者任何一个图层)对象,您需要使用mapLayerViews的属性。mapLayerViews是一个NSDictionary的对象。NSDictionary是一种以键值对(key/value)存储的集合。mapLayerViews中的键(key)是图层的名称,值(value)是图层对象。

Layer view是实际中用来承载Graphic layer的容器,它实现了AGSLayerView协议。因为它是协议,所以进行局部变量的声明时语法稍有不同,需要注意一下。

以下代码就是获取layer view的过程:

最终,您可以将上面的步骤精简到以下这句代码实现:

您可以查看AGSLayerView的agsLayer来获知图层的实时信息,例如从服务器端或客户端返回的错误。代码如下:

添加Graphic 要素

Graphic layer是用来添加Graphic要素的图层,通常您要添加的Graphics都来自任务执行的结果,例如查询等。当然,您也可以通过程序创建Graphic,您需要先创建一个AGSGraphic的实例,然后为Graphic提供一个相应的几何对象(例如点、线、多边形),再指定一个展示Graphic所用的符号,或者制定一个渲染器。如果有需要,您还可以为Graphic赋上一些属性。

以下代码展示了创建Graphic并将其添加到myGraphicsLayer的过程:

从task返回的Graphics都有完整的几何信息,但是都不包含符号化的信息,所以在将这些Graphics添加到Graphic layer的时候都需要您先为每个Graphic指定符号或者渲染器。以下的代码展示了为查询操作返回的Graphics添加符号化信息的过程:

请查看“符号化要素”(Working with Symbols and Renderers)的文档获知更多相关内容。

Graphic 属性标注

Graphic可以包含许多以键值对表示的属性信息,例如,代表城市的graphic,可以包含城市的人口、人均收入等信息。此外,Graphic还可以设置infoTemplateDelegate,用一种比较便捷的方式来显示属性标注。

如果您想点击某个gaphic的时候自动弹出其属性标注,您就必须为graphic指定一个infoTemplateDelegate,否则点击gaphic的时候不会显示标注。您可以通过一下两种方式来指定:

1) 使用自定义的infoTemplateDelegate。

2) 使用现有模版AGSCalloutTemplate。

自定义infoTemplateDelegate

自定义infoTemplateDelegate的时候,您需要让类添加AGSInfoTemplateDelegate的协议。

然后,用于设置自定义infoTemplateDelegate的类还需要实现协议相应的方法,来设置标注显示的具体内容和样式,代码如下:

说明:

如果您是通过自定义view的方式来自定义标注,那么以上title,detail以及image的委托方法就不能再起作用。

现有模版AGSCalloutTemplate

您如果不需要使用复杂的标注样式,您可以使用API提供的现有模版类AGSCalloutTemplate。这个现有模版类只允许您为标注指定名称和详细信息,样例代码如下:

说明:

AGSCalloutTemplate只适合显示以字符类型表示的属性,不适合显示数字和时间等,也不能为标注添加图片以及其它自定义内容。

符号化要素

符号就是指怎么显示graphic,例如graphic的颜色、边线类型、透明度等。ArcGIS Runtime SDK for iOS提供了许多符号类,您可以使用这些类来初始化符号样式。

渲染器是针对整个Graphic layer的渲染方案,它通graphic的某一项属性来决定哪个graphic用哪种符号。

符号的类型

可用的符号类型以及其适用的几何类型如下所示(以下类均继承自AGSSymbol):

符号类型 几何类型 说明 对应的类
简单点符号 用简单形状作为点的符号 AGSSimpleMarkerSymbol
图片点符号 用图片作为点的符号 AGSPictureMarkerSymbol
简单线符号 线 用简单的线性作为线的符号 AGSSimpleLineSymbol
组合符号 点、线、多边形 将多个符号组合形成一个新的符号 AGSCompositeSymbol
简单填充符号 多边形 用某种图案或颜色填充面 AGSSimpleFillSymbol
文本符号 点、线、多边形 用来显示几何要素的文字标注信息 AGSTextSymbol
创建符号

对于同一类几何要素通常用同一个符号来展示,这样您在创建好一个符号后用一个变量来保存符号,就可以达到复用的目的。以下代码展示了创建一个AGSSimpleMarkerSymbol类型的符号并将其用变量存储的过程:

以下代码展示了AGSSimpleFillSymbol和AGSSimpleLineSymbol的使用:

渲染器

一个渲染器包含了Graphic layer要用的所有符号,您可以通过以下代码为图层设置渲染器:

单一符号渲染器

单一符号渲染器是指只包含一种符号的渲染器,即Graphic layer中的所有graphic都采用同一种符号进行渲染,其创建方法如下:

您需要注意AGSSimpleRenderer的属性均为只读,在初始化后无法改变,且使用时渲染器的符号类型需要跟graphic的几何类型相匹配。

分类间隔渲染器

分类间隔本质上就是一种类别,每个分类间隔都包含一个最小值和最大值。将分类间隔应用于一组数据时,分类间隔将根据某个字段或属性的值将数据分为不同的类别。因为类别的定义主要取决于所具有的最小值和最大值,所以分类间隔仅适用于数值属性。您需要定义一组AGSClassBreak对象,将其存储在AGSClassBreaksRenderer类中。AGSClassBreak对象需要包括符号、最小值和最大值。分类间隔渲染器就会将每个类别映射至特定的符号。具有相似属性值的图形将会获得相同的符号。创建分类间隔渲染器示例代码如下:

唯一值渲染器

“唯一值”指一组值,每个值对于给定数据集中的特定字段或属性都是唯一的。例如,如果一组数据有一个名为 STATE_NAME 的字段,具有的值为 { Washington, Washington, Washington, Montana, Connecticut, Connecticut, Connecticut, Florida, Oklahoma, Oklahoma },则数据集 { Washington, Montana, Florida, Oklahoma } 将是一组有效的唯一值。注意在这个唯一值组内,没有重复的值。唯一值渲染器将一组唯一值映射到一组符号。

创建唯一值渲染器的示例代码如下:

时态渲染器

时态渲染器仅仅适合使用在时间感知型的图层,这种图层是指要素中包含了时间点信息或者是某个时间段信息,其中时间点信息通过一个属性来描述,时间段信息通过起始时间和结束时间两个属性来描述,渲染器此时就可以根据图层的时间信息进行符号化。

时态渲染器由两个对象组成:观察渲染对象和插值对象。

观察渲染对象用于处理没有包含时间信息的要素,或者是在地图没有时间范围的时候使用。观察渲染器可以是一个简单分类间隔渲染器或者唯一值渲染器。

插值对象则是为存储了时间信息的要素调整符号的大小和颜色。我们支持两种类型的插值方法:色带插值和时间间隔插值。

色带插值

色带插值是指根据时间的起始值和结束值会确定一组符号大小和颜色变化的范围,根据要素的时间属性同地图整体的时间跨度的比例,可以确定每个要素符号的大小和颜色。例如,如果一个要素的时间点属性处于整体时间跨度的中间,那么这个要素符号的大小和颜色就都是中间值。如果一个要素的时间属性是时间跨度,那么就根据时间跨度的大小来确定符号。

以下展示了几种色带插值的符号化方案:

时间间隔插值

时间间隔插值是指根据时间的起始值和结束值,选择一个合适的间隔,将时间均分为N段,然后确定每段的符号大小和颜色。时间间隔插值方案确定后,程序会根据要素的时间属性来确定它属于哪个分段,具体该使用什么样大小和什么样颜色的符号。

以下展示了几种时间间隔插值的符号化方案:

几何类型对象

API包含了许多轻量级的几何类,这些类用以将几何要素表示到底图上,或者发送到ArcGIS Server进行更复杂的分析。虽然ArcGIS Desktop和ArcGIS Server支持3D图形,但是API只支持二维图形。

API中包含以下5种基本几何类型 -

1)Point

2)Multipoint

3)Polyline

4)Polygon

5)Envelope

坐标系

所有的几何对象都是基于坐标系并通过多对(X,Y)来表示的,坐标系不仅表明了X,Y的意义还表明了距离单位。

坐标系可以通过WKID和WKT来表示。

不变对象与可变对象

Objective-C 支持两种类型的对象-可变对象(Mutable Object)和不可变对象,Geometry也支持两种类型,如下:

Geometry type Immutable object Mutable object
Point AGSPoint AGSMutablePoint
Multipoint AGSMultipoint AGSMutableMultipoint
Polyline AGSPolyline AGSMutablePolyline
Polygon AGSPolygon AGSMutablePolygon
Envelope AGSEnvelope AGSMutableEnvelope

Mutable Geometry在编辑时候非常好用,大部分情况下您能得到的是一个不可变的Geometry,您可以通过以下方式来获得一个Mutable Geometry。

Point

点对象通过经度和纬度来表示一个几何对象。

Multipoint

Multipoint geometries 代表多个点对象的有序集合。

Polyline

Polyline geometries 通过多个折点表示了多段直线的集合。

Polygon

Polygon geometries 代表了多个闭合图形表示的面对象。

Envelope

Envelope geometries 代表了一个几何对象的外接矩形。

JSON 表达式

几何类可以和JSON对象做如下转换:

几何操作

Geometry对象可以通过AGSGeometryEngine或者Geometry Service做复杂的地理运算。

Task

概述

在iOS的App中,要与地图交互您必须使用Task对象,我们提供以下几种Task:

1)Query Task – 获得在线服务中的信息。

2)Find Task – 查询特定的地理信息。

3)GeometryService Task –地理处理工具。

4)Locator – 地理编码服务

5)Route Task – 路径分析服务

使用Task来进行工作

所有的Task对象都是继承自AGSTask。使用这些task可以让您十分便捷访问您发布的服务,您只需要遵循以下几点便可达成:

1)实例化一个Task对象。

2)设置委托对象。

3)增加计数器计数(Retain)。

4)提交Operation。

5)等待委托对象完成请求。

实例化

因为Task对象都是由AGSTask生成的,所以他们必须通过URL进行初始化,有些加密服务需要Credential。

设置委托对象

因为Task对象是异步的,所以在完成之后需要让委托对象知道完成信息,比如以下代码表明了一个AGSQueryTaskDelegate的工作流程:

请注意委托对象是有成功完成以及失败的两种方法,请在需要的时候实现两种方法。

计数器(Retain)

让计数器加一(Retain)对于一个Task对象是十分重要的,因为一旦在提交过程当中Task被内存释放了,它将无法完成请求。

提交任务的操作

提交一个任务的操作可以让它开始执行请求:

Task对象将会在发出请求后返回句柄,您可以根据他们返回的句柄来判断具体的请求。

等待委托对象完成

在提交了Task请求之后,委托对象将会跟踪请求状态并在成功或者失败的时候通过委托的方法进行表达,关于网络请求的流量提示Task对象会自己考虑的,您可以通过NSError对象来跟踪返回的错误。

Query Task

Query Task可以让您通过ArcGIS Server支持Query的服务上查询地图的数据,Query Task查询的矢量地图的信息而不是缓存的地图切片。

您可以查看服务下放的Supported Operations来查看该服务是否支持Query。

实际上,当您对服务足够熟悉之后,您可以直接通过URL进行拼串GET来直接进行Query。

建立一个 Query task

要实例化一个Query Task您需要一个URL。

Service REST Resource
supporting Query operations
URL example
Map Service A vector layer or table http://<server>/<instance>/services/<service>/MapServer/<layer_or_table_ID>
Feature Service A vector layer or table http://<server>/<instance>/services/<service>/FeatureServer/<layer_or_table_ID>
Image Service The service itself http://<server>/<instance>/services/<service>/ImageServer

下面例子表明了如何创建一个Query Task。

如果您使用alloc方法来构建QueryTask对象了话您则可以很好的控制内存释放,但是如果通过类级方法构建的时候请注意内存控制。

查询要素

Query Task允许您查询多种类型的信息:

当执行Task的时候,API 允许您:

1)仅查询要素的数量。

2)使用 executeFeatureCountWithQuery。

3)仅查询要素的ID。

4)使用 executeForIdsWithQuery。

5)或者,通过executeWithQuery完整的查询。

请注意,您能查询到的要素的数量将是您在Server上设置的最大值和您在API中设置的最大值中较小的那个。

Query Task在返回结果上有许多属性可以设置,通过设置这些属性您可以尽可能的返回有用的结果并以尽可能自由的方式进行显示。

属性查询

您还可以通过设定Query的WHERE属性来对特定的属性进行过滤。

下面的代码就是WHERE属性的示例:

空间查询

您还可以通过Query对象来对特定的空间进行查询,下面的代码是一个Envelope的示例:

时态查询

如果您的数据是有时间属性的,那么Query也可以让您的查询有时间属性的设置,下面是几个示例:

通过要素的关联属性进行查询

如果您要查询的数据需要通过该图层或者属性表中的某个关联属性来获得,请使用AGSRelationshipQuery来进行查询。

下面的例子示范了通过属性的关联ID来进行查询:

获取结果或者处理错误

Query Task会告知委托对象请求的结果或者错误信息:

委托对象必须声明:

委托对象必须实现 queryTask:operation:didExecuteWithRelatedFeatures: 来获取成功查询到的要素信息。

类似的,委托对象通过实现 queryTask:operation:didFailRelationshipQueryWithError: 来截获错误的信息。

Route Task

Route task 允许您使用ArcGIS Server上的网格分析服务,通过网格分析服务,您可以解决点和点之间的最优路径等问题。

建立一个Route task

您需要通过一个URL来实例化一个网格分析服务:

当您创建了AGSRouteTask对象之后,请确保它的内存控制可靠,特别是通过autoReleased方式构建的AGSRouteTask。

准备输入值

您可以通过AGSRouteTaskParameters来设置AGSRouteTask的参数,如果您想要使用默认值,您也需要使用AGSRouteTask中的 retrieveDefaultRouteTaskParameters方法。

阻抗

阻抗表明了该路径分析的优先考虑因素,该因素在ArcGIS Server上通过esriNAUTCost指定,您也可以在代码中自行指定。

在上面的示例中,时间和长度被作为阻抗因素,您也可以自行指定阻抗因素。

站点

站点指定了您要进行分析网格分析的格点以及顺序,您至少要指定2个站点才能进行分析。

要素

您可以通过AGSRouteTaskParameters中的参数对Route Task的分析参数进行自由的设定,建议通过AGSStopGraphic对象进行点的指定。

如果您的路线是不同的,请指定routeName属性,如果不指定,将会作为一条线路进行分析。

您还可以通过timeWindowStart和timeWindowEnd对路网数据的时间属性进行完善。

一个站点可以有更多可设置属性,它位于Network Analysis Classes -> Class Name:Stops下。

更多API参考资料

http://help.arcgis.com/en/arcgismobile/10.0/apis/iOS/2.2/concepts/index.html