在iOS中将geojson图层添加到谷歌地图

时间:2016-02-03 02:23:22

标签: ios swift google-maps geojson

我正在编写我的第一个iOS原生应用。我正在尝试将GeoJSON图层加载到应用程序中的谷歌地图上(地图来自谷歌地图sdk),但我无法找到任何方法。我精通google地图javascript API,但我在Swift中感知事物却非常不同。

如何在原生iOS应用中将GeoJSON图层加载到地图上?

2 个答案:

答案 0 :(得分:1)

截至今天,我还没有看到任何api可以将geojson解析为ios上的谷歌地图形状。因此,您必须自己解析它,将其解析为数组,然后循环遍历数组获取每个要素,获取每个几何,属性,并根据要素类型(点,线,多边形)创建形状

以下是从mapbox绘制线条的示例,您必须将其扩展为点和多边形。

// Perform GeoJSON parsing on a background thread
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^(void)
{
    // Get the path for example.geojson in the app's bundle
    NSString *jsonPath = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"geojson"];

    // Load and serialize the GeoJSON into a dictionary filled with properly-typed objects
    NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:[[NSData alloc] initWithContentsOfFile:jsonPath] options:0 error:nil];

    // Load the `features` dictionary for iteration
    for (NSDictionary *feature in jsonDict[@"features"])
    {
        // Our GeoJSON only has one feature: a line string
        if ([feature[@"geometry"][@"type"] isEqualToString:@"LineString"])
        {
            // Get the raw array of coordinates for our line
            NSArray *rawCoordinates = feature[@"geometry"][@"coordinates"];
            NSUInteger coordinatesCount = rawCoordinates.count;

            // Create a coordinates array, sized to fit all of the coordinates in the line.
            // This array will hold the properly formatted coordinates for our MGLPolyline.
            CLLocationCoordinate2D coordinates[coordinatesCount];

            // Iterate over `rawCoordinates` once for each coordinate on the line
            for (NSUInteger index = 0; index < coordinatesCount; index++)
            {
                // Get the individual coordinate for this index
                NSArray *point = [rawCoordinates objectAtIndex:index];

                // GeoJSON is "longitude, latitude" order, but we need the opposite
                CLLocationDegrees lat = [[point objectAtIndex:1] doubleValue];
                CLLocationDegrees lng = [[point objectAtIndex:0] doubleValue];
                CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(lat, lng);

                // Add this formatted coordinate to the final coordinates array at the same index
                coordinates[index] = coordinate;
            }

            // Create our polyline with the formatted coordinates array
            MGLPolyline *polyline = [MGLPolyline polylineWithCoordinates:coordinates count:coordinatesCount];

            // Optionally set the title of the polyline, which can be used for:
            //  - Callout view
            //  - Object identification
            // In this case, set it to the name included in the GeoJSON
            polyline.title = feature[@"properties"][@"name"]; // "Crema to Council Crest"

            // Add the polyline to the map, back on the main thread
            // Use weak reference to self to prevent retain cycle
            __weak typeof(self) weakSelf = self;
            dispatch_async(dispatch_get_main_queue(), ^(void)
            {
                [weakSelf.mapView addAnnotation:polyline];
            });
        }
    }

});

这里是行的快速代码,你必须将它扩展到点和多边形

 // Parsing GeoJSON can be CPU intensive, do it on a background thread
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
        // Get the path for example.geojson in the app's bundle
        let jsonPath = NSBundle.mainBundle().pathForResource("example", ofType: "geojson")
        let jsonData = NSData(contentsOfFile: jsonPath!)

        do {
            // Load and serialize the GeoJSON into a dictionary filled with properly-typed objects
            if let jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData!, options: []) as? NSDictionary {

                // Load the `features` array for iteration
                if let features = jsonDict["features"] as? NSArray {
                    for feature in features {
                        if let feature = feature as? NSDictionary {
                            if let geometry = feature["geometry"] as? NSDictionary {
                                if geometry["type"] as? String == "LineString" {
                                    // Create an array to hold the formatted coordinates for our line
                                    var coordinates: [CLLocationCoordinate2D] = []

                                    if let locations = geometry["coordinates"] as? NSArray {
                                        // Iterate over line coordinates, stored in GeoJSON as many lng, lat arrays
                                        for location in locations {
                                            // Make a CLLocationCoordinate2D with the lat, lng
                                            let coordinate = CLLocationCoordinate2DMake(location[1].doubleValue, location[0].doubleValue)

                                            // Add coordinate to coordinates array
                                            coordinates.append(coordinate)
                                        }
                                    }

                                    let line = MGLPolyline(coordinates: &coordinates, count: UInt(coordinates.count))

                                    // Optionally set the title of the polyline, which can be used for:
                                    //  - Callout view
                                    //  - Object identification
                                    line.title = "Crema to Council Crest"

                                    // Add the annotation on the main thread
                                    dispatch_async(dispatch_get_main_queue(), {
                                        // Unowned reference to self to prevent retain cycle
                                        [unowned self] in
                                        self.mapView.addAnnotation(line)
                                    })
                                }
                            }
                        }
                    }
                }
            }
        }
        catch
        {
            print("GeoJSON parsing failed")
        }
    })

答案 1 :(得分:1)

首先将geoJSON文件添加到项目中。如果你设置谷歌地图,你可以使用以下内容:

let path = Bundle.main.path(forResource: "GeoJSON_sample", ofType: "json")
let url = URL(fileURLWithPath: path!)
geoJsonParser = GMUGeoJSONParser(url: url)
geoJsonParser.parse()

let renderer = GMUGeometryRenderer(map: mapView, geometries: geoJsonParser.features)
renderer.render()