web-dev-qa-db-fra.com

Définition du niveau de zoom maximal dans Google Maps Android Api v2

Je travaille actuellement sur le développement d'applications à l'aide de Google Maps sur l'API Android v2 de la carte.

LatLngBuilder.Builder builder = LatLngBounds.builder();
for(Marker m : markers){
    builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10);

Ce code fonctionne bien, mais je souhaite arrêter l'animation lorsque le niveau de zoom atteint 17.0f; Il semble que l'API cartographique ne dispose pas d'une telle méthode pour contrôler le niveau de zoom.

35
user2223820

Je n'ai pas trouvé de solution directe dans l'API Google Maps. Une solution potentielle à ce problème consiste à écouter l'événement OnCameraChange : chaque fois que cet événement se déclenche et que le niveau de zoom est supérieur au niveau de zoom maximal, il est possible d'appeler animateCamera () . Le code résultant serait le suivant:

@Override
public void onCameraChange(CameraPosition position) {
    float maxZoom = 17.0f;
    if (position.zoom > maxZoom)
        map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
25
Tisys

Une récente mise à jour de l'API Google Maps introduit les fonctions dont vous avez besoin:

GoogleMap.setMaxZoomPreference()

GoogleMap.setMinZoomPreference()

Cela n'empêche pas pour autant que l'animation soit lue.

24
Dmitry Serov

Voici le code Java correspondant à la solution Arvis qui a bien fonctionné pour moi:

private LatLngBounds adjustBoundsForMaxZoomLevel(LatLngBounds bounds) {
  LatLng sw = bounds.southwest;
  LatLng ne = bounds.northeast;
  double deltaLat = Math.abs(sw.latitude - ne.latitude);
  double deltaLon = Math.abs(sw.longitude - ne.longitude);

  final double zoomN = 0.005; // minimum zoom coefficient
  if (deltaLat < zoomN) {
     sw = new LatLng(sw.latitude - (zoomN - deltaLat / 2), sw.longitude);
     ne = new LatLng(ne.latitude + (zoomN - deltaLat / 2), ne.longitude);
     bounds = new LatLngBounds(sw, ne);
  }
  else if (deltaLon < zoomN) {
     sw = new LatLng(sw.latitude, sw.longitude - (zoomN - deltaLon / 2));
     ne = new LatLng(ne.latitude, ne.longitude + (zoomN - deltaLon / 2));
     bounds = new LatLngBounds(sw, ne);
  }

  return bounds;
}
12
kasimir

Document Android: https://developers.google.com/maps/documentation/Android-api/views

You may find it useful to set a prefered minimum and/or maximum zoom level. For example, this is useful to control the user's experience if your app shows a defined area around a point of interest, or if you're using a custom tile overlay with a limited set of zoom levels.

    private GoogleMap mMap;
    // Set a preference for minimum and maximum zoom.
    mMap.setMinZoomPreference(6.0f);
    mMap.setMaxZoomPreference(14.0f);
11
ChrisUser2627250

Identique à la solution Arvis mais en utilisant Location [[distanceBetween()] ( http://developer.Android.com/reference/Android/location/Location.html#distanceBetween(double , double, double, double , float [])) méthode pour calculer la distance entre des points: 

@Override
public void zoomToMarkers(Set<Marker> markers) {

    LatLngBounds.Builder builder = new LatLngBounds.Builder();
    for (Marker marker : markers) {
        builder.include(marker.getPosition());
    }
    LatLngBounds bounds = builder.build();

    // Calculate distance between northeast and southwest
    float[] results = new float[1];
    Android.location.Location.distanceBetween(bounds.northeast.latitude, bounds.northeast.longitude,
            bounds.southwest.latitude, bounds.southwest.longitude, results);

    CameraUpdate cu = null;
    if (results[0] < 1000) { // distance is less than 1 km -> set to zoom level 15
        cu = CameraUpdateFactory.newLatLngZoom(bounds.getCenter(), 15);
    } else {
        int padding = 50; // offset from edges of the map in pixels
        cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
    }
    if (cu != null) {
        mMap.moveCamera(cu);
    }
}
6
Jens

Avant d’animer la caméra, vous pouvez vérifier si les points de limite SW et NE ne sont pas trop proches et, si nécessaire, ajuster les limites:

        ...
        LatLngBounds bounds = builder.Build();

        var sw = bounds.Southwest;
        var ne = bounds.Northeast;
        var deltaLat = Math.Abs(sw.Latitude - ne.Latitude);
        var deltaLon = Math.Abs(sw.Longitude - ne.Longitude);

        const double zoomN = 0.005; // set whatever zoom coefficient you need!!!
        if (deltaLat < zoomN) {
            sw.Latitude = sw.Latitude - (zoomN - deltaLat / 2);
            ne.Latitude = ne.Latitude + (zoomN - deltaLat / 2);
            bounds = new LatLngBounds(sw, ne);
        }
        else if (deltaLon < zoomN) {
            sw.Longitude = sw.Longitude - (zoomN - deltaLon / 2);
            ne.Longitude = ne.Longitude + (zoomN - deltaLon / 2);
            bounds = new LatLngBounds(sw, ne);
        }

        map.animateCamera(CameraUpdateFactory.NewLatLngBounds(bounds, 10);

ps. Mon exemple est en c # pour Xamarin mais vous pouvez facilement l’ajuster pour Java

3
Arvis

Ceci est issu de la référence API pour la include(position) que vous utilisez:

"Inclut ce point pour la construction des limites. Les limites seront étendues au minimum pour inclure ce point . Plus précisément, il sera envisagé d'étendre les limites à la fois dans les directions est et ouest (l'une d'entre elles pouvant le monde) et choisissez le plus petit des deux. Dans le cas où les deux directions donnent des LatLngBounds de même taille, cela le prolongera dans la direction est. "

La carte effectuera un zoom arrière jusqu'à afficher tous les marqueurs que vous ajoutez dans votre boucle for.

Si vous souhaitez uniquement effectuer un zoom arrière jusqu'à 17 et afficher les marqueurs, animez d'abord le niveau 17, puis définissez les limites, puis ajoutez vos marqueurs.

@Override
public void onCameraChange(CameraPosition camPos) {

    if (camPos.zoom < 17 && mCurrentLoc != null) {
        // set zoom 17 and disable zoom gestures so map can't be zoomed out
        // all the way
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,17));
        mMap.getUiSettings().setZoomGesturesEnabled(false);
    }
    if (camPos.zoom >= 17) {
        mMap.getUiSettings().setZoomGesturesEnabled(true);
    }

    LatLngBounds visibleBounds =  mMap.getProjection().getVisibleRegion().latLngBounds;

//add the markers
2
Vishal Disawar

L'approche de @ kasimir définit un nombre minimum de degrés en latitude ou en longitude et est un peu difficile à lire. Je l'ai donc modifié pour définir un minimum de latitude, ce qui me semblait un peu plus lisible:

private LatLngBounds adjustBoundsForMinimumLatitudeDegrees(LatLngBounds bounds, double minLatitudeDegrees) {
    LatLng sw = bounds.southwest;
    LatLng ne = bounds.northeast;
    double visibleLatitudeDegrees = Math.abs(sw.latitude - ne.latitude);

    if (visibleLatitudeDegrees < minLatitudeDegrees) {
        LatLng center = bounds.getCenter();
        sw = new LatLng(center.latitude - (minLatitudeDegrees / 2), sw.longitude);
        ne = new LatLng(center.latitude + (minLatitudeDegrees / 2), ne.longitude);
        bounds = new LatLngBounds(sw, ne);
    }

    return bounds;
}
1

Avec com.google.Android.gms:play-services-maps:9.4.0, vous pouvez facilement définir le zoom min/max. Avec GoogleMap.setMinZoomPreference() et GoogleMap.setMaxZoomPreference(), vous pouvez définir un niveau de zoom minimum et/ou maximum préféré. Plus voir ici .

0
wwang

Nous ne pouvons pas restreindre directement la fonctionnalité de zoom sur la carte, mais nous pouvons essayer d'obtenir la même fonctionnalité de ce type.

add map.setOnCameraChangeListener

final float maxZoom = 10.0f;

@Override
public void onCameraChange(CameraPosition position) {

    if (position.zoom > maxZoom)
        map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
0
Ravi
map.setMinZoomPreference(floatValue);
0
Karim Elshaweish

Sur la nouvelle version de Google Maps 9.8

com.google.Android.gms:play-services-maps:9.8.0

Voici comment j'ai fait et travaillé 

    googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
        @Override
        public void onCameraMove() {
            Log.d(App.TAG, "onCameraMove");

            CameraPosition position = googleMap.getCameraPosition();

            float maxZoom = 9.0f;
            if (position.zoom > maxZoom) {

                googleMap.setMinZoomPreference(maxZoom);
            }

            Log.d(App.TAG, "position.zoom = " + position.zoom);

        }
    });
0
user2373653

Ce que j’ai fini par créer c’est créer mes propres boutons et désactiver les boutons par défaut pour avoir un contrôle total.

Quelque chose comme ça dans la mise en page pour placer les boutons:

<LinearLayout
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content"
    Android:orientation="vertical"
    Android:layout_gravity="bottom"
    Android:layout_alignParentRight="true"
    Android:layout_alignParentBottom="true">

    <Button
        Android:id="@+id/bzoomin"
        Android:layout_width="55dp"
        Android:layout_height="55dp"
        Android:gravity="center"
        Android:textSize="28sp"
        Android:text="+" />
    <Button
            Android:id="@+id/bzoomout"
            Android:layout_width="55dp"
            Android:layout_height="55dp"
            Android:gravity="center"
            Android:textSize="23sp"
            Android:text="—" />
</LinearLayout>

Ensuite, ceci dans le code pour désactiver les boutons par défaut et configurer nos nouveaux:

map.getUiSettings().setZoomControlsEnabled(false);

// setup zoom control buttons
Button zoomout = (Button) findViewById(R.id.bzoomout);
zoomout.setOnClickListener(new OnClickListener(){

    @Override
    public void onClick(View v) {
        if(map.getCameraPosition().zoom >= 8.0f){
            // Zoom like normal
            map.animateCamera(CameraUpdateFactory.zoomOut());
        }else{
            // Do whatever you want if user went too far
            Messages.toast_short(MapsActivity.this, "Maximum zoom out level reached");
        }
    }

});

Button zoomin = (Button) findViewById(R.id.bzoomin);
zoomin.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        if (map.getCameraPosition().zoom <= 14.0f) {
            // Zoom like normal
            map.animateCamera(CameraUpdateFactory.zoomIn());
        } else {
            // Do whatever you want if user went too far
            Messages.toast_short(MapsActivity.this, "Maximum zoom in level reached");
        }
    }
});
0
William W

Je ne sais pas si cela fonctionnera, mais pouvez-vous essayer ceci 

map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);

J'espère que ça aide

0
Benil Mathew