CoreData + Magical Record выполняет запрос выбора

У меня есть приложение с базой данных sqlite, которая содержит более 7000 записей с названиями городов, долготами и широтами. Кроме того, эти "города" также связаны с соответствующими полями городов в базе данных.

То, что делает мое приложение, запрашивает текущее местоположение с помощью основного местоположения, извлекает значения lon и lat, а затем находит самое близкое местоположение из базы данных.

Результат не обязательно должен быть очень точным (я просто хочу сопоставить города), поэтому я хочу использовать формулу Гипотенузы для нахождения ближайшей точки:

closest city in db: min((x1-x2)^2 +(y1-y2)^2)^(1/2)

x1, y1: lon and lat for user
x2, y2: lon and lat for points in database. 

Если бы я использовал базу данных ms-sql или sqlite, я мог бы легко создать запрос, но когда дело доходит до основных данных, у меня нет идей.

Я не хочу получать все данные (и заполнять память), а затем агрегировать эту формулу по всем полям, так есть ли способ создать запрос и получить результат из БД?

Я переосмысливаю эту проблему и упускаю простое решение?

3 ответа

Решение

Если я правильно понимаю вашу проблему, вы хотите найти ближайшие "n" города к вашему текущему местоположению.

У меня было что-то подобное, и вот как я подошел к этому.

По сути, вам, вероятно, нужно взять широту / долготу каждого города и хешировать ее в некоторый индекс. Мы используем проекцию Меркатора, чтобы преобразовать широту / долготу в x/y, а затем хэшируем это значение способом, аналогичным тому, как Google/Bing/Apple Maps хешируют свои фрагменты карты. К счастью, MapKit имеет встроенную функцию проекции Меркатора.

В псевдокоде:

for each city's lat/lon {
    CLLocationCoordinate2D coordinate = (CLLocationCoordinate2D){lat, lon};
    MKMapPoint point = MKMapPointForCoordinate(coordinate);
    //256 represents the size of a map tile at zoomLevel 20.  You can use whatever zoomLevel 
    //you want here, but we need something to quickly lookup close-by cities.
    //this is the formula you can use to determine how granular your index is
    //(256 * pow(2, (20 - zoomLevel)))
    NSInteger x = point.x/256.0;
    NSInteger y = point.y/256.0;
    save x & y in a CityHashIndex table
}

Теперь вы получаете широту текущего местоположения, хешируете ее в индекс, как указано выше, и просто пишете запрос к этой таблице CityHashIndex.

Скажем так, для простоты ваше текущее местоположение проиндексировано на 1000, 1000, Поэтому, чтобы найти близкие по городам, возможно, вы ищете города с индексами в диапазоне `900-1100, 900-1100'.

Оттуда вы теперь тянете только гораздо меньший набор городов, и требования к памяти для обработки вашей формулы гипотенузы не так уж и плохи.

Я могу рассказать подробнее, если вам интересно.

Это напрямую связано с часто задаваемым вопросом о базовых данных.

Поиск окружающих пригородов на основе широты и долготы с использованием цели C

Вычислите ограничивающий прямоугольник вокруг нужной вам точки (мин. Широта / длинна, макс. Широта / длина), затем используйте NSP-предикат для этих значений, чтобы найти все, что находится внутри рамки. Оттуда вы можете сделать расчет расстояния по результатам, которые возвращают и сортируют их.

Я бы предложил настроить его так, чтобы он мог выполнять поиск на нескольких расстояниях, чтобы вы могли видеть, находится ли город в пределах 10 миль, 100 миль и т. Д. Медленно увеличивая ограничивающую рамку, пока не получите один или несколько результатов назад.

Я бы использовал NSPredicate для определения моих критериев поиска, он будет действовать как фильтр. Я не уверен, насколько это оптимизировано, и потянет ли оно все ваши регистры, но я предполагаю, что в coreData есть какой-то механизм индексации, который оптимизирует поиск.

Вы можете посмотреть этот документ

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html

Проверьте раздел с именем

Получение определенных объектов

Другие вопросы по тегам