Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map camera position changes sharply without animation

I use google Maps SDK for iOS. I have markers on my map and want to set proper zoom so that markers are separate and also markers should be visible on screen all at once. I am able to do it.I have done using logic that if all markers are visible then zoom in. But the problem is that map camera is changing sharply. I tried a lot to animate this zoom but I failed to do to. I tried animateToCameraPosition, animateToZoom and UIView animation method.

- (BOOL)allCoordinatesVisibleWithLatitudes:(NSArray *)arrayOfLatitudes Longitudes:(NSArray *)arrayOfLongitudes
    {
    CLLocationCoordinate2D coordinate;
    for(int i=0;i<arrayOfLatitudes.count;i++)
    {
        coordinate = CLLocationCoordinate2DMake([[arrayOfLatitudes objectAtIndex:i] floatValue], [[arrayOfLongitudes objectAtIndex:i] floatValue]);
        if(![self.mapView.projection containsCoordinate:coordinate])
        {
            return NO;
        }
    }
    return YES;
}


- (void)setZoomToHaveProperView
{
    NSMutableArray * arrayOfLatitudes = [[NSMutableArray alloc] init];
    NSMutableArray * arrayOfLongitudes = [[NSMutableArray alloc] init];
    RS_SingleMatch * singleMatch = [[RS_SingleMatch alloc] init];
    float zoom = 0.0;

    // You may ignore this first for loop. it just takes coordinate of all markers in     arrays.

    for(int i=0;i<=self.userMatches.arrayOfMatches.count;i++)
    {
        if(i==self.userMatches.arrayOfMatches.count)
        {
            RS_Trip * userTrip = [[RS_Trip alloc] init];
            [arrayOfLatitudes addObject:[NSNumber numberWithFloat:userTrip.fromLat]];
            [arrayOfLongitudes addObject:[NSNumber numberWithFloat:userTrip.fromLon]];
            if(self.segmentedControl.selectedSegmentIndex == 1)
            {
                [arrayOfLatitudes addObject:[NSNumber numberWithFloat:userTrip.toLat]];
                [arrayOfLongitudes addObject:[NSNumber numberWithFloat:userTrip.toLon]];
            }
        }
        else
        {
            singleMatch = [self.userMatches.arrayOfMatches objectAtIndex:i];
            [arrayOfLatitudes addObject:[NSNumber numberWithFloat:singleMatch.fromLat]];
            [arrayOfLongitudes addObject:[NSNumber numberWithFloat:singleMatch.fromLong]];
            if(self.segmentedControl.selectedSegmentIndex == 1)
            {
                [arrayOfLatitudes addObject:[NSNumber numberWithFloat:singleMatch.toLat]];
                [arrayOfLongitudes addObject:[NSNumber numberWithFloat:singleMatch.toLong]];
            }
        }
}
    zoom = self.mapView.camera.zoom;

    // if all coordinates are visible then zoom in
    if([self allCoordinatesVisibleWithLatitudes:arrayOfLatitudes Longitudes:arrayOfLongitudes])
    {
        while ([self allCoordinatesVisibleWithLatitudes:arrayOfLatitudes Longitudes:arrayOfLongitudes])
        {
            zoom += 0.5;
            [self.mapView setCamera:[GMSCameraPosition cameraWithTarget:self.mapView.camera.target zoom:zoom]];
            [self.mapView animateToCameraPosition:[GMSCameraPosition cameraWithTarget:self.mapView.camera.targetAsCoordinate zoom:zoom]];
        }
    }
}

I also tried reversing order of setting mapview camera and animating camera in while loop of if condition. I spent 3 days just doing it. Now asking for your help. Thank you in advance.

like image 450
Geek Avatar asked Mar 19 '13 11:03

Geek


3 Answers

I think the problem with this is that calling setCamera will snap to the new zoom level without animating - and so the following call to animateToCameraPosition won't actually animate anything, as the camera is already at that position.

However, if you removed the call to setCamera then you'd probably end up in an infinite loop, as the call to animateToCameraPosition won't actually update the camera until some time later (as the animation plays), and so on the next iteration of the loop the markers would still all be visible.

What you need to do is calculate the final zoom level that you need, and then make a single call to animateToCameraPosition to move the camera there.

I posted some code for calculating the centre and zoom level for a camera to fit a bounds here:

How to setRegion with google maps sdk for iOS?

So you could use something similar to calculate a camera position which would fit your markers to the screen.

like image 79
Saxon Druce Avatar answered Oct 13 '22 13:10

Saxon Druce


Much simpler answer:

Instead of

[self.mapView setCamera:[GMSCameraPosition cameraWithTarget:self.mapView.camera.target zoom:zoom]];
[self.mapView animateToCameraPosition:[GMSCameraPosition cameraWithTarget:self.mapView.camera.targetAsCoordinate zoom:zoom]];

Do this:

[self.mapView animateToCameraPosition:[GMSCameraPosition cameraWithTarget:[GMSCameraPosition cameraWithTarget:self.mapView.camera.target zoom:zoom]]];

Works for me!

like image 11
stackOverFlew Avatar answered Oct 13 '22 13:10

stackOverFlew


GMSCameraPosition *newCameraPosition = [GMSCameraPosition cameraWithTarget:cordinate zoom:position.zoom];
dispatch_async(dispatch_get_main_queue(), ^{
        [self.mapView animateToCameraPosition:newCameraPosition];
 });
like image 6
Sajid Israr Avatar answered Oct 13 '22 11:10

Sajid Israr