arcgis for Android100.3.0 加载shp数据以及操作

it2023-03-05  94

ArcGIS Runtime 100.2.0的正式发布带来个更多移动端的处理地图的能力,例如支持WMS图层、支持海图(ENC)图层,再如基于场景相机(Camera)的视域分析。同时还提供了新的统计查询API(总和,平均值,计数,最小值,最大值,标准差或方差)。而今天要描述的重点是ArcGIS Runtime 100.2.0对Shapefile数据格式的支持,当然ArcGIS Runtime 100.2.0还增加了对OGC GeoPackage格式的支持。

对于Shapfile这一文件格式,ArcGIS Runtime SDK for Android 在100.2.0系列中推出了两大重磅利好消息:

(1) 实现对本地 Shapfile 文件的加载、显示和查询  (2) 实现对本地 Shapefile 文件的编辑,即增删改操作  毋庸置疑,对于广大的ArcGIS移动端爱好者而言,支持Shapefile编辑操作绝对是一则振奋人心的好消息。

Shapefile文件的加载

 

加载shp文件,数据量大的时候,加载速度比较慢。

shp文件 必须有least three files (.shp, .shx, .dbf) 如果有prj文件那就更好。位置准确。

在安卓端加载Shapefile文件的关键是ShapefileFeatureTable(com.esri.arcgisruntime.data.ShapefileFeatureTable)。  相比于.geodatabase文件,Shapefile文件的缺点在于只是单图层,且没有符号化,当然可以通过移动端的可视化API进行处理。

shp文件加载方式 

/** * 加载shp文件 - 方式一 * */ public void loadShpFileOne(){ // shp文件存在本地的路径 String shpPath = context.getExternalFilesDir("/shp").getPath()+ File.separator + "地名检查.shp"; shapefileFeatureTable = new ShapefileFeatureTable(shpPath); shapefileFeatureTable.loadAsync(); // 构建featureLayerr featureLayer = new FeatureLayer(shapefileFeatureTable); // 设置Shapefile文件的渲染方式 SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.GREEN, 3); // 渲染线和面 // SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 1.0f); // SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.YELLOW, lineSymbol); // SimpleRenderer renderer = new SimpleRenderer(fillSymbol); // 仅仅渲染点 SimpleRenderer renderer = new SimpleRenderer(simpleMarkerSymbol); featureLayer.setRenderer(renderer); //标注shp String strLabelDefinition = "{\"labelExpression\": \"[NAME]\",\"labelPlacement\": \"esriServerPointLabelPlacementAboveCenter\",\"symbol\": {\"color\": [255,100,0,255],\"font\": {\"size\": 6,\"family\":\"Microsoft YaHei\"},\"type\": \"esriTS\"}}"; LabelDefinition labelDefinition = LabelDefinition.fromJson(strLabelDefinition); featureLayer.getLabelDefinitions().add(labelDefinition); featureLayer.setLabelsEnabled(true); // 设置渲染图层添加到mapView mapView.getMap().getOperationalLayers().add(featureLayer); // 设置Callout mCallout = mapView.getCallout(); createCallout(); } /** * 加载shp文件 - 方式二 * */ public void loadShpFileTwo(){ // shp文件存在本地的路径 String shpPath = context.getExternalFilesDir("/shp").getPath()+ File.separator + "地名检查.shp"; //String shpPath = context.getExternalFilesDir("/shp").getPath()+ File.separator + "检查标注.shp"; mapView.setAttributionTextVisible(false); File shpFile = new File(shpPath); if (shpFile.exists()){// 判断是否存储这个文件 shapefileFeatureTable = new ShapefileFeatureTable(shpPath); shapefileFeatureTable.loadAsync(); shapefileFeatureTable.addDoneLoadingListener(new Runnable() { @Override public void run() { GeometryType geoType = shapefileFeatureTable.getGeometryType(); String name = shapefileFeatureTable.getTableName(); featureLayer = new FeatureLayer(shapefileFeatureTable); if (featureLayer.getFullExtent() != null){ mapView.setViewpointGeometryAsync(featureLayer.getFullExtent()); }else { featureLayer.addDoneLoadingListener(new Runnable() { @Override public void run() { mapView.setViewpointGeometryAsync(featureLayer.getFullExtent()); } }); } // 设置渲染图层添加到mapView mapView.getMap().getOperationalLayers().add(featureLayer); } }); }else { // 创建 shpFile.mkdirs(); } // 设置Shapefile文件的渲染方式 // 点 SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE, Color.GREEN, 5); // 线 // SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 1.0f); // 面 // SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.YELLOW, lineSymbol); // 渲染线和面 // SimpleRenderer renderer = new SimpleRenderer(fillSymbol); SimpleRenderer renderer = new SimpleRenderer(simpleMarkerSymbol); featureLayer.setRenderer(renderer); }

新增shp要素数据

/** * 增加shp要素数据 */ public void addShp() { mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { Point mapPoint = mapView.screenToLocation(new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()))); // 调用isEditable和canAdd方法判断文件是否支持编辑操作,是否可添加要素;否,则抛出信息 if (shapefileFeatureTable.isEditable() && shapefileFeatureTable.canAdd()) { // 构建待增加的Feature对象,设置几何,设置属性 Feature feature = shapefileFeatureTable.createFeature(); feature.setGeometry(mapPoint); //feature.getAttributes().put("NAME", "测试点"); // 调用addFeatureAsync方法增加要素 final ListenableFuture<Void> addFeatureOper = shapefileFeatureTable.addFeatureAsync(feature); // 在操作完成的监听事件中判断操作是否成功 addFeatureOper.addDoneListener(new Runnable() { @Override public void run() { try { addFeatureOper.get(); if (addFeatureOper.isDone()) { Toast.makeText(context, "数据添加成功",Toast.LENGTH_SHORT).show(); } } catch (InterruptedException interruptedExceptionException) { // 处理异常 } catch (ExecutionException executionException) { // 处理异常 } } }); } else { Toast.makeText(context, "shp数据不可被编辑",Toast.LENGTH_SHORT).show(); } return super.onSingleTapConfirmed(e); } // 控制旋转 @Override public boolean onRotate(MotionEvent event,double rotationAngle) { return false; } }); }

删除shp要素数据 

/** * 删除shp要素数据 * */ public void delShp(){ mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { android.graphics.Point clickPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())); // identify the GeoElements in the given layer final ListenableFuture<IdentifyLayerResult> futureIdentifyLayer = mapView .identifyLayerAsync(shapefileFeatureTable.getFeatureLayer(), clickPoint, 10, false, 1); futureIdentifyLayer.addDoneListener(new Runnable() { @Override public void run() { try { // call get on the future to get the result IdentifyLayerResult layerResult = futureIdentifyLayer.get(); List<GeoElement> resultGeoElements = layerResult.getElements(); if (!resultGeoElements.isEmpty()) { for (Object element : resultGeoElements) { if (element instanceof Feature) { Feature feature = (Feature) element; // 调用delFeatureAsync方法删除要素 final ListenableFuture<Void> delFeatureOper = shapefileFeatureTable.deleteFeatureAsync(feature); delFeatureOper.addDoneListener(new Runnable() { @Override public void run() { try { delFeatureOper.get(); if (delFeatureOper.isDone()) { Toast.makeText(context, "数据删除成功",Toast.LENGTH_SHORT).show(); } } catch (InterruptedException interruptedExceptionException) { // 处理异常 } catch (ExecutionException executionException) { // 处理异常 } } }); } } } } catch (Exception e1) { Toast.makeText(context, "选择失败!",Toast.LENGTH_SHORT).show(); } } }); return super.onSingleTapConfirmed(e); } // 控制旋转 @Override public boolean onRotate(MotionEvent event,double rotationAngle) { return false; } }); }

修改shp要素数据 

/** * 查询并修改shp要素数据 --- 第一种方法 * */ public void updataShp(){ mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { android.graphics.Point mTapPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())); mSelectedFeatures = new ArrayList<>(); // identify the GeoElements in the given layer final ListenableFuture<IdentifyLayerResult> futureIdentifyLayer = mapView .identifyLayerAsync(shapefileFeatureTable.getFeatureLayer(), mTapPoint, 10, false, 1); futureIdentifyLayer.addDoneListener(new Runnable() { @Override public void run() { try { // call get on the future to get the result IdentifyLayerResult layerResult = futureIdentifyLayer.get(); List<GeoElement> resultGeoElements = layerResult.getElements(); if (!resultGeoElements.isEmpty()) { for (Object element : resultGeoElements) { if (element instanceof Feature) { Feature mFeatureGrafic = (Feature) element; showCallout(mFeatureGrafic); // 添加 mSelectedFeatures.add(mFeatureGrafic); /* Map<String, Object> mQuerryString = mFeatureGrafic.getAttributes(); for(String key : mQuerryString.keySet()){ Log.i("Show"+key,String.valueOf(mQuerryString.get(key))); }*/ } } }else { mCallout.dismiss(); } } catch (Exception e1) { Toast.makeText(context, "选择失败!",Toast.LENGTH_SHORT).show(); } } }); return super.onSingleTapConfirmed(e); } // 控制旋转 @Override public boolean onRotate(MotionEvent event,double rotationAngle) { return false; } }); } /** * 查询并修改shp要素数据 --- 第二种方法 * */ public void updataShpTwo(){ mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { final Point clickPoint = mapView .screenToLocation(new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()))); int tolerance = 10; double mapTolerance = tolerance * mMapView.getUnitsPerDensityIndependentPixel(); // create objects required to do a selection with a query Envelope envelope = new Envelope(clickPoint.getX() - mapTolerance, clickPoint.getY() - mapTolerance, clickPoint.getX() + mapTolerance, clickPoint.getY() + mapTolerance, mapView.getSpatialReference()); QueryParameters query = new QueryParameters(); query.setGeometry(envelope); final ListenableFuture<FeatureQueryResult> featureQueryResultFuture = shpPointFileFTable.getFeatureLayer().selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW); featureQueryResultFuture.addDoneListener(new Runnable() { @Override public void run() { FeatureQueryResult featureQueryResult = null; try { featureQueryResult = featureQueryResultFuture.get(); } catch (ExecutionException ex) { ex.printStackTrace(); } catch (InterruptedException ex) { ex.printStackTrace(); } // create an Iterator Iterator<Feature> iterator = featureQueryResult.iterator(); Feature feature = null; int counter = 0; while (iterator.hasNext()) { feature = iterator.next(); counter++; Log.d(TAG, "Selection #: " + counter + " Table name: " + feature.getFeatureTable().getTableName()); } // Callout showCallout(mFeatureGrafic); // 添加 mSelectedFeatures.add(mFeatureGrafic); /* Map<String, Object> mQuerryString = mFeatureGrafic.getAttributes(); for(String key : mQuerryString.keySet()){ Log.i("Show"+key,String.valueOf(mQuerryString.get(key))); }*/ } }); return super.onSingleTapConfirmed(e); } // 控制旋转 @Override public boolean onRotate(MotionEvent event,double rotationAngle) { return false; } }); }

 

查询shp数据 

/** * 查询shp方式 */ public void queryByIdentify() { mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context,mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())); final ListenableFuture<IdentifyLayerResult> identifyLayerResultListenableFuture = mapView.identifyLayerAsync( shapefileFeatureTable.getFeatureLayer(), screenPoint, 12, false, 10); identifyLayerResultListenableFuture.addDoneListener(new Runnable() { @Override public void run() { try { IdentifyLayerResult identifyLayerResult = identifyLayerResultListenableFuture.get(); String name = identifyLayerResult.getLayerContent().getName(); List<GeoElement> elements = identifyLayerResult.getElements(); for (GeoElement element : elements) { Map<String, Object> attributes = element.getAttributes(); Geometry geometry = element.getGeometry(); //高亮显示选中区域 mMapView.setViewpointGeometryAsync(geometry.getExtent()); SimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE,Color.argb(100, 255, 0, 0), 10); SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 3); SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.RED, lineSymbol); if (mGraphicsOverlay != null) { ListenableList<Graphic> graphics = mGraphicsOverlay.getGraphics(); if (graphics.size() > 0) { graphics.removeAll(graphics); } } Graphic graphic = new Graphic(geometry, simpleMarkerSymbol); mGraphicsOverlay.getGraphics().add(graphic); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } }); return super.onSingleTapConfirmed(e); } }); } /** * 查询shp方式1:selectFeaturesAsync(查询不出数据) */ public void queryBySelectFeaturesAsync() { mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { shapefileFeatureTable.getFeatureLayer().clearSelection(); final Point clickPoint = mapView.screenToLocation(new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY()))); int tolerance = 10; double mapTolerance = tolerance * mapView.getUnitsPerDensityIndependentPixel(); SpatialReference spatialReference = mapView.getSpatialReference(); Envelope envelope = new Envelope(clickPoint.getX() - mapTolerance, clickPoint.getY() - mapTolerance, clickPoint.getX() + mapTolerance, clickPoint.getY() + mapTolerance, spatialReference); QueryParameters query = new QueryParameters(); query.setGeometry(envelope); query.setSpatialRelationship(QueryParameters.SpatialRelationship.WITHIN); final ListenableFuture<FeatureQueryResult> future = featureLayer.selectFeaturesAsync(query, FeatureLayer.SelectionMode.NEW); future.addDoneListener(new Runnable() { @Override public void run() { try { FeatureQueryResult result = future.get(); //mFeatureLayer.getFeatureTable().deleteFeaturesAsync(result); Iterator<Feature> iterator = result.iterator(); int counter = 0; while (iterator.hasNext()) { counter++; Feature feature = iterator.next(); Map<String, Object> attributes = feature.getAttributes(); for (String key : attributes.keySet()) { Log.e("xyh" + key, String.valueOf(attributes.get(key))); } //高亮显示选中区域 featureLayer.selectFeature(feature); Geometry geometry = feature.getGeometry(); mMapView.setViewpointGeometryAsync(geometry.getExtent()); //也可以通过添加graphic高亮显示选中区域 // // SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 3); // SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.RED, lineSymbol); // // if (mGraphicsOverlay != null) { // ListenableList<Graphic> graphics = mGraphicsOverlay.getGraphics(); // if (graphics.size() > 0) { // graphics.removeAll(graphics); // } // } // Graphic graphic = new Graphic(geometry, fillSymbol); // mGraphicsOverlay.getGraphics().add(graphic); } } catch (Exception e) { e.printStackTrace(); } } }); return super.onSingleTapConfirmed(e); } }); } /** * 查询shp方式2:queryFeaturesAsync(查询不出数据) */ public void queryByQueryFeaturesAsync() { mapView.setOnTouchListener(new DefaultMapViewOnTouchListener(context, mapView) { @Override public boolean onSingleTapConfirmed(MotionEvent e) { android.graphics.Point screenPoint = new android.graphics.Point(Math.round(e.getX()), Math.round(e.getY())); Point clickPoint = mapView.screenToLocation(screenPoint); QueryParameters query = new QueryParameters(); query.setGeometry(clickPoint);// 设置空间几何对象 FeatureTable mTable = featureLayer.getFeatureTable();//得到查询属性表 final ListenableFuture<FeatureQueryResult> featureQueryResult = mTable.queryFeaturesAsync(query); featureQueryResult.addDoneListener(new Runnable() { @Override public void run() { try { FeatureQueryResult result = featureQueryResult.get(); Iterator<Feature> iterator = result.iterator(); int counter = 0; while (iterator.hasNext()) { counter++; Feature feature = iterator.next(); Map<String, Object> attributes = feature.getAttributes(); for (String key : attributes.keySet()) { Log.e("xyh" + key, String.valueOf(attributes.get(key))); } //高亮显示选中区域 Geometry geometry = feature.getGeometry(); mMapView.setViewpointGeometryAsync(geometry.getExtent()); SimpleLineSymbol lineSymbol = new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 3); SimpleFillSymbol fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.RED, lineSymbol); if (mGraphicsOverlay != null) { ListenableList<Graphic> graphics = mGraphicsOverlay.getGraphics(); if (graphics.size() > 0) { graphics.removeAll(graphics); } } Graphic graphic = new Graphic(geometry, fillSymbol); mGraphicsOverlay.getGraphics().add(graphic); } } catch (Exception e) { e.printStackTrace(); } } }); return super.onSingleTapConfirmed(e); } }); }

 

最新回复(0)