wake-up-neo.com

Android Karte v2 zoomen, um alle Markierungen anzuzeigen

Ich habe 10 Marker im GoogleMap. Ich möchte so weit wie möglich hineinzoomen und alle Markierungen im Blick behalten. In der früheren Version kann dies mit zoomToSpan() erreicht werden, aber in Version 2 habe ich keine Ahnung, wie man das macht. Außerdem kenne ich den Radius des Kreises, der sichtbar sein muss.

269

Sie sollten die Klasse CameraUpdate verwenden, um (wahrscheinlich) alle programmatischen Kartenbewegungen durchzuführen.

Berechnen Sie dazu zunächst die Grenzen aller Marker wie folgt:

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

Erhalten Sie dann ein Bewegungsbeschreibungsobjekt, indem Sie die Fabrik verwenden: CameraUpdateFactory:

int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);

Verschieben Sie zum Schluss die Karte:

googleMap.moveCamera(cu);

Oder wenn Sie eine Animation wünschen:

googleMap.animateCamera(cu);

Das ist alles :)

Erläuterung 1

Fast alle Bewegungsmethoden setzen voraus, dass das Objekt Map den Layoutprozess bestanden hat. Sie können warten, bis dies mit dem Konstrukt addOnGlobalLayoutListener geschieht. Details finden Sie in den Kommentaren zu dieser Antwort und den verbleibenden Antworten. Sie können auch einen vollständigen Code zum Festlegen der Kartenausdehnung mit addOnGlobalLayoutListener hier finden .

Klarstellung 2

In einem Kommentar wird darauf hingewiesen, dass die Verwendung dieser Methode für nur einen Marker dazu führt, dass der Zoom der Karte auf eine "bizarre" Zoomstufe eingestellt wird (die meiner Meinung nach die maximale für einen bestimmten Standort verfügbare Zoomstufe ist). Ich denke, das wird erwartet, weil:

  1. Die Instanz LatLngBounds bounds Hat die Eigenschaft northeast gleich southwest, was bedeutet, dass der von dieser bounds bedeckte Teil der Erdoberfläche genau Null ist. (Dies ist logisch, da ein einzelner Marker keinen Bereich hat.)
  2. Indem Sie bounds an CameraUpdateFactory.newLatLngBounds Übergeben, fordern Sie im Wesentlichen eine Berechnung einer solchen Zoomstufe an, dass bounds (mit einer Fläche von Null) die gesamte Kartenansicht abdeckt.
  3. Sie können diese Berechnung tatsächlich auf einem Blatt Papier durchführen. Die theoretische Zoomstufe, die die Antwort ist, ist + ∞ (positive Unendlichkeit). In der Praxis unterstützt das Map -Objekt diesen Wert nicht, daher wird es auf eine vernünftigere Maximalstufe beschränkt, die für einen bestimmten Standort zulässig ist.

Anders ausgedrückt: Wie kann Map object wissen, welche Zoomstufe es für eine einzelne Position wählen soll? Vielleicht sollte der optimale Wert 20 sein (wenn es sich um eine bestimmte Adresse handelt). Oder vielleicht 11 (wenn es eine Stadt darstellt). Oder vielleicht 6 (wenn es ein Land darstellt). API ist nicht so schlau und die Entscheidung liegt bei Ihnen.

Sie sollten also einfach prüfen, ob markers nur einen Ort hat, und in diesem Fall einen der folgenden verwenden:

  • CameraUpdate cu = CameraUpdateFactory.newLatLng(marker.getPosition()) - Gehe zur Markierungsposition, lasse die aktuelle Zoomstufe intakt.
  • CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(marker.getPosition(), 12F) - Gehe zur Markierungsposition und stelle die Zoomstufe auf den willkürlich gewählten Wert 12 ein.
766
andr

Google Map V2

Die folgende Lösung funktioniert für Android Marshmallow 6 (API 23, API 24, API 25, API 26, API 27, API 28). Sie funktioniert auch in 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);
110
Zumry Mohamed

Ich konnte den onGlobalLayoutlistener nicht verwenden, daher ist hier eine andere Lösung, um den Fehler "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." zu vermeiden:

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

Damit

Ich musste addOnGlobalLayoutListener verwenden, um das entsprechende Beispiel zu erhalten

ihre Google Map befindet sich beispielsweise in 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
        }
    });
13
Eugene Voronoy

Funktioniert gut für mich.

In diesem Code werden mehrere Markierungen mit einem bestimmten Zoom auf dem Kartenbildschirm angezeigt.

// Deklarierte Variablen

private LatLngBounds bounds;
private LatLngBounds.Builder builder;

// Methode zum Hinzufügen mehrerer Markierungspunkte mit einem darstellbaren Symbol

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());

    }

// Zum Hinzufügen mehrerer auf der Karte sichtbarer Markierungen

@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);
8
BK19

Hinweis - Dies ist keine Lösung für die ursprüngliche Frage. Dies ist eine Lösung für eines der diskutierten Unterprobleme oben .

Lösung zu @andr Erläuterung 2 -

Es ist sehr problematisch, wenn sich nur ein Marker in der Schranke befindet und die Zoomstufe daher auf einen sehr hohen Wert eingestellt ist ( Stufe 21 ). Und Google bietet keine Möglichkeit, die maximale Zoomstufe zu diesem Zeitpunkt festzulegen. Dies kann auch passieren, wenn mehr als ein Marker vorhanden ist, diese aber alle ziemlich nahe beieinander liegen. Dann tritt auch das gleiche Problem auf.

Lösung - Angenommen, Sie möchten, dass Ihre Karte die 16-fache Zoomstufe nicht überschreitet. Dann nach dem Tun -

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

Überprüfen Sie, ob Ihre Zoomstufe die Stufe 16 überschritten hat (oder was auch immer Sie wollen) -

float currentZoom = mMap.getCameraPosition().zoom;

Und wenn diese Stufe größer als 16 ist, was nur dann der Fall ist, wenn sehr wenige Markierungen vorhanden sind oder alle Markierungen sehr nahe beieinander liegen, zoomen Sie einfach Ihre Karte an dieser bestimmten Position heraus, indem Sie die Zoomstufe auf 16 einstellen.

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

Auf diese Weise haben Sie nie das Problem der "bizarren" Zoomstufe, das auch von @andr sehr gut erklärt wird.

3
Jyotman Singh

das würde helfen .. von 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));
                }
            });
        }
    }

für klare Informationen schauen Sie sich diese URL an. https://github.com/googlemaps/Android-samples/blob/master/ApiDemos/app/src/main/Java/com/example/mapdemo/MarkerDemoActivity.Java

2
Amit Tumkur

Ich hatte ein ähnliches Problem, mit folgendem Code wurde das Problem behoben:

CameraUpdateFactory.newLatLngBounds(bounds, 200, 200, 5) In der Regel sind die Standortunterschiede in meinem Fall nicht mehr als zwei Nachbarstädte.

Zoom auf alle Markierungen auf der Karte google maps v2

1

Alle Markierungen mit Google Map anzeigen

In diesen Methoden speichern Sie alle Markierungen und zoomen automatisch, um alle Markierungen in Google Map anzuzeigen.

// 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);
}
0

Verwenden Sie die Methode "getCenterCoordinate", um die Zentralkoordinate zu ermitteln und in CameraPosition zu verwenden.

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();
}

Ich habe einen anderen Weg, um das Gleiche zu tun, funktioniert perfekt. Um alle Markierungen auf dem Bildschirm anzeigen zu können, benötigen wir eine mittlere Länge und eine Zoomstufe. Hier ist die Funktion, die Ihnen beides gibt und alle Latlng-Objekte des Markers als Eingabe benötigt.

 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);
}

Diese Funktion gibt ein Pair-Objekt zurück, das Sie wie folgt verwenden können

Pair pair = getCenterWithZoomLevel (l1, l2, l3 ..); mGoogleMap.moveCamera (CameraUpdateFactory.newLatLngZoom (pair.first, pair.second));

sie können den Zoom um -1 anpassen, anstatt die Markierungen durch Auffüllen von Bildschirmgrenzen zu schützen.

0
Anuj Jindal