1.5.2 实现第一个WebGIS后台REST服务接口
在创建后台REST服务接口之前,首先创建一个名为“WCFService+OpenLayer+ECharts”的文件夹;接着在该文件夹下创建一个app文件夹;然后在app文件夹下分别创建data_shp文件夹和lib文件夹,lib文件夹用于存放项目中需要引用的本地资源;最后在lib文件夹中创建ECharts文件夹、jQuery文件夹、OpenLayers文件夹,将下载的ECharts文件、jQuery文件和OpenLayers文件分别放在所对应的文件夹中。自定义的目录如图1-5所示,项目的目录结构也可以根据个人的习惯来定义。
图1-5 自定义的目录
在开发Web系统时,会经常出现跨域问题。跨域问题是指浏览器不能执行其他网站的脚本,这是由浏览器的同源(是指协议、域名、端口三者相同)策略造成的,是浏览器对JavaScript施加的安全限制。由于存在跨域问题,使得AJAX请求无法发送,所以需要调用编写的ResponseMsgFactory.cs来解决该问题。首先将ResponseMsgFactory.cs放到WCFService文件夹下;然后在Visual Studio 2012中右键单击项目名称“WCFService”,在弹出的右键菜单中依次选择“现有项”→“添加”,将ResponseMsgFactory.cs添加到项目中,如1-6所示。
图1-6 添加现有项
通过调用ResponseMsgFactory.cs中ProcessHttpOPTIONS方法,可判断服务器接收到的是不是OPTIONS请求,如果是,则返回服务器信息,并通过ResponseMsgFactory类获得指定格式的数据,调用代码如程序代码1-3所示。ResponseMsgFactory.cs中ProcessHttpOPTIONS方法的具体实现如程序代码1-4所示。
程序代码1-3 调用ProcessHttpOPTIONS方法
程序代码1-4 ProcessHttpOPTIONS方法的实现
由于本书需要调用ArcGIS数据库来存储后台所使用的疫情数据,因此后台需要获得ArcGIS数据库的许可,这可以通过调用InitializePlatform.cs中的InitializeApplication方法来实现。添加InitializePlatform.cs中的方法同添加ResponseMsgFactory.cs中的方法一样,调用代码如程序代码1-5所示。InitializePlatform.cs中InitializeApplication方法的具体实现如程序代码1-6所示。
程序代码1-5 调用InitializeApplication方法
程序代码1-6 InitializeApplication方法的实现
为了方便后台读取ArcGIS中shp文件的属性表数据,可以通过引用ArcGIS中的部分动态链接库文件来调用ArcGIS中的查询方法,从而获得shp文件的属性表数据。想要获得动态链接库文件,首先要在ArcGIS安装包中,找到并单击SDK_dotnet文件夹,接着双击setup.exe,然后一直单击“Next”按钮,安装完成后,可在“%ArcGIS%\DeveloperKit10.2\DotNet”下找到本书使用的动态链接库文件,将这些动态链接库文件放到项目的“bin”文件夹下的“Debug”文件夹中,最后在Visual Studio 2012中右键单击项目名称“WCFService”,在弹出的右键菜单中依次选择“添加引用”→“浏览”,可将“Debug”文件夹下的动态链接库文件添加到项目中,如图1-7所示。
图1-7 在项目中添加动态链接库文件
通过ServiceBehavior中的一些属性可以控制服务的实例、线程等。其中InstanceContextMode用于设置服务实例的生命周期,其值是Single;ConcurrencyMode用于设置服务以单线程模式运行,其值是Single。如果要把未处理的异常作为SOAP错误消息发送给客户端,就需要把IncludeExceptionDetailInFaults设置为true。AspNetCompatibilityRequirements用于启用ASP.NET兼容性模式,如程序代码1-7所示。
程序代码1-7 设置ServiceBehavior属性
接下来设置疫情数据存储的路径,即“path=@"..\..\..\data_shp"”,该路径是数据文件夹的相对路径,每一个“..\”代表的是上一级目录。首先调用IFeatureWorkspace接口中的OpenFromFile方法打开data_shp文件夹,再调用OpenFeatureClass方法打开该文件夹下名为HBconfirmed_0302的shp文件,读者可以根据自身需要设置其他的shp文件名。设置shp文件所在路径及工作空间的代码如程序代码1-8所示。
程序代码1-8 设置shp文件所在路径及工作空间
由于本书使用的疫情数据时间字段名中含有字母“T”,为了使后续的折线图不出现“T”,需要首先调用fields.get_Field方法获取属性表中所有字段,然后调用get_Field方法获得含有字母“T”的字段名,最后调用Substring方法去掉时间字段名中的字母“T”,如程序代码1-9所示。
程序代码1-9 获取字段名并去掉字段名中的首字母“T”
处理完字段名之后,还需要调用IFeatureClass.Search方法来查询属性表中的字段值。“WhereClause=""”表示查询所有的数据。IFeatureClass.Search(pQueryFilter,false)的作用是根据pQueryFilter从FeatureClass中选取特定的Feature,该方法会返回一个IFeatureCursor对象。IFeatureCursor对象用于指向被筛选出来的符合条件的Feature。IFeatureCursor.NextFeature方法将游标指向下一个满足条件的Feature,第一次使用该方法时会返回第一个Feature,再次调用会返回第二个Feature,最后一个要素被遍历后再次调用该接口,则会返回null。IFeatureClass.Search方法的第二个参数设置为false,也就是说每执行一次IFeatureClass.NextFeautre方法,上一条记录的Feature值都会保存在内存中,如程序代码1-10所示。
程序代码1-10 查询属性表中的字段值
在遍历所有要素后,调用pFeature.get_Value方法获取属性表的时间字段值,如程序代码1-11所示。
程序代码1-11 获取属性表的时间字段值