2016-07-30 88 views
2

我有一個由我的自定義羣集渲染器extends DefaultClusterRenderer配置的谷歌羣集管理器處理的地圖片段。只渲染谷歌地圖上的可見羣集項目的最佳方式

我已經overritten功能onBeforeClusterItemRenderedonBeforeClusterRendered能夠diplay我的照片:

enter image description here

現在,如果用戶在它放大是沒有意義的渲染不可見區域的所有項目。 這很容易發現,如果該項目是在可見光區域:

private Boolean isInBounds(LatLng position) { 
    return map.getProjection().getVisibleRegion().latLngBounds.contains(position); 
} 

但是,如果我跳過渲染,如果該項目當前不可見,它將是空的時,地圖上的用戶滾動。

那麼,如果用戶滾動以及如何重新呈現不在可見邊界內的項目,誰知道如何獲取事件? (從可見到不可見,反之亦然)?

(對不起,我的英文很不好)

+0

你怎麼就聚集標記加載圖像?任何示例代碼。謝謝。 – ZZzzZZzz

回答

2

這是我的解決方案。它工作得很好,只渲染可見物品。 我用相機改變監聽器重新渲染,現在變成了可見的物品:

private void onBeforeClusterOrClusterItemRendered(final Cluster<MediaItem> cluster, final MediaItem mediaItem, final MarkerOptions markerOption 
    if(!isAdded()) 
     return; 

    // In visible area? 
    Marker marker = cluster == null ? getMarker(mediaItem) : getMarker(cluster); 
    Boolean isInBounds = isInBounds(marker != null ? marker.getPosition() : mediaItem.getPosition(), null); 

    if(isInBounds) { 
     // ... 
    } 
} 

private Boolean isInBounds(LatLng position, LatLngBounds latLngBounds) { 
    return (latLngBounds == null ? mMap.getProjection().getVisibleRegion().latLngBounds : latLngBounds).contains(position); 
} 

@Override 
protected void onBeforeClusterItemRendered(final MediaItem mediaItem, final MarkerOptions markerOptions) { 
    onBeforeClusterOrClusterItemRendered(null, mediaItem, markerOptions); 
} 

@Override 
protected void onBeforeClusterRendered(final Cluster<MediaItem> cluster, final MarkerOptions markerOptions) { 
    final MediaItem mediaItem = MediaPicker.getBestRated(new ArrayList<>(cluster.getItems())); 
    onBeforeClusterOrClusterItemRendered(cluster, mediaItem, markerOptions); 
} 

...

// Re render 
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { 
    @Override 
    public void onCameraChange(CameraPosition cameraPosition) { 
     mClusterManager.onCameraChange(cameraPosition); 
     final LatLngBounds latLngBounds = mMap.getProjection().getVisibleRegion().latLngBounds; 

     // Cluster only 
     Collection<Marker> clusters = mClusterManager.getClusterMarkerCollection().getMarkers(); 
     for(Marker marker : clusters) { 
      if(isInBounds(marker.getPosition(), latLngBounds)) 
       onBeforeClusterRendered(getCluster(marker), new MarkerOptions()); 
     } 

     // Cluster item only 
     Collection<Marker> markers = mClusterManager.getMarkerCollection().getMarkers(); 
     for(Marker marker : markers) { 
      if(isInBounds(marker.getPosition(), latLngBounds)) 
       onBeforeClusterItemRendered(getClusterItem(marker), new MarkerOptions()); 
     } 
    } 
}); 
+0

isAdded()方法丟失 – luky

+0

如果需要,您可以跳過這一行。這是片段的一種方法。 –

+0

我在幾次測試後更改了我的代碼,以便在地圖上僅添加可見項目。這使它更平滑。 –

3

我有類似的問題。我跟蹤用戶的初始位置並在他周圍顯示地圖標記。如果用戶選擇在初始縮放之外尋找,我下載其他標記。執行:

map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { 

      @Override 
      public void onCameraChange(CameraPosition cameraPosition) { 
       setCurrentRadius(); 
       viewCenter = cameraPosition.target; 
       if (isNewGrounds(viewCenter, viewRadius)) { 
        downloadExtraPrinters(viewCenter,viewRadius); 
       } 
       myClusterManager.onCameraChange(cameraPosition); 
      } 
     }); 

    private void setCurrentRadius() { 
     Projection projection = map.getProjection(); 
     VisibleRegion currentView = projection.getVisibleRegion(); 
     LatLng cameraCenter = map.getCameraPosition().target; 
     float[] projectionRadius = new float[1]; 
     Location.distanceBetween(currentView.farLeft.latitude, currentView.farLeft.longitude, cameraCenter.latitude, cameraCenter.longitude, projectionRadius); 
     viewRadius = Math.round((projectionRadius[0]/1000.0f) + 0.5f); 
    } 

/** Method checks if camera goes outside bounds of previously downloaded area **/ 
    protected boolean isNewGrounds(LatLng center, int radius) { 
     //Check if it is the first time to update 
     if (coveredGroundsCenter== null) { 

      coveredGroundsCenter=center; 
      coveredGroundsRadius= (int)(radius * EXTRA_RADIUS); 

      return true; 
     }else { 
      float[] centerDistance = new float[1]; 
      Location.distanceBetween(coveredGroundsCenter.latitude, coveredGroundsCenter.longitude, center.latitude, center.longitude, centerDistance); 

      int criticalDistance = (int) Math.round((centerDistance[0]/1000.0f) + 0.5f) + radius; 

      if (coveredGroundsRadius >= criticalDistance) { 
       return false; 
      } else { 
       coveredGroundsCenter = center; 
       coveredGroundsRadius = (int) (radius * EXTRA_RADIUS); 
       return true; 
      } 
     } 
    } 

EXTRA_RADIUS是一個常數,我使用有肉眼可見的地圖區域外的小幅度,所以最小的攝像機運動難道不引起我的地圖下載和重新渲染。我選擇此邊距爲當前半徑的50%:

private static final double EXTRA_RADIUS=1.5; 
private LatLng coveredGroundsCenter; 
private int coveredGroundsRadius; 
private LatLng viewCenter; 
+0

謝謝。我認爲我可以使用你的部分代碼。 –

+0

您的回答很有用,但在cameraUpdateListener中,我無法強制重新渲染不可見區域中的項目。 如果我打電話給clusterManager.clear和clusterManager.add ...它工作(強制重新渲染所有項目),但這不乾淨,所有項目都在閃爍... –

+0

嗯。多數民衆贊成我是如何實施它。我清除然後添加它們。我也使用自定義標記(屏幕上顯示〜400)和你一樣。不閃爍,不閃爍。 idk,也許標記圖片質量設置得太高? 如果你發現一些優化,請讓我知道,也許我可以改善我的代碼:) –