我有CLLoaction的warpper类
包装
Location
我必须根据当前位置过滤存储的let locations = realm.objects(Location)
var locationsInRadius = [Location]()
for l in locations {
let location = CLLocation(latitude: l.lat, longitude: l.long)
if (location.distanceFromLocation(currentLocation) < radius){
locationsInRadius.append(l)
}
}
以查找半径为1km的那些。我认为NSPredicate with block可以完成这项工作,但是领域并不支持它。所以我的问题是我可以通过其他方式实现它吗?
当然,我可以这样做:
{{1}}
但根据过滤器的整体领域概念,它感觉不对。
答案 0 :(得分:4)
您无法按距离搜索对象,但可以使用边界框进行搜索。只需将longitude
和 // 0. This example uses MapKit to calculate the bounding box
import MapKit
// 1. Plenty of answers for this one...
let currentLocation = CLLocationCoordinate2DMake(37.7749295, -122.4194155)
// 2. Create the bounding box with, 1km radius
let region = MKCoordinateRegionMakeWithDistance(currentLocation, 1000, 1000)
let northWestCorner = CLLocationCoordinate2DMake(
currentLocation.latitude + (region.span.latitudeDelta),
currentLocation.longitude - (region.span.longitudeDelta)
)
let southEastCorner = CLLocationCoordinate2DMake(
currentLocation.latitude - (region.span.latitudeDelta),
currentLocation.longitude + (region.span.longitudeDelta)
)
// 3. Filter your objects
let predicate = NSPredicate(format: "lat BETWEEN {%f, %f} AND lon BETWEEN {%f, %f}",
northWestCorner.latitude,
southEastCorner.latitude,
northWestCorner.longitude,
southEastCorner.longitude
)
let nearbyLocations = realm.objects(MyLocation).filter(predicate)
字段添加到您的对象,然后:
在代码中,可能会这样:
CLLocation
请注意,您仍然可以将{{1}}对象存储起来用于其他目的,但您无法进行搜索。
另请注意,由于这会搜索一个方框而不是您想要的方框,一个半径为1公里的圆,这可以返回大于1公里的结果。如果那不好,你需要减少半径或制作更高级的谓词。
答案 1 :(得分:2)
出于某种原因,使用单个谓词(lat BETWEEN {%f, %f} AND lon BETWEEN {%f, %f}
)不适用于当前版本的Realm。我正在使用这个好的库:https://github.com/mhergon/RealmGeoQueries
这就是谓词在内部构建的方式,它可以正常工作:https://github.com/mhergon/RealmGeoQueries/blob/master/GeoQueries.swift:
let topLeftPredicate = NSPredicate(format: "%K <= %f AND %K >= %f", latitudeKey, box.topLeft.latitude, longitudeKey, box.topLeft.longitude)
let bottomRightPredicate = NSPredicate(format: "%K >= %f AND %K <= %f", latitudeKey, box.bottomRight.latitude, longitudeKey, box.bottomRight.longitude)
let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [topLeftPredicate, bottomRightPredicate])
基本上,以下是如何使用它:
let results = try! Realm()
.findNearby(YourModelClass.self, origin: location.coordinate, radius: 500, sortAscending: nil)
您还可以通过使用自己的命名(latitudeKey和longitudeKey)传递2个额外参数来更改默认的“lat”和“lng”键。
感谢https://github.com/mhergon提供此lib。