2017-06-09 103 views
1

無論地圖上點擊的順序如何,我都想創建一個規則的多邊形形狀。目前我面臨一個問題,如果點擊地圖以下列方式繪製多邊形然後它工作正常順序是 左上角右上角右下角左下角。如果這個順序保持不變,那麼多邊形繪製是非常好的類似,如果我點擊右上角,左上角和右下角,它也繪製得很好。如果當我爲了改變單一品脫不會得出正確的形狀的多邊形 圖像1 enter image description here地圖上的規則形狀多邊形Android地圖單擊

圖片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; 
       } 
      } 
     }); 

我關心的是我要畫不管點擊地圖上的順序如何,都有規則的形狀

+0

你可能想看看什麼是[凸包(https://en.wikipedia.org/wiki/Convex_hull)以及如何實現它 – antonio

回答

1

最後我推導出了創建規則形狀多邊形的解決方案。這與凸面船體無關。 以下是創建規則形狀多邊形的步驟,無論您是在地圖上點擊時鐘明智還是在地圖上按計數器時鐘。

  1. 查找中點多邊形的邊的
  2. 計算由中間點的每個邊緣和之間找出距離最近的座標的座標要被繪製
  3. 最近的座標=具有最小的邊緣座標從中間點到距離要繪製
  4. 移動通過移陣列權 繼在端最近的座標是代碼:
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; 
      } 
     } 

    });