![WebGIS之ECharts大数据图形可视化](https://wfqqreader-1252317822.image.myqcloud.com/cover/350/44819350/b_44819350.jpg)
1.5.2 实现第一个WebGIS后台REST服务接口
在创建后台REST服务接口之前,首先创建一个名为“WCFService+OpenLayer+ECharts”的文件夹;接着在该文件夹下创建一个app文件夹;然后在app文件夹下分别创建data_shp文件夹和lib文件夹,lib文件夹用于存放项目中需要引用的本地资源;最后在lib文件夹中创建ECharts文件夹、jQuery文件夹、OpenLayers文件夹,将下载的ECharts文件、jQuery文件和OpenLayers文件分别放在所对应的文件夹中。自定义的目录如图1-5所示,项目的目录结构也可以根据个人的习惯来定义。
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_8.jpg?sign=1739046155-nH1rpTbcxPQuy5leozn0BqI4rvzVBMzW-0-0f50453fa1e2a916e6e120a0e2319f6b)
图1-5 自定义的目录
在开发Web系统时,会经常出现跨域问题。跨域问题是指浏览器不能执行其他网站的脚本,这是由浏览器的同源(是指协议、域名、端口三者相同)策略造成的,是浏览器对JavaScript施加的安全限制。由于存在跨域问题,使得AJAX请求无法发送,所以需要调用编写的ResponseMsgFactory.cs来解决该问题。首先将ResponseMsgFactory.cs放到WCFService文件夹下;然后在Visual Studio 2012中右键单击项目名称“WCFService”,在弹出的右键菜单中依次选择“现有项”→“添加”,将ResponseMsgFactory.cs添加到项目中,如1-6所示。
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_9.jpg?sign=1739046155-m16NEwdM4mnHuWLblwsBnZbs0geFHBOK-0-ab518520eee02f1a1f8e333331ba6202)
图1-6 添加现有项
通过调用ResponseMsgFactory.cs中ProcessHttpOPTIONS方法,可判断服务器接收到的是不是OPTIONS请求,如果是,则返回服务器信息,并通过ResponseMsgFactory类获得指定格式的数据,调用代码如程序代码1-3所示。ResponseMsgFactory.cs中ProcessHttpOPTIONS方法的具体实现如程序代码1-4所示。
程序代码1-3 调用ProcessHttpOPTIONS方法
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_10.jpg?sign=1739046155-Wpyl2SDz9GNVi8qFIPsb5BcRS4MaLpsp-0-f1e5dc5559319e45f09cc2a048a12c46)
程序代码1-4 ProcessHttpOPTIONS方法的实现
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_11.jpg?sign=1739046155-EcNo4rv1v2nHq6kD8GnfOf4yAXxT35GV-0-a049fcabba1ffdcf5948d56d058eb0b4)
由于本书需要调用ArcGIS数据库来存储后台所使用的疫情数据,因此后台需要获得ArcGIS数据库的许可,这可以通过调用InitializePlatform.cs中的InitializeApplication方法来实现。添加InitializePlatform.cs中的方法同添加ResponseMsgFactory.cs中的方法一样,调用代码如程序代码1-5所示。InitializePlatform.cs中InitializeApplication方法的具体实现如程序代码1-6所示。
程序代码1-5 调用InitializeApplication方法
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_12.jpg?sign=1739046155-8gQqGUU6Vo2Jcu0bXIuLPn3nmGquHxiX-0-2cac15a081b2b7937c79fc1e16c4c99f)
程序代码1-6 InitializeApplication方法的实现
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_13.jpg?sign=1739046155-QnEHHOfAGV930Cio2gvmnmQvxOMmpkXq-0-0fa401e24e260dc253ec4bf7b4cf56ce)
为了方便后台读取ArcGIS中shp文件的属性表数据,可以通过引用ArcGIS中的部分动态链接库文件来调用ArcGIS中的查询方法,从而获得shp文件的属性表数据。想要获得动态链接库文件,首先要在ArcGIS安装包中,找到并单击SDK_dotnet文件夹,接着双击setup.exe,然后一直单击“Next”按钮,安装完成后,可在“%ArcGIS%\DeveloperKit10.2\DotNet”下找到本书使用的动态链接库文件,将这些动态链接库文件放到项目的“bin”文件夹下的“Debug”文件夹中,最后在Visual Studio 2012中右键单击项目名称“WCFService”,在弹出的右键菜单中依次选择“添加引用”→“浏览”,可将“Debug”文件夹下的动态链接库文件添加到项目中,如图1-7所示。
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_14.jpg?sign=1739046155-yTxtlSxBvUmgypQFFVJxsDLN56XbAgWY-0-3234eeb80f614771effb2f45e3246125)
图1-7 在项目中添加动态链接库文件
通过ServiceBehavior中的一些属性可以控制服务的实例、线程等。其中InstanceContextMode用于设置服务实例的生命周期,其值是Single;ConcurrencyMode用于设置服务以单线程模式运行,其值是Single。如果要把未处理的异常作为SOAP错误消息发送给客户端,就需要把IncludeExceptionDetailInFaults设置为true。AspNetCompatibilityRequirements用于启用ASP.NET兼容性模式,如程序代码1-7所示。
程序代码1-7 设置ServiceBehavior属性
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_15.jpg?sign=1739046155-oFzvteVrjIKsm86WTXSe7gvOLcbQ3Q3w-0-dfc2c05949b6be0b60cf347adc06aa77)
接下来设置疫情数据存储的路径,即“path=@"..\..\..\data_shp"”,该路径是数据文件夹的相对路径,每一个“..\”代表的是上一级目录。首先调用IFeatureWorkspace接口中的OpenFromFile方法打开data_shp文件夹,再调用OpenFeatureClass方法打开该文件夹下名为HBconfirmed_0302的shp文件,读者可以根据自身需要设置其他的shp文件名。设置shp文件所在路径及工作空间的代码如程序代码1-8所示。
程序代码1-8 设置shp文件所在路径及工作空间
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_16.jpg?sign=1739046155-nwxNpOpPcBTiFp0HD5TmSPCqzK8maRYo-0-3939789db02ddc3620f30542ee7fca89)
由于本书使用的疫情数据时间字段名中含有字母“T”,为了使后续的折线图不出现“T”,需要首先调用fields.get_Field方法获取属性表中所有字段,然后调用get_Field方法获得含有字母“T”的字段名,最后调用Substring方法去掉时间字段名中的字母“T”,如程序代码1-9所示。
程序代码1-9 获取字段名并去掉字段名中的首字母“T”
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_17.jpg?sign=1739046155-ibpMn4dZmDmc8A1RfVygzQ9IXFeXkXKq-0-a239c025fb1e9ad6bd600bcecd9a2df1)
处理完字段名之后,还需要调用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 查询属性表中的字段值
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_18.jpg?sign=1739046155-3bTibpUQq4GMv9IY5WadEkOFyoHRIz9c-0-e0460889e4f653ef980c4e702b7a9e99)
在遍历所有要素后,调用pFeature.get_Value方法获取属性表的时间字段值,如程序代码1-11所示。
程序代码1-11 获取属性表的时间字段值
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_19.jpg?sign=1739046155-BXSxh03RiKdKotdcuKQAGhnpJWhFC428-0-b533ecb99ca1fce6c2fc8427760eaea8)