《ArcGIS Runtime SDK for Android開發筆記》——離在線一體化技術:離線矢量數據下載

一、前言

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.二、發佈具備同步能力的FeatureService服務

  過程參考 數據製做篇:發佈具備同步能力的FeatureService服務 一文。html

轉載請註明出處:http://www.cnblogs.com/gis-luq/p/5858048.html java

二、demo實現過程

ArcGIS Runtime SDK 配置實現過程略:具體請參考:android

基於Android Studio構建ArcGIS Android開發環境
git

基於Android Studio構建ArcGIS Android開發環境(離線部署)數據庫

2.一、Demo UI實現

activity_main.xmlwindows

<?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.二、在Android清單文件AndroidManifest.xml中增長網絡及存儲訪問權限

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

2.三、實現離線地理數據庫下載邏輯

基本思路:

  1. 設置.geodatabase文件存儲路徑
  2. 根據FeatureService服務獲取FeatureServiceInfo服務參數信息
  3. 根據FeatureServiceInfo信息建立離線地理數據庫文件、
  4. 從已經下載的本地Geodatabase文件中加載矢量數據

下載數據的核心功能類說明:

  • GeodatabaseSyncTask類,實現下載同步功能api

  • 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 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));
                }
            }
        }
    }

}

三、Demo運行結果

源代碼託管地址:http://git.oschina.net/gis-luq/RuntimeOfflineEditapp

四、參考資料

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

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服務

相關文章
相關標籤/搜索