Android Google Maps PolygonOptions未从给定的坐标集绘制。

4
我正在尝试绘制一个复杂的多边形,围绕着一条路线,按照给定的半径跟随其步骤。为此,我在路线的每个步骤(坐标)周围绘制了50边形的均匀多边形(实际上是圆形)。现在,我获得了所有绘制在路线周围的圆圈的坐标集,我可以在地图上看到它们,但它们重叠在一起,这不太好看,而且在地图上添加如此大量的覆盖物也不是一个好的做法。

enter image description here

现在我需要做的是将我现有的所有多边形合并成一个多边形,并在地图上绘制它。
我尝试删除每两个多边形的交点(测试多边形1的点是否位于多边形2内,反之亦然),并将其余的坐标合并到一个数组中,然后构建我的新多边形,但它没有成功。以下是我如何执行此操作的代码片段:
public ArrayList<PolygonOptions> polygons = new ArrayList<>();

// lineOptions is the set of route coordinates
    for (int i = 0; i < lineOptions.getPoints().size() - 1; i++) {
        // Draw a circle around each point of the route
        PolygonOptions circle1 = drawCircle(lineOptions.getPoints().get(i), 0.1);
        PolygonOptions circle2 = drawCircle(lineOptions.getPoints().get(i + 1), 0.1);
        // Draw a convex hull between every two successive circles
        PolygonOptions convexHull = convexHull(circle1, circle2);

        convexHull.strokeWidth(0);
        convexHull.fillColor(0x7F729E47);
        activity.range.add(activity.mMap.addPolygon(convexHull));
        polygons.add(convexHull);
    }


if (polygons.size() == 1) {
        pts.addAll(polygons.get(0).getPoints());
    } else {
        for (int i = 0; i < polygons.size() - 1; i++) {
            ArrayList<LatLng> pts1 = new ArrayList<>();
            ArrayList<LatLng> pts2 = new ArrayList<>();
            pts1.addAll(polygons.get(i).getPoints());
            pts2.addAll(polygons.get(i + 1).getPoints());

            for (int j = 0; j < pts1.size(); j++) {
                if (pointInPolygon(pts1.get(j), pts2)) {
                    pts1.remove(j);
                }
            }

            for (int j = 0; j < pts2.size(); j++) {
                if (pointInPolygon(pts2.get(j), pts1)) {
                    pts2.remove(j);
                }
            }

            pts.addAll(pts1);
            pts.addAll(pts2);
        }
    }

// This part didn't work
// PolygonOptions range = new PolygonOptions();
// range.addAll(pts);
// range.strokeWidth(0);
// range.fillColor(0x7F729E47);
// activity.range.add(activity.mMap.addPolygon(range));

嘿AymanKun,我有和你一样的需求,请问你能否分享一些Polyline Buffer的代码给我? - Mohit Trivedi
2个回答

2
根据@antonio的指示,使用JTS拓扑学套件,我成功地绘制了一条路线周围的多边形(缓冲路线)并定义了半径。当我在JTS库中使用缓冲函数时,得到了路线的缓冲区,但是端点是椭圆形的。我阅读了相关资料,发现这是因为计算出的坐标被投影在地球地图上,而地球不是平面的,当路线靠近地球极地时,端点会更加椭圆形,而当靠近赤道线(0度纬度)时则更加圆形。无论如何,我使用库中的另一个功能将我在问题中已有的所有多边形合并起来,这就是结果:

enter image description here

    public ArrayList<Polygon> polys = new ArrayList<>();

    //lineOptions is the set of route coordinates
    for (int i = 0; i < lineOptions.getPoints().size() - 1; i++) {
        // Draw a circle around each point of the route
        PolygonOptions circle1 = drawCircle(lineOptions.getPoints().get(i), 0.1);
        PolygonOptions circle2 = drawCircle(lineOptions.getPoints().get(i + 1), 0.1);


        // Draw a convex hull between every two successive circles
        PolygonOptions convexHull = convexHull(circle1, circle2);



        List<LatLng> latLngs = convexHull.getPoints();
        List<Coordinate> coords = new ArrayList<>();

        for (int j=0; j<latLngs.size(); j++) {
            coords.add(new Coordinate(latLngs.get(j).latitude, latLngs.get(j).longitude));
            if(j==latLngs.size()-1)
                coords.add(new Coordinate(latLngs.get(0).latitude, latLngs.get(0).longitude));
        }

        Coordinate[] coordinates = coords.toArray(new Coordinate[coords.size()]);

        GeometryFactory fact = new GeometryFactory();
        LinearRing linear = new GeometryFactory().createLinearRing(coordinates);
        Polygon poly = new Polygon(linear, null, fact);

        polys.add(poly);

    }


    PolygonOptions combine = combineIntoOnePolygon(polys);
    combine.strokeWidth(0);
    combine.fillColor(0x7F729E47);
    activity.range = activity.mMap.addPolygon(combine);

进行合并的函数:

static PolygonOptions combineIntoOnePolygon(Collection<Polygon> geometries ){
    Geometry all = null;
    PolygonOptions allPolygon = new PolygonOptions();

    for(Iterator<Polygon> i = geometries.iterator(); i.hasNext(); ){
        Polygon geometry = i.next();
        if( geometry == null ) continue;
        if( all == null ){
            all = geometry;
        }
        else {
            all = all.union( geometry );
        }
    }

    List<Coordinate> bufferCoordinates = Arrays.asList(all.getCoordinates());

    for (Coordinate c : bufferCoordinates) {
        allPolygon.add(new LatLng(c.x, c.y));
    }

    return allPolygon;
}

@MohitTrivedi 这是对我起作用的解决方案。 - AymanKun

1
你需要计算线的缓冲区。根据维基百科的定义:
缓冲区是由一组点确定的边界区域,该区域与对象上的所有节点沿着线段的指定最大距离。
通过闵可夫斯基和计算几何图形的缓冲区。闵可夫斯基和取两个多边形(一个是你的折线,另一个是圆形,如果你想要圆形端点)并将第二个多边形沿着第一个多边形的路径移动。
你可以找到一些具体实现闵可夫斯基和的例子进行学习。例如https://github.com/perelo/computational-geometry/blob/master/src/computational_geometry/model/algorithms/Minkowski.java

闵可夫斯基和生成了一个包括交点的点集,而在我的情况下,这将产生类似于我已经拥有的东西,我想摆脱那些点并仅保留最外层的点,凸包不行,因为在我的情况下,缓冲折线会导致带孔的凹多边形。我找不到凹壳或非凸壳的实现。 - AymanKun
1
Minkowski和的良好实现应该删除交点。你可以查看JTS(Java Topology Suite http://www.vividsolutions.com/jts/JTSHome.htm)。这个库可以为任何几何形状生成缓冲区,而且还有其他很棒的功能。你可以将它包含在你的项目中(它在Android上的表现非常好),但你需要将你的数据转换为JTS对象和反向转换。 - antonio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接