2016-07-30 53 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,也许标记图片质量设置得太高? 如果你发现一些优化,请让我知道,也许我可以改善我的代码:) –