2011-01-17 16 views
6

Pracuję nad aplikacją dla systemu Android, która już istnieje na telefonie iPhone.Problem z dużą liczbą znaczników na mapie

W aplikacji dostępna jest mapa, która zawiera (policzyłem) około 800 znaczników w czterech grupach zaznaczonych rysunkami w czterech różnych kolorach. Każda grupa może być włączona lub wyłączona. Informacje o znacznikach Mam na liście. Tworzę mapOverlay dla każdej grupy, a następnie załączam tę nakładkę do mapy. Mocno wierzę, że część kodująca zrobiłem poprawnie. Ale i tak dołączę mój kod ...

Chodzi o to, że mój Nexus One nie poradzi sobie z mapą z tymi wszystkimi znacznikami. Trwa około 15 sekund, aby narysować 500 znaczników. Następnie, gdy wszystkie narysowane, mapa nie jest całkiem gładka. Trudno jest powiększać i nawigować. Można to zrobić, ale doświadczenie jest złe i chciałbym zobaczyć, czy coś można tam zrobić. Wiem, że jeśli uniknę String> Double conversion, mógłbym zaoszczędzić trochę czasu, ale wątpię, by to było znaczące.

iPhone wydaje się nie mieć problemów z wyświetlaniem wszystkich tych znaczników. Wyświetlenie ich wszystkich zajmuje około 1-2 sekund, a powiększanie i przesuwanie nie jest takie złe. Zwolnienie jest zauważalne, ale wciąż akceptowalne. Osobiście uważam, że nie jest dobrze narysować wszystkich tych znaczników, ale aplikacja jest zaprojektowana przez kogoś innego i nie powinienem wprowadzać żadnych drastycznych zmian.

Nie jestem pewien, co tutaj zrobić. Wygląda na to, że będę musiał wymyślić inną funkcjonalność, może użyć lokalizacji GPS, jeśli jest znana, i narysować tylko znaczniki w pewnym promieniu, lub, jeśli nie jest znana lokalizacja, użyć środka ekranu (mapy) i narysować znaczniki wokół tego. Będę musiał mieć rozsądne wyjaśnienie dla moich szefów na wypadek, gdyby dokonałem tych zmian.

Doceniam czy ktoś ma jakieś idy.

I kod:

List<Overlay> mapOverlays = mapView.getOverlays(); 
    Drawable drawable = this.getResources().getDrawable(R.drawable.pin_blue); 
    drawable = this.getResources().getDrawable(R.drawable.pin_blue); 
    ArrList = appState.GetSleepArrList(); 
    ItemizedOverlay itemizedoverlay = new ItemizedOverlay(drawable, this); 
    ... 
    ... 
     for (int m = 0; m < ArrList.size(); m++) { 
      tName = ArrList.get(m).get("name").toString(); 
      tId = ArrList.get(m).get("id").toString(); 
      tLat = ArrList.get(m).get("lat").toString();; 
      tLng = ArrList.get(m).get("lng").toString();; 
      try { 
       lat = Double.parseDouble(tLat); 
       lng = Double.parseDouble(tLng); 
       p1 = new GeoPoint(
         (int) (lat * 1E6), 
         (int) (lng * 1E6)); 
       OverlayItem overlayitem = new OverlayItem(p1, tName, tId); 
       itemizedoverlay.addOverlay(overlayitem); 
      } catch (NumberFormatException e) { 
       Log.d(TAG, "NumberFormatException" + e);  
      } 
     } 
     mapOverlays.add(itemizedoverlay); 
     mapView.postInvalidate(); 

................................

public class ItemizedOverlay extends ItemizedOverlay<OverlayItem> 
{ 
    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>(); 
    private Context mContext; 
    public HelloItemizedOverlay(Drawable defaultMarker, Context context) 
    { 
     super(boundCenterBottom(defaultMarker)); 
     mContext = context; 
    } 

    public void addOverlay(OverlayItem overlay) 
    { 
     mOverlays.add(overlay); 
     populate(); 
    } 
    @Override 
    protected OverlayItem createItem(int i) 
    { 
     return mOverlays.get(i); 
    } 
    @Override 
    public int size() 
    { 
     return mOverlays.size(); 
    } 
    @Override 
    protected boolean onTap(int index) 
    { 
     final OverlayItem item = mOverlays.get(index); 
        ... EACH MARKER WILL HAVE ONCLICK EVENT THAT WILL PRODUCE CLICABLE 
        ... BALOON WITH MARKER'S NAME.   
     return true; 
    }  
}  
+0

I miałaś odczytać kod aby być uczciwym, ale tak, użyłem mojego własnego algorytmu uproszczenia trasy. Musiałem wykreślić około 1379 oznaczeń miejsc i zredukowałem je do 65. Jeśli jesteś zainteresowany, z przyjemnością wytłumaczę algo, ale ponieważ nie robimy zadań domowych na tej stronie, nie mogę ci dać "teh-codez" :) – Reno

+2

Gdzieś w na tym forum czytałem, że ItemizedOverlay jest zaprojektowany na tuziny przedmiotów. Jeśli istnieje więcej przełączeń na nakładkę, może to być konieczne. Mogę to potwierdzić. Dwie aplikacje z ponad 1000 ItemizedOverlay potrzebowały minuty, by narysować. Po przejściu na Overlay zawsze trwa to od 2 do 4 sekund. –

+0

Reno, czy możesz wyjaśnić swój algorytm optymalizacyjny? Po prostu nie ma mapy dla wszystkich tych znaczników. Jest zbyt wolny i zbyt zagracony. – bobetko

Odpowiedz

3

Cóż. Okazało się, że wywołuję funkcję populate() za każdym razem po dodaniu znacznika. Wyjąłem metodę populate() z metody addOverlay() i wywołuję ją po zakończeniu pętli. Wszystkie markery pokazują się teraz niemal natychmiast. Jedynym problemem jest teraz to, że mapa jest bardzo niereagująca przy niższym powiększeniu (pokazując wiele znaczników naraz). Nie widzę rozwiązania tego problemu, chyba że wymyślę, jak zmniejszyć liczbę znaczników na mapie, gdy mapa jest pomniejszona ... myśląc, aby je jakoś pogrupować ... obecnie pracuję nad tym ...

+0

nie było to już wspomniano tutaj: http://stackoverflow.com/questions/2848189/efficient-map-overlays-in-android-google-map ????????? ..... zamiast narzekać mógłbyś wypróbować to, co tam wspomniano ... tak czy inaczej .... – Ahsan

0

Mam ten sam problem przy ładowaniu wielu znaczników na mapie, ale wprowadziłem pewne opóźnienie w ładowaniu znacznika i wyświetlania mapy. Pierwsza mapa wyświetlania i po pewnym opóźnieniu załaduje wszystkie znaczniki. które ładują się szybciej do pewnego stopnia.

2

Tam są dwa sposoby na uproszczenie trasy.

1) Jeśli otrzymałeś nagłówek wszystkich punktów. Możesz zachować tolerancję pozycji, powiedz jeśli różnica pozycji między point A and B to 0.5 Po prostu narysuj linię od A do B i zignoruj ​​punkty pomiędzy.

2) Jeśli nie masz nagłówka. Zrób trójkąt, jak pokazano na rys. Jeśli h leży w granicach między swoimi, należy pominąć punkty pomiędzy i narysować linię od A to B enter image description here

Można również użyć innej route simplification algorithms.


Patrz także:

Route uproszczenie - Douglas Puecker Algorithm

Powiązane problemy