Swift, Google Map Fit Bound for All the Markers

Swift GoogleMaps fitBounds Zoom

I solved the problem by myself. I use DispatchQueue to set the right zoom to my map.

Here is my final code:

override func loadView() {

var markerList = [GMSMarker]()

// Create a GMSCameraPosition
let camera = GMSCameraPosition.camera(withLatitude: 40.4167 , longitude: -3.70325, zoom: 8)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.isMyLocationEnabled = true
view = mapView

mapView.settings.myLocationButton = true
//mapView.setMinZoom(10, maxZoom: 20)

//create markers
for loc in arrayOfMapStops {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: loc.lat, longitude: loc.long)
marker.title = loc.address
marker.snippet = loc.type
if loc.type == "Entrega" {marker.icon = GMSMarker.markerImage(with: .green)}
else {marker.icon = GMSMarker.markerImage(with: .blue)}
marker.map = mapView
markerList.append(marker)
}

delay(seconds: 3) { () -> () in
//fit map to markers
var bounds = GMSCoordinateBounds()
for marker in markerList {
bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fit(bounds, withPadding: 100.0)
mapView.animate(with: update)
}
}

func delay(seconds: Double, completion:@escaping ()->()) {
let when = DispatchTime.now() + seconds
DispatchQueue.main.asyncAfter(deadline: when) {
completion()
}
}

:)

How to fit bounds for coordinate array with google maps sdk for iOS?

Here's my solution for this problem. Building a GMSCoordinateBounds object by multiple coordinates.

- (void)focusMapToShowAllMarkers {       
CLLocationCoordinate2D myLocation = ((GMSMarker *)_markers.firstObject).position;
GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] initWithCoordinate:myLocation coordinate:myLocation];

for (GMSMarker *marker in _markers)
bounds = [bounds includingCoordinate:marker.position];

[_mapView animateWithCameraUpdate:[GMSCameraUpdate fitBounds:bounds withPadding:15.0f]];
}

Updated answer: Since GMSMapView markers property is deprecated, you should save all markers in your own array.

updated swift 3 answer:

    func focusMapToShowAllMarkers() {
let firstLocation = (markers.first as GMSMarker).position
var bounds = GMSCoordinateBoundsWithCoordinate(firstLocation, coordinate: firstLocation)

for marker in markers {
bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fitBounds(bounds, withPadding: CGFloat(15))
self.mapView.animate(cameraUpdate: update)
}

swift - how to fit GMSMapView (google map) to show all markers and prevent over zoom

I found a simple trick to solve the problem. You can use setMinZoom before fit and animate to prevent over zoom and then setMinZoom again to allow user zoom.

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)
}

mapView.setMinZoom(1, maxZoom: 15)//prevent to over zoom on fit and animate if bounds be too small

let update = GMSCameraUpdate.fit(bounds, withPadding: 50)
mapView.animate(update)

mapView.setMinZoom(1, maxZoom: 20) // allow the user zoom in more than level 15 again

Fit entire Google Map in zoom level in Swift project

You can use GMSCoordinateBounds(path:) to fit all coordinates. But it will display a world size scale if you update the camera right after your another update. So you can use dispatch_after to solve the problem.

 override func viewDidLoad() {
super.viewDidLoad()

self.view.backgroundColor = UIColor.whiteColor();
let camera = GMSCameraPosition.cameraWithLatitude(-37.813047, longitude: -72.8561644, zoom:5)
mapView = GMSMapView.mapWithFrame(CGRectZero, camera:camera)

let marker = GMSMarker()
marker.position = camera.target
marker.snippet = "Hello World"
marker.appearAnimation = kGMSMarkerAnimationPop
marker.map = mapView

self.view = mapView

delay(seconds: 2) { () -> () in
let path = GMSMutablePath()
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.0))
path.addCoordinate(CLLocationCoordinate2DMake(37.45, -122.0))
path.addCoordinate(CLLocationCoordinate2DMake(37.45, -122.2))
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.2))
path.addCoordinate(CLLocationCoordinate2DMake(37.36, -122.0))

let rectangle = GMSPolyline(path: path)
rectangle.map = self.mapView

let bounds = GMSCoordinateBounds(path: path)

self.mapView!.animateWithCameraUpdate(GMSCameraUpdate.fitBounds(bounds, withPadding: 15.0))
}
}

The delay method uses the dispatch_after:

func delay(#seconds: Double, completion:()->()) {
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * seconds ))

dispatch_after(popTime, dispatch_get_main_queue()) {
completion()
}
}

Sample Image



Related Topics



Leave a reply



Submit