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 есть какой-то механизм индексации, который оптимизирует поиск.
Вы можете посмотреть этот документ
Проверьте раздел с именем
Получение определенных объектов