《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据下载

原文链接:http://www.cnblogs.com/gis-luq/p/5858048.html


1、前言

1.1、环境准备:

  • ArcGIS for Desktop 10.4.1(10.2.1以上版本即可)
  • ArcGIS for Server 10.4.1 (10.2.1以上版本即可)
  • PostgreSQL、Microsoft SQL Server、或 Oracle 设置企业级地理数据库

1.2、发布具有同步能力的FeatureService服务

  过程参考 数据制作篇:发布具有同步能力的FeatureService服务 一文。

image

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

2、demo实现过程

ArcGIS Runtime SDK 配置实现过程略:具体请参考:

基于Android Studio构建ArcGIS Android开发环境

基于Android Studio构建ArcGIS Android开发环境(离线部署)

2.1、Demo UI实现

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.downgdb.MainActivity">

<!-- MapView -->
<com.esri.android.map.MapView
android:id="@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
mapoptions.MapType="Topo"
mapoptions.ZoomLevel="5"
mapoptions.center="28.671298, 104.066404" />

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:id="@+id/linearLayout"
android:background="@color/primary_material_light">

<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/editTextGDBUrl"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_weight="1"
android:text="http://192.168.1.212:6080/arcgis/rest/services/testdata/FeatureServer" android:inputType="textUri" />

<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="数据下载"
android:id="@+id/btnDownGDB" />
</LinearLayout>

</RelativeLayout>

2.2、在Android清单文件AndroidManifest.xml中增加网络及存储访问权限

1
2
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2.3、实现离线地理数据库下载逻辑

基本思路:

  1. 设置.geodatabase文件存储路径
  2. 根据FeatureService服务获取FeatureServiceInfo服务参数信息
  3. 根据FeatureServiceInfo信息创建离线地理数据库文件、
  4. 从已经下载的本地Geodatabase文件中加载矢量数据

下载数据的核心功能类说明:

  • GeodatabaseSyncTask类,实现下载同步功能

  • GenerateGeodatabaseParameters,下载数据时所需的参数对象,该类构造函数一共有7个根据需要选择:

image

本次示例代码主要用到以下三个参数:

    • featureServerInfo 服务参数信息
    • geodatabaseExtent 地图下载区域范围
    • geodatabaseSpatialReference 地图空间参考
  • CallbackListener,完成GDB数据库下载的回调函数类,在该回调中我们只可以执行一些操作,如示例里在回调中删除了在线的服务图层,加载离线的数据图层到地图上进行显示。通过Geodatabase本地数据库可以获取要素图层列表List<GdbFeatureTable>对象,通过newFeatureLayer(gdbFeatureTable)来创建一个离线要素图层进行要素显示。

  • GeodatabaseStatusCallback,本地数据库回调状态类,在数据下载过程中会有很多状态改变,各种状态改变时都会走这个类的回调函数。
  • GeodatabaseTask.generateGeodatabase通过该方法生成离线数据库和相应的要素表,方法需要传递上面介绍的三个参数和一个数据库存储的路径。

完整代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
package com.example.downgdb; 
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import com.esri.android.map.FeatureLayer;
import com.esri.android.map.MapView;
import com.esri.core.ags.FeatureServiceInfo;
import com.esri.core.geodatabase.Geodatabase;
import com.esri.core.geodatabase.GeodatabaseFeatureTable;
import com.esri.core.map.CallbackListener;
import com.esri.core.tasks.geodatabase.GenerateGeodatabaseParameters;
import com.esri.core.tasks.geodatabase.GeodatabaseStatusCallback;
import com.esri.core.tasks.geodatabase.GeodatabaseStatusInfo;
import com.esri.core.tasks.geodatabase.GeodatabaseSyncTask;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
protected static final String TAG = "downGDB";
private Context context; private MapView mMapView;//地图容器

private EditText editTextDownGDBUrl;//GDB地址
private Button btnDownGDB;//下载GDB

private static String onlineFeatureLayerUrl;//在线FeatureLayer地址
private static String localGdbFilePath;//离线GDB地址

private GeodatabaseSyncTask gdbSyncTask;//离线地理数据库下载Task
private ProgressDialog mProgressDialog;//状态框

@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

context = this; // 默认软键盘不弹出
getWindow().setSoftInputMode( WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
this.mMapView = (MapView)findViewById(R.id.map);
this.editTextDownGDBUrl = (EditText)findViewById(R.id.editTextGDBUrl); //获取并设置在线服务地址
this.onlineFeatureLayerUrl = this.editTextDownGDBUrl.getText().toString();

mProgressDialog = new ProgressDialog(context); //设置点击进度对话框外的区域对话框不消失
mProgressDialog.setCanceledOnTouchOutside(false);
mProgressDialog.setTitle("正在创建离线地理数据库副本"); //绑定按钮设置下载事件
btnDownGDB = (Button)this.findViewById(R.id.btnDownGDB);
btnDownGDB.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
downloadData(onlineFeatureLayerUrl);//下载离线数据
}
});

}

/**
* Geodatabase文件存储路径
*/
static String createGeodatabaseFilePath() {
return Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "/RuntimeOfflineEdit"
+ File.separator + "demo.geodatabase";
}

/**
* 下载离线地理数据库
* @param url FeatureService服务地址
* 例如:http://192.168.1.212:6080/arcgis/rest/services/testdata/FeatureServer
* 支持ArcGIS for Server 10.2.1以上版本,必须开启FeatureServer要素同步功能 */
private void downloadData(String url) {
Log.i(TAG, "Create GeoDatabase"); // create a dialog to update user on progress
mProgressDialog.show();

gdbSyncTask = new GeodatabaseSyncTask(url, null);
gdbSyncTask.fetchFeatureServiceInfo(new CallbackListener<FeatureServiceInfo>() {
@Override public void onError(Throwable arg0) {
Log.e(TAG, "获取FeatureServiceInfo失败");
}

@Override public void onCallback(FeatureServiceInfo fsInfo) { if (fsInfo.isSyncEnabled()) {
createGeodatabase(fsInfo);
}
}
});
}

/**
* 根据FeatureServiceInfo信息创建离线地理数据库文件
* @param featureServerInfo 服务参数信息 */
private void createGeodatabase(FeatureServiceInfo featureServerInfo) { // 生成一个geodatabase设置参数
GenerateGeodatabaseParameters params = new GenerateGeodatabaseParameters(
featureServerInfo, mMapView.getMaxExtent(), mMapView.getSpatialReference()); // 下载结果回调函数
CallbackListener<String> gdbResponseCallback = new CallbackListener<String>() {
@Override public void onError(final Throwable e) {
Log.e(TAG, "创建geodatabase失败");
mProgressDialog.dismiss();
}

@Override public void onCallback(String path) {
Log.i(TAG, "Geodatabase 路径: " + path);
mProgressDialog.dismiss();
loadGeodatabase(path);
}
}; // 下载状态回调函数
GeodatabaseStatusCallback statusCallback = new GeodatabaseStatusCallback() {
@Override public void statusUpdated(final GeodatabaseStatusInfo status) {
final String progress = status.getStatus().toString(); //在UI线程更新下载状态
((Activity)context).runOnUiThread(new Runnable(){
@Override public void run() {
mProgressDialog.setMessage("数据下载中,请稍后……");
}
});

}
}; //设置离线地理数据库存储路径
localGdbFilePath = createGeodatabaseFilePath(); //执行下载Geodatabase数据库
gdbSyncTask.generateGeodatabase(params, localGdbFilePath, false, statusCallback, gdbResponseCallback);
}

/** * 加载离线地理数据库
* @param path .geodatabse文件路径
*/
private void loadGeodatabase(String path) { // 创建一个geodatabase数据库
Geodatabase localGdb = null; try {
localGdb = new Geodatabase(path);
} catch (FileNotFoundException e) {
e.printStackTrace();
} // 添加FeatureLayer到MapView中
if (localGdb != null) {
for (GeodatabaseFeatureTable gdbFeatureTable : localGdb.getGeodatabaseTables()) {
if (gdbFeatureTable.hasGeometry()){
mMapView.addLayer(new FeatureLayer(gdbFeatureTable));
}
}
}
}
}

3、Demo运行结果

image

源代码托管地址:http://git.oschina.net/gis-luq/RuntimeOfflineEdit

4、参考资料

https://developers.arcgis.com/android/api-reference/reference/com/esri/core/tasks/geodatabase/package-summary.html

http://blog.csdn.net/arcgis_all/article/details/20442663

相关内容列表

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:概述

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据下载

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据编辑

《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据同步

《ArcGIS Runtime SDK for Android开发笔记》——数据制作篇:发布具有同步能力的FeatureService服务

文章若无特殊说明均为原创,原创作品,允许转载,转载时请务必以超链接形式标明文章出处、作者信息和本声明。
博客:http://www.cnblogs.com/gis-luq​ 作者:gis-luq 邮箱:luqiang.gis@foxmail.com

如果觉着我的文章不错,打赏我一包辣条吧 O(∩_∩)O
-------------本文结束 感谢您的阅读-------------