1、概述
ArcGIS 10 中可以通过Interoperablility模块来加载由外部数据源或ArcGIS Server发布的标准的WFS服务(10默认支持WFS1.1.0),如图1所示。使用过ArcGIS该功能的朋友应该会注意到,在初次加载WFS数据时数据加载的速度会比较慢,而当以后再次加载时速度就非常快了。而造成这种现象的原因主要在于ArcGIS在初次加载WFS数据的同时将其全部数据在本地机器上做了缓存,当下次再次访问该WFS服务时,则可直接访问本地缓存无需访问网络资源,如图2所示。
图1
图2 ArcGIS与WFS交互的体系结构图
ArcGIS如此的WFS数据访问模式在很大程度上确实能够大幅提高WFS的访问效率,但这种 ArcGIS与WFS交互的体系结构图模式也同时带来了一个较大的缺点,即无法及时反映WFS数据源中数据的变化,如图3和图4。
图3 更新前ArcGIS中访问WFS数据的截图
图4 更新后ArcGIS中访问WFS数据的截图(同图3)
同时,ArcGIS本身也并没有提供相应的机制或参数以使得用户能够控制本地缓存的更新。所以,这就触发了笔者希望通过研究其缓存和运行原理,以从中探求控制本地缓存更新的方法。而这也便是本文的缘起。
2、运行原理
ArcGIS中对WFS访问客户端的支持是基于FME来实现的,所以新建WFS连接的界面的风格与FME基本一致,如下图所示:
图5 新建对话框
图6 参数对话框
当使用Interoperability模块新建了一个WFS连接后,ArcGIS会在目录“%userprofile%\AppData\Roaming\Safe Software\Interoperability”中自动生成一个后缀为“.fdl”的WFS连接文件。将该文件使用文本编辑器打开,可以发现该文件其实就是存储了所有用于定义该WFS连接的相关参数:
图7 WFS连接文件
同时,在ArcGIS中对该WFS连接的所有操作,包括连接的创建、修改、访问等操作均以日志的形式存储在同级目录的log目录下,如图:
图8 互操作log文件
通过查看对应的log文件笔者发现,原来ArcGIS在建立WFS连接的同时会自动将WFS中所有的要素全部加载并缓存在本地文件中,同时为了加快对本地缓存要素的查看,还为这些要素做了空间索引,证据如下:
2010-12-21 11:15:37| 50.0| 0.0|STATS |Stored 6 feature(s) to FME feature store file `C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPC_1292901310941_3684'
2010-12-21 11:15:37| 50.0| 0.1|STATS |Storing feature(s) to FME feature store file `C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPCS_1292901310944_3684'
2010-12-21 11:15:37| 50.0| 0.0|STATS |Stored 0 feature(s) to FME feature store file `C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPCS_1292901310944_3684'
2010-12-21 11:15:37| 50.1| 0.0|INFORM|Saving spatial index into file 'C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPCS_1292901310944_3684.fsi'
2010-12-21 11:15:37| 50.1| 0.0|INFORM|Finished saving spatial index into file 'C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPCS_1292901310944_3684.fsi'
2010-12-21 11:15:37| 50.1| 0.0|INFORM|Saving spatial index into file 'C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPC_1292901310941_3684.fsi'
然后,笔者有进一步地查看了以上四个文件,发现其中:
1、文件FFSPC_1292901310941_3684用于存储要素实体;
2、文件FFSPC_1292901310941_3684.fsi存储了要素的空间索引;
3、文件FFSPCS_1292901310944_3684存储了要素的数据结构;
4、文件FFSPCS_1292901310944_3684.fsi似乎没有使用(先存个疑)。
同时,以上这些文件通过同级目录中的MasterTable.xml文件来管理,并且该文件管理了所有与互操作相关的数据缓存,ArcGIS内嵌的FME互操作模块正是结合上述的.fdl连接文件以及该xml文件来访问缓存的WFS数据的。
<? xml version="1.0" encoding="UTF-8" ?>
< fmeobjects-cache-table fme-build-number ="6213" >< id-cache >< id >< single-properties >< property name ="reader-type" value ="WFS" /></ single-properties >< multi-value-properties >< property name ="datasets" >< item value ="http://esri-wangxin-male:8399/arcgis/services/WfsPoly/MapServer/WFSServer" /></ property ></ multi-value-properties >< string-array-properties >< pairs name ="keywords" >< property name ="COORDINATE_SYSTEM" value ="" />< property name ="FEATURE_TYPE_ATTRIBUTE" value ="fme_feature_type" />< property name ="FILTER_EXPRESSION" value ="" />< property name ="FME_FEATURE_IDENTIFIER" value ="" />< property name ="HTTP_AUTH_METHOD" value ="Basic" />< property name ="HTTP_AUTH_USER" value ="" />< property name ="HTTP_PROXY" value ="null" />< property name ="HTTP_PROXY_AUTH_METHOD" value ="Basic" />< property name ="HTTP_PROXY_PORT" value ="null" />< property name ="HTTP_PROXY_USER" value ="" />< property name ="IDs" value ="WfsPoly:school {school}" />< property name ="MAXX" value ="" />< property name ="MAXY" value ="" />< property name ="MAX_RESULT_FEATURES" value ="30000" />< property name ="MERGE_SCHEMAS" value ="YES" />< property name ="METAFILE" value ="WFS" />< property name ="MINX" value ="" />< property name ="MINY" value ="" />< property name ="ORIENTATION_RULE" value ="RIGHT_HAND_RULE" />< property name ="SPATIAL_INDEX_ATTRIBUTE" value ="fme_feature_type" />< property name ="SPATIAL_INDEX_ATTRIBUTE" value ="fme_type" />< property name ="TABLELIST" value =""WfsPoly:school {school}"" />< property name ="UNIQUE_ID_ATTRIBUTE" value ="FME_FEATURE_ID" />< property name ="USE_HTTP_AUTH" value ="NO" />< property name ="USE_PROXY_SERVER" value ="NO" />< property name ="USE_SEARCH_ENVELOPE" value ="NO" />< property name ="XSD_DOC" value ="" /></ pairs ></ string-array-properties ></ id >< cache >< single-properties >< property name ="time-stamp" value ="2010-12-22 22:28:29" />< property name ="schema-spatial-index-path" value ="C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPCS_1293028109579_2672" />< property name ="time-based-expiry" value ="yes" />< property name ="spatial-index-path" value ="C:\Users\ADMINI~1\AppData\Local\Temp\INTEROP\FFSPC_1293030594489_5328" /></ single-properties ></ cache ></ id-cache ></ fmeobjects-cache-table >
3、更新缓存的方法
笔者在文件MasterTable.xml中笔者还发现了<property name="time-based-expiry" value="yes"/>,该参数似乎是用于指定对应的缓存是否基于时间过期,但笔者查了很多资料都没能查到FME中默认的过期时间到底是多少,如果有朋友知道请能告诉我。不过在实际应用场景中,单纯地由客户端基于过期时间的自动更新显然有些不合理——过期时间太短,则刷新过于频繁而影响效率;过期时间太长,则无法反映最新数据。所以,WFS的缓存过期应该是由数据源更新来驱动的,即数据源更新的同时进行缓存的刷新。在ArcGIS的产品体系统对于WFS的使用无非是两种技术路线,一是直接将ArcDesktop作为WFS客户端来使用WFS服务,另一种是将WFS服务发布到ArcGIS Server中,并有Server将其再发布成Server支持的其它服务。所以,针对这两种路线,其对应的缓存更新的方法如下:
A、在ArcDesktop中的更新的缓存的方法
1)删除MasterTable.xml文件中目标缓存对应的实体;
2)删除该实体中引用的同目录下的要素缓存文件、要素索引文件、要素架构文件、以及要素架构索引文件;
3)在ArcCatalog中刷新对应的WFS连接。
当再次访问该WFS连接时,ArcDesktop会重新从数据源加载并缓存要素到新建的本地缓存文件中。
B、在ArcGIS Server中更新缓存的方法
1)删除MasterTable.xml文件中目标缓存对应的实体;
2)删除该实体中引用的同目录下的要素缓存文件、要素索引文件、要素架构文件、以及要素架构索引文件;
3)在ArcCatalog或Web版的ArcGIS Server Manager中重新启动对应的服务。
当再次访问该服务时,ArcGIS Server会重新从数据源加载并缓存要素到新建的本地缓存文件中。
4、我们在哪
由于FME中WFS本地缓存更新机制导致ArcGIS的无法有效地满足WFS数据源更新频繁的场景下的最新数据访问需求,所以笔者从ArcGIS中WFS互操作模块运行原理的角度想读者介绍了关于ArcGIS在WFS互操作时所涉及的操作和数据文件的相关原理性的知识,并在此基础上进一步分别介绍了在ArcDesktop和ArcGIS Sever环境下WFS缓存更新的方法。但是,需要注意的是,本文介绍的方法也只是治标不治本的。真正治本的还是应该由OGC进一步完善WFS标准,从而使得WFS能够支持轻量级的更新提醒机制,然后再由ArcGIS定期的去扫描该WFS是否更新。若已更新,则自动加载更新后的WFS数据并将其缓存在本地,如此既可以提高数据的访问效率,又能够不因为扫描数据源更新的频度过高而影响带宽和服务器计算资源。