Reputation: 593
I'm currently working on developing apps by using Google maps android API v2. My code is as follows. Suppose map has several markers and zoom up to show all markers in display.
LatLngBuilder.Builder builder = LatLngBounds.builder();
for(Marker m : markers){
builder.include(m.getPosition());
}
LatLngBounds bounds = builder.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10);
This code is working fine but I want to stop animating when the zoom level reached to 17.0f; It seems map API does not have such method to control zoom level. Does anybody know any idea to solve this problem?
Upvotes: 42
Views: 51565
Reputation: 582
Zoom Levels are the followings:
1f: World 5f: Landmass/continent 10f: City 15f: Streets 20f: Buildings
val setMin = 10f
val setMax = 20f
googleMap.setMaxZoomPreference(setMax)
googleMap.setMinZoomPreference(setMin)
Upvotes: 1
Reputation: 329
From Android doc: 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);
Upvotes: 19
Reputation: 3
On the new Google Maps 9.8
com.google.android.gms:play-services-maps:9.8.0
This is how I did and worked
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);
}
});
Upvotes: 0
Reputation: 1023
We can not restrict map zoomin feature directly, but we can try to get same feature like this.
add map.setOnCameraChangeListener
final float maxZoom = 10.0f;
@Override
public void onCameraChange(CameraPosition position) {
if (position.zoom > maxZoom)
map.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
Upvotes: 0
Reputation: 871
A recent update to the Google Maps API introduces the functions you require:
GoogleMap.setMaxZoomPreference()
GoogleMap.setMinZoomPreference()
It still does not prevent the animation from playing, though.
Upvotes: 31
Reputation: 615
With com.google.android.gms:play-services-maps:9.4.0
you can easily set min/max zoom. With GoogleMap.setMinZoomPreference()
and GoogleMap.setMaxZoomPreference()
you can set a prefered minimum and/or maximum zoom level. More see here.
Upvotes: 0
Reputation: 6383
Same as Arvis solution but using Location
's [distanceBetween()
](http://developer.android.com/reference/android/location/Location.html#distanceBetween(double, double, double, double, float[])) method to calculate distance between to 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);
}
}
Upvotes: 7
Reputation: 8363
Before animate Camera you can check if SW and NE points of bounds are not too close and if necessary adjust bounds:
...
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. My example is in c# for Xamarin but you can easly adjust it for java
Upvotes: 3
Reputation: 1806
What I ended up doing is creating my own buttons and disabling the default ones so I would have full control.
Something like this in the layout to place the buttons:
<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>
Then this in the code to disable the default buttons and setup our new ones:
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");
}
}
});
Upvotes: 0
Reputation: 17762
@kasimir's approach sets a minimum number of degrees in either the latitude or longitude, and felt a little hard to read. So I tweaked it to just set a minimum on the latitude, which I felt like was a bit more readable:
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;
}
Upvotes: 1
Reputation: 1219
Here is the corresponding Java code for Arvis' solution which worked well for me:
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;
}
Upvotes: 14
Reputation: 144
This is from the API reference for the include(position)
you're using:
"Includes this point for building of the bounds. The bounds will be extended in a minimum way to include this point. More precisely, it will consider extending the bounds both in the eastward and westward directions (one of which may wrap around the world) and choose the smaller of the two. In the case that both directions result in a LatLngBounds of the same size, this will extend it in the eastward direction."
The map will zoom out until it can show all of the markers you're adding in your for loop.
If you want to only zoom out to 17 and still show markers, animate to zoom level 17 first, then get the bounds for it, and then add your markers.
@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
Upvotes: 2
Reputation: 948
I have not found any direct solution in the Google Maps API. A potential solution to this problem consists in listening against the OnCameraChange event: Whenever this event triggers and the zoom level is above the maximum zoom level, it is possible to call animateCamera(). The resulting code would be the following:
@Override
public void onCameraChange(CameraPosition position) {
float maxZoom = 17.0f;
if (position.zoom > maxZoom)
map_.animateCamera(CameraUpdateFactory.zoomTo(maxZoom));
}
Upvotes: 25
Reputation: 1977
You can get the max zoom level by calling it getMaxZoomLevel()
and then set that value:
mGoogleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(fromPosition, getMaxZoomLevel()));
Upvotes: -2
Reputation: 1634
Im not sure if this will work but can you try this
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
Hope it helps
Upvotes: 2
Reputation: 10545
The map has a property called maxZoom. Simply set this to your value when you create your map
Upvotes: -4