I'm trying to implement an autocomplete search on Google Maps that will show the location that the user selects on the map with a marker.
Search works fine. The problem is as follows. When I select a location from the search results, I get a GMSPlace object that has the correct name as the selected value, correct place ID (confirmed using this link), but incorrect coordinates (-180.0,-180.0
, or the kCLLocationCoordinate2DInvalid
constant). I tested this on multiple locations.
Most of this code was borrowed from documentation for the Places API.
import UIKit
import GoogleMaps
import GooglePlaces
class ViewController: UIViewController, UISearchBarDelegate {
@IBOutlet weak var mapContainer: UIView!
var mapView: GMSMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.mapView = GMSMapView(frame: self.mapContainer.frame)
self.view.addSubview(self.mapView)
}
// Code from https://developers.google.com/places/ios-sdk/autocomplete#add_an_autocomplete_ui_control
@IBAction func searchByAddress(_ sender: Any) {
// Present the Autocomplete view controller when the button is pressed.
let autocompleteController = GMSAutocompleteViewController()
autocompleteController.delegate = self
// Specify the place data types to return.
let fields: GMSPlaceField = GMSPlaceField(rawValue: UInt(GMSPlaceField.name.rawValue) |
UInt(GMSPlaceField.placeID.rawValue))!
autocompleteController.placeFields = fields
// Display the autocomplete view controller.
present(autocompleteController, animated: true, completion: nil)
}
}
extension ViewController: GMSAutocompleteViewControllerDelegate {
// Handle the user's selection.
func viewController(_ viewController: GMSAutocompleteViewController, didAutocompleteWith place: GMSPlace) {
let position: CLLocationCoordinate2D = place.coordinate
let camera = GMSCameraPosition.camera(withLatitude: position.latitude, longitude: position.longitude, zoom: 10)
let newMapView = GMSMapView.map(withFrame: self.mapContainer.frame, camera: camera)
self.mapView = newMapView
self.view.addSubview(newMapView)
let marker = GMSMarker()
marker.position = position
marker.title = place.name
marker.map = self.mapView
viewController.dismiss(animated: true, completion: nil)
}
func viewController(_ viewController: GMSAutocompleteViewController, didFailAutocompleteWithError error: Error) {
// TODO: handle the error.
print("Error: ", error.localizedDescription)
}
// User canceled the operation.
func wasCancelled(_ viewController: GMSAutocompleteViewController) {
viewController.dismiss(animated: true, completion: nil)
}
// Turn the network activity indicator on and off again.
func didRequestAutocompletePredictions(_ viewController: GMSAutocompleteViewController) {
UIApplication.shared.isNetworkActivityIndicatorVisible = true
}
func didUpdateAutocompletePredictions(_ viewController: GMSAutocompleteViewController) {
UIApplication.shared.isNetworkActivityIndicatorVisible = false
}
}
Any help would be appreciated!
From the place_id you got, query Place Details something like https://maps.googleapis.com/maps/api/place/details/json?placeid={placeid}&key={key} and you can get the lat and lng from result.
I was facing the same issue and went through the Place SDK documentation which says clearly that we should define before hand to the GMSPlaceField of what details do we need exactly and if you had followed the doc completely, it would be resulting only in the name and placeId being populated. So while instantiating your GMSAutoCompleteViewController define in the following way.
**let fields: GMSPlaceField = GMSPlaceField(rawValue:UInt(GMSPlaceField.name.rawValue) |
UInt(GMSPlaceField.placeID.rawValue) |
UInt(GMSPlaceField.coordinate.rawValue) |
GMSPlaceField.addressComponents.rawValue |
GMSPlaceField.formattedAddress.rawValue)!
autocompleteController.placeFields = fields**
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