I am working on an app that displays certain markers based on a radius around your current location. The radius is between 100 - 5000 meters. I change the radius with an UISlider and redraw the GMSCircle.
My problem is that I want to update the camera zoom according to the slider value but I don't have an idea by which scale to divide.
This is how I create the camera in the viewDidLoad method where the initial zoom value is 15:
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:locationManager.location.coordinate.latitude longitude:locationManager.location.coordinate.longitude zoom:15];
Here's a screenshot of what I am working on.

Does anyone know what scale should I use to move the zoom accordingly?
Thanks a lot!
Granit
I just created extension for GMSCameraUpdate.
input parameters:
coordinate - your center coordinate
radius - radius of visible bounds
extension GMSCameraUpdate {
static func fit(coordinate: CLLocationCoordinate2D, radius: Double) -> GMSCameraUpdate {
var leftCoordinate = coordinate
var rigthCoordinate = coordinate
let region = MKCoordinateRegionMakeWithDistance(coordinate, radius, radius)
let span = region.span
leftCoordinate.latitude = coordinate.latitude - span.latitudeDelta
leftCoordinate.longitude = coordinate.longitude - span.longitudeDelta
rigthCoordinate.latitude = coordinate.latitude + span.latitudeDelta
rigthCoordinate.longitude = coordinate.longitude + span.longitudeDelta
let bounds = GMSCoordinateBounds(coordinate: leftCoordinate, coordinate: rigthCoordinate)
let update = GMSCameraUpdate.fit(bounds, withPadding: -15.0)
return update
}
}
With the help of Saxon Druce,finally I did it.
class MapUtil {
class func translateCoordinate(coordinate: CLLocationCoordinate2D, metersLat: Double,metersLong: Double) -> (CLLocationCoordinate2D) {
var tempCoord = coordinate
let tempRegion = MKCoordinateRegionMakeWithDistance(coordinate, metersLat, metersLong)
let tempSpan = tempRegion.span
tempCoord.latitude = coordinate.latitude + tempSpan.latitudeDelta
tempCoord.longitude = coordinate.longitude + tempSpan.longitudeDelta
return tempCoord
}
class func setRadius(radius: Double,withCity city: CLLocationCoordinate2D,InMapView mapView: GMSMapView) {
let range = MapUtil.translateCoordinate(city, metersLat: radius * 2, metersLong: radius * 2)
let bounds = GMSCoordinateBounds(coordinate: city, coordinate: range)
let update = GMSCameraUpdate.fitBounds(bounds, withPadding: 5.0) // padding set to 5.0
mapView.moveCamera(update)
// location
let marker = GMSMarker(position: city)
marker.title = "title"
marker.snippet = "snippet"
marker.flat = true
marker.map = mapView
// draw circle
let circle = GMSCircle(position: city, radius: radius)
circle.map = mapView
circle.fillColor = UIColor(red:0.09, green:0.6, blue:0.41, alpha:0.5)
mapView.animateToLocation(city) // animate to center
}
}
For Swift 3
extension GMSCircle {
var bounds: GMSCoordinateBounds {
return [0, 90, 180, 270].map {
GMSGeometryOffset(position, radius, $0)
}.reduce(GMSCoordinateBounds()) {
$0.includingCoordinate($1)
}
}
}
Usage:
mapView.animate(with: .fit(circle.bounds))
Here's a simpler solution for getting the bounds of a GMSCircle.
It doesn't rely on MapKit and avoids the two calls that change the camera position (moveCamera and animateToLocation)
import GoogleMaps
extension GMSCircle {
func bounds () -> GMSCoordinateBounds {
func locationMinMax(_ positive : Bool) -> CLLocationCoordinate2D {
let sign: Double = positive ? 1 : -1
let dx = sign * self.radius / 6378000 * (180 / .pi)
let lat = position.latitude + dx
let lon = position.longitude + dx / cos(position.latitude * .pi / 180)
return CLLocationCoordinate2D(latitude: lat, longitude: lon)
}
return GMSCoordinateBounds(coordinate: locationMinMax(true),
coordinate: locationMinMax(false))
}
}
After adding this file to your project, all you have to do is:
let update = GMSCameraUpdate.fit(myCircle.bounds())
myMap.animate(with: update)
where myCircle and myMap are replaced by the actual circle and map.
You could use the fitBounds method of GMSCameraUpdate, passing in a GMSCoordinateBounds which is calculated from the edges of your circle.
Based on this answer, it looks like you could use MKCoordinateRegionMakeWithDistance to convert your centre (lat/lon) plus radius (metres) into a MKCoordinateRegion, which will convert the metres into a span in degrees, therefore allowing you to calculate the coordinates in degrees which you'd use to create the GMSCoordinateBounds.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With