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