您现在的位置: 主页 > 嵌入式操作系统 > Android > 外业数据采集平台(GPS+AndroidStudio+Arcgisforandroid100.2.1)
本文所属标签:
为本文创立个标签吧:

外业数据采集平台(GPS+AndroidStudio+Arcgisforandroid100.2.1)

来源:fromnet 网络用户发布,如有版权联系网管删除 2018-07-06 

欢迎加入QQ沟通交流群:186178114(群名:外业数据采集(GIS+GPS))

外业数据采集平台

1.综述

在室外,通过平板或者手机接收GPS坐标,实时绘制点、线、面数据,以便为后续进行海域监测、土地确权、地图绘图提供有效数据和依据。

2.技术路线

Android studio3.0.1+Arcgis for android 100.2.1+GPS

2.1Android studio工具:

2.2Android studio工具下载地址:

http://www.android-studio.org/index.php/download/hisversion

2.2.1Android studio安装与配置

参考博客地址:https://www.cnblogs.com/xiadewang/p/7820377.html

2.3Arcgis for android

Arcgis for androidESRI公司专门为Android手机开发GIS地图软件的一套API,整合广泛的地图和GIS能力在线或离线,包括编辑,分析,地理编码,路由,网络地图管理,数据可视化,移动地图包和矢量平铺层。

2.3.1Arcgis for android SDK

https://developers.arcgis.com/android/latest/

2.3.2Arcgis for android配置

http://www.cnblogs.com/gis-luq/p/4760370.html

2.4技术架构

外业数据采集平台采用的是Android最原生也是最基础的架构,可以理解为MVCController即是ActivityFragment,但是这两者掌握了Android系统中绝大多数的资源,并且在内部直接控制View,因此传统的Android App一般是以ActivityFragment为核心,将网络模块,数据库管理模块,文件管理模块,常用工具类等分离成若干工具类包,供ActivityFragment使用。由于项目不是很大,最后决定采用Android默认的架构,而没有采用MVP或者MVVM架构。

3.平台展示与实例代码

3.1登录与主界面

3.1.1登录

3.1.2主界面

包含最基本的:放大、缩小、旋转、指北针、比例尺等基本功能。

3.2基础功能

3.2.1导入矢量

支持导入内置SD卡和外置SD卡中.shp格式的数据。

 1 private ShapefileFeatureTable featureLayerShapefile(String filePath, String fileType, boolean 2         isFullExtent, String dapFilePath, boolean isVisible, float opacity, boolean isCheckLayerName) { 3     if (!check(filePath, "SHP", isCheckLayerName)) { 4         return null; 5     } 6     ShapefileFeatureTable shapefileFeatureTable = new ShapefileFeatureTable(filePath); 7     shapefileFeatureTable.loadAsync(); 8     ShapefileFeatureTable finalShapefileFeatureTable = shapefileFeatureTable; 9     shapefileFeatureTable.addDoneLoadingListener(() -> {10         if (finalShapefileFeatureTable.getLoadStatus() == LoadStatus.LOADED) {11             // create a feature layer to display the shapefile12             FeatureLayer featureLayer = new FeatureLayer(finalShapefileFeatureTable);13             if ("".equals(dapFilePath)) {14                 featureLayer.setDescription(filePath);15             } else {16                 featureLayer.setDescription(dapFilePath);17             }18             featureLayer.setVisible(isVisible);19             mMapView.getMap().getOperationalLayers().add(featureLayer);20             if (isFullExtent) {21                 Envelope envelope = LayerUtil.GetLayerFullExtend(featureLayer);22                 if (envelope != null && !envelope.isEmpty()) {23                     mMapView.setViewpointGeometryAsync(envelope24                             , LayerUtil.FullExtendPadding);25                 }26             }27         } else {28             String error = "Shapefile feature table failed to load: " +29                     finalShapefileFeatureTable30                             .getLoadError().toString();31             Log.e(TAG, error);32         }33     });34 35     return shapefileFeatureTable;36 } 

3.2.2导入影像

支持导入内置SD卡和外置SD卡中.tif影像格式的数据。

 1 private Layer loadLocalTif(ArcGISMap arcGISMap, String filePath, String extendName, boolean 2             isVisible, float opacity, boolean isCheckLayerName) { 3         if (!check(filePath, extendName, isCheckLayerName)) { 4             return null; 5         } 6         Raster raster = new Raster(filePath); 7         if (raster == null) 8             return null; 9 10         final RasterLayer rasterLayer = new RasterLayer(raster);11         rasterLayer.setName("基础底图");12         rasterLayer.setDescription(filePath);13         rasterLayer.setVisible(isVisible);14         rasterLayer.setOpacity(opacity);15         Basemap basemap = new Basemap(rasterLayer);16         mMapView.getMap().setBasemap(basemap);17         rasterLayer.addDoneLoadingListener(new Runnable() {18             @Override19             public void run() {20                 mMapView.setViewpointGeometryAsync(rasterLayer.getFullExtent(), LayerUtil21                         .FullExtendPadding);22                 mMapView.setViewpointScaleAsync(MyConfig.initialScale);23             }24         });25         mMapView.setViewpointScaleAsync(MyConfig.initialScale);26 27         return rasterLayer;28     } 

3.2.3全图

将所有图层中所有要素范围作为地图的显示范围。

1  Envelope envelope = LayerUtil.GetFullExtend(mMapView);2  if (envelope != null) {3      mMapView.setViewpointGeometryAsync(envelope, LayerUtil.FullExtendPadding);4  }

3.2.4属性识别

识别最上层的点、线、面要素。

 1 @Override 2     public boolean onSingleTapConfirmed(MotionEvent e) { 3         android.graphics.Point screenPoint = new android.graphics.Point((int) e.getX(), (int) e.getY()); 4         final ListenableFuture> identifyFuture = mMapView 5                 .identifyLayersAsync( 6                         screenPoint, 20, false, 25); 7         identifyFuture.addDoneListener(new Runnable() { 8             @Override 9             public void run() {10                 try {11                     List identifyLayersResults = identifyFuture.get();12                     for (IdentifyLayerResult identifyLayerResult : identifyLayersResults) {13                         if (identifyLayerResult.getElements().size() > 0) {14                             GeoElement topmostElement = identifyLayerResult.getElements().get(0);15                             if (topmostElement instanceof Feature) {16                                 Feature identifiedFeature = (Feature) topmostElement;17                                 LayerContent layerContent = identifyLayerResult.getLayerContent();18                                 String layerName = "";19                                 if (layerContent != null)20                                     layerName = layerContent.getName();21                                 Map attrs = identifiedFeature.getAttributes();22                                 String[] itemArr = new String[items.size()];23                                 itemArr = items.toArray(itemArr);24                                 showIdentifyInfo(itemArr, layerName);25                                 break;26                             }27                         }28                     }29                 } catch (InterruptedException | ExecutionException ex) {30                 }31             }32         });33 34         return true;35     }

3.2.5图层管理

包括图层顺序(置顶、置底、上移、下移)、图层标注(能标注该图层中多个字段)、图层样式(能改变图层中要素的颜色、宽度等信息)、图层移除、图层缩放到(缩放到选择图层的所有要素的范围)等功能;

 1 private void loadLayers(boolean isToast,List listChecked) { 2         if (mapView == null) { 3             return; 4         } 5         linearLayoutContent.removeAllViews(); 6         LayerList layers = mapView.getMap().getOperationalLayers(); 7         boolean layersLoaded = initialLayers(layers, 2,listChecked); 8         if(layersLoaded) 9         {10             linearLayoutContent.addView(ViewUtil.AddDividerView(this));11         }12         Basemap basemap = mapView.getMap().getBasemap();13         LayerList baseLayers = basemap.getBaseLayers();14         boolean baseLayersLoaded = initialLayers(baseLayers, 1,listChecked);15     }16 17     /**18      * @param layers19      * @param layerType //1:底图  2:操作类20      * @return21      */22     private boolean initialLayers(LayerList layers, int layerType,List listChecked) {23         if (layers == null || layers.size() == 0) {24             return false;25         }26         for (int j = layers.size() - 1; j > -1; j--) {27             Layer layer = layers.get(j);28             boolean isChecked=false;29             if(listChecked!=null) {30                 isChecked= listChecked.contains(layer.getName());31             }32             addItem(layer, layerType,isChecked);33         }34         return true;35     }

 1 private void initialLineSymbol(SimpleLineSymbol lineSymbol) 2     { 3         rowFillColor.setVisibility(View.INVISIBLE); 4         rowIsFill.setVisibility(View.INVISIBLE); 5         txtSymbolColor.setText("线颜色:"); 6         txtSymbolSize.setText("线宽度:"); 7         txtType.setText("线样式:"); 8  9         btnSymbolColor.setBackgroundColor(lineSymbol.getColor());10         seekBarSymbolSize.seekBar.setProgress((int)lineSymbol.getWidth());11         initialColorPick(lineSymbol.getColor(),btnSymbolColor);12     }13 14 private SimpleLineSymbol setLineSymbol(SimpleLineSymbol lineSymbol)15     {16         lineSymbol.setColor(ViewUtil.GetButtonBackgoundColor(btnSymbolColor));17         lineSymbol.setWidth(seekBarSymbolSize.seekBar.getProgress());18         return lineSymbol;19     }

 1 private void initialListView() 2     { 3             FeatureLayer featureLayer=(FeatureLayer)layer; 4             List fieldList=  featureLayer.getFeatureTable().getFields(); 5             List labelDefinitionList=  featureLayer.getLabelDefinitions(); 6             boolean isLabel=featureLayer.isLabelsEnabled(); 7            for (Field field :fieldList) 8            { 9                CheckBox checkBox=new CheckBox(this);10                String fileName=field.getAlias();11                if(TextUtils.isEmpty(fileName))12                {13                    fileName=field.getName();14                }15                checkBox.setText(fileName);16                checkBox.setTag(field);17                if(isLabel)18                {19                    for (LabelDefinition labelDefinition:labelDefinitionList)20                    {21                      String jsonString =labelDefinition.toJson();22                        try {23                            JSONObject jObject = new JSONObject(jsonString);24                            if(jObject!=null)25                            {26                            JSONObject jObjectItem=    jObject.getJSONObject("labelExpressionInfo");27                                if(jObjectItem!=null)28                                {29                                    String expression=jObjectItem.getString("expression");30                                    String[] expressionContent=expression.split("\.");31                                    if(expressionContent.length>1)32                                    {33                                     String[] expressionField=   expressionContent[1].split(";");34                                     if(expressionField.length>0)35                                     {36                                        if( expressionField[0].equals(field.getName()))37                                        {38                                            checkBox.setChecked(true);39                                        }40                                     }41                                    }42                                }43                            }44                        } catch (JSONException e) {45 46                        }47                    }48                }49 50                listViewLabel.addView(checkBox);51            }52     }53 54     public void btnLabelOk_Click(View view)55     {56             FeatureLayer featureLayer = (FeatureLayer) layer;57             List checkedFieldList = getCheckedFields();58             featureLayer.getLabelDefinitions().clear();59             if(checkedFieldList!=null&&checkedFieldList.size()>0) {60                 for (Field field : checkedFieldList) {61                     LabelDefinition labelDefinition = LayerUtil.CreateFillLabelDefinition(field.getName());62                     featureLayer.getLabelDefinitions().add(labelDefinition);63                 }64                 featureLayer.setLabelsEnabled(true);65             }66             else67             {68                 featureLayer.setLabelsEnabled(false);69             }70             finish();71     }

3.2.6距离测量

通过手在屏幕中点击开始,双击停止,支持动态显示每段线的距离(以米为单位)。

 1 public boolean onDoubleTap(MotionEvent point) { 2  3 if (geoType == GeometryType.POLYLINE)//绘制线 4         { 5             if (!lineGeometry.isSketchValid()) { 6                 removeGraphic(pCurrGraphic); 7             } else { 8                 updateGraphic(lineGeometry.toGeometry()); 9             }10             PartCollection partCollection = lineGeometry.getParts();11             if (partCollection.size() == 0) {12                 return false;13             }14             Part part = partCollection.get(partCollection.size() - 1);15             int count = part.getPointCount();16             if (count <= 2) {17                 return false;18             }19             double length = GeometryEngine.lengthGeodetic(lineGeometry.toGeometry(), new20                     LinearUnit(LinearUnitId.METERS), GeodeticCurveType.GEODESIC);21             Graphic lengthGriphic = new Graphic(ptCurrent, getTextSymbol(getFormatString(length,22                     2, "米"), TextSymbol.HorizontalAlignment.RIGHT, TextSymbol.VerticalAlignment23                     .TOP));24             drawLayer.getGraphics().add(lengthGriphic);25 26    }27 28  } 

3.2.7面积测量

通过手在屏幕中点击开始,双击停止,会形成一个面要素,并显示长度和面积(以米为单位)。

 1 public boolean onDoubleTap(MotionEvent point) { 2  3 if (!polygonGeometry.isSketchValid()) { 4     removeGraphic(pCurrGraphic); 5     return true; 6 } else { 7     updateGraphic(polygonGeometry.toGeometry()); 8 } 9 10 double area = GeometryEngine.areaGeodetic(polygonGeometry.toGeometry(), new AreaUnit11         (AreaUnitId.SQUARE_METERS), GeodeticCurveType.GEODESIC);12 Graphic areaGriphic = new Graphic(ptCurrent, getTextSymbol(getFormatString(area, 2,13         "平方米"), TextSymbol.HorizontalAlignment.LEFT, TextSymbol.VerticalAlignment14         .BOTTOM));15 drawLayer.getGraphics().add(areaGriphic);16 17 double length = GeometryEngine.lengthGeodetic(polygonGeometry.toPolyline(), new18         LinearUnit(LinearUnitId.METERS), GeodeticCurveType.GEODESIC);19 Point ptShift = mapView.screenToLocation(new android.graphics.Point(Math.round(point20         .getX()), Math.round(point.getY()) + 30));21 Graphic lengthGriphic = new Graphic(ptShift, getTextSymbol(getFormatString(length,22         2, "米"), TextSymbol.HorizontalAlignment.RIGHT, TextSymbol.VerticalAlignment23         .TOP));24 drawLayer.getGraphics().add(lengthGriphic);25 26  }

3.2.8清除覆盖物

清除上面距离测量或者面积测量的图形要素。

1 if (mearsureGraphicsOveray != null) {2     mearsureGraphicsOveray.getGraphics().clear();3 }

3.2.9当前位置

点击此按钮,将GPS最近一次接受点的位置置于地图中心位置,并增加图标。

 1 public boolean startGPSCurrent(boolean isRequestUpdate) { 2     if (GPSLocationManager.gpsLocationManager == null) { 3         GPSLocationManager.gpsLocationManager = GPSLocationManager.getInstances 4                 (MainActivity 5                         .this); 6     } 7     if (currentLocationListener == null) { 8         currentLocationListener = new MyGPSCurrentLocationListener(); 9     }10     if (isRequestUpdate)11         GPSLocationManager.gpsLocationManager.stop(2);12     //开启定位13     GPSLocationManager.gpsLocationManager.start(currentLocationListener,14             isRequestUpdate, 100, 2);15 16     return true;17 }18 19  20 21 class MyGPSCurrentLocationListener implements GPSLocationListener {22     @Override23     public void UpdateLocation(Location location) {24         if (location != null) {25             LocationUtil.AddOrUpdateLocation(MainActivity.this, location,26                     locationGraphicsOveray,27                     spatialReference, mMapView);28             if (GPSLocationManager.gpsLocationManager != null) {29                 GPSLocationManager.gpsLocationManager.stop(2);30             }31         }32     }33 34 }

3.2.10数据导出

将采集到的点、线、面数据导出成.shp格式数据,并支持删除要素功能。

 1 public void initialGridData(ShapefileFeatureTable shapefileFeatureTable, GridView gridView, 2                                 int gridType, Context context, boolean isDisplayToastInf) { 3         List fileds = shapefileFeatureTable.getFields(); 4         Map gridTitle = new HashMap(); 5  6         for (String field : LayerUtil.mFields) { 7             String key = field; 8             keysList.add(key); 9             String alias = LayerUtil.GetAliasNameByFieldName(key);10             gridTitle.put(key, alias);11         }12         gridDataList.add(gridTitle);13         QueryParameters qParameters = new QueryParameters();14         String whereClause = "1=1";15         qParameters.setWhereClause(whereClause);16         final ListenableFuture future = shapefileFeatureTable17                 .queryFeaturesAsync(qParameters);18         FeatureQueryResult result = null;19         try {20             result = future.get();21             Iterator features = result.iterator();22             while (features.hasNext()) {23                 Feature feature = features.next();24                 Map attrs = feature.getAttributes();25 26                 Map dd = new HashMap();27                 for (String field : LayerUtil.mFields) {28                     dd.put(field, String.valueOf(attrs.get(field)));29                 }30                 gridDataList.add(dd);31             }32         } catch  {33 34         }35         String[] keys = keysList.toArray(new String[keysList.size()]);36         GridViewAdapter adapter = new GridViewAdapter(context, gridDataList);37         gridView.setAdapter(adapter);38     } 

3.2.11系统设置

设置GPS接收坐标间隔以及地图经纬度显示格式。

 1 @Override 2         public boolean onPreferenceChange(Preference preference, Object value) { 3             String stringValue = value.toString(); 4             if (preference instanceof ListPreference) { 5                 ListPreference listPreference = (ListPreference) preference; 6                 if (listPreference.getKey().equals(updateMapFormatKey)) { 7                     PreferencesUtil.setPrefString(this.getActivity(), updateMapFormatKey, String.valueOf(stringValue)); 8                 } else if (listPreference.getKey().equals(updateCollectIntervalKey)) { 9                     PreferencesUtil.setPrefString(this.getActivity(), updateCollectIntervalKey, String.valueOf(stringValue));10                     MyConfig.mMinTime=Long.parseLong(stringValue);11                 }12             }13 14             return true;15         } 

3.3高级功能

3.3.1拍照

拍取外业测量点的实况,并在照片上增加 经纬度、备注信息,信息录入完毕后,保存即可,为后续数据处理增加依据。

 1 public void takePhoto(Activity activity) { 2         int currentapiVersion = android.os.Build.VERSION.SDK_INT; 3         Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 4         if (hasSdcard()) { 5             SimpleDateFormat timeStampFormat = new SimpleDateFormat( 6                     "yyyy_MM_dd_HH_mm_ss"); 7             String filename = timeStampFormat.format(new Date()); 8             File tempFile = new File(FileUtils.GetDefaultPath(this) + "/" + MyConfig.OutCameraDir, 9                     filename + ".jpg");10             imageView.setTag(tempFile);11             if (currentapiVersion < 24) {12                 imageUri = Uri.fromFile(tempFile);13                 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);14             } else {15                 ContentValues contentValues = new ContentValues(1);16                 contentValues.put(MediaStore.Images.Media.DATA, tempFile.getAbsolutePath());17                 imageUri = activity.getContentResolver().insert(MediaStore.Images.Media18                         .EXTERNAL_CONTENT_URI, contentValues);19                 intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);20             }21         }22     } 

3.3.2点采集

根据GPS坐标,实时生成点要素,并随位置变化而变化地图中心点,点击 “结束”会弹出属性保存界面;

3.3.3线采集

根据GPS坐标,实时生成线要素,并随位置变化而变化地图中心点,点击 “结束”会弹出属性保存界面;

3.3.4面采集

根据GPS坐标,实时生成面要素,并随位置变化而变化地图中心点,点击 “结束”会弹出属性保存界面;

3.3.5停止编辑

 1 private void addOrUpdateGeometry(Location point ) { 2         if (point == null || point.isEmpty() || point.getX() == 0 || point.getY() == 0) 3             return; 4  5  6         switch (collectGeometryType) { 7             case POINT: 8                 if (collectPointTable == null) { 9                     return;10                 }11                 collectFeatures.add(pointF);12                 toastGpsInfo("点采集数据", "", collectFeatures.size());13                 break;14             case POLYLINE:15                 if (collectLineTable == null) {16                     return;17                 }18                 lineGeometry.addPoint(point);19                 collectPoints.add(point);20                 if (lineGeometry.isSketchValid()) {21                     if (polylineFeature == null) {22                         polylineFeature = collectLineTable.createFeature();23                         polylineFeature.setGeometry(lineGeometry.toGeometry());24                         collectLineTable.addFeatureAsync(polylineFeature);25                     } else {26                         polylineFeature.setGeometry(lineGeometry.toGeometry());27                         collectLineTable.updateFeatureAsync(polylineFeature);28                     }29                 }30                 toastGpsInfo("线采集数据", "", collectPoints.size());31                 break;32             case POLYGON:33                 if (collectAreaTable == null) {34                     return;35                 }36                 polygonGeometry.addPoint(point);37                 collectPoints.add(point);38                 if (polygonGeometry.isSketchValid()) {39                     if (polygonFeature == null) {40                         polygonFeature = collectAreaTable.createFeature();41                         polygonFeature.setGeometry(polygonGeometry.toGeometry());42                         collectAreaTable.addFeatureAsync(polygonFeature);43                     } else {44                         polygonFeature.setGeometry(polygonGeometry.toGeometry());45                         collectAreaTable.updateFeatureAsync(polygonFeature);46                     }47                 }48                 toastGpsInfo("面采集数据", "", collectPoints.size());49                 break;50         }51     } 

3.3.6撤销

若有GPS坐标发生偏移,可以根据此功能进行撤销,一直可以撤销到第一个采集到的点。

 1 private boolean deleteFirstFeature(ShapefileFeatureTable shapefileFeatureTable, Feature 2             defaultFeature) { 3         if (shapefileFeatureTable == null) 4             return false; 5         if (shapefileFeatureTable.getTotalFeatureCount() == 1) { 6             if (defaultFeature == null) 7                 return false; 8             String delFid = ""; 9             Map item = defaultFeature.getAttributes();10             if (item != null) {11                 delFid = String.valueOf(item.get(CollectEidtActivity.attrFID));12             }13             QueryParameters qParameters = new QueryParameters();14             String whereClause = CollectEidtActivity.attrFID + "=" + delFid;15             qParameters.setReturnGeometry(true);16             qParameters.setWhereClause(whereClause);17 18             final ListenableFuture featuresResult = shapefileFeatureTable19                     .queryFeaturesAsync(qParameters);20 21             FeatureQueryResult features;22             try {23                 features = featuresResult.get();24                 if (!features.iterator().hasNext()) {25                     return false;26                 }27                 shapefileFeatureTable28                         .deleteFeaturesAsync(features).get();29                 return true;30             } catch (Exception ex) {31                 return false;32             }33         }34 35         return false;36     }

欢迎加入QQ沟通交流群:186178114(群名:外业数据采集(GIS+GPS)) 欢迎各位前来围观,提出建设性意见,谢谢!



              查看评论 回复



嵌入式交流网主页 > 嵌入式操作系统 > Android > 外业数据采集平台(GPS+AndroidStudio+Arcgisforandroid100.2.1)
 数据 图层 地图

"外业数据采集平台(GPS+AndroidStudio+Arcgisforandroid100.2.1)"的相关文章

网站地图

围观()