我们知道对于移动GIS来说,数据主要分为两种类型:底图数据(basemap layers)和业务数据(operational layers)。在《ArcGIS移动客户端离线底图的几种解决方案》一文中,已经讨论了ArcGIS for iOS/Windows Phone/Android三种客户端底图离线的方案和解决办法,本文中则来讨论一下业务数据离线的可能性。
首先我们得考虑一下业务数据离线的实际需求。以成熟的ArcGIS Mobile产品为例,它拥有完整的离线缓存(MobileCache)。而ArcGIS新的移动客户端中,目前均以在线服务数据为基础,没有离线数据的存储格式,因此我们首先得解决如何存储离线业务数据这个问题。我想到的格式有四种:json文本,shapefile,Sqlite,和Spatialite。因为这四种格式均已少量文件形式存在,且对空间数据有不同程度的支持,比较适合移动平台利用。对于MobileCache的使用,最常见的需求有两种,一种是数据采集(增/删/改),另一种是对离线数据的查询和分析。我们来分别考虑这两种需求。
一、数据采集
ArcGIS for iOS/Windows Phone/Android三种移动客户端中,在线的数据采集和同步是通过FeatureLayer+FeatureService的方式来完成的。而离线的情况下,没有了FeatureService的支持,我们主要通过GraphicsLayer或FeatureLayer来完成数据的采集工作。需要考虑两个问题,一个是离线数据的获取(比如需要编辑已有图形的属性数据),另一个是离线数据的提交(将改动同步回服务器数据库中)。而在离线数据获取之后,提交之前的这段时间内,就需要以某种格式来支持数据的编辑。
ArcGIS客户端API在2.0版本后,提供了Editor类,可以很容易完成对GraphicsLayer的图形编辑,属性编辑就不用多说了。比如ArcGIS API for Windows Phone中,我们就可以用同样的思路来完成离线编辑过程。这就是我们离线数据采集的思路。
json文本格式。esri在REST API中定义了自己的基于json的数据存储方式,包括空间和属性数据。通过FeatureLayer加载在线服务,将其中所有的要素通过通过ToJson方法(或FeatureSet.ToJson())保存为json文本格式,就完成了数据的下载工作;离线后,可通过GraphicsLayer来加载这些json文本数据(FeatureSet.FromJson()),使用Editor类对其图形和属性进行编辑,或对新增数据进行采集。完成后,就得到了一个经过编辑的json文本;之后网络条件允许时,再次通过在线FeatureLayer的方式,将编辑后的json数据加载,利用FeatureService同步回服务器端。此方法对于iOS API和Windows Phone API可直接适用,Android API在正式版发布后应该会完善其对json格式的支持。
shapefile格式。由于shapefile格式公开,有许多现成的类库提供了支持,因此可以考虑将它作为离线数据的载体。离线数据的获取非常方便,只需在服务器将数据导出为shapefile格式,即可分发到移动设备上。而在移动设备上加载shapefile,绘制成GraphicsLayer,每个平台都可以找找现成的类库来使用,Windows Phone见这里,iOS见这里;依然利用Editor类对GraphicsLayer的数据进行编辑和采集;最后需要将GraphicsLayer的数据写回shapefile中。之后回到室内,可将shapefile再倒入服务器数据库中。关于.NET中可供参考的几个包含Shapefile读写功能的库:sharpmapv2,egis,NetTopologySuite等。
Spatialite数据库。Spatialite是基于Sqlite的一个C语言库,支持空间数据操作的单文件数据库(类似于Postgresql+PostGIS),支持WKT,WKB和自己的三种空间数据格式,此外通过PROJ.4支持动态投影,还支持Buffer,Union等空间操作,是移动平台上空间数据存储的理想选择。编辑和采集依然通过GraphicsLayer和Editor类来完成。但和上面的shapefile一样,数据的获取和提交需要做转换工作。
Sqlite数据库。把它放在最后有两方面原因。一是在离线方案的讨论中,我们已经知道几乎每个移动平台上对Sqlite数据库都有很好的支持;二是它本身并不支持空间数据格式,所以不仅要进行格式转换,还要自己来解决空间数据的存储。但对于在不支持Spatialite的移动平台上又想使用数据库来管理数据的情况,可以考虑Sqlite。此处就不详细讨论了。
对于数据采集这个需求,四种数据格式从理论上均可很好地支持。API中对json方式的读写有原生的支持,因此不需要进行任何格式转换;而后三种存储均需要自己来完成与Graphic的数据转换工作。总的来说,由于移动数据采集工作一般携带的业务数据量较少,因此用json文本来存储数据比较方便,也非常容易实现。
二、查询和分析
离线的业务数据,经常需要进行一些属性查询工作,除此之外,还有空间的查询和简单的几何运算或关系判断。在ArcGIS Mobile的离线缓存中,这些功能都提供了很好的支持,但ArcGIS for iOS/Windows Phone/Android中,上述需求都是通过各种Task配合在线服务来完成的,不支持离线功能。真对上述提出的几种数据源,来分析一下查询和分析的功能如何实现。
json文本格式。对于这种格式,在加载为GraphicsLayer后,我们可以利用Linq语言来进行类似属性查询工作;通过Envelope. Intersects方法/GraphicsLayer. FindGraphicsInHostCoordinates方法可完成空间查询(矩形)。
Shapefile格式。同上。
Sqlite。同上。
Spatialite数据库。Spatialite具有原生的空间数据操作能力,包括Union,Buffer等,还可以通过sql语句进行基于空间索引的空间查询,功能比较强大,可完成离线的空间查询和分析需求。但依然需要进行ArcGIS<–>Spatialite数据格式转换。
对于离线查询和分析这个需求,只有Spatialite数据库这种格式支持比较全面。目前Spatialite有iOS,Windows Mobile,Android等平台上的支持,Windows Phone暂时无解。 但值得注意的的是ArcGIS API for Android和ArcGIS API for iOS(1.8版本之后),都提供了GeometryEngine(ios版,Android版)这个类,被称作离线的几何图形引擎。可在客户端完成GeometryService的大部分功能,比如area,length,buffer,union,cut,simplify,project等,这是具有里程碑意义的一步。很早的时候我就期待客户端的GeometryService功能了,并尝试自己实现了一小部分。我们可以同样期待在未来的Windows Phone API,甚至Javascript/Flex/Silverlight API中,给我们带来同样的惊喜。
结论:ArcGIS新的移动客户端中,离线数据采集需求可以并容易实现;简单的离线的查询和分析完全可通过json数据源实现;复杂的查询和分析实现与平台有关,iOS和Android可以实现。但还是期待ArcGIS在以后给我们带来原生的离线功能支持。
什么?你说还有File Geodatabase API?它看上去功能是不错,但移动平台上的类库不知道esri会不会或者何时才能编译出来了。