2016-06-18 7 views
3

Ich versuche, ein komplexes Polygon um eine Route zu zeichnen, seine Schritte mit einem bestimmten Radius folgen. Dazu habe ich 50-seitige gleichförmige Polygone (die praktisch Kreise sind) um jeden Schritt (Koordinate) der Route gezogen. Jetzt erhalte ich eine Menge von Koordinaten aller geplotteten Kreise um die Route, und ich kann sie auf der Karte sehen, aber sie sind überlappt, was nicht sehr gut aussieht, und es ist keine gute Übung, eine so große Anzahl von Überlagerungen hinzuzufügen die Karte.Android Google Maps PolygonOptions nicht aus angegebenen Koordinaten

enter image description here

Also, was ich jetzt tun müssen, ist es, alle Polygone zu verschmelzen Ich habe jetzt in einem Polygon und es in der Karte grafisch darzustellen.

Ich versuchte, die Schnittpunkte von jeweils zwei Polygonen zu löschen (zu testen, ob Punkte von Polygon1 innerhalb von Polygon2 liegen und umgekehrt) und alle übrigen Koordinaten in einem Array zusammenzufassen und dann mein neues Polygon zu konstruieren, aber es hat nicht funktioniert . Hier ist ein Code-Ausschnitt, wie ich das mache:

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)); 
+0

hey AymanKun, ich habe die gleiche Anforderung wie Sie, können Sie mir bitte einige Code für Polyline Buffer teilen? –

Antwort

1

Sie müssen den Puffer der Linie berechnen. Nach Wikipedia:

Ein Puffer ist ein Bereich, durch den Begrenzungsbereich durch einen Satz von Punkten zu einem bestimmten maximalen Abstand von allen Knoten entlang Segmenten eines Objekts bestimmt definiert sind.

Der Puffer einer Geometrie wird mit Minkowski sum berechnet. Die Minkowsky-Summe nimmt zwei Polygone (eine ist Ihre Polylinie und die andere ist ein Kreis, wenn Sie abgerundete Kappen haben wollen) und bewegt die zweite durch den Pfad der ersten.

Sie können einige konkrete Implementierungen der Minkowski-Summe finden, die Sie studieren können. Beispiel: https://github.com/perelo/computational-geometry/blob/master/src/computational_geometry/model/algorithms/Minkowski.java

+0

Die Minkowski-Summe erzeugt eine Menge von Punkten einschließlich Schnittpunkten, die in meinem Fall etwas erzeugen werden, was ich bereits habe, ich möchte diese Punkte loswerden und nur die äußersten Punkte behalten, der Convexe-Rumpf wird das nicht tun, weil in meinem Fall Die gepufferten Polylinien würden konkave Polygone mit Löchern ergeben. Ich konnte keine Konkav- oder Nichtkonvex-Rumpfimplementierung finden. – AymanKun

+1

Eine gute Umsetzung der Minkowski-Summe sollte Schnittpunkte entfernen. Sie können sich JTS (Java Topology Suite http://www.vividsolutions.com/jts/JTSHome.htm) ansehen. Diese Bibliothek kann (neben anderen großartigen Funktionalitäten) Puffer für jede Geometrie erzeugen.Sie können es in Ihr Projekt aufnehmen (es funktioniert hervorragend unter Android), aber Sie müssen Ihre Daten in JTS-Objekte und zurück transformieren. – antonio

2

Den Anweisungen von @ antonio folgend, konnte ich mithilfe von JTS Topology Suit ein Polygon um die Route (Puffern der Route) mit einem definierten Radius zeichnen. Als ich die Pufferfunktion in der JTS-Bibliothek benutzte, erhielt ich einen Puffer der Route, aber die Kappen waren oval, ich lese darüber und dies geschieht, weil die berechneten Koordinaten auf der Erdkarte projiziert werden, die nicht flach ist, die Kappen werden ovaler wenn die Route näher an den Erdpolen liegt, und mehr rund, wenn sie näher an der Äquatorlinie liegen (0º Breite). Wie auch immer, habe ich eine andere Funktionalität von thhe Bibliothek zur Vereinigung all Polygone, die ich bereits in meiner Frage habe, und das war das Ergebnis:

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); 

Die Funktion, die die Kombination funktioniert:

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; 
} 
+0

@MohitTrivedi hier ist die Lösung, die für mich arbeitete – AymanKun