2014-02-26 12 views
11

In meiner Android-Anwendung muss ich ein Clusterelement in meiner GoogleMap löschen und erneut hinzufügen, das meinen aktuellen Standort darstellt. Aber wenn ich diesen Code ausführen:Problem beim Entfernen des Elements aus dem Clustermanager

clusterMng.remove(myitem); 

ich diese Ausnahme erhalten:

java.lang.UnsupportedOperationException: NonHierarchicalDistanceBasedAlgorithm.remove  
not implemented. 

Kann mir jemand erklären, was das bedeutet? Muss ich einige Methoden von ClusterManager.java in der externen Bibliothek neu schreiben? Oder kann ich einfach meinen Algorithmus ändern?

Antwort

14

standardmäßig ClusterManager verwendet NonHierarchicalDistanceBasedAlgorithm, die nicht zu entfernen Elemente nicht implementiert.

Versuchen zu verwenden GridBasedAlgorithm statt (es Elemente unterstützt entfernen):

clusterMng.setAlgorithm(new GridBasedAlgorithm<MyClusterItem>()); 

Oder für eine bessere Leistung, wickeln Sie es mit PreCachingAlgorithmDecorator, wie ClusterManager standardmäßig tut:

clusterMng.setAlgorithm(new PreCachingAlgorithmDecorator<MyClusterItem>(new GridBasedAlgorithm<MyClusterItem>())); 
+1

Dies ist eine gute Lösung, aber der Algorithmus mit 'PreCachingAlgorithmDecorator' Verpackung ist nicht notwendig, da es automatisch tut dies in der 'setAlgorithm()' Methode. –

8

Wie @SergePopulov sagte, implementiert NonHierarchicalDistanceBasedAlgorithm das Entfernen von Elementen nicht. Für diejenigen, die GridBasedAlgoritm nicht verwenden möchten, aber dennoch einzelne Elemente aus NonHierarchicalDistanceBasedAlgorithm entfernen müssen, gibt es eine andere Lösung.

Mit diesem Link (Source) können Sie den Quellcode für den von den Entwicklern in github bereitgestellten NonHierarchicalDistanceBasedAlgorithm finden.

Was ich getan habe, ist nur die alten Cluster-Elemente zu speichern, löschen Sie den ClusterManager und fügen Sie die alten Elemente erneut, aber fügen Sie nicht die eine, die durch die Methode übergeben wird.

Erstellen Sie zuerst eine separate Klasse und fügen Sie den Klassencode NonHierarchicalDstanceBasedAlgorithm ein.

public class CustomNonHierarchicalDistanceBasedAlgorithm<MarkerItem extends ClusterItem> implements Algorithm<MarkerItem> 
{ 
    //copy code here 
} 

Nach dieser Methode find removeItem und ersetzen Sie es mit diesem Code:

@Override 
public void removeItem(MarkerItem item) 
{ 
    final Collection<QuadItem<MarkerItem>> items = new ArrayList<QuadItem<MarkerItem>>(); 
    final PointQuadTree<QuadItem<MarkerItem>> quadTree = new PointQuadTree<QuadItem<MarkerItem>>(0, 1, 0, 1); 

    for (QuadItem<MarkerItem> temp : mItems) 
    { 
     if (item.getPosition() != temp.getPosition()) 
     { 
      synchronized (quadTree) 
      { 
       items.add(temp); 
       quadTree.add(temp); 
      } 
     } 
    } 

    clearItems(); 

    for (QuadItem<MarkerItem> temp : items) 
    { 
     synchronized (mQuadTree) 
     { 
      mItems.add(temp); 
      mQuadTree.add(temp); 
     } 
    } 
} 

Danach gehen, wo Ihre ClusterManager erstellt und Einfügen von Code unter Ihrem Klassennamen enthält:

clusterManager.setAlgorithm(new CustomNonHierarchicalDistanceBasedAlgorithm<MarkerItem>()); 

Wo ist Ihr MarkerItem Ihre Klasse, die ClusterItem implementiert hat. Und es sollte jetzt funktionieren.

Vergessen Sie nicht, Ihre ClusterManager recluster, nachdem Sie das Element entfernen, indem Sie:

clusterManager.cluster(); 
+0

Ich bekomme MarkerItems kann nicht in eine Typfehlermeldung aufgelöst werden –

+0

In welcher Klasse? –

7

Hier ist, wie ich es tat:

@Override 
public void removeItem(T item) { 
    final QuadItem<T> quadItem = new QuadItem<T>(item); 
    synchronized (mQuadTree) { 
     mItems.remove(quadItem); 
     mQuadTree.remove(quadItem); 
    } 
} 

ich auch equals() und hashCode() in QuadItem umgesetzt als es wird im TODO des NonHierarchicalDistanceBasedAlgorithm Quellcodes empfohlen:

@Override 
public boolean equals(Object o) { 
    if (this == o) { 
     return true; 
    } 
    if (!(o instanceof QuadItem)) { 
     return false; 
    } 

    QuadItem quadItem = (QuadItem) o; 

    return mClusterItem.equals(quadItem.mClusterItem); 

} 

@Override 
public int hashCode() { 
    return mClusterItem.hashCode(); 
} 

Schließlich habe ich implementiert equals() und hashCode() in meiner Nachkommenschaft ClusterItem.

+0

bestätigt, dass diese Lösung funktioniert! Leistungsmäßig scheint es gut zu sein. Kann über 1k Marker – Gibberish

+0

@Viachaslau Tysianchuk umgehen, wie hast du es geschafft, den NonHierarchicalDistanceBasedAlgorithm.QuadItem zu modifizieren, um diese Methoden zu implementieren? Musstest du die Bibliothek als Modul benutzen? – desgraci

+1

@desgraci Ich habe den vollständigen Quellcode von android-maps-utils in mein Projekt kopiert, weil ich noch einige Änderungen vornehmen musste. Für diesen Fall könnte das Kopieren nur des NonHierarchicalDistanceBasedAlgorithm ausreichen. –