《ArcGIS Runtime SDK for Android开发笔记》——(11)、ArcGIS Runtime SDK常见空间数据加载

 ArcGIS Runtime SDK for Android 支持多种类型空间数据源、每一种都提供了相应的图层来直接加载,图层Layer是空间数据的载体,其主要继承关系及类型说明如下图所示:

转载请注明出处:http://www.cnblogs.com/gis-luq/p/5062715.html

 

1、图层分类解析

Layer是所有图层的基类,声明了空间参考、最大范围、初始范围、单位和图层委托等基本属性,还有图层加载的相关方法。

同时对于MapView的空间参考,最大范围,初始范围若不特殊指定,即为第一个加入MapView的图层相关信息所决定。这也是初学ArcGIS Android开发特别需要注意的地方,其后加入的所有图层也须与第一个一致,否则会导致加载不成功。

图层大体可以分成三大类:在线图层、离线图层、交互图层。

1.1、在线图层

在线主要包括静态图层(TiledLayer)和动态图层(DynamicLayer)两大类。

此外继承交互图层GraphicLayer的ArcGISFeatureLayer也是在线图层的一种,用于在线要素编辑。

静态图层泛指缓存过的地图服务,除非服务端删除或更新缓存,否则客户端请求的数据永远是固定不变的,而动态图层正好相反,服务器根据每个请求动态的生成数据,一静一动各有用途。这两种图层都是由ArcGIS for Server提供。

1.2、离线图层

离线图层主要包括:栅格图层、离线矢量图层两大类。

栅格图层主要包括:ArcGISLocalTiledLayer(用于加载紧凑型切片、TPK),RasterLayer(用于加载 ASRP/USRP、CIB1,5,10、DTED0, 1, 2、GeoPackage、GeoTIFF、HFA、HRE、IMG、JPEG、JPEG2000、NITF、PNG、RPF、SRTM1, 2格式的影像数据)

离线矢量图层主要包括:FeatureLayer(用于加载shapeFile、Runtime Content<.geodatabase>格式的矢量数据)

特殊说明:这里需要注意FeatureLayer和ArcGISFeatureLayer的区别,FeatureLayer继承于Layer用于离线矢量数据的加载,ArcGISFeatureLayer继承于GraphicLayer,用于加载ArcGIS for Server 发布的FeatureService服务,做在线编辑使用。

1.3、交互图层

交互图层即负责和用户打交道的图层,比如绘制点、线、面;画一个矩形,圆,这些都是需要先存储在零时图层。用于响应用户的绘制操作。在ArcGIS Runtime SDK中交互图层主要通过GraphicLayer实现。

 

2、常见空间数据的加载方法

常见空间数据类型主要有:在线底图服务;离线底图的tpk和缓存切片、影像数据;离线矢量的.geodatabase,shapFile文件。

2.1、加载ArcGIS在线数据源

ArcGIS在线的数据源有很多种,包括地图服务、要素服务、影像服务等,同时,ArcGIS Runtime SDK for Android中也提供了各种相应的图层来加载在线数据,具体如下:

2.1.1、ArcGISTiledMapServiceLayer

ArcGISTiledMapServiceLayer图层对应ArcGIS for Server服务中的切片服务,由于切片都是事先做好的,ArcGISTiledMapServiceLayer不能对图层中的数据进行更改,除非更新服务缓存,在ArcGIS Runtime SDK for Android中,也不允许对此类型的数据进行查询,通常用做底图使用。同时,因为加载的是缓存切片,这个类型的图层是ArcGIS Runtime SDK for Android中相应请求最快的图层之一,它采用多个线程,通常是使用单独线程来处理请求和绘制图片,并且异步处理。用法如下:

        map = (MapView)findViewById(R.id.map);
        // Add tiled layer to MapView
        ArcGISTiledMapServiceLayer tileLayer = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer");
        map.addLayer(tileLayer);

 2.1.2、ArcGISDynamicMapServiceLayer

ArcGISDynamicMapServiceLayer图层对应ArcGIS for Server服务中的动态服务,动态地图服务的地图数据是按照移动设备范围读取的。  ArcGISDynamicMapServiceLayer图层通常包含多个图层,这些图层由server根据请求来渲染并以raster image形式返回,并且返回的raster并不包含feature的额外信息。它的功能特点是更新非常方便,并能及时呈现给用户,同时,图层的可视性和空间参考可以改变,可以给图层添加单独的layer definition,ArcGIS for Server为每个image动态投影,而地图的空间参考是由第一个加载的图层决定。

它的性能特点是,它的渲染时间取决于请求数据的数量和复杂度,因此一般都比tiled map server要慢,因此,它适合数据经常发生改变、或者需要针对不同的用户呈现不同的数据,且要素信息(如attributes,geometry,symbol等)不需要的情况。

它的用法与ArcGISTiledMapServiceLayer图层相同,示例代码如下:

        map = (MapView)findViewById(R.id.map);
        // Add DynamicMapServiceLayer to MapView
        ArcGISDynamicMapServiceLayer agsDynlyr = new ArcGISDynamicMapServiceLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Population_World/MapServer");
        map.addLayer(agsDynlyr);        

2.1.3、ArcGISImageServiceLayer

 ArcGISImageServiceLayer图层对应ArcGIS for Server服务中的影像服务,它为移动端使用影像数据提供了一种途径,通过这种方式调用的影像数据通常可以用来作为底图。调用影像服务也非常简单,同调用上述服务一样,示例代码如下:

map = (MapView)findViewById(R.id.map);
map.addLayer(new ArcGISImageServiceLayer("http://myserver/arcgis/rest/services/MyImage/ImageServer",null));

2.1.4、ArcGISFeatureLayer

ArcGISFeatureLayer图层对应ArcGIS for Server服务中的Feature Service,该图层可以是空间图层,也可以是非空间的表,该图层包含了要素最丰富的信息,其中的每个要素都能被空间查询和SQL查询。从Feature Service中请求要素时以JSON格式返回,每个要素都单独渲染,因此与其它图层类型相比,要素图层具有最丰富的功能。

只有Feature Service(要素服务)才可以具备在线数据编辑功能,因此,如果想要对某个数据进行在线编辑或同步,需要将其发布成Feature Service,并在移动端新建一个ArcGISFeatureLayer图层以加载该服务。该图层有一些设定,这些设定能影响图层的性能,包括请求时间,返回大小、处理和响应时间等(设置需要在图层initialized完成之后进行)。

  • ŸOut fields:可以通过outFields()方法来限制返回的属性字段的数量,可以减少网络传输和响应处理的时间;

  • ŸMax Allowable offset:使用Max Allowable offset()方法可以限制要素返回的顶点数量,以地图单位设置的数值将用来在server返回要素之前简化要素的顶点,当你正在编辑要素时不应该使用此方法,可能会导致顶点丢失和TOPO关系的破坏。

  • ŸArcGISFeatureLayer在调用时可以设置3种模式(mode),不同模式返回数据的方式和执行的效率不同:

  1. Snapshot mode:快照模式能从Server上快速取回要素,能减少响应时间,但如果图层包含大量、复杂的要素时,可能会导致设备停止响应,因为有大量的要素需要绘制,也会导致ArcGIS for Server达到它返回要素数量的上线。ArcGIS Server 9.3.1的默认限制是500,10.0是1000,当然,这个数据可以在server端进行配置。建议小数据量的dataset才使用snapshot mode。

  2. On demand mode:On demand mode需要在客户端和服务器之间传递更多的请求,适合展示变化的数据,该mode适合包含复杂要素的大数据量的dataset,因为它只请求和返回需要的要素,不过,为图层设置比例尺限制仍然是有必要的。

  3. Selection mode:该模式下,一开始并不向服务器请求任何要素,只有当选择集出现时,要素才被加载,这种mode适合于不需要将所有要素展示在客户端,而只是强调一些特殊的要素,如,有一个road图层,使用了feature layer不支持的自定义的符号,但是又需要对该图层进行web edit,此时,你可以使用一个dynamic map service layer和一个feature layer in selection mode,将需要编辑的road选择出来,以简单的符号绘制并存储在feature layer以实现编辑,当编辑完成后,清除选择并刷新dynamic map service来查看更新。

ArcGISFeatureLayer图层继承自GraphicsLayer,因此也具有该图层的所有操作。调用该图层的示例代码如下:

String url =
"https://servicesbeta.esri.com/ArcGIS/rest/services/SanJuan/TrailConditions/FeatureServer/0";
        map = (MapView)findViewById(R.id.map);
//按照快照方式加载该图层
map.addLayer(new ArcGISFeatureLayer(url,MODE.ONDEMAND));
setContentView (map);

 

2.2、加载tpk和紧凑型切片

紧凑型切片是在ArcGIS 10中出现的一种新的切片缓存文件格式,与之前的松散型切片存储相比,它具有迁移方便、创建更快、节省存储空间等诸多优点。紧凑型存储主要有两种文件:bundle和bundlx,前者用于存储切片数据,后者是切片数据的索引文件,一个bundle文件中最多可存储128*128个切片。

tpk是ArcGIS 10.1中推出的一种新的数据切片缓存文件类型,主要是用于将紧凑型切片文件打包形成离线地图包,这样做的好处是可以进一步减少缓存切片文件的数目,节省存储空间,并更加方便的迁移(迁移紧凑型切片时可能一个市就成千上万个细小的文件,而一个市的tpk包可能只有一个文件)。

tpk和紧凑型切片都可以在ArcGIS Runtime SDK for Android中作为离线底图被加载。具体的tpk和紧凑型切片的制作请参见博文http://blog.csdn.net/arcgis_mobile/article/details/8048549, http://www.cnblogs.com/gis-luq/p/4950157.html

ArcGISLocalTiledLayer是ArcGIS Runtime SDK for Android中专门用来添加离线数据包(底图)的图层,该图层目前支持两种格式的离线数据:一个是紧凑型切片,另一个就是tpk。使用起来也很简单,实例化该类的一个对象,并在构造函数中输入数据的路径即可,代码示例如下:

        map = (MapView)findViewById(R.id.map);
        // Add Local tiled layer to MapView
        ArcGISLocalTiledLayer agsLocaltiledlyr = new ArcGISLocalTiledLayer("file:///mnt/sdcard/ArcGIS/sample/HelloWorld/Layers");
        map.addLayer(agsLocaltiledlyr);

 

2.3、加载影像数据

ArcGIS Runtime SDK for Android 从10.2.4开始支持直接读取本地影像数据,数据类型包含:ASRP/USRP、CIB1,5,10、DTED0, 1, 2、GeoPackage、GeoTIFF、HFA、HRE、IMG、JPEG、JPEG2000、NITF、PNG、RPF、SRTM1, 2

FileRasterSource是加载本地影像数据文件类,地图视图中以RasterLayer作为图层对象展示出来。代码如下:

String rasterPath = Environment.getExternalStorageDirectory().getPath() + "/raster/test.tif";
FileRasterSource rasterSource;
try {  
 rasterSource = new FileRasterSource(rasterPath);  
} catch (IllegalArgumentException ie) {
  Log.d(TAG, "null or empty path");
} catch (FileNotFoundException fe) {
  Log.d(TAG, "raster file doesn't exist");
} catch (RuntimeException re) {
  Log.d(TAG, "raster file can't be opened");
}
RasterLayer rasterLayer = new RasterLayer(rasterSource);
mMapView.addLayer(rasterLayer);

 

2.4、加载离线的.geodatabase本地文件

.geodatabase文件是ArcGIS 10.2中专为业务数据的离线而推出的一种数据格式,本质上,它仍然是SQLite数据库的封装,在SQLite数据模型的基础上,Esri计划逐步实现桌面端Geodatabase数据模型的存储,不仅包括Feature Class,还包括镶嵌数据集、网络数据集等。目前,主要实现了Feature Class的存储。

即,在ArcGIS 10.2.2中,要使用完全的离线功能,可以使用ArcGIS for Desktop提供的GP工具来将需要编辑和离线的业务数据导出到.geodatabase中,也可以直接从ArcGIS for Server上的要素服务中下载数据,并在移动端存储为.geodatabase,从而实现完全离线的移动应用。具体的.geodatabase文件的制作方法请参见http://blog.csdn.net/arcgis_all/article/details/19110351

ArcGIS Runtime SDK for Android中也提供了具体的Geodatabase类和FeatureLayer图层来加载.geodatabase文件,常用的类包括Geodatabase、GeodatabaseFeatureTable、GeodatabaseFeature、GeodatabaseFeatureServiceTable等,分别用来打开geodatabase数据文件、获取要素图层、获取图层中的具体要素,以及获取在线的要素服务。具体来讲,加载.geodatabase文件的步骤有如下几步:

1、  实例化一个Geodatabase对象,这个类有两个构造函数,都需要指定本地数据库的存储路径;

2、  创建一个GeodatabaseFeatureTable对象实例,用来获取需要的图层;

3、  创建一个FeatureLayer来存储获取的图层,并将获取的图层加载到地图中;

4、  调用dispose()方式释放资源。

示例代码如下:

            //实例化geodatabase对象,并指定文件目录
         gdb = new Geodatabase("{/path/to/geodatabase}");
            //实例化gdbfeaturetable对象,并获取第一个图层
            gdbfeaturetable = gdb.getGeodatabaseFeatureTableByLayerId(0);
            //    创建一个FeatureLayer来存储获取的图层,并将获取的图层加载到地图中
            featurelayer = new FeatureLayer(gdbfeaturetable);
            mMapView.removeAll();
            mMapView.addLayer(featurelayer);    
            //    调用dispose()方式释放资源
            gdb.dispose();

 

2.5、加载ShapeFile文件

ShapeFile文件:ArcGIS平台中最常见的数据格式,包含属性信息、投影信息等。新版本的SDK(10.2.4开始)可以直接加载.shp文件进行数据的展示、查询。代码加载如下:

       ShapefileFeatureTable shpTable = new ShapefileFeatureTable(shpUrl);
            FeatureLayer fl = new FeatureLayer(shpTable);
            fl.setRenderer(new SimpleRenderer(new SimpleMarkerSymbol(
                    Color.BLACK, 2, STYLE.CIRCLE)));
            mapView.addLayer(fl);

 

posted on 2015-12-21 17:55  gis-luq  阅读(7543)  评论(0编辑  收藏  举报