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.
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.