领域过滤器CLLocation

时间:2015-10-18 16:25:41

标签: ios swift realm cllocation

我有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}}

但根据过滤器的整体领域概念,它感觉不对。

2 个答案:

答案 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) 字段添加到您的对象,然后:

  1. 获取当前位置
  2. 围绕该位置创建一个边界框
  3. 通过边界框过滤对象
  4. 在代码中,可能会这样:

    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。

相关问题