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

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

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服务 一文。

技术分享

转载请注明出处: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

<?xml version="1.0" encoding="utf-8"?><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中增加网络及存储访问权限

    <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个根据需要选择:

技术分享

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

    • featureServerInfo 服务参数信息
    • geodatabaseExtent 地图下载区域范围
    • geodatabaseSpatialReference 地图空间参考
  •  CallbackListener<Geodatabase>,完成GDB数据库下载的回调函数类,在该回调中我们只可以执行一些操作,如示例里在回调中删除了在线的服务图层,加载离线的数据图层到地图上进行显示。通过Geodatabase本地数据库可以获取要素图层列表List<GdbFeatureTable>对象,通过newFeatureLayer(gdbFeatureTable)来创建一个离线要素图层进行要素显示。
  •  GeodatabaseStatusCallback,本地数据库回调状态类,在数据下载过程中会有很多状态改变,各种状态改变时都会走这个类的回调函数。
  •  GeodatabaseTask.generateGeodatabase通过该方法生成离线数据库和相应的要素表,方法需要传递上面介绍的三个参数和一个数据库存储的路径。

 完整代码示例:

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 one rror(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 one rror(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运行结果

技术分享

源代码托管地址: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开发笔记》——离在线一体化技术:离线矢量数据下载