2016-07-30 19 views
2

У меня есть фрагмент карты, который обрабатывается диспетчером кластеров Google, который я сконфигурировал с помощью моего собственного рендеринга кластера extends DefaultClusterRenderer.Лучший способ визуализации только видимых элементов кластера на карте google

Я overritten функции onBeforeClusterItemRendered и onBeforeClusterRendered, чтобы иметь возможность 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 является константой я использую, чтобы иметь небольшой запас за пределами видимой области карты, так что малейшее движение камеры Wouldnt вызвать мою карту, чтобы загрузить и повторно вынести. Я выбрал эту маржу на 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

Hm. вот как я его реализовал. Я очищаю и добавляю их. Im также использует пользовательские маркеры (~ 400 на экране) так же, как и вы. Не мигает, не мигает. idk, возможно, качество изображения маркеров слишком велико? Если вы обнаружите оптимизацию, сообщите мне, возможно, я тоже смог бы улучшить свой код :) –

 Смежные вопросы

  • Нет связанных вопросов^_^