Skip To Content

Displaying the location on a map

In this topic

Many iOS devices such as the iPod Touch, iPad, and iPhone provide information about the device's location. iOS includes a framework known as CoreLocation that abstracts how the location is retrieved, whether through Wi-Fi, cellular networks, or GPS. The framework also provides an API for developers to incorporate location capabilities into their applications and configure it based on their needs.

The map component, AGSMapView, shields developers from dealing with the complexity of the CoreLocation framework and provides an easy way to display and track the device's location on the map. The AGSLocationDisplay object associated with the map provides a facade over the CoreLocation framework making it easier to work with location services.

Start displaying the location

On older operating systems such as iOS 7 or earlier, displaying the device's location on the map is as simple as invoking the startDataSource method on the AGSLocationDisplay object after the map has finished loading.

-(void) mapViewDidLoad:(AGSMapView*)mapView {
 	[self.mapView.locationDisplay startDataSource];
}

Starting with iOS 8, apps must explicitly request authorization to access the device's location services. Two authorization modes are available - WhenInUse and Always depending on whether the app wants access to location only in the foreground, or both foreground and background respectively. By default, the map requests for WhenInUse authorization. You need to add the NSLocationWhenInUseUsageDescription key to your app's Info.plist file along with the text to be displayed to the user when asking for authorization.

By default, the map uses a blue, round symbol to display the device's location. The map always tries to get the most accurate location available. Depending on signal strength, satellite positions, and other factors, the reported location could be the best approximation. The map displays a blue circle around the location symbol to indicate the range of accuracy.

Default location symbol
Default symbol showing location

As the device moves, the map responds to location updates and appropriately updates the location symbol's position.

Location data sources

AGSLocationDisplay only manages the display of location information on a map. It does not proactively retrieve any location information. Instead, it relies on a location data source to provide location updates on a frequent basis. You can use any of the provided data sources, or you can plug in your custom data sources to feed location updates to the map. AGSLocationDisplay defaults to AGSCLLocationManagerLocationDisplayDataSource if nothing is provided.

AGSCLLocationManagerLocationDisplayDataSource

This data source uses the iOS CoreLocation framework to retrieve location updates through GPS, WiFi, or cellular networks. It attempts to retrieve the most accurate information, as frequently as possible.

AGSSimulatedLocationDisplayDataSource

This data source allows you to simulate location updates based on any polyline geometry. Each vertex in the polyline is used to fire a location update.

//The polyline geometry along which location updates should be simulated
AGSPolyline* route = ...;

//Create the data source. Assign the geometry.
AGSSimulatedLocationDisplayDataSource* simulatedDS = [[AGSSimulatedLocationDisplayDataSource alloc] init];
[simulatedDS setLocationsFromPolyline:route];

//Set data source 
self.mapView.locationDisplay.dataSource = simulatedDS;

AGSGPXLocationDataSource

This data source uses the first track or route in a GPX file to simulate location updates.

//Create the data source using a GPX file on the web
NSURL* url = [NSURL URLWithString:@"http://www.topografix.com/fells_loop.gpx"];
AGSGPXLocationDataSource* gpxDS = [[AGSGPXLocationDataSource alloc] initWithURL:url];

//Or, create the data source using a GPX file on the device
NSString* pathToGPXOnDevice = ...;
AGSGPXLocationDataSource* gpxDS = [[AGSGPXLocationDataSource alloc] initWithPath:pathToGPXOnDevice];

//Set data source 
self.mapView.locationDisplay.dataSource = gpxDS;

Autopan modes

The map provides a number of presets that define how the map behaves when location updates are received.

Off mode

In this mode, the map only updates the position of the location symbol on the map. It does not re-center. Therefore, it is possible that the location symbol may move off the screen in response to location updates.

Default mode

In this mode, the map attempts to keep the location symbol on-screen by re-centering the location symbol when the symbol moves outside a "wander extent." Therefore, the location symbol may move freely within the wander extent, but as soon as the symbol exits the wander extent, the map re-centers the symbol.

By default, the wander extent is half the size of the map's viewable extent, but you can customize the wander extent by modifying the wanderExtentFactor on AGSLocationDisplay. A value of 1 implies a wander extent equal to the size of the map's viewable extent, and the location symbol may move up to the edge of the map before the map re-centers. A value of 0 implies an infinitesimal wander extent, and the map re-centers on every location update.

self.mapView.locationDisplay.autoPanMode = AGSLocationDisplayAutoPanModeDefault ;
self.mapView.locationDisplay.wanderExtentFactor = 0.75; //75% of the map's viewable extent

If a user pans the map in this mode, the mode automatically changes its Autopan mode to Off, preventing the user from having to "fight" with the map that may otherwise try to re-center based on future location updates.

Navigation mode

This mode is best for in-vehicle navigation. In this mode, the location symbol is pinned to a point on the screen, and always points towards the top edge of the device. The map pans and rotates based on location updates, and the direction the device is travelling in. Therefore, the location symbol appears stationary, while the map underneath it appears to be moving and rotating.

The position of the location symbol can be adjusted by modifying the navigatonPointHeightFactor property on AGSLocationDisplay. A value of 0 implies the location symbol should be positioned at the bottom edge of the map, and 1 implies the top edge. A value between 0 and 1 positions the symbol somewhere along the center line from the bottom edge to the top edge.

self.mapView.locationDisplay.autoPanMode = AGSLocationDisplayAutoPanModeNavigation ;
self.mapView.locationDisplay.navigationPointHeightFactor  = 0.25; //25% along the center line from the bottom edge to the top edge

If a user pans the map in this mode, the mode automatically changes to Off.

Compass Navigation mode

This mode is better when the user is walking. As in Navigation mode, the location symbol is pinned to a point on the screen, and always points towards the top edge of the device. However, the map rotates based on the user's bearing relative to the magnetic north, and not based on the direction the device travels in, which is the case in Navigation mode. Therefore, the map reflects what lies ahead of the user as the user pivots around their location.

The location symbol position can be adjusted by modifying navigatonPointHeightFactor. A value of 0 implies the location symbol should be positioned at the bottom edge of the map, and 1 implies the top edge. A value between 0 and 1 positions the symbol somewhere between the bottom and top edges.

self.mapView.locationDisplay.autoPanMode = AGSLocationDisplayAutoPanModeCompassNavigation ;
self.mapView.locationDisplay.navigationPointHeightFactor  = 0.5; //50% along the center line from the bottom edge to the top edge

If a user pans the map in this mode, the mode automatically changes to Off.

Note:

If your application allows the device interface orientation to change, pass the new orientation to the AGSLocationDisplay object so that it can appropriately reposition the location symbol.

Stop displaying the location

To stop displaying the device's location, invoke the stopDataSourcemethod.

[self.mapView.locationDisplay stopDataSource];

Customizing the location symbol

The SDK provides three default images that are used for the location symbol. These images, LocationDisplay.png", LocationDisplayCourse.png, and LocationDisplayHeading.png, are included in ArcGIS.bundle.

Without heading
LocationDisplay.png symbol showing location only
With heading
LocationDisplayCourse.png symbol showing location and course (direction of travel)
With bearing
LocationDisplayHeading.png symbol showing location and heading (compass bearing)

Depending on the Autopan mode in use, and the type of information provided by the location updates, one of the default images will be used for the location symbol.

In the Off, Default, and Navigation modes, the LocationDisplay.png image is used only when location information is available. LocationDisplayCourse.png is used if both location and course (direction of travel) information are available. In the Off and Default modes, the LocationDisplayCourse.png image is appropriately rotated by an amount specified by the course to display the direction in which the device is travelling; however, in Navigation mode, the map rotates instead.

Note:

Course information is only available when the device is moving at some non-trivial velocity. This is why the map typically only displays the LocationDisplayCourse.png symbol when the device is travelling in a vehicle.

In the Compass Navigation mode, the LocationDisplayHeading.png image is used to display the device's location and bearing.

You can change the location symbol by providing your own PNG images. Your images must have the same name as the default images and be part of your Xcode project. The images in your Xcode project are given precedence over the default ones provided in ArcGIS.bundle. Where possible, it is recommended that you also include high resolution versions of your images for devices with retina display. Name the high resolution versions LocationDisplay@2x.png, LocationDisplayCourse@2x.png, and LocationDisplayHeading@2x.png.

Location symbol images
Images for location symbol
Note:

Image names are case sensitve.

Displaying location information in the callout

You can use the AGSCallout object to display the location information on the map. To display a callout, you need to set one of your classes as the callout's deletage. You do this by making your class (typically a view controller) adopt the <AGSCalloutDelegate> protocol.

@interface ViewController : UIViewController <AGSCalloutDelegate>
...
}

Next you must set the callout's delegate.

self.mapView.callout.delegate = self;

Finally, you implement the callout:willshowForLocationDisplay: method defined in the protocol. In the example below, we set the callout's title and details.

-(BOOL)callout:(AGSCallout *)callout willShowForLocationDisplay:(AGSLocationDisplay *)locationDisplay {
    
    callout.title = @"<title text>";
    callout.detail = @"<detail text>";

    return YES;
}
The method implementation returns YES at the end. This instructs the map to display the callout. If you want to temporarily disable the callout you can set the allowCallout property on the AGSMapView to NO.

Accessing location information

AGSLocationDisplay provides the device's location in two ways.

The location property contains the information provided by the underlying data source. The location coordinates will be in a spatial reference chosen by the data source. For example, if the data source is of type AGSCLLocationManagerLocationDisplayDatasource, the coordinates will be in WGS84.

The mapLocation method provides the same location information; however, the coordinates are projected into the map's spatial reference.

Listening for location updates

The location property on AGSLocationDisplay is Key-Value Observing (KVO) compliant. You can attach an observer to this property to be notified of location updates.

- (void)registerAsObserver {
  [ self.mapView.locationDisplay addObserver:self
                      forKeyPath:@"location"
                         options:(NSKeyValueObservingOptionNew)
                         context:NULL];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
  if ([keyPath isEqual:@"location"]) {
   NSLog(@"Location updated to %@", [self.mapView.locationDisplay mapLocation]);
  }
}

For more information on KVO, refer to Apple's Key-Value Observing Programming Guide.

See Also