How to load a KML file URL into Google Maps using iOS API?

I’ve got Google Map embedded in a View Controller in a Map on an iPhone. I can create my map using:

GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:39.93
                                                        longitude:-75.17
                                                             zoom:12];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];

// use GPS to determine location of self
mapView_.myLocationEnabled = YES;
mapView_.settings.myLocationButton = YES;
mapView_.settings.compassButton = YES;

Now, I want to add a kml file (from a URL) that displays a route. I would imagine there is something within GMSMapView to allow this either as a layer or something else, but I’m not having any luck. I’ve seen the KMS Tutorial but that uses some other kit, MK something. Anyway, is there a way I can load a KML file using the Google Maps for iOS API?

  • KMLViewer Apple's example not working
  • 3 Solutions Collect From Internet About “How to load a KML file URL into Google Maps using iOS API?”

    I know this question is more than 1 year old but I couldn’t find any solution, so I hope my solution will be useful.

    You can load KML into GMSMapView using iOS-KML-Framework. I’ve ported this code from a project that was using KML-Viewer

    Add method for parsing KML from the given URL, make sure you pass correct app bundle to dispatch_queue_create():

    - (void)loadKMLAtURL:(NSURL *)url
    {
        dispatch_queue_t loadKmlQueue = dispatch_queue_create("com.example.app.kmlqueue", NULL);
    
        dispatch_async(loadKmlQueue, ^{
            KMLRoot *newKml = [KMLParser parseKMLAtURL:url];
    
            [self performSelectorOnMainThread:@selector(kmlLoaded:) withObject:newKml waitUntilDone:YES];
        });
    }
    

    Handle the KML parsing result or error:

    - (void)kmlLoaded:(id)sender {
        self.navigationController.view.userInteractionEnabled = NO;
    
        __kml = sender;
    
        // remove KML format error observer
        [[NSNotificationCenter defaultCenter] removeObserver:self name:kKMLInvalidKMLFormatNotification object:nil];
    
        if (__kml) {
            __geometries = __kml.geometries;
    
            dispatch_async(dispatch_get_main_queue(), ^{
                self.navigationController.view.userInteractionEnabled = YES;
    
                [self reloadMapView];
            });
        } else {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.navigationController.view.userInteractionEnabled = YES;
    
                UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil)
                                                                    message:NSLocalizedString(@"Failed to read the KML file", nil)
                                                                   delegate:nil
                                                          cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                                          otherButtonTitles:nil];
                [alertView show];
            });
        }
    }
    

    Go over the geometry items from KML and add them to the GMSMapView as markers:

    - (void)reloadMapView
    {
        NSMutableArray *annotations = [NSMutableArray array];
    
        for (KMLAbstractGeometry *geometry in __geometries) {
            MKShape *mkShape = [geometry mapkitShape];
            if (mkShape) {
                if ([mkShape isKindOfClass:[MKPointAnnotation class]]) {
                    MKPointAnnotation *annotation = (MKPointAnnotation*)mkShape;
    
                    GMSMarker *marker = [[GMSMarker alloc] init];
                    marker.position = annotation.coordinate;
                    marker.appearAnimation = kGMSMarkerAnimationPop;
                    marker.icon = [UIImage imageNamed:@"marker"];
                    marker.title = annotation.title;
                    marker.userData = [NSString stringWithFormat:@"%@", geometry.placemark.descriptionValue];
                    marker.map = self.mapView;
    
                    [annotations addObject:annotation];
                }
            }
        }
    
        // set bounds in next run loop.
        dispatch_async(dispatch_get_main_queue(), ^{
    
            GMSCoordinateBounds *bounds = [[GMSCoordinateBounds alloc] init];
    
            for (id <MKAnnotation> annotation in annotations)
            {
                bounds = [bounds includingCoordinate:annotation.coordinate];
            }
    
            GMSCameraUpdate *update = [GMSCameraUpdate fitBounds:bounds];
            [self.mapView moveCamera:update];
            [self.mapView animateToViewingAngle:50];
        });
    
    }
    

    At the end of the last method we’re updating the camera view to fit all the markers that were added to the map. You can remove this part if it’s not needed.

    KML is not yet supported in the SDK. Please file a feature request in the issue tracker.

    This is how I solved similar problem using mentioned iOS-KML-Framework.

    #import <GoogleMaps/GoogleMaps.h>
    #import "KML.h"
    
    @property (weak, nonatomic) IBOutlet GMSMapView *mapView;
    
    - (void)loadZonesFromURL:(NSURL *)url {
    
    KMLRoot* kml = [KMLParser parseKMLAtURL: url];
    
    for (KMLPlacemark *placemark in kml.placemarks) {
        GMSMutablePath *rect = [GMSMutablePath path];
    
        if ([placemark.geometry isKindOfClass:[KMLPolygon class]]) {
            KMLLinearRing *ring = [(KMLPolygon *)placemark.geometry outerBoundaryIs];
    
            for (KMLCoordinate *coordinate in ring.coordinates) {
                [rect addCoordinate:CLLocationCoordinate2DMake(coordinate.latitude, coordinate.longitude)];
            }
    
            GMSPolygon *polygon = [GMSPolygon polygonWithPath:rect];
            polygon.fillColor = [UIColor colorWithRed:67.0/255.0 green:172.0/255.0 blue:52.0/255.0 alpha:0.3];
            polygon.map = self.mapView;
    
        }
    
    }
    
    
    }