Google map zoom in between LatLng Bounds
Asked Answered
C

3

6

I have two markers on a map that should both show at the same time.

This is achieved through :

 final LatLngBounds.Builder builder = new LatLngBounds.Builder();
    for (Marker markerTemp : markers) {
        builder.include(markerTemp.getPosition());
    }

this works fine. However, when the markers are close to each other the map is very zoomed out. This is how it happens: 1- I choose two locations that are close to each other (zoom is good) 2- I choose two locations that are far from each other (zoom is good) 3- I choose two locations which are close to each other (zoom stays the same and the markers over lap).

I have checked so many links including:

(1) https://stackoverflow.com/questions/34247347/initialize-google-map-to-zoom-to-bounds (2) bounds google maps

(3) Setting max zoom level in google maps android api v2 (4) Android map v2 zoom to show all the markers

(5) Adjusting google map (api v2) zoom level in android (6) Set a max zoom level on LatLngBounds builder

(7) android Zoom-to-Fit All Markers on Google Map v2

Catfish answered 8/7, 2016 at 10:31 Comment(9)
why don't you check the distance between the locations and if they are close enough zoom in more?Blinding
I can't understand which is the difference between point 1 and 3... if points are too close (let's say a couple of meters) the bounding box is maybe to small to be shown. Pay attention if the two points are on the same line (same Lat or same Lng), it could lead to problems on creating the bounding box!Irksome
@Tony tried that in a certain approach. If you have an example I will be more than happy to try it.Catfish
@NDorigatti let us say I have a marker in USA and another in France the map zooms to show both. Then I change the markers to one in USA and the other in USA, the map stays at the initial zoom (doesn't zoom in). So the markers are appearing too close to each otherCatfish
Which code do you use to zoom to the second bound? Do you create a NEW builder when you have ONLY the two USA markers? Maybe you are adding ALSO the france marker at the second step!Irksome
If you can calculate the distance between the location's then I can give a solution based on that as an answerMidkiff
@Stallion I can calculate the distance between the two locationsCatfish
@NDorigatti final LatLngBounds.Builder builder = new LatLngBounds.Builder(); this is found inside a function that gets called every time the markers are updated. therefore, the builder are getting re-created everytimeCatfish
You cycle over ALL the markers.. do some debug on that cycle and check which markers are inside the list, probably you still have old markers in it (say France), that are added again and againIrksome
M
2

You can get distance between two location through the below function and find the zoom level based on that.

Method to find direct distance between two location

location1.distanceTo(location2);

Now to calculate the radius , use the following. dummy_radius will be half of above value

double circleRad = dummy_radius*1000;//multiply by 1000 to make units in KM

private int getZoomLevel(double radius){
            double scale = radius / 500;
            return ((int) (16 - Math.log(scale) / Math.log(2)));
}

float zoomLevel = getZoomLevel(circleRad);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLon, zoomLevel));
Midkiff answered 8/7, 2016 at 10:51 Comment(1)
I will give it a try nowCatfish
R
4

It sounds like you use a function to only zoom out when necessary, but not to zoom in as close as possible. Can you post the part that you use to animate the camera as well?

If you simply use

LatLngBounds bounds = builder.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 20));

it should work. And make sure to call it and do not wrap it in a check that looks if the bounds are already visible.

Rover answered 8/7, 2016 at 10:41 Comment(1)
I am doing exactly the same. it is still the same issue. ThnxCatfish
M
2

You can get distance between two location through the below function and find the zoom level based on that.

Method to find direct distance between two location

location1.distanceTo(location2);

Now to calculate the radius , use the following. dummy_radius will be half of above value

double circleRad = dummy_radius*1000;//multiply by 1000 to make units in KM

private int getZoomLevel(double radius){
            double scale = radius / 500;
            return ((int) (16 - Math.log(scale) / Math.log(2)));
}

float zoomLevel = getZoomLevel(circleRad);
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(LatLon, zoomLevel));
Midkiff answered 8/7, 2016 at 10:51 Comment(1)
I will give it a try nowCatfish
L
2

Complete solution of this problem without using map padding. This function will take all latlng object and will return back with a Pair<LatLng, Integer> where first will be the pair.first will be center and pair.second will be the zoom level.

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

you can use it like follwing

Pair<LatLng, Integer> pair = getCenterWithZoomLevel(l1,l2,l3..);
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(pair.first, pair.second));
Leukoderma answered 12/12, 2017 at 22:8 Comment(1)
distance = distance(center, l[count]); - distance() function is missing in the snippetKraul

© 2022 - 2024 — McMap. All rights reserved.