ArcGIS for Android 离线数据空间分析--叠加分析

Android 同时被 2 个专栏收录
43 篇文章 0 订阅
12 篇文章 9 订阅

  上一章我们以I查询为例讲述了在ArcGIS for Android里如何进行离线数据空间查询,通过ArcGIS 10.2以上的SDK里中QueryParamters类里设置查询参数,然后到对应空间数据库里查询即可。在了解如何空间查询以后,接下来我们以叠加分析为例说下ArcGIS for Android里如何进行离线数据的空间分析。

      空间分析,顾名思义就是对空间数据进行分析,所以首先也是要进行空间查询,然后将查询结果用空间分析工具进行处理,最后再将处理后的结果进行归类统计。

  相比起空间查询来,我们多用了空间分析工具,在ArcGIS for Android里空间分析工具都是放在GeometryEngine类里,我们看下官方文档里是怎么说的:


  

  简要翻译下就是这个类里提供了一系列的方法来实现空间数据的运算。而这些方法名,如果对于ArcGIS比较熟的同学会发现,这就是ArcGIS里空间分析工具的名字,而且和这些工具使用的方法完全一样。我们以叠加分析为例,到时候就会用到Intersect叠加工具,用来处理得到两个矢量图形数据公共的部分。

   不用多说,先上效果图以及空间分析时候的动态图,其中统计后的图表展示是用HelloChart完成。


















  

      再来看看代码如何实现的。

      首先我们先划出需进行叠加分析的图形:

mMapView.setOnSingleTapListener(new OnSingleTapListener() {
    @Override
    public void onSingleTap(float v, float v1) {
        Point mPoint = mMapView.toMapPoint(v, v1);// 选择点
        mPoints.add(mPoint);// 选择点加入点的集合
        Graphic messurePoint = new Graphic(mPoint, mMarkerSymbol);// 点的要素初始化
        messureLayer.addGraphic(messurePoint);// 点的要素添加到图层
        if (mPoints.size() == 1) {
            messurePolygon.startPath(mPoints.get(0));// 设置面的初始点
        }
        if (mPoints.size() > 1) {
            messureLayer.removeAll();
            messurePolyline.setEmpty();
            messurePolygon.lineTo(mPoint);// 连接到当前点击的点
            messurePolygon.lineTo(mPoints.get(0));// 连接到初始点
            for (int i = 0; i < mPoints.size() - 1; i++) {
                messureLine.setStart(mPoints.get(i));
                messureLine.setEnd(mPoints.get(i + 1));
                messurePolyline.addSegment(messureLine, true);
                messureLayer.addGraphic(new Graphic(mPoints.get(i), messureMarkerSymbol));
            }
            messureLayer.addGraphic(new Graphic(mPoints.get(mPoints.size() - 1), messureMarkerSymbol));
            messureLine.setStart(mPoint);
            messureLine.setEnd(mPoints.get(0));
            messurePolyline.addSegment(messureLine, true);
            messureLineGraphic = new Graphic(messurePolyline, messureLineSymbol);
            messureAreaGraphic = new Graphic(messurePolygon, messureFillSymbol);// 初始化面的要素
            messureLayer.addGraphic(messureAreaGraphic);// 将面的要素添加到图层
            messureLayer.addGraphic(messureLineGraphic);
            messurePolygon.startPath(mPoint);// 将当前点设为初始点
        }
    }
});

      这样我们就得到了名为一个messurePolygon的面,然后用这个面去进行空间查询:

mMapView.setOnLongPressListener(new OnLongPressListener() {
    @Override
    public boolean onLongPress(float v, float v1) {
        try {
            QueryParameters query = new QueryParameters();
            query.setOutFields(new String[] { "*" });// 设置返回字段的数组
            query.setGeometry(messurePolygon);// 设置空间几何对象
            if (dataFeatureLayer == null) {
                return false;
            } else {
                FeatureTable mTable = dataFeatureLayer.getFeatureTable();
                mTable.queryFeatures(query, new CallbackListener<FeatureResult>() {
                    @Override
                    public void onCallback(FeatureResult featureResul) {
                        Landresult = getLandUseStatusAnalysisResultByPoints(featureResul);
                        Message msg = new Message();
                        msg.what = ANALYSIS;
                        handler.sendMessage(msg);
                    }

                    @Override
                    public void onError(Throwable throwable) {

                    }
                });

            }
        } catch (Exception e) {
            Toast toast = Toast.makeText(MainActivity.this, "查寻异常", Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();
        }
        return false;
    }
});

      得到的结果我们首先会用叠加工具进行叠加处理,将处理的结果保存:

for (Object resultItem : featureResult) {
    Feature feature = (Feature) resultItem;// 遍历出一个结果
    if (feature instanceof Feature) {
        Feature searchFeature = (Feature) feature;
        Map<String, Object> mQuerryString = feature.getAttributes();
        Geometry mGeometry = GeometryEngine.intersect(searchFeature.getGeometry(), messurePolygon,
                mMapView.getSpatialReference());
        PAnalysistItemInfo itemInfoTemp = new PAnalysistItemInfo();
        mGeometry = GeometryEngine.geodesicDensifyGeometry(mGeometry, mMapView.getSpatialReference());
        String dltype = getLandType("DLBM", mQuerryString).toString();
        if (dltype.equals("")) {
            continue;
        }
        // 储存属性信息
        itemInfoTemp.setDlName(mQuerryString.get("DLMC").toString());
        String area1 = String.format("%.2f", Double.valueOf(
                        GeometryEngine.geodesicArea(mGeometry, mMapView.getSpatialReference(), null))
                        * 0.0015);
        itemInfoTemp.setDlArea(area1);
        itemInfoTemp.setDlType(dltype);

        // 储存图形信息
        Graphic mFeatureResultGraphic = new Graphic(mGeometry, pAnalysistSymbol);
        pointAnalysistGraphics.add(mFeatureResultGraphic);

    }
}

      然后就是归类统计了,这里举的例子是地类图斑的例子,根据图斑的属性按照农用地,建设用地和未利用地进行归类统计:

LandUseStatusItem item = new LandUseStatusItem();
item.AdmName = qsName;
// 初始化
item.FarmLand = new FarmLand();
item.FarmLand.TotalNums = 0;
item.FarmLand.TotalArea = 0.0;
item.FarmLand.LandTypeMap = new HashMap<>();
item.FarmLand.GraphicList = new ArrayList<Graphic>();
item.BuildLand = new BuildLand();
item.BuildLand.TotalNums = 0;
item.BuildLand.TotalArea = 0.0;
item.BuildLand.LandTypeMap = new HashMap<>();
item.BuildLand.GraphicList = new ArrayList<Graphic>();
item.NoUseLand = new NoUseLand();
item.NoUseLand.TotalNums = 0;
item.NoUseLand.TotalArea = 0.0;
item.NoUseLand.LandTypeMap = new HashMap<>();
item.NoUseLand.GraphicList = new ArrayList<Graphic>();
item.GraphicList = new ArrayList<Graphic>();
// 归类计算
if (paList != null && !paList.isEmpty()) {
    for (PAnalysistItemInfo paItem : paList) {
        Double area = 0.0;
        Graphic graphic = null;
        try {
            area = Double.parseDouble(paItem.getDlArea());
            graphic = paItem.getGraphic();
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
        item.GraphicList.add(graphic);
        if (paItem.getDlType().equals("农用地")) {
            item.FarmLand.TotalNums = item.FarmLand.TotalNums + 1;
            item.FarmLand.TotalArea = item.FarmLand.TotalArea + area;
            item.FarmLand.GraphicList.add(graphic);
            if (item.FarmLand.LandTypeMap.isEmpty()) {
                // 十二类无数据时处理
                LandType landTypeItem = new LandType();
                landTypeItem.TotalNums = 1;
                landTypeItem.TotalAreas = area;
                landTypeItem.LandTypeCode = "";
                landTypeItem.LandTypeName = paItem.getDlName();
                landTypeItem.Graphic = new ArrayList<Graphic>();
                landTypeItem.Graphic.add(graphic);
                item.FarmLand.LandTypeMap.put(paItem.getDlName(), landTypeItem);
            } else {
                if (item.FarmLand.LandTypeMap.containsKey(paItem.getDlName())) {
                    // 存在该类数据时处理
                    if (item.FarmLand.LandTypeMap.get(paItem.getDlName()) != null) {
                        try {
                            item.FarmLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalNums = item.FarmLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalNums + 1;
                            item.FarmLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalAreas = item.FarmLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalAreas + area;
                            item.FarmLand.LandTypeMap.get(paItem.getDlName()).Graphic.add(graphic);
                        } catch (Exception e) {
                            String ee = e.toString();
                        }
                    }

                } else {
                    // 已有十二类其他数据而没有该类时处理
                    LandType landTypeItem = new LandType();
                    landTypeItem.TotalNums = 1;
                    landTypeItem.TotalAreas = area;
                    landTypeItem.LandTypeCode = "";
                    landTypeItem.LandTypeName = paItem.getDlName();
                    landTypeItem.Graphic = new ArrayList<Graphic>();
                    landTypeItem.Graphic.add(graphic);
                    item.FarmLand.LandTypeMap.put(paItem.getDlName(), landTypeItem);
                }
            }
        } else if (paItem.getDlType().equals("建设用地")) {
            item.BuildLand.TotalNums = item.BuildLand.TotalNums + 1;
            item.BuildLand.TotalArea = item.BuildLand.TotalArea + area;
            item.BuildLand.GraphicList.add(graphic);
            if (item.BuildLand.LandTypeMap.isEmpty()) {
                // 十二类无数据时处理
                LandType landTypeItem = new LandType();
                landTypeItem.TotalNums = 1;
                landTypeItem.TotalAreas = area;
                landTypeItem.LandTypeCode = "";
                landTypeItem.LandTypeName = paItem.getDlName();
                landTypeItem.Graphic = new ArrayList<Graphic>();
                landTypeItem.Graphic.add(graphic);
                item.BuildLand.LandTypeMap.put(paItem.getDlName(), landTypeItem);
            } else {
                if (item.BuildLand.LandTypeMap.containsKey(paItem.getDlName())) {
                    // 存在该类数据时处理
                    if (item.BuildLand.LandTypeMap.get(paItem.getDlName()) != null) {
                        try {
                            item.BuildLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalNums = item.BuildLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalNums + 1;
                            item.BuildLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalAreas = item.BuildLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalAreas + area;
                            item.BuildLand.LandTypeMap.get(paItem.getDlName()).Graphic.add(graphic);
                        } catch (Exception e) {
                            String ee = e.toString();
                        }
                    }

                } else {
                    // 已有十二类其他数据而没有该类时处理
                    LandType landTypeItem = new LandType();
                    landTypeItem.TotalNums = 1;
                    landTypeItem.TotalAreas = area;
                    landTypeItem.LandTypeCode = "";
                    landTypeItem.LandTypeName = paItem.getDlName();
                    landTypeItem.Graphic = new ArrayList<Graphic>();
                    landTypeItem.Graphic.add(graphic);
                    item.BuildLand.LandTypeMap.put(paItem.getDlName(), landTypeItem);
                }
            }
        } else if (paItem.getDlType().equals("未利用地")) {
            item.NoUseLand.TotalNums = item.NoUseLand.TotalNums + 1;
            item.NoUseLand.TotalArea = item.NoUseLand.TotalArea + area;
            item.NoUseLand.GraphicList.add(graphic);
            if (item.NoUseLand.LandTypeMap.isEmpty()) {
                // 十二类无数据时处理
                LandType landTypeItem = new LandType();
                landTypeItem.TotalNums = 1;
                landTypeItem.TotalAreas = area;
                landTypeItem.LandTypeCode = "";
                landTypeItem.LandTypeName = paItem.getDlName();
                landTypeItem.Graphic = new ArrayList<Graphic>();
                landTypeItem.Graphic.add(graphic);
                item.NoUseLand.LandTypeMap.put(paItem.getDlName(), landTypeItem);
            } else {
                if (item.NoUseLand.LandTypeMap.containsKey(paItem.getDlName())) {
                    // 存在该类数据时处理
                    if (item.NoUseLand.LandTypeMap.get(paItem.getDlName()) != null) {
                        try {
                            item.NoUseLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalNums = item.NoUseLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalNums + 1;
                            item.NoUseLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalAreas = item.NoUseLand.LandTypeMap
                                    .get(paItem.getDlName()).TotalAreas + area;
                            item.NoUseLand.LandTypeMap.get(paItem.getDlName()).Graphic.add(graphic);
                        } catch (Exception e) {
                            String ee = e.toString();
                        }
                    }

                } else {
                    // 已有十二类其他数据而没有该类时处理
                    LandType landTypeItem = new LandType();
                    landTypeItem.TotalNums = 1;
                    landTypeItem.TotalAreas = area;
                    landTypeItem.LandTypeCode = "";
                    landTypeItem.LandTypeName = paItem.getDlName();
                    landTypeItem.Graphic = new ArrayList<Graphic>();
                    landTypeItem.Graphic.add(graphic);
                    item.NoUseLand.LandTypeMap.put(paItem.getDlName(), landTypeItem);
                }
            }

        }
    }
}

      最后就是将统计的结果在前端展示出来,具体的代码我就不贴了。demo资源我上传在:http://download.csdn.net/detail/bit_kaki/9919120。有兴趣的可以自己下载看看

  • 1
    点赞
  • 10
    评论
  • 1
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

评论 10 您还未登录,请先 登录 后发表或查看评论
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

bit_kaki

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值