在上一篇咱们已经实现了离线地理数据库的下载,这一篇咱们着重介绍离线数据库的加载与编辑。html
因为ArcGIS Runtime SDK for Android 10.2.X版本并没提供要素绘制功能,因此本篇中的要素绘制部分基于以前开源的Drawtools3.0工具实现。java
本DEMO主要实现了:离线地理数据库加载、要素样式模板加载,要素新建、要素选择并开启编辑状态、要素删除等操做。因为内容较多涉及编辑部分仅详细介绍对Geodatabase的要素添加、要素删除、要素更新部分,其他请自行查阅源代码。android
转载请注明出处:http://www.cnblogs.com/gis-luq/p/5858055.html git
ArcGIS Runtime SDK for Android中提供了具体的Geodatabase类和FeatureLayer图层来加载.geodatabase文件,经常使用的类包括Geodatabase、GeodatabaseFeatureTable、GeodatabaseFeature、GeodatabaseFeatureServiceTable等,分别用来打开geodatabase数据文件、获取要素图层、获取图层中的具体要素,以及获取在线的要素服务。具体来说,加载.geodatabase文件的步骤有以下几步:数据库
一、 实例化一个Geodatabase对象,这个类有两个构造函数,都须要指定本地数据库的存储路径;api
二、 建立一个GeodatabaseFeatureTable对象实例,用来获取须要的图层;ide
三、 建立一个FeatureLayer来存储获取的图层,并将获取的图层加载到地图中;函数
四、 调用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.二、加载本地要素样式模板post
绘制要素时每每会须要知道待绘制要素的图层名称以及要素的符号化样式,这里咱们以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); //将要素样式模板赋值给imgButton ImageButton 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(); } } }
要素编辑最核心的是FeatureTable中的增删改方法,经过这些方法能够实现本地数据库中要素编辑操做。
FeatureTable中的经常使用方法以下:
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(); }
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(); }
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); } @Override public boolean onLongPressUp(MotionEvent point) { handleTap(point); //长按放大镜选择事件 super.onLongPressUp(point); return true; } @Override public 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() { @Override public 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 } }
完整代码不按期更新,具体请查阅DEMOt源代码,托管地址:http://git.oschina.net/gis-luq/RuntimeOfflineEdit
转载请注明出处: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服务