2011-12-02 64 views
2

我對Mapview,Overlay和ItemizedOverlay的使用經驗非常有限。我已經看到了一些簡單的代碼示例,它們使用一個drawable來覆蓋和itemizedOverlays,但我不確定如何處理這些需求:我想在地圖視圖上繪製多個drawable(例如:地圖中心的星形圖標,以及一些其他重疊項目的其他圖標),但我想要一個不可點擊(明星)。我是否應該使用Overlay和ItemizedOverlay來實現這個目標?在地圖上使用多畫圖

此外,我的下一個問題是介紹問題:如果我有500個項目要顯示在地圖上,顯示該信息的實用方法是什麼?再次,我幾乎沒有開發和使用地圖應用程序的經驗。

+1

這是一個壞主意,在地圖上顯示500個項目一次,因爲性能將是非常糟糕的。嘗試過濾出來,只顯示其中一些 – Craigy

+0

這是一個很好的問題。特別是如果您開始考慮將您的積分聚集在某些縮放級別。如果您發現自己需要以更高的縮放級別顯示多個點,則可以考慮將疊加層聚合爲一個,並在放大時相應地展開羣集。 – topwik

回答

1

幾周前我面臨同樣的情況。

您應該爲每個不同的drawable使用一個ItemizedOverlay,然後將overlayItems添加到ItemizedOverlay。

最方便的方法是擴展ItemizedOverlay,以便爲每個需要的樣式定義標記和點擊行爲。

對於第二部分,出於性能方面的考慮,您不應該一次只填寫一次您所有500個物品的地圖。我使用了一個動態添加到屬於地圖顯示範圍的地圖標記的系統。

這裏是我的ItemizedOverlay的片段,可能是您的兩個問題有用:

private class MarkerItemized_Overlay extends ItemizedOverlay<OverlayItem> { 



     private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>(); 
    Context mContext; 

    public MarkerItemizedOverlay(Drawable marker, Context context) { 
     super(boundCenterBottom(marker)); 
     mContext = context; 
    } 

    public void addOverlay(OverlayItem overlay) { 
     if (!mOverlays.contains(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(final int index) { 
     OverlayItem item = mOverlays.get(index); 

     AlertDialog.Builder dialog = new AlertDialog.Builder(mContext); 
     dialog.setTitle(item.getTitle()); 
     dialog.setMessage(item.getSnippet()); 
     dialog.setNegativeButton("Annuler", 
       new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int whichButton){} 
     }); 
     dialog.setPositiveButton("Naviguer", 
       new DialogInterface.OnClickListener() { 
      public void onClick(DialogInterface dialog, int whichButton){ showDirections(mOverlays.get(index).getPoint()); } 
     }); 
     dialog.setInverseBackgroundForced(true); 
     dialog.show(); 
     return true; 
    } 
    public boolean contains(Store store) { 
     return mOverlays.contains(store); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent e, MapView mapView) { 

     if (e.getAction() == MotionEvent.ACTION_UP) { 
      GeoPoint newCenter = mapView.getMapCenter(); 
      int minLat, maxLat, minLng, maxLng; 
      minLat = mapCenter.getLatitudeE6() - mapView.getLatitudeSpan()/2; 
      maxLat = mapCenter.getLatitudeE6() + mapView.getLatitudeSpan()/2; 
      minLng = mapCenter.getLongitudeE6() - mapView.getLongitudeSpan()/2; 
      maxLng = mapCenter.getLongitudeE6() + mapView.getLongitudeSpan()/2; 
      if (newCenter.getLatitudeE6() > maxLat || 
        newCenter.getLatitudeE6() < minLat || 
        newCenter.getLongitudeE6() > maxLng || 
        newCenter.getLongitudeE6() < minLng) 
      { 
       mapCenter = mapView.getMapCenter(); 
       Location mapCenterLoc = new Location(providerName); 
       mapCenterLoc.setLatitude(newCenter.getLatitudeE6()/1E6); 
       mapCenterLoc.setLongitude(newCenter.getLongitudeE6()/1E6); 
       Store[] newClosestStores = storeDB.getClosestStores(mapCenterLoc); 

       for (int i = 0; i < newClosestStores.length; i++) 
        if (! itemizedOverlay.contains(newClosestStores[i])) 
         setMarker(newClosestStores[i]); 
      } 
     } 
     return super.onTouchEvent(e, mapView); 
    } 
}