我正在做一个非常简单的操作。我正在对地图中的一堆位置进行排序,以创建一个封闭的圆圈,如下所示:
var maxLong: Double = -180
var maxLat: Double = -180
var minLong: Double = 180
var minLat: Double = 180
for coord in inCoordinates {
maxLong = max(coord.longitude, maxLong)
maxLat = max(coord.latitude, maxLat)
minLong = min(coord.longitude, minLong)
minLat = min(coord.latitude, minLat)
}
let nw: CLLocation = CLLocation(latitude: maxLat, longitude: minLong)
let se: CLLocation = CLLocation(latitude: minLat, longitude: maxLong)
let center = CLLocationCoordinate2D(latitude: (maxLat + minLat) / 2.0, longitude: (maxLong + minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)
非常简单(是的,我知道IDL问题,但是我想保持简单)。
我想知道的是,是否有某种方法可以将循环构建为reduce的变体,最终您将得到如下结果:
let enclosingRect: MKMapRect = inCoordinates.magikalReduce {
// Magic Happens Here -Queue Doug Henning GIF
}
所以返回的rect包含蒸馏点。
是的,我知道我可以简单地扩展Array(可能带有类型限定符)以使用计算所得的属性来完成此操作,但是这样做有悖于此目的。上面的代码相当有效,我不想增加开销,只是为了花哨(这意味着,即使我可以做到,使用起来也可能效率太低)。
这更多是出于好奇的探索,而不是技术上的需求。上面的代码对我来说很好,并且相对简单。
答案 0 :(得分:2)
你是说
// calculate the enclosing rect with `reduce` and `union`, you have to create an `MKMapRect` from each coordinate
let enclosingRect = inCoordinates.reduce(MKMapRect.null) { $0.union(MKMapRect(origin: MKMapPoint($1), size: MKMapSize())) }
答案 1 :(得分:1)
您可以创建一个struct
来保存最小/最大经度和纬度值,然后使用reduce
,在其中使用这些值的初始值来创建初始结果,然后创建一个更新的版本struct
进行必要的min
/ max
计算。
struct MinMaxCoordinates {
let maxLong:Double
let maxLat:Double
let minLong:Double
let minLat:Double
}
let minMaxCoordinates = inCoordinates.reduce(MinMaxCoordinates(maxLong: -180, maxLat: -180, minLong: 180, minLat: 180), {minMax, coord in
return MinMaxCoordinates(maxLong: max(minMax.maxLong, coord.longitude), maxLat: max(minMax.maxLat, coord.latitude), minLong: min(minMax.minLong, coord.longitude), minLat: max(minMax.minLat, coord.latitude))
})
let nw: CLLocation = CLLocation(latitude: minMaxCoordinates.maxLat, longitude: minMaxCoordinates.minLong)
let se: CLLocation = CLLocation(latitude: minMaxCoordinates.minLat, longitude: minMaxCoordinates.maxLong)
let center = CLLocationCoordinate2D(latitude: (minMaxCoordinates.maxLat + minMaxCoordinates.minLat) / 2.0, longitude: (minMaxCoordinates.maxLong + minMaxCoordinates.minLong) / 2.0)
let radiusInMeters = abs(nw.distance(from: se)) / 2.0
return MKCircle(center: center, radius: radiusInMeters)