地图上的常规形状多边形Android地图单击

时间:2017-06-09 12:05:06

标签: android google-maps polygon

无论点击地图的顺序如何,我都想创建一个正多边形。目前我面临一个问题,如果点击地图以下面的方式绘制多边形然后它正常工作正在跟随 左上角右下角右下角。如果维持这个顺序,那么多边形绘制完全相同,如果我点击右上角,左上角右下角,它也绘制得非常好。如果我改变一个品脱,以便它不会绘制正确形状的多边形 IMAGE1 enter image description here

图片2 enter image description here

代码2绘制多边形如下

     gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                llClearSelection.setVisibility(View.VISIBLE);
                gMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker)).position(latLng));
                if (markerClicked) {
//                    latLngArrayListPolygon.clear();
                    if (polygon != null) {
                        polygon.remove();
                        polygon = null;
                    }

                    polygonOptions.add(latLng);
                    latLngArrayListPolygon.add(latLng);
                    polygonOptions.strokeColor(Color.RED);
                    polygonOptions.fillColor(shadeColor);
                    polygon = gMap.addPolygon(polygonOptions);
                    if (latLngArrayListPolygon.size() > 1)
                        ivSaveMap.setVisibility(View.VISIBLE);
                    else
                        ivSaveMap.setVisibility(View.GONE);
                } else {
                    if (polygon != null) {
                        polygon.remove();
                        polygon = null;
                    }
                    polygonOptions = new PolygonOptions().add(latLng);
                    latLngArrayListPolygon.add(latLng);
                    markerClicked = true;
                }
            }
        });

我担心的是我想绘制一个规则的形状而不管点击地图的顺序

2 个答案:

答案 0 :(得分:1)

最后,我推导出了创建规则形状多边形的解决方案。这与Convex船体无关。 以下是创建常规形状多边形的步骤,无论您是在地图上点击时钟方式还是在地图上按时钟方式点击。

  
      
  1. 找到多边形边缘的中点
  2.   
  3. 通过查找每条边的中点与要绘制的坐标之间的距离来计算最近的坐标
  4.   
  5. 最近的坐标=从中点到要绘制的坐标的距离最小的边
  6.   
  7. 通过向右移动数组来移动最后的最近坐标   以下是代码:
  8.   
 ArrayList<LatLng> latLngArrayListPolygon = new ArrayList<>();
ArrayList<Double> distancesFromMidPointsOfPolygonEdges = new ArrayList<>();
    private void adjustPolygonWithRespectTo(LatLng point) {
        double minDistance = 0;

        if (latLngArrayListPolygon.size() > 2) {
            distancesFromMidPointsOfPolygonEdges.clear();
            //midPointsOfPolygonEdges?.removeAll()

            for (int i = 0; i < latLngArrayListPolygon.size(); i++) {
                // 1. Find the mid points of the edges of polygon
                ArrayList<LatLng> list = new ArrayList<>();

                if (i == (latLngArrayListPolygon.size() - 1)) {
                    list.add(latLngArrayListPolygon.get(latLngArrayListPolygon.size() - 1));
                    list.add(latLngArrayListPolygon.get(0));
                } else {
                    list.add((latLngArrayListPolygon.get(i)));
                    list.add((latLngArrayListPolygon.get(i + 1)));
                }


                LatLng midPoint = computeCentroid(list);

                // 2. Calculate the nearest coordinate by finding distance between mid point of each edge and the coordinate to be drawn
                Location startPoint = new Location("");
                startPoint.setLatitude(point.latitude);
                startPoint.setLongitude(point.longitude);
                Location endPoint = new Location("");
                endPoint.setLatitude(midPoint.latitude);
                endPoint.setLongitude(midPoint.longitude);
                double distance = startPoint.distanceTo(endPoint);

                distancesFromMidPointsOfPolygonEdges.add(distance);
                if (i == 0) {
                    minDistance = distance;
                } else {

                    if (distance < minDistance) {
                        minDistance = distance;
                    }
                }
                //midPointsOfPolygonEdges?.append(midPoint)
            }

            // 3. The nearest coordinate = the edge with minimum distance from mid point to the coordinate to be drawn
            int position = minIndex(distancesFromMidPointsOfPolygonEdges);


            // 4. move the nearest coordinate at the end by shifting array right
            int shiftByNumber = (latLngArrayListPolygon.size() - position - 1);

            if (shiftByNumber != latLngArrayListPolygon.size()) {
                latLngArrayListPolygon = rotate(latLngArrayListPolygon, shiftByNumber);
            }
        }

        // 5. Now add coordinated to be drawn
        latLngArrayListPolygon.add(point);
    }

    public static int minIndex(ArrayList<Double> list) {
        return list.indexOf(Collections.min(list));
    }

    public static <T> ArrayList<T> rotate(ArrayList<T> aL, int shift) {
        if (aL.size() == 0)
            return aL;

        T element = null;
        for (int i = 0; i < shift; i++) {
            // remove last element, add it to front of the ArrayList
            element = aL.remove(aL.size() - 1);
            aL.add(0, element);
        }

        return aL;
    }

    private LatLng computeCentroid(List<LatLng> points) {
        double latitude = 0;
        double longitude = 0;
        int n = points.size();

        for (LatLng point : points) {
            latitude += point.latitude;
            longitude += point.longitude;
        }

        return new LatLng(latitude / n, longitude / n);
    }

点击地图绘制多边形是以下

 gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
        @Override
        public void onMapClick(LatLng latLng) {
            gMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker)).position(latLng));
            if (markerClicked) {
                if (polygon != null) {
                    polygon.remove();
                    polygon = null;
                }
                adjustPolygonWithRespectTo(latLng);
                PolygonOptions polygonOptions = null;
                for (int i = 0; i < latLngArrayListPolygon.size(); i++)
                    if (i == 0)
                        polygonOptions = new PolygonOptions().add(latLngArrayListPolygon.get(0));
                    else
                        polygonOptions.add(latLngArrayListPolygon.get(i));
                polygonOptions.strokeColor(Color.BLACK);
                polygonOptions.strokeWidth(5f);
                polygonOptions.fillColor(shadeColor);
                polygon = gMap.addPolygon(polygonOptions);
            } else {
                if (polygon != null) {
                    polygon.remove();
                    polygon = null;
                }
                polygonOptions = new PolygonOptions().add(latLng);
                latLngArrayListPolygon.add(latLng);
                markerClicked = true;
            }
        }

    });

答案 1 :(得分:0)

查看How can I determine whether a 2D Point is within a Polygon?

当您的用户点击地图时,您必须确定新顶点是在多边形内还是外部。如果它在里面,请忽略。否则,添加多边形并为多边形中的每个点运行算法。

希望这有帮助。