Navigating the map

The Map View includes options for defining and changing the map extent as well as the user experience when the extent is modified. It is important to note that the basmap layer (the first layer added to the map) will define the follow properties for the map:

While initial extent can be modified, the spatial reference cannot be changed explicitly. This document will discuss both developer and end-user solutions for working with map extent.

Setting the map extent

To set the map extent, use the zoomToEnvelope:animated: method on the map view by passing in an evelope geometry representing the area you want to zoom to.

-(void)viewDidLoad{
  [super viewDidLoad];

 //add a layer to the map
 AGSTiledMapServiceLayer*tiledLayer=[AGSTiledMapServiceLayer tiledMapServiceLayerWithURL:[NSURLURLWithString:@"http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer"]];
[self.mapViewaddMapLayer:tiledLayerwithName:@"Tiled Layer"];

  //zoom to an area
 AGSEnvelope *envelope = [AGSEnvelope envelopeWithXmin:-124.83145667 ymin:30.49849464 xmax:-113.91375495  ymax:44.69150688  spatialReference:mapView.spatialReference];
 [self.mapView zoomToEnvelope:envelope animated:NO];
}
Alternatively, you can also zoom to an arbitrary geometry on the map (such as the shape of a country or a river) using the zoomToGeometry:withPadding:animated: method.
NoteNote:

The envelope or geometry you use to zoom the map must have the same spatial reference as that of the map.

Getting the map extent

You may not know the extent of the map until the map has been loaded. You can use the visibleArea property of the map view to get the extent of the map.

AGSPolygon* mapExtent = self.mapView.visibleArea;

The visibleArea property returns a polygon which contains a vertex for each of the four corners of the map, starting with the top-left corner, progressing in a clockwise direction.

If the map does not contain any rotation, the area represented by the visibleArea polygon will coincide exactly with the polygon's enclosing envelope. Thus you could use the visibleArea polygon or its envelope as the map extent.

However, if the map has been rotated, the visibleArea polygon and the polygon's envelope will be different. The envelope will represent an area that is slightly bigger than the polygon such that it entirely contains the polygon. In such a case, you should use the visibleArea polygon to get the map extent.

Tracking panning and zooming

The map view provides two notifications for extent changes, MapDidEndPanning and MapDidEndZooming. These notifications are broadcast after the map has been panned or zoomed, respectively. The following code is an example of how to listen for notifications when the user pans or zooms the map. It displays an alert showing the new map extent retrieved from the envelope property of the map view:

- (void)mapViewDidLoad:(AGSMapView *)mapView  {

  // register for "MapDidEndPanning" notifications
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToEnvChange:)
    name:@"MapDidEndPanning" object:nil];

  // register for "MapDidEndZooming" notifications
  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(respondToEnvChange:) 
    name:@"MapDidEndZooming" object:nil];

  ...
}

// The method that should be called when the notification arises
- (void)respondToEnvChange: (NSNotification*) notification {

  //create the string containing the new map extent NSString*
  NSString* theString = [[NSString alloc] initWithFormat:@"xmin = %f,\nymin =
    %f,\nxmax = %f,\nymax = %f", mapView.envelope.xmin,
    mapView.envelope.ymin, mapView.envelope.xmax,
    mapView.envelope.ymax];

  //display the new map extent in a simple alert
  UIAlertView* alertView = [[UIAlertView alloc]	initWithTitle:@"mapViewDidEndPanning" 
    message:theString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
  [alertView show];
  [alertView release];
  [theString release];

}

You should note that these notifications are broadcast when the processor is idle, thus there might be a slight delay between when the user finished performing the action and when the notification was raised. Also, notificatons are delievered on the main thread. You should not block this thread by pefroming expensive tasks otherwise your application will appear sluggish to the user.

Changing the map extent

As mentioned previously, you can use the zoomToEnvelope:animated: method on a map view to set a map view's extent. You can also center the map at a given point using the map view's centerAtPoint:animated: method:

AGSPoint *newPoint = [AGSPoint pointWithX:-93.032201 y:49.636213 spatialReference:self.mapView.spatialReference];
[self.mapView centerAtPoint:newPoint animated:NO];

User gestures

The user can perform several gestures which change the map view's extent at run-time. All of these will trigger either the MapDidEndPanning and MapDidEndZooming notifications.

User Action

Map Action

Notification raised

Pinch-In

Zoom out on map

MapDidEndZooming

Pinch-Out

Zoom in on map

MapDidEndZooming

Double Tap

Zoom in on map

MapDidEndZooming

Two finger Tap

Zoom out on map

MapDidEndZooming

Swipe (any direction)

Pan map in direction of swipe

MapDidEndPanning

Two finger Twist*

Rotate the map

NoteNote:

You must enable the allowRotationByPinching property on AGSMapView to enable the Two finger Twist gesture.

9/21/2012