zoukankan      html  css  js  c++  java
  • 《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 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运行结果

    源代码托管地址: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服务

  • 相关阅读:
    正则表达式解析
    Selenium自动化测试系列文章汇总
    Python自动化测试-正则表达式解析
    滴滴滴,ITester软件测试小栈所有资源放送!
    Selenium自动化测试-文件上传
    Selenium自动化测试-浏览器基本操作
    2020牛客暑期多校第四场-H Harder Gcd Problem(贪心构造)
    2020牛客暑期多校第三场F-Fraction Construction Problem-分数构造题(拓展欧几里得)
    洛谷P1919--A*B Problem升级版(NTT优化高精度乘法)
    洛谷P4721-分治FFT(NTT分治)
  • 原文地址:https://www.cnblogs.com/gis-luq/p/5858048.html
Copyright © 2011-2022 走看看