Mapkit. Получение близлежащих мест с сервера и, возможно, их кеширование (например, для использования в автономном режиме)

Я разрабатываю приложение для iOS 5, которое хочу передать на сервер, предоставляя информацию о близлежащих местах для данного местоположения: местоположения мест и аннотации. Я хочу использовать MapKit для заполнения моей карты этой информацией.

Я не нашел прямой информации по следующим вопросам:

  1. Имеется ли в MapKit функция тайлов (способ Google Maps) из коробки, и нужно ли мне дополнительно работать над ней, если нет?
  2. Как лучше всего получать информацию о местах (положение маркеров и аннотации) с сервера?
  3. Можно ли кэшировать эту информацию, чтобы пользователь мог видеть близлежащие места «своего города» в автономном режиме?

На самом деле вопросы 2 и 3 взаимосвязаны: оба они решают проблему невыполнения поиска информации (местоположения + аннотации), которая уже присутствует на карте несколько раз.

Надеюсь, я не упускаю из виду что-то очевидное.

Спасибо!

Обновление 1: (Что касается мест, а не карт). В частности, меня интересует, как мне создавать "вручную созданные" логические плитки для регионов, содержащих места, которые я получаю с сервера, чтобы они не требовали повторной загрузки при прокрутке пользователем карта? Я знаю, что могу сам заняться реализацией этой функции. Например, следует ли мне записывать места, только что загруженные в локальное хранилище, с помощью Core Data сразу после их получения или организовать некоторую очередь? Или как я могу узнать, когда мне нужно выполнить запрос о конкретном регионе на сервере, а когда я просто получаю локальные данные, которые уже есть на устройстве? Я просто хочу знать, есть ли какие-нибудь рекомендуемые подходы, лучшие практики? Надеюсь, я ясно написал здесь.

Обновление 2: меня интересуют лучшие практики (ссылки, пример), чтобы не создавать все это (пункты 2 + 3) с нуля. Существуют ли какие-либо рамки, содержащие этот или хороший учебник?


person Stanislav Pankevich    schedule 07.09.2012    source источник


Ответы (2)


@Stanislaw - Мы реализовали описанные вами функции в приложении под названием PreventConnect для одного из наших клиентов. У клиента уже были некоторые данные, хранящиеся в таблице Google Fusion. Мы расширили существующее решение, добавив еще одну таблицу Google Fusion, в которой хранятся геокоординаты для ряда местоположений. Все это сказано, чтобы ответить на ваши вопросы ...

1) Сама часть карты довольно нестандартная, плитки и тому подобное, но вам нужно будет немного кодировать, чтобы получить степень масштабирования, падение булавки, аннотации и тому подобное, работающие так, как вы ожидаете, что они будут работать .

2) Мы нашли решение Google Fusion достаточно эффективным. Если вы не хотите использовать Google Fusion, есть другие поставщики облачных баз данных, такие как StackMob, database.com и многие другие. Google бесплатный, и у них есть SDK для iOS, который упрощает взаимодействие с Google Fusion.

3) Совершенно верно! Мы кэшируем большую часть данных в хранилище Core Data локально на устройстве. Это значительно улучшает производительность и скорость отклика.

person radesix    schedule 07.09.2012
comment
rasesix, спасибо за ответ. Я нашел это слишком расплывчатым. По пункту 2 - мне не нужно работать с поставщиками баз данных - вместо этого у меня есть удаленный сервер: я получаю информацию о местах от него, используя его API (поэтому строки GF совершенно неактуальны). Пункт 1 - это то, что я имел в виду, задавая свой вопрос - вы только что подтвердили мыслями, спасибо. Пункт 3 - мне, наверное, больше интересно знать известные подходы к этому. Я обновил свой вопрос, добавив больше деталей - надеюсь, они описывают то, что я хочу, более ясно. - person Stanislav Pankevich; 09.09.2012
comment
radesix, извините за опечатку при написании вашего имени. - person Stanislav Pankevich; 09.09.2012

Пора написать твердый ответ на этот мой вопрос (я мог написать его год назад, но почему-то я забыл об этом).


Имеется ли в MapKit функция тайлов (способ Google Maps) из коробки, и нужно ли мне дополнительно работать над ней, если нет?

Ответ положительный: в MapKit он есть. Ключевые слова здесь overlays (MKOverlay, MKOverlayView and others). См. еще один мой ответ.

Смотрите также:

Сессия WWDC 2010: настройка карт с наложениями,

Apple-WWDC10-TileMap.


Как лучше всего получать информацию о местах (положение маркеров и аннотации) с сервера?

Собственно с тех пор я мало что узнал о «лучших практиках» - к сожалению, мне о них никто не сказал :( - поэтому я опишу «свои практики».

Прежде всего, есть две стратегии заполнения карты MapKit местами:

Первая стратегия заключается в заполнении вашей карты местами по запросу: представьте, что вы хотите отобразить и увидеть все места поблизости (например, на расстоянии не более 1 км от текущего местоположения пользователя) - этот подход предполагает, что вы спрашивайте у вашего сервера только места для интересующей вас коробки. Это означает что-то вроде: «если я нахожусь в Берлине (а я ожидаю 200 мест в Берлине), зачем мне когда-либо искать места из России, Японии, .. . (10000+ мест) ».

Этот подход приводит к тому, что полагается на функциональность «плиток», которая задает адрес N1: карты Google и карты Apple обычно рисуются с использованием «плиток», поэтому для вашей части карты «Берлин» вы полагаетесь на соответствующие плитки «Берлин», которые рисуются с помощью MKMapView - вы используете их размеры, чтобы запрашивать у своего сервера только места в поле «Берлин» (см. мой связанный ответ и демонстрационное приложение там).

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

Вторая стратегия - получить все места сразу (да, все эти 10000+ или больше) и использовать Core Data для получения мест, необходимых для видимых частей карты, которые вам интересны.

Второй подход означает, что во время первого запуска вы отправляете своему серверу запрос на выборку всех мест (у меня в приложении около 2000). Важно здесь то, что вы ограничиваете поля, которые вы выбираете, только географическими, которые вам действительно нужны для вашей карты: id, latitude, longitude.

Эта выборка "fetch-all" оказывает значительное влияние на время первого запуска моего приложения (на "самом старом" iPhone 4 у меня есть около 700 мс на весь Fetch + Parse-JSON-into-Core-Data процесс, и обширные тесты показывают мне, что это Core Data и его вставки - узкое место), но тогда у вас будет вся необходимая геоинформация о ваших местах на вашем устройстве.

Обратите внимание, что какую бы стратегию вы ни использовали, вы должны эффективно получать эти географические точки:

Представьте себе объект Core Data Place, который имеет следующую структуру полей (код preudo-Objective-C):

// Unique identificator
NSNumber *id,

// Geo info
NSNumber *latitude,
NSNumber *longitude,

// The rest "heavy" info  
NSString *name,
NSString *shortDescription,
NSString *detailedDescription, etc

Эффективная выборка мест означает, что вы запрашиваете только ваше место, записывающее геоданные с вашего сервера, чтобы сделать процесс этого зеркального отображения как можно быстрее.

См. Также эту горячую тему: Улучшить процесс зеркального отображения базы данных сервера в базу данных клиента через JSON?.

Проблема кластеризации выходит за рамки этого вопроса, но по-прежнему очень актуальна и влияет на весь алгоритм, который вы используете для всего процесса. Единственное замечание, которое я оставлю здесь, это то, что все текущие существующие решения кластеризации будут требуют, чтобы вы использовали вторую стратегию - у вас должны быть подготовлены все места, прежде чем вы столкнетесь с алгоритмами кластеризации, которые будут организовывать ваши места на карте - это означает, что если вы решите использовать кластеризацию, вы должны использовать стратегию № 2.

Соответствующие ссылки по кластеризации:

Сессия WWDC 2011: географическая визуализация информации с помощью MapKit,

Как эффективно отображать большие объемы данных на iOS Карты,

kingpin - решение для кластеризации с открытым исходным кодом: производительное и простое в использовании.


Можно ли кэшировать эту информацию, чтобы пользователь мог видеть близлежащие места «своего города» в автономном режиме?

Да, обе стратегии делают это: первая кэширует места, которые вы видите на своей карте - если вы наблюдали часть карты Берлина, у вас будет кешированная часть Берлина ...

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

person Stanislav Pankevich    schedule 26.01.2014