I need to set at the same time tilt and bounds to th camera in my map.
So I think I need this:
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50));
but I don't know how can I add also tilt.
If I try to insert other code, like this:
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(mMap.getCameraPosition().target)
.zoom(mMap.getCameraPosition().zoom)
.bearing(30)
.tilt(45)
.build()));
only the second animation is done. So, the tilt is applied, but I have not the correct bounds.
So, the question, as said in the question's title: how can I set both tilt and bounds for my camera?
Why don't you wait for the first animation with the bounds to complete, then animate the tilt when it finishes?
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50),
new CancelableCallback() {
#Override
public void onFinish() {
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder(mMap.getCameraPosition())
.bearing(30)
.tilt(45)
.build()));
}
#Override
public void onCancel() {
}
});
Related
I am using the google maps api v2 for my new google maps app. And I wondered how to calculate the coordinates of 4 edges of the current screen position so that I can search for markers that are directly in the camera view. Any ideas about how it is possible to achieve ? I thought about something with the center of the camera view and zoom but can't figure out how to continue.
Here is the proper answer to get the coordinates of upper right corner and down left corner:
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition position) {
LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds;
//fetchData(bounds);
ne = bounds.northeast;
sw = bounds.southwest;
//new DownloadJSON().execute();
//Log.e("LatLngs"," southwest: "+sw+" northeast: "+ne);
}
});
I have my map with a 60° tilt, and I need to set it in 60 again after the user touches the compass, because it sets the tilt to 0°
Question is a little but old, but I´ve run into a similar problem. My solution was:
ImageView compass = (ImageView)mMapView.findViewWithTag("GoogleMapCompass");
compass.setOnClickListener(new View.OnClickListener()
{
#Override public void onClick(final View v)
{
// React on compass click
}
});
Would resetting the tilt angle in OnCameraChangeListener do the trick?
I am using this to get the bounds of markers on my map:
markerList.add(m);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markerList) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
CameraUpdate updatecamera = CameraUpdateFactory.newLatLngBounds(bounds, 50);
map.animateCamera(updatecamera);
After getting update, I would like to tilt the map to 30 degrees.
I have used this to tilt the camera in the past, but it is not working with the bounds feature:
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(meLoc).zoom(6).bearing(0).tilt(30).build();
map.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
How do I add this tilt after getting the bounds?
Thanks
As you say, the Android Maps API v2 doesn't currently directly support animating the camera with both bounds and tilt info.
One workaround is to use the following steps:
Do the camera animation you want to perform with the bounds, but leave out the tilt
Listen for the end of the above camera animation, get the current camera position, and then perform the tilt
This has the effect of moving the camera to the bounds while looking straight down (i.e., tilt = 0), and then tilting the camera in place. I've found that this works well in some use cases, and actually looks nice, but in others its kind of awkward. It may or may not work for your particular use case.
To implement this, let's assume you have a main class MapScreen.java where your map is implemented. You'll need change it to include the camera listener interface, a reference to the camera position, a reference to your activity, an initial tilt value you want to use (you can alternately set this at runtime), and a default camera padding:
public class MapScreen extends FragmentActivity implements GoogleMap.OnCameraChangeListener {
...
private GoogleMap map;
public static CameraPosition lastCameraPosition;
public static MapScreen mapScreen;
public static float CAMERA_INITIAL_TILT = 30.0f;
public static int CAMERA_PADDING = 100;
...
public void onCreate(Bundle savedInstanceState) {
...
mapScreen = this;
...
//Set up map object here like normal
map = ((SupportMapFragment)(getSupportFragmentManager().findFragmentById(R.id.map))).getMap();
...
//Set camera change listener
map.setOnCameraChangeListener(this);
}
...
}
In this class, you'll also need to add a method to listen and save the location of the camera when the first animation stops:
#Override
public void onCameraChange(CameraPosition position) {
//Save the last camera position so we can reference it when tilting the camera following animations
lastCameraPosition = position;
}
Also, add an inner class you can reference that performs the tilt after the first animation finishes (with a slight delay to get the correct CameraPosition):
public class tiltOnFinishAnimation implements CancelableCallback {
#Override
public void onCancel() {
//Do nothing
}
#Override
public void onFinish() {
//We want to run the tilt animation, but the CameraPosition needed to center the camera in the right place
//is only available after the onFinish() method completes. So, we delay this by 10 ms to let the CameraPosition update
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
mapScreen.runOnUiThread(new Runnable() {
public void run() {
if(lastCameraPosition != null){
//Finish with a tilt
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(lastCameraPosition.target)
.zoom(lastCameraPosition.zoom)
.bearing(lastCameraPosition.bearing)
.tilt(CAMERA_INITIAL_TILT)
.build();
//Perform the tilt!
mapScreen.map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
});
}
}, 10);
}
}
Finally, when you want to move the camera, execute your normal code, but first identify some of the map view attributes needed for animating the camera correctly based on orientation, and include a reference to the callback to execute when the first part of the animation without the tilt stops:
//Get the View height and width, so we don't exceed the screen size after padding for the camera updates
int width;
int height;
if(mapFragment != null){
width = mapFragment.getView().getWidth();
height = mapFragment.getView().getHeight();
}else{
//If the map fragment hasn't been instantiated yet, use the entire display
if (android.os.Build.VERSION.SDK_INT >= 13){
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}else{
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
}
}
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
//Use verticle size for padding
CAMERA_PADDING = (int) (height * 0.2f);
}else{
//Use horizontal size for padding
CAMERA_PADDING = (int) (width * 0.2f);
}
//Your code
markerList.add(m);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markerList) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
//Here's the new code below that triggers first the movement to the bounds, then the tilt (as a callback)
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, width, height, CAMERA_PADDING), new tiltOnFinishAnimation());
In order to set GoogleMap Tilt and Bound all marker you need to use following code.
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 75));
CameraPosition camPos = new CameraPosition.Builder(googleMap.getCameraPosition())
.target(bounds.getCenter())
.bearing(bearing).tilt(45).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(camPos));
The key point is not having an animateCamera(..) followed by another animateCamera(..) without enough delay, as they overlap. So you should better use moveCamera(..) first and then animateCamera(..), or use some delay technique for the second animateCamera(..) such as new Handler().postDelayed(..).
I am trying to zoom on a map
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(mBounds, this.getResources().getDisplayMetrics().widthPixels,
height, padding);
mMap.animateCamera(cameraUpdate, duration, null);
And after that I want to scroll the map vertically
CameraUpdate cameraUpdate =
CameraUpdateFactory.scrollBy(0, amountToScroll);
mMap.animateCamera(cameraUpdate, duration, null);
The thing is ... it is not working. If I call the scroll right after the zoom, only the scroll is taken into account. If I scroll the map once the zoom animation is finished I will have 2 animations.
I would like to do both operations with the same animation, is it possible?
If you call animateCamera multiple times, only the last one will finish its action.
The easy fix would be to use moveCamera instead of the first call to animateCamera, but that's not a nice solution from UX perspective.
The other way would be to do the math yourself and fill mBounds with the bounds you really want to show.
The easiest way to do it is to use CancelableCallback. You should check the first action is complete and then call the second:
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, size.x, height, 0), new CancelableCallback() {
#Override
public void onFinish() {
CameraUpdate cu_scroll = CameraUpdateFactory.scrollBy(0, 500);
mMap.animateCamera(cu_scroll);
}
#Override
public void onCancel() {
}
});
I have a google map (com.google.android.gms.maps.GoogleMap) where I have some markers set.
I am able to, separately,
1) adjust zoom level and center the map on a boundary:
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(getZoomBounds(), 10));
and
2) center the map above one of the markers:
LatLng poiSelectedLatLng = new LatLng(markerSelected.getPosition().latitude
+ offset, markerSelected.getPosition().longitude);
mMap.animateCamera(CameraUpdateFactory.newLatLng(poiSelectedLatLng));
but, for the life of me, I can't just do both, adjust the zoom level using newLatLngBounds and then center the map somewhere else. Whatever I do last is what I see happening in the map.
How do I do this?
For future visitors this is how you can chain camera animations:
map.animateCamera(CameraUpdateFactory.newLatLngBounds(getZoomBounds(), 10), 2000, new CancelableCallback() {
#Override
public void onFinish() {
LatLng poiSelectedLatLng = new LatLng(markerSelected.getPosition().latitude + offset, markerSelected.getPosition().longitude);
map.animateCamera(CameraUpdateFactory.newLatLng(poiSelectedLatLng));
}
#Override
public void onCancel() {
}
});
Also see AnimateCameraChainingExampleActivity.java for an example how to chain infinitely.
Try using both moveCamera and animateCamera...
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(getZoomBounds(), 10));
LatLng poiSelectedLatLng = new LatLng(markerSelected.getPosition().latitude
+ offset, markerSelected.getPosition().longitude);
mMap.animateCamera(CameraUpdateFactory.newLatLng(poiSelectedLatLng));
moveCamera will move directly to that spot while animateCamera will provide the moving effect. They are linear in nature so one will happen after the other however layering them as I have done above will provide the potential effect you are looking for.
If you are trying to see the actual movement of both calls on the UI you will need to register for the callback post the completion of the animation as needed.