Episode #67

# Map Overlays

14 minutes
Published on May 16, 2013

## This video is only available to subscribers.Get access to this video and 541 others.

In this episode we take the shape file data we parsed in episode 66 and use it to draw outlines around US States. We do this using the MKPolygon overlay in combination with MKPolygonView, which allows us to fill & stroke the provided vertices.

## Parse the points into a list of states

We first want to keep an array to hold the states we've parsed:

``````@property (nonatomic, strong) NSMutableArray *states;
``````

We initialize this right before processing the shapes:

``````self.states = [NSMutableArray arrayWithCapacity:numEntities];
``````

We can pass each shape off to our `WARState` class, which will just be a container for a collection of polygons. It's easy to think that each state is 1 connected polygon, but a few states have islands that are not connected.

``````for (int i=0; i&lt;numEntities; i++) {
WARState *state = [[WARState alloc] initWithShapeObject:shpObject];
}
``````

## Converting the shapes into map overlays

Next, we need to loop over each states polygons, creating a `CLLocationCoordinate2D` array of points. Since we captured ours in an `NSArray`, they are all boxed as `NSValue` objects. We'll need to unbox them here.

``````  for (WARState *state in self.states) {
for (WARPolygon *polygon in state.polygons) {
int count = [polygon.coordinates count];
CLLocationCoordinate2D coords[count];

// convert each boxed value to a value on the stack, and add it to our array
for (int c=0; c&lt;count; c++) {
NSValue *coordValue = polygon.coordinates[c];
CLLocationCoordinate2D coord = [coordValue MKCoordinateValue];
coords[c] = coord;
}

// create the overlay
MKPolygon *polygon = [MKPolygon polygonWithCoordinates:coords count:count];
}
}
``````

Now our map has overlays, but we haven't done any rendering. Similar to `MKAnnotation`, `MKOverlay` only provides the requisite data to describe the overlay. Rendering is handled by a companion view. To provide this view, we need to conform to the `MKMapViewDelegate` protocol and implement the `mapView:viewForOverlay:` method.

## Providing the overlay view

``````-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay {
if ([overlay isKindOfClass:[MKPolygon class]]) {
MKPolygonView *view = [[MKPolygonView alloc] initWithPolygon:overlay];
view.strokeColor = [UIColor blueColor];
view.lineWidth = 2;
view.lineCap = kCGLineCapRound;
view.fillColor = [[UIColor redColor] colorWithAlphaComponent:0.4];
return view;
} else {
return nil;
}
}
``````

Now you can build and run the application to see the polygons overlaid on top of the map.