iOS, How to use GMSCoordinateBounds to show all the markers of the map?

家住魔仙堡 提交于 2019-11-29 20:45:36
- (void)focusMapToShowAllMarkers
{

    GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];

    for (GMSMarker *marker in <An array of your markers>)
        bounds = [bounds includingCoordinate:marker.position];

    [<yourMap> animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:30.0f]];


}

UPDATE:

are you sure there is nothing wrong in you array of markers and the coordinates? I've tried this code and is working perfectly. I've put this on the viewDidAppear

NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:[[NSDictionary alloc]initWithObjectsAndKeys:@"44.66",@"latitude",@"21.33",@"longitude", nil],
                         [[NSDictionary alloc]initWithObjectsAndKeys:@"44.66",@"latitude",@"21.453",@"longitude", nil],
                         [[NSDictionary alloc]initWithObjectsAndKeys:@"44.44",@"latitude",@"21.993",@"longitude", nil],
                         [[NSDictionary alloc]initWithObjectsAndKeys:@"44.635",@"latitude",@"21.553",@"longitude", nil],
                         [[NSDictionary alloc]initWithObjectsAndKeys:@"44.3546",@"latitude",@"21.663",@"longitude", nil],
                         [[NSDictionary alloc]initWithObjectsAndKeys:@"44.6643",@"latitude",@"21.212",@"longitude", nil],
                         [[NSDictionary alloc]initWithObjectsAndKeys:@"44.63466",@"latitude",@"21.3523",@"longitude", nil],nil];
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];
CLLocationCoordinate2D location;
for (NSDictionary *dictionary in array)
{
    location.latitude = [dictionary[@"latitude"] floatValue];
    location.longitude = [dictionary[@"longitude"] floatValue];
    // Creates a marker in the center of the map.
    GMSMarker *marker = [[GMSMarker alloc] init];
    marker.icon = [UIImage imageNamed:(@"marker.png")];
    marker.position = CLLocationCoordinate2DMake(location.latitude, location.longitude);
    bounds = [bounds includingCoordinate:marker.position];
    marker.title = dictionary[@"type"];
    marker.map = mapView_;
}
[mapView_ animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:30.0f]];

This is my result:

Swift 3 - Xcode 8

var bounds = GMSCoordinateBounds()
        for marker in yourArrayOfMarkers
        {
            bounds = bounds.includingCoordinate(marker.position)
        }
        let update = GMSCameraUpdate.fit(bounds, withPadding: 60)
        mapView.animate(with: update)

Clean swift 3 version:

let bounds = markers.reduce(GMSCoordinateBounds()) { 
    $0.includingCoordinate($1.position) 
}

mapView.animate(with: .fit(bounds, withPadding: 30.0))

Swift solution using GMSCoordinateBounds() without path,

var bounds = GMSCoordinateBounds()
for location in locationArray
{
    let latitude = location.valueForKey("latitude")
    let longitude = location.valueForKey("longitude")

    let marker = GMSMarker()
    marker.position = CLLocationCoordinate2D(latitude:latitude, longitude:longitude)
    marker.map = self.mapView
    bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fitBounds(bounds, withPadding: 100)
mapView.animateWithCameraUpdate(update)
@IBOutlet weak var mapView: GMSMapView!

let camera = GMSCameraPosition.cameraWithLatitude(23.0793, longitude:  
72.4957, zoom: 5)
mapView.camera = camera
mapView.delegate = self
mapView.myLocationEnabled = true

*** arry has dictionary object which has value of Latitude and Longitude. ***
let path = GMSMutablePath()

for i in 0..<arry.count {

   let dict = arry[i] as! [String:AnyObject]
   let latTemp =  dict["latitude"] as! Double
   let longTemp =  dict["longitude"] as! Double

   let marker = GMSMarker()
   marker.position = CLLocationCoordinate2D(latitude: latTemp, longitude: longTemp)
   marker.title = "Austrilia"
   marker.appearAnimation = kGMSMarkerAnimationNone
   marker.map = self.mapView

   path.addCoordinate(CLLocationCoordinate2DMake(latTemp, longTemp))

  } 

  let bounds = GMSCoordinateBounds(path: path)
  self.mapView!.animateWithCameraUpdate(GMSCameraUpdate.fitBounds(bounds, withPadding: 50.0))
mars

The easiest way I have found is to create a GMSMutablePath and then add all the coordinates of your markers to it. Then you can use the GMSCoordinateBounds initializer initWithPath: to create the bounds.

Once you have the bounds, you can create the GMSCameraUpdate and use it to animate the map to the visible bounds containing all of your markers.

For example, if you have an array of GMSMarker's:

NSArray *myMarkers;   // array of marker which sets in Mapview
GMSMutablePath *path = [GMSMutablePath path];

for (GMSMarker *marker in myMarkers) { 
   [path addCoordinate: marker.position];
}
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithPath:path];

[_mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds]];

As for Google Maps version 2.0.0 if you try to create a GMSCoordinateBounds using the default constructor GMSCoordinateBounds() and you check the "valid" flag it will be returning false and it won't make the animateWithCameraUpdate: move.

Swift 2.3 Solution

    if let myLocation = mapView.myLocation {
        let path = GMSMutablePath()
        path.addCoordinate(myLocation.coordinate)

        //add other coordinates 
        //path.addCoordinate(model.coordinate)

        let bounds = GMSCoordinateBounds(path: path)
        mapView.animateWithCameraUpdate(GMSCameraUpdate.fitBounds(bounds, withPadding: 40))
    }

We can find the same code every where , but make sure that it is in viewDidAppear() method

//bounding to a region of markers
GMSCoordinateBounds *bounds =
[[GMSCoordinateBounds alloc] initWithCoordinate:sourceMarker.position coordinate:destMarker.position];
[_mapView moveCamera:[GMSCameraUpdate fitBounds:bounds withPadding:50.0]];

You could iterate your map markers and get the further point to the east, west, north and south and make [[GMSCoordinateBounds alloc] initWithRegion:]

As per documentation, GMSCoordinateBounds can't be mutated.

GMSCoordinateBounds is immutable and can't be modified after construction.

- (GMSCoordinateBounds *)includingCoordinate:(CLLocationCoordinate2D)coordinate;
- (GMSCoordinateBounds *)includingBounds:(GMSCoordinateBounds *)other;

So we can mutate GMSCoordinateBounds by using above methods includingCoordinate: (for extending coordinates) and includingBounds: (for extending bounds).

So Swift code will looks like below:

var gmsBounds = GMSCoordinateBounds()
for coordinate in coordinates {
    let marker = GMSMarker(position: coordinate)
    gmsBounds = gmsBounds.includingCoordinate(position)
    marker.map = mapView
}
mapView.animate(with: GMSCameraUpdate.fit(gmsBounds, withPadding: 30.0))

Additional Notes:

If you add custom marker view, add padding as width of marker view in addition to required padding.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!