Swift GoogleMaps fitBounds Zoom - swift

New coder try to fit GoogleMap in my view.
I have searched a lot of information and I have come to this conclusion, but it does not work for me.
override func loadView() {
var markerList = [GMSMarker]()
// Create a GMSCameraPosition
let camera = GMSCameraPosition.camera(withLatitude: 4.390205, longitude: 2.154007, 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)
}
//fit map to markers
var bounds = GMSCoordinateBounds()
for marker in markerList {
bounds = bounds.includingCoordinate(marker.position)
}
let update = GMSCameraUpdate.fit(bounds)
mapView.moveCamera(update)
}
The map is not adjusted with the proper zoom.
Anyone can help me with the zoom issue?
Thanks in advance :)

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

Related

Creating own marker with iconView on Google Maps

I created my own marker with iconView for showing my own position. As you can see it is the green one. But every time I move the screen it is reloading my green view and it seems lagging. I don't have the same problem with the other marker shown, which are simple png.
How can I solve that? I can solve that problem by removing the line mapView.clear() But the result is that every loaded marker don't go away if I zoom out. So the map gets more and more crowded.
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
mapView.clear()
let fullCordinate = "\(mapView.camera.target.latitude),\(mapView.camera.target.longitude)"
networkGoogleApiConnect.fetchPoi(geoCordinate: fullCordinate)
networkGoogleApi.testVariable.forEach {
let marker1 = GMSMarker()
marker1.position = CLLocationCoordinate2D(latitude: $0.position.lat, longitude: $0.position.lng)
marker1.title = $0.title
marker1.icon = UIImage(named: "house")
var dict = [String:String]()
dict["id"] = $0.id
marker1.userData = dict
marker1.map = mapView
locationManager.stopUpdatingLocation()
}
locationManager.delegate=self
let neuLongitudeEigenerStandort = locationManager.location!.coordinate.longitude
let neuLatitudeEigenerStandort = locationManager.location!.coordinate.latitude
let fullCordinateEigenerStandort = "\(neuLatitudeEigenerStandort),\(neuLongitudeEigenerStandort)"
let ownMarker = GMSMarker()
ownMarker.iconView = UIView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
ownMarker.iconView?.backgroundColor = .green
ownMarker.position = CLLocationCoordinate2D(latitude: neuLatitudeEigenerStandort, longitude: neuLongitudeEigenerStandort)
ownMarker.title = "Eigene Position"
ownMarker.snippet = "GPS"
ownMarker.icon = GMSMarker.markerImage(with: .blue)
ownMarker.map = mapView
}

Google map Zooming

I'm trying to zoom google map on particular pin from lat long.it working fine but i want to change pin image when zoom in on pin in swift.i have doing like this but there have putting 2 image on same lat long.
func zoom(lat: Double, long : Double){
CATransaction.begin()
CATransaction.setValue(1, forKey: kCATransactionAnimationDuration)
// It will animate your camera to the specified lat and long
let camera = GMSCameraPosition.camera(withLatitude: lat, longitude: long, zoom: 15)
self.mapView!.animate(to: camera)
let position = CLLocationCoordinate2D(latitude: lat,longitude: long)
let marker = GMSMarker()
marker.map = self.mapView
marker.icon = UIImage.init(named: "pin-1")
CATransaction.commit()
}
You can put a function that detects changes in your zoom level then put a condition that will change the value of your marker icon.
Here is how my code looks like:
import UIKit
import GoogleMaps
class ViewController: UIViewController, GMSMapViewDelegate {
let marker = GMSMarker()
override func viewDidLoad() {
}
override func loadView() {
// Create a GMSCameraPosition that tells the map to display the
// coordinate -33.86,151.20 at zoom level 6.
let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6.0)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
self.view = mapView
mapView.delegate = self
// Creates a marker in the coordinate of the map.
marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)
marker.title = "Sydney"
marker.snippet = "Australia"
marker.map = mapView
marker.icon = UIImage(named: "pin_orange")
}
//This detect the changes in the cameraposition
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
let zoom = mapView.camera.zoom
print("map zoom is ",String(zoom))
//put a condition here to change the icon of your marker
if zoom > 6 {
marker.icon = UIImage(named: "icon1")
}else{
marker.icon = UIImage(named: "icon2")
}
}
}
Hope this helps!

Download and cache the MKMapSnapshotter image using SDWebimage

I want to show mapView in UITableViewCells,
So I actually wrote this code
class DataPointTableCell: UITableViewCell {
#IBOutlet weak var mapView: MKMapView!
func addAnnotaionToMapView(_ coordinates: Coordinate) {
removePreviousCoordinate()
let viewCoorindate = CLLocationCoordinate2D(latitude: coordinates.latitude, longitude: coordinates.longitude)
let annotation = MKPointAnnotation()
annotation.coordinate = viewCoorindate
mapView.addAnnotation(annotation)
// animate is turned to false on purpose.
mapView.animateToPoint(viewCoorindate, animated: false)
}
private func removePreviousCoordinate() {
let annotations = self.mapView.annotations
self.mapView.removeAnnotations(annotations)
}
}
The problem with this approach is that it animates the mapView location and then adds the marker as it deques the cell.
I went with another approach i.e. by using MKMapSnapshotter
private func setMapImage() {
let rect = self.mapImageView.bounds
let mapSnapshotOptions = MKMapSnapshotter.Options()
// Set the region of the map that is rendered.
let needleLocation = CLLocationCoordinate2DMake(15.4952364, 73.8343293)
let region = MKCoordinateRegion(center: needleLocation, latitudinalMeters: 1000, longitudinalMeters: 1000)
mapSnapshotOptions.region = region
// Set the scale of the image. We'll just use the scale of the current device, which is 2x scale on Retina screens.
mapSnapshotOptions.scale = UIScreen.main.scale
// Set the size of the image output.
mapSnapshotOptions.size = CGSize(width: 300, height: 300)
// Show buildings and Points of Interest on the snapshot
mapSnapshotOptions.showsBuildings = true
mapSnapshotOptions.showsPointsOfInterest = false
let snapshot = MKMapSnapshotter(options: mapSnapshotOptions)
snapshot.start { snapshot, error in
guard let snapshot = snapshot, error == nil else {
print("\(error!.localizedDescription)")
return
}
UIGraphicsBeginImageContextWithOptions(mapSnapshotOptions.size, true, 0)
snapshot.image.draw(at: .zero)
let pinView = MKPinAnnotationView(annotation: nil, reuseIdentifier: nil)
let pinImage = pinView.image
var point = snapshot.point(for: needleLocation)
if rect.contains(point) {
let pinCenterOffset = pinView.centerOffset
point.x -= pinView.bounds.size.width / 2
point.y -= pinView.bounds.size.height / 2
point.x += pinCenterOffset.x
point.y += pinCenterOffset.y
pinImage?.draw(at: point)
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
DispatchQueue.main.async {
self.mapImageView.image = image
}
}
}
This works fine but I can't cache image based on anything.
So the help that I wanted is how to download and cache the mapImage using SDWebimage.
First add a unique key for your cell
var youUniqueCellKey = "Key"
Then in setMapImage first check if an image is already Cached or not and assign it to your mapImageView
private func setMapImage() {
if let image = SDImageCache.shared().imageFromCache(forKey: youUniqueCellKey) {
self.mapImageView.image = image
} else {
// Add your rest of your code here
// At the end
var imageToStore = UIImage() // Your mapImage
SDImageCache.shared().store(imageToStore, forKey: youUniqueCellKey, completion: nil)
}
}

Google map view color error

I would like to change marker position if button tapped. I tried like below. but it will look like this. Some how color will be changed to like so.
How can I fix this? Thank you!
#objc func changeMarker() {
let next = CLLocationCoordinate2DMake(40.730610, -73.935242)
mapView.camera = GMSCameraPosition.camera(withLatitude: next.latitude, longitude: next.longitude, zoom: 13)
let marker = GMSMarker(position: next)
marker.title = "over here"
marker.map = mapView
}
Add this marker and try this
func addMarker() {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: CLLocationDegrees(yourCoordinateLatitude), longitude: CLLocationDegrees(yourCoordinateLongitude))
marker.map = mapView
}
Now you can zoom to your marker
func zoomToCoordinate(coordinate: CLLocationCoordinate2D, zoom: Float) {
CATransaction.begin()
CATransaction.setValue(1, forKey: kCATransactionAnimationDuration)
let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: zoom)
self.animate(to: camera)
CATransaction.commit()
}
I would call it like this
mapView.clear() // to clear your mapView
mapView.addMarker()
mapView.zoomToCoordinate(coordinate: yourCoordinate, zoom: 15)
Always check if your function is called and if the coordinations are correct.
This code works in my project. If it doesn't work for your project please share more code from you.

Make Info window Marker Google Maps Always Appear Swift

i have info window that shows after tapped, but how to make it always appear? Without user tap on the marker. I'm using Google Maps.
here's my code :
mapView.delegate = self
let camera = GMSCameraPosition.camera(withLatitude: coordinate.lat, longitude: coordinate.long, zoom: 20)
mapView.animate(to: camera)
for state in states {
let marker = GMSMarker()
marker.position = CLLocationCoordinate2DMake(state.lat, state.long)
print(marker.position)
marker.title = "Country"
marker.snippet = "Places"
marker.map = mapView
mapView.selectedMarker = marker
marker.map = mapView
}
thanks before
First we need to Add a marker.
let position = CLLocationCoordinate2D(latitude: 10, longitude: 10)
let marker = GMSMarker(position: position)
marker.title = "Hello World"
marker.map = mapView
We can Customize the marker image by this:-
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.icon = UIImage(named: "house")
london.map = mapView
//To change the Marker Opacity use below
marker.opacity = 0.6
To Rotate a marker:-
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let degrees = 90.0
let london = GMSMarker(position: position)
london.groundAnchor = CGPoint(x: 0.5, y: 0.5)
london.rotation = degrees
london.map = mapView
And to Add an info window:-
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.snippet = "Population: 8,174,100"
london.map = mapView
To Set an info window to refresh automatically
marker.tracksInfoWindowChanges = true
To Change the position of an info window
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let london = GMSMarker(position: position)
london.title = "London"
london.snippet = "Population: 8,174,100"
london.infoWindowAnchor = CGPoint(x: 0.5, y: 0.5)
london.icon = UIImage(named: "house")
london.map = mapView
For more details you can go Here
try to move mapView.selectedMarker = marker to delegate function mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool function