Displaying current location on Google maps

heyred picture heyred · May 22, 2014 · Viewed 7.1k times · Source

I have an iOS app that uses Google Maps SDK to display a map within my app.

I have managed to get the map displaying but I dont know how to set the camera or the marker to the users current location.

I have hard coded the coordinates just to test is the map working but I am now stuck on how to display current location of the user.

Here is my code to centre the camera to a coordinate

- (void)viewDidLoad
{
    [super viewDidLoad];

    GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:47.995602 longitude:-78.902153 zoom:6];

    self.mapView = [GMSMapView mapWithFrame:CGRectZero camera:camera];

    self.mapView.myLocationEnabled = YES;
    self.mapView.mapType = kGMSTypeNormal;
    self.mapView.accessibilityElementsHidden = NO;
    self.mapView.settings.scrollGestures = YES;
    self.mapView.settings.zoomGestures = YES;
    self.mapView.settings.compassButton = YES;
    self.mapView.settings.myLocationButton = YES;
    self.mapView.delegate = self;
    self.view = self.mapView;

    [self placeMarkers];
}

And here is the code to display the marker at coordinates

-(void)placeMarkers
{
    GMSMarker *marker = [[GMSMarker alloc] init];

    marker.position = CLLocationCoordinate2DMake(47.995602, -78.902153);
    marker.title = @"PopUp HQ";
    marker.snippet = @"Durham, NC";
    marker.icon = [GMSMarker markerImageWithColor:[UIColor blueColor]];
    marker.opacity = 0.9;
    marker.map = self.mapView;
}

I have tried to get the current position as follows:

CLLocationCoordinate2D *myLocation = self.mapView.myLocation.coordinate;

but I get the error:

Initializing 'CLLocationCoordinate2D' with an expression of incompatible type 'CLLocationCoordinate2D'

How can I get the current location to pass to the camera as well as marker?

Answer

NigelG picture NigelG · May 22, 2014

CLLocationCoordinate2D is just a struct containing a latitude and longitude, so you can simply use

CLLocationCoordinate2D myLocation = self.mapView.myLocation.coordinate;

It is also worth using KVO to observe changes to myLocation, as it is possible that the mapView won't yet have a valid location.

To explain further about KVO:

You can add an observer for the myLocation property as follows:

[self.mapView addObserver:self
          forKeyPath:@"myLocation"
             options:(NSKeyValueObservingOptionNew |
                      NSKeyValueObservingOptionOld)
             context:NULL];

You should then implement the following method:

- (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary *)change
                   context:(void *)context {
    if ([keyPath isEqualToString:@"myLocation"]) {
//            NSLog(@"My position changed");
    }
}

You can then safely access self.mapView.myLocation.coordinate knowing that the location is valid.

Don't forget to remove yourself as an observer when the mapview is deallocated:

[self.mapView removeObserver:self forKeyPath:@"myLocation"];

As Saxon has already mentioned, the mapview will show it's own current position indicator. The marker that you are adding will be shown in addition, but it is likely that mapview doesn't yet having a valid position when you are creating the marker, so it is being added at latitude/longitude 0,0 which is in the middle of the ocean.