![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=1739369208-oYvKn6j8uLQ8FF4ynFgBsEGqYC3yiTdS-0-51de0a34322559462c35ae4b564d95dc)
图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=1739369208-WJvtnFEaEFCfYt1eRHlJ6ygZFzXrSFY7-0-f86b9f6ccf09fac0d448713a14557ba0)
图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=1739369208-0blvrSS7O75l1FZHqrY9hZvjw4ZJViHP-0-30ca4d5c6819844bff1c2409ca61018c)
程序代码1-4 ProcessHttpOPTIONS方法的实现
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_11.jpg?sign=1739369208-fFpdAIg6InWz5uHXML0B9iffnB4r8PuQ-0-c8c93c89f68661034d6d89c44d005c8d)
由于本书需要调用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=1739369208-iahnAKguptVtUefpnn6sckbICTzuCLLf-0-27d785dafd034a310d02457ca3875d2f)
程序代码1-6 InitializeApplication方法的实现
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_13.jpg?sign=1739369208-l5kF9p5EEcGHT5QFtr7rQ0HuBx2feGgB-0-f33a624889a32dad38ff46cede8e7e5f)
为了方便后台读取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=1739369208-rPPX7rDo8Jq8BUsuU27tIK5GNzGE33WS-0-a185c44da650a96860ad3a6400eb3c04)
图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=1739369208-YXtSqUnSxEQzPsowr9Vh09uC6wrwNVNz-0-323d0bdfbc5789a6d4d46cfe9839f2b7)
接下来设置疫情数据存储的路径,即“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=1739369208-ymFG3txsqtn1uK9fVnCMr4VReaRBfdnT-0-d18b64f069cf3e2e89fab422f9a66a1d)
由于本书使用的疫情数据时间字段名中含有字母“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=1739369208-KPly0QrRelqphQZBhdSgNIUWJZ8ZQK9Q-0-c1975c7feb900e33b4c6b23e5a619581)
处理完字段名之后,还需要调用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=1739369208-t5aaP77NsF8yVqDesAdTk8YT4abaXuPU-0-bb105f67e85547d7fb524fe6cfb8a5e8)
在遍历所有要素后,调用pFeature.get_Value方法获取属性表的时间字段值,如程序代码1-11所示。
程序代码1-11 获取属性表的时间字段值
![img](https://epubservercos.yuewen.com/646D32/23949922509623906/epubprivate/OEBPS/Images/txt001_19.jpg?sign=1739369208-pINqzk1LcmwdlhpG8cCu3fQEKMBl2LsX-0-8abd390f375e6d7a0e9883122d98b1c6)