《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据编辑...
1、前言
在上一篇我们已经实现了离线地理数据库的下载,这一篇我们着重介绍离线数据库的加载与编辑。
由于ArcGIS Runtime SDK for Android 10.2.X版本并没提供要素绘制功能,所以本篇中的要素绘制部分基于之前开源的Drawtools3.0工具实现。
本DEMO主要实现了:离线地理数据库加载、要素样式模板加载,要素新建、要素选择并开启编辑状态、要素删除等操作。由于内容较多涉及编辑部分仅详细介绍对Geodatabase的要素添加、要素删除、要素更新部分,其余请自行查阅源代码。
转载请注明出处:http://www.cnblogs.com/gis-luq/p/5858055.html
2、离线要素编辑实现过程
2.1、加载本地离线要素
ArcGIS Runtime SDK for Android中提供了具体的Geodatabase类和FeatureLayer图层来加载.geodatabase文件,常用的类包括Geodatabase、GeodatabaseFeatureTable、GeodatabaseFeature、GeodatabaseFeatureServiceTable等,分别用来打开geodatabase数据文件、获取要素图层、获取图层中的具体要素,以及获取在线的要素服务。具体来讲,加载.geodatabase文件的步骤有如下几步:
1、 实例化一个Geodatabase对象,这个类有两个构造函数,都需要指定本地数据库的存储路径;
2、 创建一个GeodatabaseFeatureTable对象实例,用来获取需要的图层;
3、 创建一个FeatureLayer来存储获取的图层,并将获取的图层加载到地图中;
4、 调用dispose()方式释放资源。
/*** 读取Geodatabase中离线地图信息* @param geodatabsePath 离线Geodatabase文件路径*/private void addFeatureLayer(String geodatabsePath) {Geodatabase localGdb = null;try {localGdb = new Geodatabase(geodatabsePath);} catch (FileNotFoundException e) {e.printStackTrace();}layerList = new ArrayList<>();// 添加FeatureLayer到MapView中if (localGdb != null) {for (GeodatabaseFeatureTable gdbFeatureTable : localGdb.getGeodatabaseTables()) {if (gdbFeatureTable.hasGeometry()){FeatureLayer layer = new FeatureLayer(gdbFeatureTable);mMapView.addLayer(layer);}}}}
2.2、加载本地要素样式模板
绘制要素时往往会需要知道待绘制要素的图层名称以及要素的符号化样式,这里我们以geodatabse中的FeatureLayer为例演示要素样式模板获取流程。
/*** 添加要素绘制样式模板* 获取图层要素模板并添加到featureTempleteView* @param layer*/private void addFeatureTemplate(FeatureLayer layer) {List<FeatureTemplate> featureTemp = ((GeodatabaseFeatureTable) layer.getFeatureTable()).getFeatureTemplates();for (FeatureTemplate featureTemplate : featureTemp) {GeodatabaseFeature g = null;try {g = ((GeodatabaseFeatureTable) layer.getFeatureTable()).createFeatureWithTemplate(featureTemplate, null);Renderer renderer = layer.getRenderer();Symbol symbol = renderer.getSymbol(g);float scale = context.getResources().getDisplayMetrics().density;int widthInPixels = (int) (35 * scale + 0.5f);Bitmap bitmap = SymbolHelper.getLegendImage(symbol, widthInPixels, widthInPixels);//将要素样式模板赋值给imgButtonImageButton imageButton = new ImageButton(context);imageButton.setImageBitmap(bitmap);imageButton.setTag(layer);//保存当前待编辑图层((LinearLayout)featureTempleteView).addView(imageButton);//添加到要素样式模板列表imageButton.setOnClickListener(new ImageButtonOnClickListener());} catch (TableException e) {e.printStackTrace();Toast.makeText(MainActivity.this, "Error:" + e.getLocalizedMessage(), Toast.LENGTH_SHORT).show();}}}
2.2、编辑本地离线要素
要素编辑最核心的是FeatureTable中的增删改方法,通过这些方法可以实现本地数据库中要素编辑操作。
FeatureTable中的常用方法如下:
- addFeature,增加本地要素
- addFeatures,一次添加多个要素到离线数据库中
- deleteFeature,删除本地要素
- deleteFeatures,删除多个本地要素
- queryFeatures,查询本地要素
- updateFeature,更新要素到本地
- updateFeatures更新多个要素到本地
2.2.1、要素添加
private FeatureLayer selectFeatureLayer;//当前选中图层private Graphic selectGraphic = null;//待添加要素(零时图层中获取)
try {GeodatabaseFeatureTable geodatabaseFeatureTable = (GeodatabaseFeatureTable)selectFeatureLayer.getFeatureTable();GeodatabaseFeature gdbFeature = new GeodatabaseFeature(null, selectGraphic.getGeometry(), geodatabaseFeatureTable);long fid = geodatabaseFeatureTable.addFeature(gdbFeature);// 添加要素Log.d(TAG,"要素添加成功,Feature ID:"+fid); } catch (TableException e) {e.printStackTrace(); }
2.2.2、要素删除
private FeatureLayer selectFeatureLayer;//当前选中图层private Feature selectFeature = null;//当前选中要素
GeodatabaseFeatureTable geodatabaseFeatureTable = (GeodatabaseFeatureTable)selectFeatureLayer.getFeatureTable(); try {if (selectFeature!=null){eodatabaseFeatureTable.deleteFeature(selectFeature.getId());//删除要素} } catch (TableException e) {e.printStackTrace(); }
2.2.3、要素矢量信息更新
private FeatureLayer selectFeatureLayer;//当前选中图层private Feature selectFeature = null;//当前选中要素private Graphic selectGraphic = null;//待更新要素(零时图层中获取)
try {GeodatabaseFeatureTable geodatabaseFeatureTable = (GeodatabaseFeatureTable)selectFeatureLayer.getFeatureTable();geodatabaseFeatureTable.updateFeature(selectFeature.getId(),selectGraphic.getGeometry());//更新要素Log.d(TAG,"要素更新成功"); } catch (TableException e) {e.printStackTrace(); }
扩展说明:如何选中要素,以及如何处理具有压盖关系的要素选择问题?
针对这两个问题我们一并处理,首先扩展MapOnTouchListener类,实现长按出现放大镜,并选中要素。选中要素时我们采用遍历当前所有图层的方式,找出每个图层中第一个被选中的要素,然后弹窗提示供用户选择。
//全局定义信息private List<FeatureLayer> layerList;//矢量图层列表private GraphicsLayer graphicsLayer = null;//零时图层private FeatureLayer selectFeatureLayer;//当前选中图层private Graphic selectGraphic = null;//当前选中要素(零时图层)private Feature selectFeature = null;//当前选中要素
要素选中扩展事件。
/*** 地图窗口默认Touch事件* 支持长按放大镜选种要素*/ public class MapSelectFeatureOnTouchListener extends MapOnTouchListener{public MapSelectFeatureOnTouchListener(Context context, MapView view) {super(context, view);}@Overridepublic boolean onLongPressUp(MotionEvent point) {handleTap(point);//长按放大镜选择事件super.onLongPressUp(point);return true;}@Overridepublic boolean onSingleTap(final MotionEvent e) {//单击响应事件return true;}/*** 获取当前选中要素* @param point*/private void handleTap(MotionEvent point) {MotionEvent screePoint = point;//选中图层信息final List<SelectFeatureInfo> selectFeatureInfoList = new ArrayList<>();//记录当前选中要素信息,涉及多个图层情况for (int i=0;i<layerList.size();i++){FeatureLayer featureLayer = layerList.get(i);featureLayer.setSelectionColor(Color.YELLOW);featureLayer.setSelectionColorWidth(10);long[] selids = featureLayer.getFeatureIDs(screePoint.getX(), screePoint.getY(), 1);if (selids.length >= 1) {SelectFeatureInfo selectFeatureInfo = new SelectFeatureInfo();selectFeatureInfo.featureLayer = featureLayer;selectFeatureInfo.selectFeatureID = selids[0];selectFeatureInfoList.add(selectFeatureInfo);}}//根据待选图层确定是否弹窗选择if(selectFeatureInfoList.size()>1){//当前选中要素大于1个图层AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);builder.setTitle("请确认选择哪个图层要素?");//指定下拉列表的显示数据final String[] layerNamelist = getSelectFeatureInfoListName(selectFeatureInfoList);//设置一个下拉的列表选择项builder.setItems(layerNamelist, new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which){Toast.makeText(MainActivity.this, "选择的图层为:" + layerNamelist[which], Toast.LENGTH_SHORT).show();SelectFeatureInfo selectFeaInfo = getFeatureLayerbyName(selectFeatureInfoList,layerNamelist[which]);setSelectFeature(selectFeaInfo);//根据选中图层信息选中当前要素}});builder.show();}else if(selectFeatureInfoList.size()==1) {SelectFeatureInfo selectFeaInfo = selectFeatureInfoList.get(0);setSelectFeature(selectFeaInfo);//根据选中图层信息选中当前要素}}/*** 设置选中图层的要素选中信息* @param selectFeaInfo 待选图层信息*/private void setSelectFeature(SelectFeatureInfo selectFeaInfo) {clearFeatureSelection();//设置选中状态前,清空已选择要素selectFeaInfo.featureLayer.selectFeature(selectFeaInfo.selectFeatureID);selectFeatureLayer = selectFeaInfo.featureLayer;selectFeature = selectFeatureLayer.getFeature(selectFeaInfo.selectFeatureID);switch (selectFeature.getGeometry().getType()){case POINT:case MULTIPOINT:selectGraphic = new Graphic(selectFeature.getGeometry(), DrawSymbol.markerSymbol, null);break;case LINE:case POLYLINE:selectGraphic = new Graphic(selectFeature.getGeometry(), DrawSymbol.mLineSymbol,null);break;case ENVELOPE:case POLYGON:selectGraphic = new Graphic(selectFeature.getGeometry(), DrawSymbol.mFillSymbol, null);break;default:break;}}/*** 通过图层名称获取要素* @param name 图层名称* @return 选中图层信息*/private SelectFeatureInfo getFeatureLayerbyName(List<SelectFeatureInfo> selectFeatureInfoList,String name){SelectFeatureInfo selectinfo= null;for (int i=0;i<selectFeatureInfoList.size();i++){FeatureLayer tmplayer = selectFeatureInfoList.get(i).featureLayer;if (tmplayer.getName().equals(name)){selectinfo = selectFeatureInfoList.get(i);//选中图层信息}}return selectinfo;}/*** 获取待选择要素列表名称* @param selectFeatureInfoList 待选中要素列表信息* @return*/private String[] getSelectFeatureInfoListName(List<SelectFeatureInfo> selectFeatureInfoList) {List<String> lsname = new ArrayList<>();for (int i=0;i<selectFeatureInfoList.size();i++){lsname.add(selectFeatureInfoList.get(i).featureLayer.getName());}return lsname.toArray(new String[lsname.size()]);}/*** 记录当前选中要素信息*/public class SelectFeatureInfo{public FeatureLayer featureLayer ;//当前选中要素public long selectFeatureID ;//当前选中要素ID} }
3、完整代码
完整代码不定期更新,具体请查阅DEMOt源代码,托管地址:http://git.oschina.net/gis-luq/RuntimeOfflineEdit
4、运行后编辑结果(以备同步测试使用)
转载请注明出处:http://www.cnblogs.com/gis-luq/p/5858055.html
相关内容列表
《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服务
文章若无特殊说明均为原创,原创作品,允许转载,转载时请务必以超链接形式标明文章出处、作者信息和本声明。 博客:http://www.cnblogs.com/gis-luq 作者:gis-luq 邮箱:luqiang.gis@foxmail.com
转载于:https://www.cnblogs.com/telwanggs/p/6434476.html
《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据编辑...相关推荐
- 《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:概述
1.前言 数据生产和数据展示是常见的两大专业级移动GIS应用场景,这里我们针对数据生产环节的ArcGIS的离在线一体化技术给大家做一个基本的介绍和梳理. 使用ArcGIS离在线一体化技术首先需要以下基 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——离在线一体化技术:离线矢量数据同步...
1.前言 上一篇文章中我们实现了离线要素的编辑操作,这一篇中主要介绍离在线一体化技术中最后一个环节离线数据的同步功能,通过对数据的上传,服务器端的版本化管理,实现数据生产管理的整个流程. 转载请注明出 ...
- 《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以上版本即可) Postg ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(7)、示例代码arcgis-runtime-samples-android的使用...
1.前言 学习ArcGIS Runtime SDK开发,其实最推荐的学习方式是直接看官方的教程.示例代码和帮助文档,因为官方的示例一般来说都是目前技术最新,也是最详尽的.对于ArcGIS Runtim ...
- 《ArcGIS Runtime SDK for Android开发笔记》
开发笔记之基础教程 ArcGIS Runtime SDK for Android 各版本下载地址 <ArcGIS Runtime SDK for Android开发笔记>--(1).And ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(6)、基于Android Studio的ArcGIS Android工程结构解析...
1.前言 Android Studio 是第一个Google官方的 Android 开发环境.其他工具,例如 Eclipse,在 Android Studio 发布之前已经有了大规模的使用.为了帮助开 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(9)、空间数据的容器-地图MapView
1.前言 在上一篇内容里介绍了 关于ArcGIS Android开发的未来("Quartz"版Beta)相关内容,期间也提到了关于API接口的重构,开发思路的调整,根据2015UC ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(5)、基于Android Studio构建ArcGIS Android开发环境(离线部署)...
1.前言 在上一篇的内容里我们介绍了基于Android Studio构建ArcGIS Runtime SDK for Android开发环境的基本流程,流程中我们采用的是基于Gradle的构建方式,在 ...
- 《ArcGIS Runtime SDK for Android开发笔记》——(4)、基于Android Studio构建ArcGIS Android开发环境...
1.前言 2015年1月15日,发布ArcGIS Runtime SDK for Android v10.2.5版本.从该版本开始默认支持android studio开发环境,示例代码的默认开发环境也 ...
最新文章
- Vi非正常退出导致敏感信息泄露
- 相移波束形成算法的MATLAB仿真
- 多视图几何总结——等距变换、相似变换、仿射变换和射影变换
- 求复变函数的 Taylor 展式与 Laurent 展式[华中师范大学2010年复变函数复试试题]...
- Linux - man page
- Go 语言:我那么值钱,我骄傲了吗?
- WordCount--统计输入文件的字符数、行数、单词数(java)--初级功能
- 54. mysqli 扩展库
- 修改centos7的MAC地址
- mysql2005错误码_SQL Server2005 常见错误及解决方案
- 异常处理·psftp·local unable to open
- 大数据查询语句SQL
- 微信开发学习总结(一)——微信开发环境搭建
- 使用telnet登陆smtp服务发邮件(带身份验证)
- 12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁
- “长不大”的云计算第一股
- 串口和VGA接口具体引脚定义
- 不是我说,不掌握这些坑,你敢用BigDecimal吗?
- jabref java_一个开源的参考文献管理软件:JabRef
- 一键重装系统win10超详细教程
热门文章
- Spark Streaming之checkpoint机制
- Apache 服务器 参数设置
- dcs 管理计算机的功能,计算机控制系统 第三章 集散控制系统(DCS).doc
- 中国科技大学计算机学院叶辉,中国科技大学计算机科学与技术学院导师教师师资介绍简介-黄文超...
- python3 在线工具_Curl转python在线工具
- 使用VS2015的Visual Studio Installer打包
- format python value error_格式化计算变量时出现“ValueError:无效的格式说明符”
- (2)散列表是怎么进行查找的
- ARM裸机环境搭建(U-Boot命令详解)
- 读写自旋锁详解,第 2 部分(来自IBM)