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.
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));
}
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.
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;
}
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);
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);
}
}
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
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
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;
}
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 .
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));
}
map.setMinZoomPreference(floatValue);
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);
}
});
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");
}
}
});
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