J'ai 10 marqueurs dans le GoogleMap
. Je veux faire un zoom avant et garder tous les marqueurs en vue? Dans la version précédente, ceci pouvait être obtenu à partir de zoomToSpan()
, mais je ne sais absolument pas comment faire cela. De plus, je connais le rayon du cercle qui doit être visible.
Vous devez utiliser la classe CameraUpdate
pour effectuer (probablement) tous les mouvements de carte programmatiques.
Pour ce faire, calculez d’abord les bornes de tous les marqueurs comme ceci:
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
Obtenez ensuite un objet de description de mouvement en utilisant la fabrique: CameraUpdateFactory
:
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
Enfin déplacez la carte:
googleMap.moveCamera(cu);
Ou si vous voulez une animation:
googleMap.animateCamera(cu);
C'est tout :)
Clarification 1
Presque toutes les méthodes de déplacement nécessitent que l'objet Map
ait réussi le processus de présentation. Vous pouvez attendre que cela se produise en utilisant la construction addOnGlobalLayoutListener
. Les détails peuvent être trouvés dans les commentaires à cette réponse et les réponses restantes. Vous pouvez également trouver un code complet pour définir l'étendue de la carte à l'aide de addOnGlobalLayoutListener
ici .
Clarification 2
Un commentaire note que l'utilisation de cette méthode pour un seul marqueur entraîne un zoom de la carte défini sur un niveau de zoom "bizarre" (qui, à mon avis, correspond au niveau de zoom maximal disponible pour un emplacement donné). Je pense que cela est prévu parce que:
LatLngBounds bounds
aura la propriété northeast
égale à southwest
, ce qui signifie que la partie de la surface de la terre couverte par cette bounds
vaut exactement zéro. (Ceci est logique puisqu'un seul marqueur n'a pas de surface.)bounds
à CameraUpdateFactory.newLatLngBounds
, vous demandez essentiellement un calcul d'un niveau de zoom tel que bounds
(ayant une surface nulle) couvre toute la vue de la carte.Map
ne prend pas cette valeur en charge, il est donc limité à un niveau maximal plus raisonnable autorisé pour un emplacement donné.Une autre façon de le dire: comment l'objet Map
peut-il savoir quel niveau de zoom doit-il choisir pour un emplacement unique ? Peut-être que la valeur optimale devrait être 20 (si cela représente une adresse spécifique). Ou peut-être 11 (si cela représente une ville). Ou peut-être 6 (si cela représente un pays). L'API n'est pas si intelligent et la décision vous appartient.
Donc, vous devriez simplement vérifier si markers
n'a qu'un seul emplacement et si oui, utilisez l'un des:
CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition())
- aller à la position du marqueur, laisser le niveau de zoom actuel intact.CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F)
- allez à la position du marqueur, réglez le niveau de zoom sur une valeur choisie arbitrairement 12.La solution suivante fonctionne pour Android Marshmallow 6 (API 23, API 24, API 25, API 26, API 27, API 28). Cela fonctionne aussi à Xamarin.
LatLngBounds.Builder builder = new LatLngBounds.Builder();
//the include method will calculate the min and max bound.
builder.include(marker1.getPosition());
builder.include(marker2.getPosition());
builder.include(marker3.getPosition());
builder.include(marker4.getPosition());
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.10); // offset from edges of the map 10% of screen
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
mMap.animateCamera(cu);
Je ne pouvais pas utiliser onGlobalLayoutlistener, voici donc une autre solution pour éviter l'erreur "Map size can't be 0. Most likely, layout has not yet occured for the map view. Either wait until layout has occurred or use newLatLngBounds(LatLngBounds, int, int, int) which allows you to specify the map's dimensions."
:
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 15));
}
});
Alors
J'avais besoin d'utiliser addOnGlobalLayoutListener pour obtenir l'échantillon approprié
par exemple, votre carte Google se trouve dans RelativeLayout:
RelativeLayout mapLayout = (RelativeLayout)findViewById(R.id.map_layout);
mapLayout.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//and write code, which you can see in answer above
}
});
Travailler bien pour moi.
À partir de ce code, j'affiche plusieurs marqueurs avec un zoom particulier sur l'écran de la carte.
// Variables déclarées
private LatLngBounds bounds;
private LatLngBounds.Builder builder;
// Méthode pour ajouter plusieurs points de repère avec une icône pouvant être dessinée
private void drawMarker(LatLng point, String text) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(point).title(text).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon));
mMap.addMarker(markerOptions);
builder.include(markerOptions.getPosition());
}
// Pour ajouter plusieurs marqueurs visibles sur la carte
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
builder = new LatLngBounds.Builder();
for (int i = 0; i < locationList.size(); i++) {
drawMarker(new LatLng(Double.parseDouble(locationList.get(i).getLatitude()), Double.parseDouble(locationList.get(i).getLongitude())), locationList.get(i).getNo());
}
bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 0);
mMap.animateCamera(cu);
Remarque - Ce n'est pas une solution à la question d'origine. C'est une solution à l'un des sous-problèmes discutés ci-dessus .
Solution à @andr Clarification 2 -
C'est vraiment problématique quand il n'y a qu'un seul marqueur dans les limites et à cause de cela, le niveau de zoom est réglé sur un niveau très élevé ( niveau 21 ). Et Google ne fournit aucun moyen de définir le niveau de zoom maximal à ce stade. Cela peut aussi arriver quand il y a plus d'un marqueur mais qu'ils sont tous assez proches les uns des autres. Ensuite, le même problème se produira.
Solution - Supposons que votre carte ne dépasse jamais le niveau de zoom de 16. Puis après avoir fait -
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
mMap.moveCamera(cu);
Vérifiez si votre niveau de zoom a franchi le niveau 16 (ou celui que vous souhaitiez) -
float currentZoom = mMap.getCameraPosition().zoom;
Et si ce niveau est supérieur à 16, ce qui ne le sera que s'il y a très peu de marqueurs ou si tous les marqueurs sont très proches les uns des autres, il vous suffit alors de faire un zoom arrière sur votre carte à cette position en définissant le niveau de zoom sur 16.
mMap.moveCamera(CameraUpdateFactory.zoomTo(16));
De cette façon, vous n'aurez jamais le problème de niveau de zoom "bizarre" expliqué très bien par @andr aussi.
cela aiderait .. de google apis demos
private List<Marker> markerList = new ArrayList<>();
Marker marker = mGoogleMap.addMarker(new MarkerOptions().position(geoLatLng)
.title(title));
markerList.add(marker);
// Pan to see all markers in view.
// Cannot zoom to bounds until the map has a size.
final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
if (mapView!=null) {
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@SuppressWarnings("deprecation") // We use the new method when supported
@SuppressLint("NewApi") // We check which build version we are using.
@Override
public void onGlobalLayout() {
//Calculate the markers to get their position
LatLngBounds.Builder b = new LatLngBounds.Builder();
for (Marker m : markerList) {
b.include(m.getPosition());
}
// also include current location to include in the view
b.include(new LatLng(mLocation.getLatitude(),mLocation.getLongitude()));
LatLngBounds bounds = b.build();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mapView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
}
});
}
}
pour des informations claires, regardez cette URL. https://github.com/googlemaps/Android-samples/blob/master/ApiDemos/app/src/main/Java/com/example/mapdemo/MarkerDemoActivity.Java
J'ai eu un problème similaire, en utilisant le code suivant a résolu le problème:
CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5)
généralement les différences d'emplacement dans mon cas ne sont pas plus de deux villes voisines.
zoom pour adapter tous les marqueurs sur la carte google maps v2
Afficher tous les marqueurs avec Google map
Dans ces méthodes, stockez tous les marqueurs et effectuez automatiquement un zoom pour afficher tous les marqueurs dans google map.
// Declare the Markers List.
List<MarkerOptions> markerList;
private BitmapDescriptor vnrPoint,banPoint;
public void storeAllMarkers()
{
markerList=new ArrayList<>();
markerList.removeAll(markerList);
// latitude and longitude of Virudhunagar
double latitude1=9.587209;
double longitude1=77.951431;
vnrPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_1);
LatLng vnr = new LatLng(latitude1, longitude1);
MarkerOptions vnrMarker = new MarkerOptions();
vnrMarker.position(vnr);
vnrMarker.icon(vnrPoint);
markerList.add(vnrMarker);
// latitude and longitude of Bengaluru
double latitude2=12.972442;
double longitude2=77.580643;
banPoint=BitmapDescriptorFactory.fromResource(R.drawable.location_icon_2);
LatLng ban = new LatLng(latitude2, longitude2);
MarkerOptions bengalureMarker = new MarkerOptions();
bengalureMarker.position(ban);
bengalureMarker.icon(banPoint);
markerList.add(bengalureMarker);
// You can add any numbers of MarkerOptions like this.
showAllMarkers();
}
public void showAllMarkers()
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (MarkerOptions m : markerList) {
builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
int padding = (int) (width * 0.30);
// Zoom and animate the google map to show all markers
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding);
googleMap.animateCamera(cu);
}
Utilisez la méthode "getCenterCoordinate" pour obtenir la coordonnée centrale et l'utiliser dans CameraPosition.
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setScrollGesturesEnabled(true);
mMap.getUiSettings().setTiltGesturesEnabled(true);
mMap.getUiSettings().setRotateGesturesEnabled(true);
clientMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_taxi))
);
clientMarker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_location))
);
camPos = new CameraPosition.Builder()
.target(getCenterCoordinate())
.zoom(17)
.build();
camUpd3 = CameraUpdateFactory.newCameraPosition(camPos);
mMap.animateCamera(camUpd3);
}
public LatLng getCenterCoordinate(){
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(new LatLng(Double.valueOf(-12.1024174), Double.valueOf(-77.0262274)));
builder.include(new LatLng(Double.valueOf(-12.1024637), Double.valueOf(-77.0242617)));
LatLngBounds bounds = builder.build();
return bounds.getCenter();
}
J'ai une autre façon de faire cette même chose fonctionne parfaitement. L’idée derrière tous les marqueurs à l’écran est donc d’avoir besoin d’un centre de hauteur et d’un niveau de zoom. voici la fonction qui vous donnera les deux et qui nécessite l’entrée de tous les objets Latlng du marqueur.
public Pair<LatLng, Integer> getCenterWithZoomLevel(LatLng... l) {
float max = 0;
if (l == null || l.length == 0) {
return null;
}
LatLngBounds.Builder b = new LatLngBounds.Builder();
for (int count = 0; count < l.length; count++) {
if (l[count] == null) {
continue;
}
b.include(l[count]);
}
LatLng center = b.build().getCenter();
float distance = 0;
for (int count = 0; count < l.length; count++) {
if (l[count] == null) {
continue;
}
distance = distance(center, l[count]);
if (distance > max) {
max = distance;
}
}
double scale = max / 1000;
int zoom = ((int) (16 - Math.log(scale) / Math.log(2)));
return new Pair<LatLng, Integer>(center, zoom);
}
Cette fonction retourne l’objet Pair que vous pouvez utiliser comme
Pair pair = getCenterWithZoomLevel (l1, l2, l3 ..); mGoogleMap.moveCamera (CameraUpdateFactory.newLatLngZoom (pair.first, pair.second));
vous pouvez au lieu d’utiliser un rembourrage pour éloigner vos marqueurs des limites de l’écran, vous pouvez ajuster le zoom de -1.