Swift - GoogleMaps SDK get coordinates on touch

I am new to swift and the Google Maps SDK, and was wondering how to get the coordinates of where the user has tapped using the Google Maps SDK. For example if a user holds their finger down on a certain place on a map, a annotation is created there. I would really appreciate your help, thanks.

Upvotes: 4

Views: 5678

Answers (4)

MohamedDorgham
MohamedDorgham

Reputation: 1

By following the answer of @Nayan Dave, you can get the coordinates by tap and also get the placeMark geocode using the code below:

        func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
        let geocoder = GMSGeocoder()
        geocoder.reverseGeocodeCoordinate(coordinate) { response, error in

            if error != nil {
                print("reverse geodcode fail: \(error!.localizedDescription)")
            } else {
                if let places = response?.results() {
                    if let place = places.first {
                        if let lines = place.lines {

                 // this will print the address formatted in on line

                        print("GEOCODE: Formatted Address: \(lines)")

              // GEOCODE: Formatted Address: ["213 Borough High St, London SE1 1JA, UK"]

                        }
                    } else {
                        print("GEOCODE: nil first in places")
                    }
                } else {
                    print("GEOCODE: nil in places")
                }
            }
        }
        // this to clear any marker on map
        mapView.clear()

        // this to center the camera of the map to the tapped area

        let camera = GMSCameraPosition.camera(withLatitude: coordinate.latitude, longitude: coordinate.longitude, zoom: 15.0)
        mapView.animate(to: camera)

        // this to add a marker on the tapped location

        let marker = GMSMarker(position: coordinate)
        marker.appearAnimation = .pop
        marker.map = mapView
  
    }

Upvotes: 0

Nayan Dave
Nayan Dave

Reputation: 1680

For Swift 5.0+

First, make sure you have added GMSMapViewDelegate delegate to your ViewController Class

Add this default function in your class

func mapView(_ mapView: GMSMapView, didLongPressAt coordinate: CLLocationCoordinate2D) {
   debugPrint("Coordinates: ", coordinate)
}

If you just want coordinates, then above function is perfect for you But if you want to create Marker or get local address from touch then see below function

func mapView(_ mapView: GMSMapView, didLongPressAt coordinate: CLLocationCoordinate2D) {
    let marker = GMSMarker(position: coordinate) //Add this line if you want to add marker

    let decoder = CLGeocoder()
    decoder.reverseGeocodeLocation(CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)) { placemarks, err in
        if let placeMark = placemarks?.first {
            let plName = placeMark.name ?? placeMark.subThoroughfare ?? placeMark.thoroughfare! //Place Name

            var address : String! = "" //This will be the local address
            if let subLocality = placeMark.subLocality ?? placeMark.name {
                address.append(subLocality)
                address.append(", ")
            }
            if let city = placeMark.locality ?? placeMark.subAdministrativeArea {
                address.append(city)
                address.append(", ")
            }
            if let state = placeMark.administrativeArea, let country = placeMark.country {
                address.append(state)
                address.append(", ")
                address.append(country)
            }
            // Add Marker:
            marker.title = plName
            marker.snippet = address
            marker.appearAnimation = .pop
            marker.map = mapView
        }
    }
 }

This Function does not only get coordinates but creates a Marker with all the details fetched from the coordinates(Like PlaceName, city, state,country etc.) too

If you just want local address, then remove all the code lines related to marker

The reason why i have used CLGeocoder and not GMSGeocoder from GoogleMapDelegate is that Apple's CLGeocoder is much more precise in getting the place-name while GMSGeocoder does not fetch place-name accurately.

  • Also Note that : Apple's Geocoding requests are rate-limited for each app, so making too many requests in a short period of time may cause some of the requests to fail.

Upvotes: 0

Sreeraj VR
Sreeraj VR

Reputation: 1574

Try this

    extension ViewController: GMSMapViewDelegate {

    func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D)    
      {

        print("Tapped at coordinate: " + String(coordinate.latitude) + " "
                + String(coordinate.longitude))
      }

    }

Upvotes: 0

George McDonnell
George McDonnell

Reputation: 1455

In the GMSMapViewDelegate there is a method named: mapView:didLongPressAtCoordinate: which is called after a long-press gesture at a particular coordinate. See the reference here.

By implementing this method you could then add a marker to the map view:

func mapView(mapView: GMSMapView!, didLongPressAtCoordinate coordinate: CLLocationCoordinate2D) {
     let marker = GMSMarker(position: coordinate)
     marker.title = "Hello World"
     marker.map = mapView
}

For a tap gesture a similar delegate method can be implemented called mapView:didTapAtCoordinate: which can be used in a similar way:

func mapView(mapView: GMSMapView!, didTapAtCoordinate coordinate: CLLocationCoordinate2D) {
     print("Tapped at coordinate: " + String(coordinate.latitude) + " " 
                                    + String(coordinate.longitude))
}

Upvotes: 13

Related Questions