Фильтр основных данных по расстоянию от текущего местоположения пользователя - PullRequest
1 голос
/ 29 апреля 2020

У меня есть класс NSManagedObject, который сохраняется в базе данных SQLite в Core Data. Этот объект имеет постоянные свойства широты и долготы. Я пытаюсь создать NSFetchedRequestController, который выбирает все экземпляры этого класса, которые находятся на определенном расстоянии от пользователя. Проведя некоторые исследования, кажется невозможным сделать это с Core Data, потому что Core Data поддерживает только запросы в стиле ограничивающего прямоугольника, а не предикаты с блоками.

Например, у меня есть класс групп с широтой и долготой свойства. Учитывая широту и долготу (скажем, пользователя), выберите все группы, которые находятся в радиусе 6 миль от заданной широты и долготы.

class Group{
     var latitude: Float
     var longitude: Float
}

Я хотел бы воспользоваться преимуществами Core Data Индексирование R-Tree для быстрого запроса ограничивающего прямоугольника широты и долготы экземпляров моего класса рядом с моим пользователем. Затем я хотел бы отфильтровать результаты с более точным предикатом, используя мой собственный блок кода, чтобы увидеть, какие из экземпляров находятся в текущем местоположении моих пользователей. Вот запрос «Ограничивающий прямоугольник».

let request: NSFetchRequest<Group> = Group.fetchRequest()
let (topLeft,bottomRight) = boundingBox(center: center, radius: searchRadius)
let maxLat = topLeft.latitude
let minLon = topLeft.longitude
let minLat = bottomRight.latitude
let maxLon = bottomRight.longitude
let predicate = NSPredicate(format: "(%f < longitude AND longitude < %f) AND (%f < latitude AND latitude < %f)", minLon, maxLon, minLat, maxLat)
request.predicate = predicate

Проблема в том, что я хотел бы получить выборку, которая выглядела бы так:

let location: CLLocation = /* Initialize a CLLocation */

let predicate = NSPredicate { (obj, _) -> Bool in
     let object = obj as! Group
     let objLocation = CLLocation(latitude: Double(object.latitude), longitude: Double(object.longitude))
     return location.distance(from: objLocation) < 9656 //6 miles in meters
}

Контроллер результатов NSFetched не позволяет предикат с блок. Между этими двумя выгодами есть существенная разница. Первая получает все группы в ограничивающем прямоугольнике (minLat, minLon, maxLat и maxLat), вторая получает все группы в круге данного радиуса.

Затем я хочу использовать NSFetchedRequestController для отображения результаты в виде таблицы, а также воспользоваться хорошими функциями автоматического обновления. Но, конечно, Core Data поддерживает только запросы в стиле ограничивающего прямоугольника, а не метод двухэтапного фильтра, который мне нужен. Есть ли правильное решение?

Я открыт для использования других баз данных, если Core Data просто не будет работать с этим типом использования. Я взглянул на YapDatabase, и он кажется более гибким и включает индексирование R-Tree, но я обеспокоен тем, что он не очень хорошо поддерживается. Realm не поддерживает индексирование R-Tree.

...