I have an app that uses a Google Map Fragment and i want to set somehow a limit to the zoom level that the user can get to by using the +/- icons provided in the map fragment.
Is there any known way to do this?
MY SOLUTION:
private final GoogleMap.OnCameraChangeListener mOnCameraChangeListener =
new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
Log.d("Zoom", "Zoon: " + cameraPosition.zoom);
if (cameraPosition.zoom > 16.01) {
getMap().animateCamera(CameraUpdateFactory.zoomTo(16));
}
}
};
in onViewCreated() :
//set the zoom limit
getMap().setOnCameraChangeListener(mOnCameraChangeListener);
So far this is showing me the zoom level each time the zoom level changes. i am not sure how i can limit the zoom here though... i can't just do cameraPosition.zoom=15 since it's a final variable.
Any suggestions highly appreciated.
You cannot limit zoom as of version 4.0.30 of the API.
There is a pending feature request for that here: https://code.google.com/p/gmaps-api-issues/issues/detail?id=4663
If you cannot wait, you can try to implement something like this: http://youtube.com/watch?v=-nCZ37HdheY
This uses OnCameraChangeListener and GoogleMap.animateCamera.
You can remove the zoom buttons and use your own, where you have more control. Then, you can disable buttons as needed based upon business rules.
Related
I am trying to change the zoom level when I click on my Location button but it is always getting default zoom value.
Guess what, the zoom doesn't work only in Animate part. If I use moveCamera it changes the zoom level to what I have specified.
Here is what I am trying:
googleMap.setOnMyLocationButtonClickListener(new OnMyLocationButtonClickListener()
{
#Override
public boolean onMyLocationButtonClick()
{
Log.e("Inside","Click part");
LatLng ll = new LatLng(curlat,curlong);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, 20);
googleMap.animateCamera(update);
return false;
}
});
Not sure what is wrong here in the animate part?
You should return true instead of false. Otherwise the map performs the default action in addition, which most probably (I did not check in detail) includes to move to the current position (same as your ll) but using the "current" zoom level. The current zoom level has not yet changed much, if you animate the camera. But it has changed completely if you move the camera directly without animation.
I need to zoom out my map. I have tried --mMapView.zoomout();-- but it only zoom out 1 level, I want to zoom out further. I know can do in .xml --mapoptions.ZoomLevel="5"-- but I wanted to put in my Activity Class. Some guides is needed, thank you very much.
MapOptions option = new MapOptions(MapOptions.MapType type);
// Sets zoom level.
option.setZoom(int zoom);
// Switches basemap by the given options.
mMapView.setMapOptions(MapOptions options);
I think, Best way to handle zoom with animation,Even, it will work nice if you add any other layer like "One Map".
/* set zoom level */
double LEVEL=5;
mMapView.centerAt(lat, lng, false);
mMapView.setScale(ZOOM_LEVEL, true);
if you want to show current location with proper Zooming use below code
mMapView.getLocationDisplayManager().setAutoPanMode(LocationDisplayManager.AutoPanMode.LOCATION);
mMapView.getLocationDisplayManager().start();
I am trying to set min zoom level to be 15 and user cannot zoom out of that level but he can zoom into 20 .
So throughout the app the user can use zoom enabled(true) but cannot go out of zoom level 15.Should I disable zoom afte 15 ? but that would even disable zoom in .
I dont know how to manage onl one condition in this case .How do I do it.I really appreciate any help.
Thanks in Advance
public OnCameraChangeListener getCameraChangeListener()
{
return new OnCameraChangeListener()
{
#Override
public void onCameraChange(CameraPosition position)
{
Log.d("Zoom", "Zoom: " + position.zoom);
if(previousZoomLevel != position.zoom)
{
isZooming = true;
if(zoomscale==15){
googleMap.getUiSettings().setZoomGesturesEnabled(false);
googleMap.getUiSettings().setZoomControlsEnabled(false);
}
}
previousZoomLevel = position.zoom;
}
};
}
As of current version (3.2.65) there is no API for setting min/max zoom level.
Hopefully there will be in the future, as this is already requested on gmaps-api-issues.
Anyway there is a way to handle it nicely in your own code: in onCameraChange if zoom is smaller than 15, call GoogleMap.animateCamera back to zoom 15. It will not stop the user from zooming out to see the whole world, but it will start zooming in after user finishes doing what they feel like doing. It will look similar to this: http://youtube.com/watch?v=-nCZ37HdheY (not only zoom, but also position is "corrected").
Try this
This won't allow the user to zoom out after the given zoom level.
mMap.setMinZoomPreference(float yourDesiredLevel);
We all know that some of the predefined landmarks on Google Maps does not appear on a lower zoom level, but on a higher zoom level, it suddenly appears. I would like to know If I can make a customized marker not appear at lower zoom levels, then appear at higher ones.
EDIT: Here is a snippet of my code.
// Changing marker icon
marker.icon(BitmapDescriptorFactory.fromResource(R.drawable.gasbig));
// adding marker
map.addMarker(marker);
//position on Center
CameraPosition cameraPosition = new CameraPosition.Builder().target(
new LatLng(14.635356, 121.03272914)).zoom(16).build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
map.setOnCameraChangeListener(new OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition arg0) {
if(arg0.zoom > 7){
marker.visible(true);
}
}
});
I tried the suggestion of MaciejGórski but the marker still appears on all zoom levels. I'm sorry about the question I'm still an android newbie.
Thanks in advance.
You can do that for any Marker you want: call setVisible in OnCameraChangeListener.onCameraChange callback with true or false depending on CameraPosition.zoom value.
Edit after question edit:
You need to keep a reference to Marker instead of MarkerOptions:
// adding marker
marker = map.addMarker(markerOptions);
and call setVisible on that marker:
#Override
public void onCameraChange(CameraPosition cameraPosition) {
marker.setVisible(cameraPosition.zoom > 7);
}
Note: setVisible is always called there, but this might not be optimal when using many Markers.
You could possibly do it by modifying my answer to: Android Maps v2 - animate camera to include most markers
Otherwise using Android Maps Extensions might be a good choice. No experince with your specific needs though.
Just realized I might have misunderstood the question. Thought you meant your own markers. Nevertheless have a look at the extensions library. Could very well be that they have something useful.
We're porting an app from the v1 Maps API to the v2 API, and having trouble with markers.
We need markers that point in a specific geographic direction. In V1, we could build the bitmap pointing in the right direction at draw time, but in V2 the marker bitmap can't be changed.
I'm not sure if the best approach is to destroy and re-build all our markers when the map is rotated (which sounds like a performance problem), or to try drawing them all ourselves. That could be via a TileOverlay or via a view of our own that we sat on top of the map.
I don't really like any of these approaches. Has anyone tried any of them ?
UPDATE:
I've tried drawing via a view of our own, but that was far too laggy when the map was dragged.
I'm now destroying & recreating the markers, but that is (as expected) a performance problem, taking ~2000mS to update 60 markers.
Good news everyone! Google has added rotation to the Maps API, so we don't have to roll our own implementations anymore.
They have also added flat markers, which I guess is more related to the original question. A flattened marker will always stay in the orientation it was originally drawn on the map: https://developers.google.com/maps/documentation/android/marker#flatten_a_marker
The only requirement is that you reference the latest version of Google Play Services.
I'm also rewriting my app (Runbot) for the new API and had to figure out how to create custom markers representing milestones (like 1km, 2km, ...) and how to show or show not all of them depending on the zoom level.
I had a custom drawable that I used for the v1 API and what I do now to render the markers is about this (Position is a class of my own that holds the position and further information; all needed here is its LatLng property):
private void addMarker(Position p, MilestoneDrawable milestone) {
if (mMarkers.containsKey(p)) {
mMarkers.get(p).setVisible(true);
} else {
Marker m = mMap.addMarker(new MarkerOptions()
.position(p.latLng)
.icon(BitmapDescriptorFactory.fromBitmap(Util.drawableToBitmap(milestone)))
.anchor(0.5f, 1.0f) // bottom center
);
mMarkers.put(p, m);
}
}
Besides creating and adding the custom markers, what you see is that I keep the markers in a HashMap so I do not have to destroy and create them all the time. When it comes to zooming and deciding which ones to show, I first set all of the markers to invisible and than call addMarker() for those I want to be shown, and those which I already have in the HashMap I simply make visible again.
I hope this helps you a bit. I have a bit of mixed feelings towards the new API...
I had a similar problem where I had markers that needed to rotate. My solution was to have the object the marker represented be responsible for generating the marker. I have a few methods in the object that look like:
protected Marker getMarker(GoogleMap map) {
if (this.marker == null) {
marker = map.addMarker(new MarkerOptions().position(location).
icon(BitmapDescriptorFactory.fromBitmap(BusMarkerImageFactory.
getMarkerIcon(heading))));
}
return marker;
}
protected void updateMarker(GoogleMap map) {
if (marker != null) {
rotateIcon();
marker.setPosition(location);
} else {
getMarker(map);
}
private void rotateIcon() {
marker.setIcon(BitmapDescriptorFactory.
fromBitmap(BusMarkerImageFactory.getMarkerIcon(heading)));
}
This is from a system that draws buses with the markers pointing in the direction they are heading, so of course, your code will be different, but the concept is very similar. Instead of rebuilding the entire marker you're keeping a reference to it somewhere and then simply resetting the icon.
Of course, drawing all those bitmaps for minor changes is a drain on memory. I used a flyweight pattern in the (incorrectly named) BusMarkerImageFactory to keep 16 images for 16 possible heading ranges. It is a static class that simply takes in the heading and returns the image that I've mapped to that range.
can't you use addMarker(new MarkerOptions()) method ?
If you need a custom marker you can create an implementation of InfoWindowAdapter and use that implementation like mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
here is the documentation for InfoWindowAdapter