ArcGIS For Android 利用线对面进行分割

本文介绍如何在ArcGIS For Android 10.2.8版本中,因GeometryEngine缺少Segment方法,通过自定义代码实现线对面分割功能。主要难点在于判断线与面交点顺序与原面点集顺序的匹配,该逻辑在segmentation方法中完成。操作涉及编辑图层、高亮图层及要素高亮的取消。
摘要由CSDN通过智能技术生成

需求是要将一个面用线将其分割成两块或多块的面。这个面包括多路径面的极端情况。
在ArcGIS For Android提供的API中 GeometryEngine工具类中未有Segment这个方法,在官网查阅中发现在最新的100.0.0版本中是有这个方法的,但是项目中使用的是10.2.8的版本,Eris在这两个版本变化很大,要换SDK十分麻烦,要更换和地图有关的所有地方,所以只能自己动手去写这个分割逻辑。

具体代码

private void previousSegmentation(Geometry gonGeo, Geometry lineGeo) {
    // 这个面的集合用来做遍历
    List<Geometry> gonGraphics = new ArrayList<Geometry>();
    // 取线的最后一个点 判断是否穿过面
    MultiPath multiPath = (MultiPath) lineGeo;
    MultiPath multiPathGon = (MultiPath) gonGeo;
    boolean isIsland = false;

    Point pointLast = multiPath.getPoint(multiPath.getPointCount() - 1);
    Point pointFirst = multiPath.getPoint(0);
    // 判断分割首要条件为线与面相交,并且线的第一个点与最后一个点不和面相交
    if (!GeometryEngine.intersects(gonGeo, pointFirst, mMapView.getSpatialReference())
            && !GeometryEngine.intersects(gonGeo, pointLast, mMapView.getSpatialReference())
            && GeometryEngine.intersects(gonGeo, lineGeo, mMapView.getSpatialReference())
            ) {
        // 遍历多路径 生成面集合
        SegmentIterator segmentIterator = multiPathGon.querySegmentIterator();
        while (segmentIterator.nextPath()) {
            Polygon polygonPath = new Polygon();
            while (segmentIterator.hasNextSegment()) {
                polygonPath.addSegment(segmentIterator.nextSegment(), false);
            }
            polygonPath.removePoint(polygonPath.getPointCount() - 1);
            gonGraphics.add(polygonPath);
        }
        if (gonGraphics.size() > 1) {
            // 对自身集合遍历 判断是否是环岛面
            for (int i = 0; i < gonGraphics.size(); i++) {
                for (int j = 0; j < gonGraphics.size(); j++) {
                    if (i != j && GeometryEngine.contains(gonGraphics.get(i),
                            gonGraphics.get(j), mMapView.getSpatialReference())) {
                        isIsland = true;
                        break;
                    }
                }
            }
        }
        if (isIsland) { // 如果是环岛面
            List<List<Geometry>> doubleGeo = new ArrayList<List<Geometry>>();
            // 第一步 区分大面和小面
            // 对面集合进行按面积大小的冒泡排序
            for (int k = 0; k < gonGraphics.size(); k++) {
                for (int z = 0; z < gonGraphics.size() - 1 - k; z++) {
                    double index = Math.abs(gonGraphics.get(z).calculateArea2D());
                    double index1 = Math.abs(gonGraphics.get(z + 1).calculateArea2D());
                    if (index < index1) {
                        gonGraphics.add(z, gonGraphics.get(z + 1));
                        gonGraphics.remove(z + 2);
                    }
                }
            }
            // 对面进行分组
            for (int i = 0; i < gonGraphics.size(); i++) {
                List<Geometry> singleGeo = new ArrayList<Geometry>();
                if (gonGraphics.get(i).calculateArea2D() > 0) {// 环岛小面的面积是负数
                    for (int j = 0; j < gonGraphics.size(); j++) {
                        if (i != j && GeometryEngine.contains(gonGraphics.get(i),
                                gonGraphics.get(j), mMapView.getSpatialReference())) {
                            if (singleGeo.isEmpty()) {// 如果暂时没有面 则是未放入大面
                                singleGeo.add(gonGraphics.get(i));// 取到大面
                            }
                            singleGeo.add(gonGraphics.get(j));// 取到被包含的小面
                        }
                    }
                    if (singleGeo.isEmpty()) {// 是空的情况 就是单一的普通的面
                        singleGeo.add(gonGraphics.get(i));
                    }// 不是空的情况 就是有环岛的面
                    doubleGeo.add(singleGeo);
                }
            }
            // 存放结果的集合
            List<Geometry> result = new ArrayList<Geometry>();
            for (int a = 0; a < doubleGeo.size(); a+
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值