2017-03-14 12 views
5

Kullanıcı ekranına göre sunucudan belirteçleri dinamik olarak yükleyen google haritaları içeren bir android haritamız var. Örneğin, kullanıcı haritayı hareket ettirirse, sunucuya istekte bulundum ve ekran sınırları gönderiyorum ve buna bağlı olarak daha sonra ayrıştırılan ve gerçek göstericilere oluşturulan işaretleyici verileri (id ve düzeltmeler) elde ediyorum. Sorun şu ki, kullanıcı aynı alana (hangi işaretleyicilerin daha önce oluşturulduğu) geri dönüyorsa, hala aynı talebi alıyorum ve aynı verileri alıyorum (ama açıkçası o işaretleyiciyi yeniden yaratmayacağım, böylece sadece tüm döngüler için bu döngüde çalışıyorum) harita üzerinde ve harita işaretleyici kimliği eşit sunucu veri işaretleyici id göndermek olup olmadığını kontrol ve eşitse bu yaklaşım en iyi olduğunu düşünmüyorum Ancak ben sadece)Android Etiketleri dinamik olarak düzenle en iyi strateji

try { 
       Collection<MarkerItemData> mapMarkers = algorithm.getItems(); 
       JSONObject jsonObject = new JSONObject(strings[0]); 
       JSONArray respondArray = jsonObject.getJSONArray("respond"); 
       list = new ArrayList(); 
       for (int i = 0; i < respondArray.length(); i++) { 
        JSONObject station = respondArray.getJSONObject(i); 
        int id = station.getInt("_id"); 
        boolean skip = false; 
        for (final MarkerItemData m : mapMarkers) { 
         if (m.getId() == id) { 
          skip = true; 
          break; 
         } 
        } 
       } 
      } 

döngü bölünürler. Ben de

  • sunucu ekran sınırları göndermek ve ayrıca Ekrandaki tüm işaretleyici id (Ben hangi kimlikleri ekran aralığı ve içinde tüm işaretleri seçebilirsiniz (en azından bence) çalışması gerekir başka fikirleri var
  • her zaman android uygulamasından işaretleri silmek ve temelde) Şahsen ben bu kötü bir çözüm olduğunu düşünüyorum (sunucudan

her zaman tüm işaretleri yeniden Yani bu fikirlerin hangi en iyisidir) ekran sınırları olmayan ? Başka fikirlerin var mı? (Benim ingilizce için özür dilerim)

+0

Harita taşınırken her seferinde işaretçilerin konumunu almak gerekli mi? İlk önce hepsini indirip işaretçileri gösteremez misin? –

+0

@WaqasAhmedAnsari, sunucuda toplam işaret sayısı çok büyük olduğunda tüm işaretleyicileri ön plana çıkarıyorsa verimsiz oluyor – BhalchandraSW

cevap

2

Ekran sınırlarını sunucuya gönderme ve ekranda görünen işaretleyicilerin kimlik bilgileri en iyi seçimdir. Ama yine de birkaç sorun var. Ekran sınırları ile belirttiğiniz aralıkta yer alan tüm işaretçileri nasıl bulacaksınız? Yeni işaretçiler sunucunuza gelirse veya bazı işaretçiler silinirse ne olur? Böyle bir durumda bakım yapılabilir bir yapıya sahip olabilir misiniz, yoksa aralıkta bulunup bulunmadığını görmek için veritabanındaki bir işaretçiye karşılık gelen her noktayı tek tek test edebilecek misiniz? Tüm bunları göz önünde bulundurarak, depolama ve sorgulama noktalarını optimize etmenin bir yolunu bulmanız gerekir, diğer bir deyişle, işaretçileri işaret eden enlem ve boylam çiftleri. Mekansal indekslemeyi ortak mekansal indeks yöntemlerinden birini kullanarak gerçekleştirmelisiniz.

Mekansal indeksleme için birçok yöntem vardır ve biri kullanım durumuna bağlı olarak diğerinden biraz daha iyi olabilir. Uzun hikayeyi kısaltmak için, bu senaryodaki aralığı sorgulamanız gerektiğinden, bir quadtree uygulamanız gerekir. Dörtlü, her iç düğümün tam olarak dört çocuğa (kuzeybatı, kuzeydoğu, güneybatı, güneydoğu) sahip olduğu bir ağaç veri yapısı olarak adlandırılır. Bu yapı hakkında hiç bir bilginiz yoksa, temellerini bir saat içinde anlayabileceğine inanıyorum, fakat bunu ayrıntılı olarak açıklamak benim için çok fazla zaman kaybına neden olacaktır. Bu nedenle, dörtlü hakkında uygulama ayrıntılarını atladım. Bu yapıyı yapabildiğimden çok daha iyi açıklayan birkaç kaynak var ve kolayca bir açık kaynak kütüphanesi bulabiliyorsunuz.

ArrayList<LatLng> queryRange(QuadLevel level, float[] screenBounds, ArrayList<LatLng> prevPoints) { 

    // Initialize a list to hold the found points 
    ArrayList<LatLng> pointsInRange = new ArrayList<>(); 

    if (!quadtreeBounds.intersects(screenBounds)) 
     return pointsInRange; 

    // Find the points that are in the current quad level 
    for (LatLng point : level.getPoints()) { 
     // If the current point is in screen bounds and it is not contained by prevPoints 
     if (point.isInRange(screenBounds) 
      && !prevPoints.contains(point)) 
      pointsInRange.add(point); 
    } 

    // If there are no children, return 
    if (level.hasNoChildren()) 
     return pointsInRange; 

    // Else, continue to look up children 
    pointsInRange.addAll(queryRange(level.northwest, screenBounds, prevPoints)); 
    pointsInRange.addAll(queryRange(level.northeast, screenBounds, prevPoints)); 
    pointsInRange.addAll(queryRange(level.southwest, screenBounds, prevPoints)); 
    pointsInRange.addAll(queryRange(level.southeast, screenBounds, prevPoints)); 

    return pointsInRange; 
} 
1

Mağaza tüm Görünür:

Ben sadece önceki ekrana zaten olanlardan hariç ekran sınırları aralığında görünen tüm noktaları bulmak için Dörtlüağaç için sözde imsi Java yöntemini verecek Liste veya Yerel Db veya Bazı yerdeki Ekrandaki İşaretçiler Sunucusuz Mevcut İsteğin Üzerinde Mevcut İşaretçiler Üzerine Yineleme

1

HashSet<MarkerOptions>'u uzatın, böylece MarkerOptions eklendiğinde haritanıza ekleyin.

class MarkerSet extends HashSet<MarkerOptions> { 
    @Override 
    public boolean add(MarkerOptions markerOptions) { 

     boolean didAdd = super.add(markerOptions); 

     if(didAdd) { 
      mMap.addMarker(markerOptions); 
     } 
     return didAdd; 
    } 
} 

Harita etkinliklerinizde bir LatLngBounds nesnesi bulundurun.Bu LatLngBounds nesnesi, daha önce sunucudan istediğiniz verileri aldığınız sınırları saklar.

Haritanın kamerası hareket ettiğinde, sunucudan istekte bulunulmadığı ve sınırların artırılmasının sunucudan talep edilmediği durumlarda yeni sınırların geçerli olarak yüklenmiş sınırlar içinde olup olmadığını kontrol edin.

mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() { 
    @Override 
    public void onCameraMove() { 

     LatLngBounds currentBounds = mMap.getProjection().getVisibleRegion().latLngBounds; 

     if (mBounds == null) { 
      mBounds = currentBounds; 
      // Perform server request and get markers passing in currentBounds 
      // Following to be performed in server request's callback 
      MarkerOptions markerOptions = new MarkerOptions(); 
      // set marker options here 
      mMarkerSet.add(markerOptions); 

     } else { 

      if (!(mBounds.contains(currentBounds.northeast) || mBounds.contains(currentBounds.southwest))) { 
       mBounds = mBounds.including(currentBounds.northeast); 
       mBounds = mBounds.including(currentBounds.southwest); 

       // Perform server request and get markers passing in currentBounds 
       // Following to be performed in server request's callback 
       MarkerOptions markerOptions = new MarkerOptions(); 
       // set marker options here 
       mMarkerSet.add(markerOptions); 
      } 

     } 
    } 
}); 

hep currentBounds için Sunucu isteği yürütmesini emin olun. Bu algoritma, currentBounds ve mBounds üst üste geldiğinde currentBounds'u kısaltmayı başarırsanız geliştirilebilir.

Varsayım

burada bu varsayım kamera hareketleri, currentBoundsmBounds üzerinden hafifçe düşecek zaman olacağı unutmayınız. Aksi halde, yeni işaretleyiciler yüklenmez. Görüntünün atıfta bulunması, kullanıcının görünür yeşil bölgeden turuncuya doğru hareket etmesi durumunda mBounds değeri mavi dikdörtgen olacak ve bu nedenle beyaz alan kaplanmayacaktır. Bununla birlikte, pratikte, kamerayı yatay veya dikey olarak mükemmel bir şekilde taşımak kolay değildir; bu, işlenecek alan için sunucu yönteminin ve yeni işaretleyicilerin çağrılmasına neden olacaktır. Bu yardımcı olur

How mBounds will be aggregated?

Umut. :)

İlgili konular