Carte Android v2 zoom pour afficher tous les marqueurs

J’ai 10 marqueurs dans GoogleMap . Je veux agrandir autant que possible et garder tous les marqueurs en vue? Dans la version précédente, cela peut être réalisé à partir de zoomToSpan() mais dans v2, je ne sais pas du tout comment faire. 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 programmés.

Pour ce faire, calculez d’abord les limites de tous les marqueurs comme suit:

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

Ensuite, obtenez un object de description du 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’object Map ait réussi le processus de mise en page. Vous pouvez attendre que cela se produise en utilisant la construction addOnGlobalLayoutListener . Des détails peuvent être trouvés dans les commentaires de cette réponse et les réponses restantes. Vous pouvez également trouver un code complet pour définir l’étendue de la carte en utilisant addOnGlobalLayoutListener ici .

Clarification 2

Un commentaire fait remarquer que l’utilisation de cette méthode pour un seul marqueur entraîne un zoom sur la carte à un niveau de zoom «bizarre» (qui, selon moi, correspond au niveau de zoom maximal disponible pour un emplacement donné). Je pense que cela est attendu car:

  1. L’ LatLngBounds bounds aura une propriété northeastnortheast égale à southwestsouthwest , ce qui signifie que la partie de la surface de la terre couverte par cette bounds est exactement égale à zéro. (Ceci est logique car un seul marqueur n’a pas d’aire.)
  2. En transmettant des bounds à CameraUpdateFactory.newLatLngBounds vous demandez essentiellement un calcul d’un tel niveau de zoom pour que les bounds (ayant une zone nulle) couvrent toute la vue de la carte.
  3. Vous pouvez effectivement effectuer ce calcul sur une feuille de papier. Le niveau de zoom théorique qui est la réponse est + ∞ (infini positif). En pratique, l’object Map ne prend pas en charge cette valeur, il est donc limité à un niveau maximum plus raisonnable autorisé pour un emplacement donné.

Une autre façon de le dire: comment l’object Map peut-il savoir quel niveau de zoom choisir pour un seul emplacement ? Peut-être que la valeur optimale devrait être 20 (si elle 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 intelligente et la décision vous appartient.

Donc, vous devriez simplement vérifier si les markers n’ont qu’un seul emplacement et si oui, utilisez l’un des:

  • CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition()) – va à la position du marqueur, laisse le niveau de zoom actuel intact.
  • CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F) – permet d’accéder à la position du marqueur, de définir le niveau de zoom sur une valeur choisie arbitrairement 12.

Google Map V2: Zoom MarkerOptions dans les limites Meilleure solution de travail pour Android Marshmallow 6 (API 23, API 24, API 25) également, Fonctionne également dans 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().getDisplayMesortingcs().widthPixels; int height = getResources().getDisplayMesortingcs().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); 

Alors

Je devais utiliser addOnGlobalLayoutListener pour obtenir l’échantillon approprié

Par exemple, votre Google Map 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 } }); 

Je ne pouvais pas utiliser le onGlobalLayoutlistener, alors voici une autre solution pour empêcher la "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." Erreur:

 mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() { @Override public void onMapLoaded() { mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 15)); } }); 

Travaille 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 d’ajout de plusieurs points de repère avec une icône pouvant être dessinée

 private void drawMarker(LatLng point, Ssortingng text) { MarkerOptions markerOptions = new MarkerOptions(); markerOptions.position(point).title(text).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon)); mMap.addMarker(markerOptions); builder.include(markerOptions.getPosition()); } 

// Ajout de 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 – Ceci n’est pas une solution à la question d’origine. Ceci est une solution à l’un des sous-problèmes discutés ci – dessus .

Solution à @ et à la clarification 2

C’est vraiment problématique quand il n’y a qu’un seul marqueur dans les limites et que le niveau de zoom est 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 ils sont tous assez proches les uns des autres. Ensuite, le même problème se produira.

Solution – Supposons que vous souhaitiez que votre carte ne dépasse jamais 16 niveaux de zoom. Puis après avoir –

 CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding); mMap.moveCamera(cu); 

Vérifiez si votre niveau de zoom a franchi le niveau 16 (ou ce que vous voulez) –

 float currentZoom = mMap.getCameraPosition().zoom; 

Et si ce niveau est supérieur à 16, ce sera seulement s’il y a moins de marqueurs ou si tous les marqueurs sont très proches les uns des autres, alors il suffit de zoomer sur votre carte à cette position en réglant le niveau de zoom sur 16.

 mMap.moveCamera(CameraUpdateFactory.zoomTo(16)); 

De cette façon, le problème du niveau de zoom “bizarre” ne sera jamais très bien expliqué par @andr.

cela aiderait .. à partir de démos google apis

 private List 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 plus d'informations, 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 résolu le problème:

CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5) général, les différences de localisation dans mon cas ne sont pas plus de deux villes voisines.

zoom pour adapter tous les marqueurs sur la carte google maps v2

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. Donc, l’idée de montrer tous les marqueurs à l’écran nécessite un long centrage latéral et un niveau de zoom. Voici la fonction qui vous donnera les deux et nécessite tous les objects Latlng du marqueur comme entrée.

  public Pair 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(center, zoom); } 

Cette fonction retourne l’object 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 le remplissage pour éloigner vos marqueurs des limites de l’écran, vous pouvez ajuster le zoom de -1.

  //For adding a marker in Google map MarkerOptions mp = new MarkerOptions(); mp.position(new LatLng(Double.parseDouble(latitude), Double.parseDouble(longitude))); mp.snippet(strAddress); map.addMarker(mp); try { b = new LatLngBounds.Builder(); if (MapDetailsList.list != null && MapDetailsList.list.size() > 0) { for (int i = 0; i < MapDetailsList.list.size(); i++) { b.include(new LatLng(Double.parseDouble(MapDetailsList.list.get(i).getLatitude()), Double.parseDouble(MapDetailsList.list.get(i).getLongitude()))); } LatLngBounds bounds = b.build(); DisplayMetrics displayMetrics = getResources().getDisplayMetrics(); int width = displayMetrics.widthPixels; int height = displayMetrics.heightPixels; // Change the padding as per needed CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width-200, height-200, 5); // map.setCenter(bounds.getCenter()); map.animateCamera(cu); } } catch (Exception e) { } 

http://soffr.miximages.com/android/2qjybh4.png

http://soffr.miximages.com/android/flzwus.png

http://soffr.miximages.com/android/112g5fm.png