ios - 遍历 JSON 数组并将坐标添加到地图
问题描述
我正在使用API来获取纬度和经度坐标,并将它们放置在地图上,并使用它对应的地点的名称。我可以放置一个地方的经纬度坐标,但我不太确定如何将它们全部添加到地图中。我不知道该怎么做。我尝试使用 for 循环来做到这一点,但我太确定我将如何实现它。这是我到目前为止所得到的:
func getData() {
let url = "https://www.givefood.org.uk/api/2/foodbanks/"
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { [self] data, response, error in
guard let data = data, error == nil else {
print("Wrong")
return
}
var result: [Info]?
do {
result = try JSONDecoder().decode([Info].self, from: data)
}
catch {
print("Failed to convert: \(error.localizedDescription)")
}
guard let json = result else {
return
}
for each in json {
var each = 0
each += 1
let comp = json[each].lat_lng?.components(separatedBy: ",")
let latString = comp![each]
let lonString = comp![each]
let lat = Double(latString)
let lon = Double(lonString)
let locationPin: CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat!, lon!)
let location: CLLocationCoordinate2D = CLLocationCoordinate2DMake(51.55573, -0.108312)
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMetres, longitudinalMeters: regionInMetres)
mapView.setRegion(region, animated: true)
let myAn1 = MapPin(title: json[each].name!, locationName: json[each].name!, coordinate: locationPin)
mapView.addAnnotations([myAn1])
}
})
task.resume()
}
解决方案
您的循环是错误的,each
之后for
是一项Info
。Int
索引each
毫无意义,您在每次迭代中将其设置为零,因此您始终获得相同的坐标(在索引 1 处)。
首先声明name
和lat_lng
作为非可选的。所有记录都包含这两个字段。
struct Info : Decodable {
let lat_lng : String
let name : String
}
其次,为了方便起见,扩展CLLocationCoordinate2D
为从字符串创建坐标
extension CLLocationCoordinate2D {
init?(string: String) {
let comp = string.components(separatedBy: ",")
guard comp.count == 2, let lat = Double(comp[0]), let lon = Double(comp[1]) else { return nil }
self.init(latitude: lat, longitude: lon )
}
}
第三,将所有好的代码放入do
范围而不是处理选项,并在循环之前设置一次区域
func getData() {
let url = "https://www.givefood.org.uk/api/2/foodbanks/"
let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler: { [self] data, response, error in
if let error = error { print(error); return }
do {
let result = try JSONDecoder().decode([Info].self, from: data!)
let location = CLLocationCoordinate2D(latitude: 51.55573, longitude: -0.108312)
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMetres, longitudinalMeters: regionInMetres)
mapView.setRegion(region, animated: true)
var pins = [MapPin]()
for info in result {
if let coordinate = CLLocationCoordinate2D(string: info.lat_lng) {
pins.append(MapPin(title: info.name, locationName: info.name, coordinate: coordinate))
}
}
DispatchQueue.main.async {
self.mapView.addAnnotations(pins)
}
}
catch {
print("Failed to convert: \(error)")
}
})
task.resume()
}
推荐阅读
- integer-overflow - 左移计数 >= 类型的宽度 [-Wshift-count-overflow]
- angular - 允许直接访问路由中定义的 Angular 应用程序 url(浏览器导航)
- java - 在其他几条消息完成后发送消息而不使用外部存储?
- c++ - C++20 模块实现分区的 hpp/cpp 拆分
- ruby-on-rails - 我应该把 entrypoint.sh 文件 Rails App for Docker 放在哪里?
- node.js - 如何在 Sequelize 函数中添加 where 子句?
- c# - 使用 Google.Apis.Auth 会导致 .Net 项目中的唯一异常
- powershell - Azure AD - 无法设置类型为“Sign”的应用程序注册密钥凭据
- regex - 使用正则表达式在连接的 id 中搜索
- python - 将数据框转换为特定的 JSON