仅在谷歌地图上渲染可见簇项目的最佳方法

Den*_*erg 7 android google-maps render markerclusterer

我有一个由谷歌集群管理器处理的地图片段,我使用自定义集群渲染器配置了该集群管理器extends DefaultClusterRenderer

我已经重写了功能onBeforeClusterItemRenderedonBeforeClusterRendered能够显示我的图片:

在此输入图像描述

现在,如果用户放大,渲染不在可见区域中的项目是没有意义的。很容易找出该项目是否在可见区域中:

private Boolean isInBounds(LatLng position) {
    return map.getProjection().getVisibleRegion().latLngBounds.contains(position);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我在该项目当前不可见的情况下跳过渲染,则当用户在地图上滚动时该项目将为空。

那么谁知道如何在用户滚动时获取事件以及如何重新渲染不在可见范围内的项目?(从可见切换到不可见,反之亦然)?

(对不起,我的英语不好)

Den*_*erg 6

这是我的解决方案。它工作得很好并且只渲染可见的项目。我使用相机更改监听器来重新渲染现在可见的项目:

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);
}
Run Code Online (Sandbox Code Playgroud)

...

// 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());
        }
    }
});
Run Code Online (Sandbox Code Playgroud)


Dov*_*das 5

我有类似的问题。我跟踪用户的初始位置并显示他周围的地图标记。如果用户选择查看初始缩放范围之外的内容,我会下载其他标记。执行:

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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

EXTRA_RADIUS 是一个常量,我用来在可见地图区域之外有一个小边距,因此最小的相机移动不会导致我的地图下载和重新渲染。我选择这个边距为当前半径的 50%:

 private static final double EXTRA_RADIUS=1.5;
 private LatLng coveredGroundsCenter;
 private int coveredGroundsRadius;
 private LatLng viewCenter;
Run Code Online (Sandbox Code Playgroud)