在线缓存功能开发分享

1. 简介

  1. 离线在线一体化
    数据存储在企业级地理数据库中,通过Arcgis桌面加载后配图处理,并发布到Arcgis for Server中,供移动端设备编辑使用,并可以同步回传版本化存档。
  2. 应用场景
    在没有网络的情况下我们需要用到在线的地图数据进行操作,这些数据需要有一定的时效性,如果采用,打包离线包的方式提前做好离线数据,那时效性相对较差。所以,用在线缓存技术可以支持这一点。

2. 在线缓存的实现逻辑思路

  • 在地图上选定区域,作为需要下载对应离线数据的地图范围(可以设定范围,也可以自定义)
  • 获取下载滴地图服务所需要的具体参数
  • 在本地创建文件,存放下载的数据,以供使用

3. 用到的核心功能类以及说明

  • GeodatabaseSyncTask类,实现下载同步功能
  • GenerateGeodatabaseParameters,下载数据时所需的参数对象,该类构造函数一共有7个根据需要选择


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

4. 代码示例

  1. 在地图上自定义一个区域
     /**
     * 绘制出在线缓存区域
     * */
    private void polygonState(Point currentPoint)throws Exception{
        if(startPoint!=null&&!startPoint.isEmpty()){
            polygon.lineTo(currentPoint);
            currentGraphic = new Graphic(polygon, symbol);
            drawLayer.updateGraphic(currentGraphicIndex,currentGraphic);

            pointGraphic=new Graphic(multiPoint,pointSymbol);
            drawLayer.updateGraphic(pointGraphicIndex,pointGraphic);
            multiPoint.add(currentPoint);
            if(lastGraphicIndex!=-1){
                drawLayer.removeGraphic(lastGraphicIndex);
            }
            lastGraphic=new Graphic(currentPoint,lastSymbol);
            lastGraphicIndex=drawLayer.addGraphic(lastGraphic);

            if(polygon.getPointCount()>=3){
                isCheckedSave=true;
                isSave=isCheckedSave;
                onlinesave.setTextColor(ContextCompat.getColor(mActivity,R.color.blue));
                onlinesave.setClickable(isSave);
            }
        }else{
            polygon=new Polygon();
            multiPoint=new MultiPoint();
            polygon.startPath(currentPoint);
            startPoint=currentPoint;
            currentGraphic=new Graphic(startPoint,symbol);
            currentGraphicIndex=drawLayer.addGraphic(currentGraphic);
            pointGraphic=new Graphic(startPoint,lastSymbol);
            pointGraphicIndex=drawLayer.addGraphic(pointGraphic);
            multiPoint.add(currentPoint);
        }
    }
    /**
     * 确定所选区域范围
     * */
    public void SaveLabel()throws Exception{
        if(isSave&&drawLayer!=null) {
            startPoint = null;
            isCheckedSave=false;
            isSave=isCheckedSave;
            onlinesave.setTextColor(ContextCompat.getColor(mActivity,R.color.gray));
            onlinesave.setClickable(isSave);
            if(currentGraphicIndex!=-1){
                Graphic graphic = drawLayer.getGraphic(currentGraphicIndex);
                if(graphic!=null){
                    Geometry geometry=graphic.getGeometry();
                    Graphic saveGraphic=null;
                    if(geometryType.equals(Geometry.Type.POLYGON)){
                        symbol=MapViewTapTool.getLabelSymbol(mActivity,geometryType,ContextCompat.getColor(mActivity,R.color.green_transparent));
                        saveGraphic=new Graphic(geometry,symbol);
                        pointSymbol=MapViewTapTool.getCircleGreenSymbol(mActivity);
                        pointGraphic=new Graphic(geometry,pointSymbol);
                    }else{
                        symbol=MapViewTapTool.getLabelSymbol(mActivity,geometryType,ContextCompat.getColor(mActivity,R.color.green));
                        saveGraphic=new Graphic(geometry,symbol);
                        pointSymbol=MapViewTapTool.getCircleGreenSymbol(mActivity);
                        pointGraphic=new Graphic(geometry,pointSymbol);
                    }
                    if(onlineCacheInfoList!=null&&onlineCacheInfoList.size()>0){
                        setView();
                        int i = 0;
                        if(onlineCacheInfoList.get(i).getCacheurl().trim().length()>0) {
                            downloadData(onlineCacheInfoList.get(i), geometry, i);//缓存featureLayer
                        }
                    }
                }
            }
        }else{
            isCheckedSave=false;
            isSave=isCheckedSave;
            onlinesave.setTextColor(ContextCompat.getColor(mActivity,R.color.gray));
            onlinesave.setClickable(isSave);
        }
    }
  1. 下载选定区域所对应的在线缓存的文件
private void downloadData(final OnlineCacheInfo onlineCacheInfo, final Geometry geometry, final int i) {
        gdbSyncTask = new GeodatabaseSyncTask(onlineCacheInfo.getCacheurl(), null);
        gdbSyncTask.fetchFeatureServiceInfo(new CallbackListener<FeatureServiceInfo>() {
                    @Override
                    public void onError(Throwable arg0) {
                        Log.e(TAG, "Error fetching FeatureServiceInfo");
                    }

                    @Override
                    public void onCallback(FeatureServiceInfo fsInfo) {
                        if (fsInfo.isSyncEnabled()) {
                           //回调获取所需要的下载的图层信息
                            createGeodatabase(onlineCacheInfo.getIds(),geometry,i);
                        }
                    }
                });

    }
    //创建下载
    private void createGeodatabase(int[] ids, final Geometry geometry, final int i) {
        SpatialReference sp=mOneMapView.getSpatialReference();
        GenerateGeodatabaseParameters params = new GenerateGeodatabaseParameters(ids, geometry,sp,true, SyncModel.GEODATABASE);

        CallbackListener<String> gdbResponseCallback = new CallbackListener<String>() {
            @Override
            public void onError(final Throwable e) {
                Log.e(TAG, "Error creating geodatabase");
                Toast.makeText(mActivity, "数据下载失败!", Toast.LENGTH_LONG).show();
                pDialog.dismiss();
            }

            @Override
            public void onCallback(String path) {
                updateFeatureLayer(path);
                if(i<onlineCacheInfoList.size()&&onlineCacheInfoList.get(i+1).getCacheurl().trim().length()>0){
                    downloadData(onlineCacheInfoList.get(i+1),geometry,i+1);
                }else {
                    pDialog.dismiss();
                    Toast.makeText(mActivity, "数据下载完成!", Toast.LENGTH_LONG).show();
                }
            }
        };
        localGdbFilePath = "对应在本地存储的存储路径以及存储名称";
        submitTask(params, localGdbFilePath, statusCallback,
                gdbResponseCallback);
    }
    private void submitTask(GenerateGeodatabaseParameters params,
                            String file, GeodatabaseStatusCallback statusCallback,
                            CallbackListener<String> gdbResponseCallback) {
        // submit task
        gdbSyncTask.generateGeodatabase(params, file, false, statusCallback,
                gdbResponseCallback);
    }
  1. 将下载完成的数据再地图上展示
//加载数据
private void updateFeatureLayer(String featureLayerPath) {
        // create a new geodatabase
        Geodatabase localGdb = null;
        try {
            localGdb = new Geodatabase(featureLayerPath);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        if (localGdb != null) {
            for (GeodatabaseFeatureTable gdbFeatureTable : localGdb
                    .getGeodatabaseTables()) {
                if (gdbFeatureTable.hasGeometry()){
                    mOneMapView.addLayer(new FeatureLayer(gdbFeatureTable));
                }
            }
        }
    }

5. 结语

在线缓存的应用,减少了手动制作离线数据的步骤,大大提高了地图制作的效率,只需发布对应的地图服务就能实现离线数据的在线下载。另外也同时保证了数据的时效性,如果对应地图服务有新的数据更改,那我们可以重新下载新的在线数据,不需要再去手动打包地图文件。

  • 最后感谢您的阅读,有机会一起探讨!
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容