Search code examples
iosmkmapviewmapkitgeojson

Draw GeoJson in Apple Maps as overlay


Can someone tell me how can I draw a GeoJson file as an overlay in apple maps? I want a complete example, I have the shapes as Polygons or MultiPolygons?

This file Countries GeoJSON is enough for me if you provided me with a code or a library to use to render it using MKMapView


Solution

  • I've found a solution in case someone wants help too.

    @interface HHLViewController
    
    + (NSArray *)countriesOverlays;
    
    @end
    
    @implementation HHLViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        NSArray *overlays = [HHLViewController countriesOverlays];
        [self.stateMapView addOverlays:overlays];
    }
    
    + (NSArray *)countriesOverlays {
        NSString *fileName = [[NSBundle mainBundle] pathForResource:@"countries" ofType:@"json"];
        NSData *overlayData = [NSData dataWithContentsOfFile:fileName];
    
        NSArray *countries = [[NSJSONSerialization JSONObjectWithData:overlayData options:NSJSONReadingAllowFragments error:nil] objectForKey:@"features"];
    
        NSMutableArray *overlays = [NSMutableArray array];
    
        for (NSDictionary *country in countries) {
    
            NSDictionary *geometry = country[@"geometry"];
            if ([geometry[@"type"] isEqualToString:@"Polygon"]) {
                MKPolygon *polygon = [HHLViewController overlaysFromPolygons:geometry[@"coordinates"] id:country[@"properties"][@"name"]];
                if (polygon) {
                    [overlays addObject:polygon];
                }
    
    
            } else if ([geometry[@"type"] isEqualToString:@"MultiPolygon"]){
                for (NSArray *polygonData in geometry[@"coordinates"]) {
                    MKPolygon *polygon = [HHLViewController overlaysFromPolygons:polygonData id:country[@"properties"][@"name"]];
                    if (polygon) {
                        [overlays addObject:polygon];
                    }
                }
            } else {
                NSLog(@"Unsupported type: %@", geometry[@"type"]);
            }
        }
    
        return overlays;
    
    }
    
    + (MKPolygon *)overlaysFromPolygons:(NSArray *)polygons id:(NSString *)title
    {
        NSMutableArray *interiorPolygons = [NSMutableArray arrayWithCapacity:[polygons count] - 1];
        for (int i = 1; i < [polygons count]; i++) {
            [interiorPolygons addObject:[HHLViewController polygonFromPoints:polygons[i] interiorPolygons:nil]];
        }
    
        MKPolygon *overlayPolygon = [HHLViewController polygonFromPoints:polygons[0] interiorPolygons:interiorPolygons];
        overlayPolygon.title = title;
    
    
        return overlayPolygon;
    }
    
    + (MKPolygon *)polygonFromPoints:(NSArray *)points interiorPolygons:(NSArray *)polygons
    {
        NSInteger numberOfCoordinates = [points count];
        CLLocationCoordinate2D *polygonPoints = malloc(numberOfCoordinates * sizeof(CLLocationCoordinate2D));
    
        NSInteger index = 0;
        for (NSArray *pointArray in points) {
            polygonPoints[index] = CLLocationCoordinate2DMake([pointArray[1] floatValue], [pointArray[0] floatValue]);
            index++;
        }
    
        MKPolygon *polygon;
    
        if (polygons) {
            polygon = [MKPolygon polygonWithCoordinates:polygonPoints count:numberOfCoordinates interiorPolygons:polygons];
        } else {
            polygon = [MKPolygon polygonWithCoordinates:polygonPoints count:numberOfCoordinates];
        }
        free(polygonPoints);
    
        return polygon;
    }
    @end