【问题标题】:Adding geojson layer to google map in iOS在iOS中将geojson图层添加到谷歌地图
【发布时间】:2016-02-03 02:23:21
【问题描述】:

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

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

【问题讨论】:

  • 您可能想查看Providing Directions。我认为这将是一个开始在 iOS 中使用 geoJSON 的好地方。
  • 你有geojson文件吗?
  • 你找到解决办法了吗?

标签: ios swift google-maps geojson


【解决方案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()

【讨论】:

【解决方案2】:

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

这里是 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];
            });
        }
    }

});

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

 // 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")
        }
    })

【讨论】:

  • 它使用 MapBox 而不是 Google Map api?
  • 由于未捕获的异常“NSInvalidArgumentException”,我正在作为终止应用程序崩溃,原因:“多点必须至少有一个顶点。”位置循环内的位置 {
  • 你能指导我怎么过去吗?
猜你喜欢
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 2020-10-21
  • 2014-05-25
  • 2016-11-24
  • 1970-01-01
  • 2018-12-08
相关资源
最近更新 更多