您的位置:首页 > 移动开发 > Android开发

Arcgis For Android之离线地图实现的几种方式

2015-04-17 10:06 351 查看

一、

在Arcgis For Android API下,既能加载Arc Server的切片文件,也能加载10.1的Title Package文件(*.tpk)。

一般来说,我们都是将Server的切片文件或者tpk文件复制到自己手机的SD卡上面。下面以我的手机为例说一下文件路径。小编没什么钱,买了一个华为的C8813Q的电信机器,正常来说,安卓的手机都是有运存,内存,和外存(SD卡存储)。运存,是程序运行是所需的存储,在程序运行结束后会有一个销毁的过程,所以运存是不做为存储的,所以,手机的内存和外存才是作为存储的,所以,一般来说,我们的离线地图是放在内存或者外存的,但是,为方便期间,个人建议将离线地图文件放在SD卡中,不支持SD卡的手机就只能放在内存了。如果既有内存,又支持SD卡,一般内存的路径为:file:///storage/sdcard0,SD卡的路径为file:///storage/sdcard1,没有SD卡的路径为:file:///storage/sdcard。

在Arcgis For Android中,实现离线地图的加载与显示,首先我们需要用Server或者10.1去做离线地图的切片文件或者切片打包文件。用Server做切片文件的大家都知道,就不多说了,切片打包文件可以参考这篇http://blog.csdn.net/arcgis_mobile/article/details/8048549文章,很详细,一看就会。有了离线地图文件,将文件拷贝到手机SD卡中,我的文件路径如下:


vcHLuMPEv8K8z8LD5qGj09DBy9Xi0KnA68/fzsS8/qOs1NqzzNDy1tDQ6NKq0ru49k1hcFZpZXfAtM/Uyr612M28o7o8L3A+CjxwPjxlbT48Y29tLmVzcmkuYW5kcm9pZC5tYXAuTWFwVmlldzxicj4KICBhbmRyb2lkOmlkPQ=="@+id/map"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

有了MapView,我们需要

1、定义一个离线图层

MapView map = null;

ArcGISLocalTiledLayer local;

2、设置离线图源

在设置里线图源的时候,可以用下面两种方式:

local = new ArcGISLocalTiledLayer("file:///storage/sdcard1/arcgis/base_map.tpk");

local = new ArcGISLocalTiledLayer("file:///storage/sdcard1/arcgis/nmg/Layers");

此外,也可以写成,不过下面这种路径的书写方式不建议,有时候会读取不到。

local = new ArcGISLocalTiledLayer("file:///mnt/sdcard/arcgis/base_map.tpk");

local = new ArcGISLocalTiledLayer("file:///mnt/sdcard/arcgis/nmg/Layers");

3、将离线图层添加到mapview显示。

map.addLayer(local);

到此,离线地图的加载与显示已经实现了,更多的功能等你去开发了。不过,你得在配置文件中加入读取外部存储的许可。

二、

1,要在ArcGIS Server中发布你的地图(发布地图请自己上网google),最好是有切片的地图,然后找到发布的文件夹



2,直接将文件夹考到SD卡的根目录上(也可以到其他的文件夹,但是要记住你的路径)

3,在eclipse中新建 ArcGIS for android项目(这个不用我再教你们了吧。不会的可以google)

3,配置layout文件,添加MapView控件
<com.esri.android.map.MapView
android:id="@+id/LocalMap"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>


4,在代码中加入一下代码
//声明MapView
MapView mMapView ;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//实例化MapView
mMapView= (MapView)findViewById(R.id.LocalMap);
//存储切片文件路径
String path="file:///mnt/sdcard/WorldMapCompact/Layers/";
//声明并实例化ArcGISLocalTiledLayer
ArcGISLocalTiledLayer localMap=new ArcGISLocalTiledLayer(path);
//将离线地图加载到MapView中
mMapView.addLayer(localMap);
}


代码中的path就是存放在SD卡上的图片文件夹,这里的路径可以修改,请自行记好就OK啦!

5,加入权限,使手机有权限读取SD卡文件
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>


6,运行 调试结果:



注意:有时出不来图,是因为你的手机在电脑上连接着,sd卡已经挂载,无法读取SD卡内容,或者有时需要在程序管理中强制停止程序后再打开才能出图。

三、

ArcGIS for Android离线数据编辑实现原理

实现ArcGIS for Android上的离线数据编辑,具体实现环境及其步骤如下:

一、 环境准备

1. 软件环境

1) ArcGIS Server10用于发布地图服务

2) ArcGIS Destop10用于切缓存图片

3) Eclipse3.6.2+ 集成开发环境

4) JDK1.6

5) Android SDK

6) Android Development Tools

7) ArcGIS API for Android1.1插件

8) ArcSDE for Oracle11g

9) Oracle11g

2. 地图服务准备

1) 在所有软件环境都已安装好后,首先我们要通过ArcGIS Server来发布两个可编辑的地图服务,也就是发布FeatureServer的地图服务,两个服务分别用于在线时的数据下载和数据上传。(上传数据时不能直接上传到实际下载的服务上去,数据编辑后需要有一个审核的过程,所以需求另一个服务进行数据临时存储,等审核通过后才可以上传的我们发布的下载服务上去)

2) 在离线状况下我们还需要一个缓存切片地图,使用ArcCatalog来切一幅缓存图片,用于后期设备端的离线地图显示(地图切片必须是紧凑型的)。

二、 实现步骤

1. 项目创建

使用eclipse创建一个ArcGIS for Android项目,并将上面通过ArcCatalog切的缓存图片的文件夹拷入到你的设备sd卡中。

2. 添加地图服务

在项目中的Activity中添加三个地图服务,一个是用于离线地图显示ArcGISLocalTiledLayer服务,另两个是用于数据下载和上传的ArcGISFeatureLayer服务;此外还添加一个GraphicsLayer用于查询出的数据显示的图层。

3. sqlite数据库

使用sqlite数据库来储存离线数据,通过扩展SQLiteOpenHelper来实现数据库和表的创建;创建表时,表结构应该与我们发布的Feature Server服务中用到的表结构基本一致(多添加一个mark字段用于标记操作的状态)。在此,关键在于空间shape字段的存储,在sqlite中没有空间字段的概念,因此,使用地图服务查询出来的数据在入库到sqlite中时,应该定制插入数据的格式,在入本地库时我们可以按照空间数据的类型:点、线和面来进行定制拼装,如点类型我们入库时可以拼成Point(X ,Y)这样的形式,下此取出时按照这种格式进行解析拼装空间对象就可以了,在定制完各种空间数据类型的表示形式后,最好编写一个工具类专门负责数据格式的解析和拼装(由于我要做的Demo只涉及点数据所以在数据库的表中没有shape字段,而是添加了X和Y两个字段来存储坐标信息)。

4. 数据编辑

在对数据进行编辑的时候,我们基本分两方面进行编辑:一个是属性编辑,另一个是空间编辑。当我们通过ArcGISFeatureLayer查询的数据,并通过我们定制的数据格式插入sqlite数据后,我们这时可以进行离线的数据操作了。

1) 属性编辑

对于属性修改无非就是对Graphic对象的中的属性进行修改,Graphic不能添加事件监听,所以不能像按钮一样,添加一个点击事件弹出该要素的相关信息,我们可以通过GraphicsLayer的getGraphicIDs(float x, float y,int tolerance)方法来获取要素及其要素的相关属性,可悲是Graphic中没提供修改属性的接口,只能新建一个Graphic对象并在他的构造方法中来添加更新后的属性或者是通过GraphicsLayer的update Graphic(int id, Map<String,Object>
attributes)的方法来更新Graphic的属性,并且将修改的要素属性更新到本地sqlite数据库中及其修改表中mark字段的状态。

2) 空间编辑

对于Graphic对象我们不仅可以改变他的属性还可以修改它的空间位置信息,对于点、线、面的修改略有不同。点修改时,直接更新Graphic的Geometry即可,不过Graphic没有提供修改Geometry的接口,我们只能通过GraphicsLayer的updateGraphic(int id, Geometry geometry)方法来实现更新它的空间位置。线和面的空间位置改变主要指的是线或面的节点的位置修改,我们可以点击线或面上的一个节点进行拖动用GeometryEngine.getNearestVertex()可以得到我们点击的点,距离几何体的哪个节点最近,并返回一个Proximity2DResult对象,通过这个对象我们可以得到这个节点Index位置,再通过线或面对象的setPoint(int
index, Point point)方法更新节点,这时我们的图形就可以改变了,将更新后的Graphic的空间对象重新解析成定义的格式入库及其修改表中mark字段的状态。

5. 数据提交

到上面的步骤,离线数据编辑功能基本完成,最后,当我们在线时,只需通过ArcGISFeatureLayer把数据提交到临时表中进行审核即可。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: