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

1、前言

上一篇文章中我们实现了离线要素的编辑操作,这一篇中主要介绍离在线一体化技术中最后一个环节离线数据的同步功能,通过对数据的上传,服务器端的版本化管理,实现数据生产管理的整个流程。

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

2、demo实现过程

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.syncgdb.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" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="离线数据同步"
        android:id="@+id/btnSync"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true" />

</RelativeLayout>

2.3、实现离线地理数据库同步

基本思路:

  1. 获取.geodatabase文件存储路径
  2. 根据FeatureService服务获取FeatureServiceInfo服务参数信息
  3. 根据FeatureServiceInfo信息同步离线地理数据库
  4. 在UI线程中反馈同步结果

完整代码

package com.example.syncgdb;

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.widget.Button;
import android.widget.Toast;

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.geodatabase.GeodatabaseFeatureTableEditErrors;
import com.esri.core.map.CallbackListener;
import com.esri.core.tasks.geodatabase.GeodatabaseStatusCallback;
import com.esri.core.tasks.geodatabase.GeodatabaseStatusInfo;
import com.esri.core.tasks.geodatabase.GeodatabaseSyncTask;
import com.esri.core.tasks.geodatabase.SyncGeodatabaseParameters;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    protected static final String TAG = "syncGDB";
    private Context context;

    private MapView mMapView;//地图容器

    private static String onlineFeatureLayerUrl = "http://192.168.1.212:6080/arcgis/rest/services/testdata/FeatureServer";//在线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);

        this.context = this;
        this.mMapView = (MapView)findViewById(R.id.map);

        //设置离线地理数据库存储路径
        localGdbFilePath = createGeodatabaseFilePath();
        //加载离线地理数据库
        addFeatureLayer(localGdbFilePath);

        mProgressDialog = new ProgressDialog(context);
        //设置点击进度对话框外的区域对话框不消失
        mProgressDialog.setCanceledOnTouchOutside(false);
        mProgressDialog.setTitle("正在同步离线地理数据库副本到服务器");

        //绑定按钮设置下载事件
        Button btnSyncGDB = (Button)this.findViewById(R.id.btnSync);
        btnSyncGDB.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                SyncOfflineData();//同步离线地理数据库
            }
        });
    }

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

    /**
     * 读取Geodatabase中离线地图信息
     * @param featureLayerPath 离线Geodatabase文件路径
     */
    private void addFeatureLayer(String featureLayerPath) {

        Geodatabase localGdb = null;
        try {
            localGdb = new Geodatabase(featureLayerPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        // 添加FeatureLayer到MapView中
        if (localGdb != null) {
            for (GeodatabaseFeatureTable gdbFeatureTable : localGdb.getGeodatabaseTables()) {
                if (gdbFeatureTable.hasGeometry()){
                    FeatureLayer layer = new FeatureLayer(gdbFeatureTable);
                    mMapView.addLayer(layer);
                }
            }
        }
    }

    /**
     * 同步离线地理数据库
     */
    private void SyncOfflineData() {

        Log.i(TAG, "Sync GeoDatabase");
        // create a dialog to update user on progress
        mProgressDialog.show();

        gdbSyncTask = new GeodatabaseSyncTask(onlineFeatureLayerUrl, 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()) {
                    SyncGeodatabase(fsInfo);
                }
            }
        });
    }

    /**
     * 根据FeatureServiceInfo信息获取离线地理数据库同步信息
     * @param featureServerInfo 服务参数信息
     */
    private void SyncGeodatabase(FeatureServiceInfo featureServerInfo) {
        try {
            // 创建一个离线地理数据库
            Geodatabase gdb = new Geodatabase(localGdbFilePath);

            // 获取离线地理数据库同步参数
            final SyncGeodatabaseParameters syncParams = gdb.getSyncParameters();

            CallbackListener<Map<Integer, GeodatabaseFeatureTableEditErrors>> syncResponseCallback
                    = new CallbackListener<Map<Integer, GeodatabaseFeatureTableEditErrors>>() {

                @Override
                public void onCallback(Map<Integer, GeodatabaseFeatureTableEditErrors> objs) {
                    mProgressDialog.dismiss();
                    if (objs != null) {
                        if (objs.size() > 0) {
                            showMakeText("同步完成,但是发生错误");
                        } else {
                            showMakeText("同步完成:同步成功");
                        }
                    } else {
                        showMakeText("同步完成:同步成功");
                    }
                }

                @Override
                public void onError(Throwable e) {
                    Log.e(TAG, "", e);
                    mProgressDialog.dismiss();
                    Toast.makeText(context, "Error:"+e.toString(), Toast.LENGTH_SHORT).show();
                }

            };

            GeodatabaseStatusCallback statusCallback = new GeodatabaseStatusCallback() {

                @Override
                public void statusUpdated(GeodatabaseStatusInfo status) {
                    final String progress = status.getStatus().toString();
                    //在UI线程更新下载状态
                    ((Activity)context).runOnUiThread(new Runnable(){
                        @Override
                        public void run() {
                            mProgressDialog.setMessage("数据同步中,请稍后……");
                        }
                    });
                }
            };

            // 执行同步
            gdbSyncTask.syncGeodatabase(syncParams, gdb, statusCallback, syncResponseCallback);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 在UI线程中执行状态提示
     * @param msg
     */
    private void showMakeText(final String msg) {
        //在UI线程更新下载状态
        ((Activity)context).runOnUiThread(new Runnable(){
            @Override
            public void run() {
                Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
            }
        });
    }

}

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

3、数据同步结果

相关内容列表

《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服务

时间: 2024-12-25 20:38:25

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

《ArcGIS Runtime SDK for Android开发笔记》——(10)、ArcGIS Runtime SDK支持的空间数据类型

1.前言 移动端的数据来源非常重要,它决定了移动端功能的实现.早期的ArcGIS Android API中,主要以接入在线的数据源为主,因此主要实现在线的地图浏览.查询和路径分析.地理处理等从操作:在v1.0.1版本中,ArcGIS移动产品第一次可以加载松散型切片,自此逐渐掀开了对本地离线数据源的支持,也因此可以在移动端实现越来越受欢迎的离线功能.现在最新的10.2.7 API离线支持数据主要包括紧凑型切片.tpk切片包..geodatabase..shp文件.地名地址库.网络数据集. 转载请注

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

1.前言 数据生产和数据展示是常见的两大专业级移动GIS应用场景,这里我们针对数据生产环节的ArcGIS的离在线一体化技术给大家做一个基本的介绍和梳理. 使用ArcGIS离在线一体化技术首先需要以下基础环境: ArcGIS for Desktop 10.2.1以上版本 ArcGIS for Server 10.2.1以上版本 使用PostgreSQL.Microsoft SQL Server.或 Oracle 设置企业级地理数据库ArcSDE. 再次在使用同步功能是必须给要素添加GlobleID

《ArcGIS Runtime SDK for Android开发笔记》

开发笔记之基础教程 ArcGIS Runtime SDK for Android 各版本下载地址 <ArcGIS Runtime SDK for Android开发笔记>——(1).Android Studio下载与安装 <ArcGIS Runtime SDK for Android开发笔记>——(2).Android Studio基本配置与使用 <ArcGIS Runtime SDK for Android开发笔记>——(3).ArcGIS Runtime SDK概述

《ArcGIS Runtime SDK for Android开发笔记》——(9)、空间数据的容器-地图MapView

1.前言 在上一篇内容里介绍了 关于ArcGIS Android开发的未来(“Quartz”版Beta)相关内容,期间也提到了关于API接口的重构,开发思路的调整,根据2015UC资料也可以知道新版预计将在明年的时候推出.届时在开发思路上将会往新版迁移. 总的来说,虽然“Quartz”版的开发思路有所变化,但总体变化不大,这里我将继续以现有正式发布版本为主梳理ArcGIS Runtime SDK for Android 开发内容. 参考API版本号:version 10.2.7.后续内容若不做特

《ArcGIS Runtime SDK for Android开发笔记》——基于Android Studio构建ArcGIS Android开发环境(离线部署)

1.前言 在上一篇的内容里我们介绍了基于Android Studio构建ArcGIS Runtime SDK for Android开发环境的基本流程,流程中我们采用的是基于Gradle的构建方式,在这种方式里主要通过设置maven仓库位置,设置编译选项.依赖版本在联网环境下下载对应SDK依赖包. 但是在网络情况不好的情况下这种方式就不行了,那怎么解决在离线环境或者内网环境实现开发流程呢?目前了解到的有两种方式: 1)配置内网环境maven仓库,预先缓存到内网环境下,然后离线调用. 2)采用直接

《ArcGIS Runtime SDK for Android开发笔记》——(15)、要素绘制Drawtools3.0工具DEMO

1.前言 移动GIS项目开发中点线面的要素绘制及编辑是最常用的操作,在ArcGIS Runtime SDK for iOS 自带AGSSketchLayer类可以帮助用户快速实现要素的绘制,图形编辑.但是在ArcGIS Runtime SDK for Android的版本中并没有提供类似的功能,实现过程相对较复杂.(10.2.8及以下版本需要用户自定义扩展实现,通过扩展MapOnTouchListener类实现,Quartz版SDK默认自带) 之前有大神gispace封装了DrawTools2.

《ArcGIS Runtime SDK for Android开发笔记》——(8)、关于ArcGIS Runtime SDK for Android开发的一些思考

1.前言 今天再一次在官网看到了ArcGIS Runtime SDK for Android下一个版本“Quartz”版的更新资料,它将是一个非常重要的更新,包括API接口的重构和开发思路的调整.具体如下图所示: 在ArcGIS Runtime SDK概述一文中已经给大家介绍了ArcGIS Runtime SDK for Android的前世今生,从2011年6月发布ArcGIS Runtime SDK for Android beta版开始,到2015年10月1日发布ArcGIS Runtim

《ArcGIS Runtime SDK for Android开发笔记》——ArcGIS Runtime SDK概述

1.前言 ArcGIS Runtime SDK是一整套用于构建原生及跨平台的应用程序开发包, 转载请注明出处:http://www.cnblogs.com/gis-luq/p/4765993.html 2.ArcGIS Runtime SDKs产品家族 相信大部分开发者对ArcGIS Runtime SDKs这个名称并不生疏,它实际上包含了一系列SDKs,用来开发应用于桌面和移动设备的应用程序.在10.2.2之前的版本中,ArcGIS Runtime SDKs包括ArcGIS Runtime S

《ArcGIS Runtime SDK for Android开发笔记》——(14)、关于ArcGIS Android 架构支持问题

1.前言 随着软硬件的进一步发展,Android设备使用64位的cpu已经开始非常普遍了.但是笔者在测试arm64-v8a(64位架构)的Android设备时,发现使用到ArcGIS Android API的环节出现程序崩溃闪退问题,经过排查,发现ArcGIS Runtime SDK for Android目前(截至10.2.8版本)并不支持arm64-v8a(64位架构),故此文特此记录和说明一下. 转载请注明出处:http://www.cnblogs.com/gis-luq/p/572758