Чтение онлайн

ЖАНРЫ

iOS. Приемы программирования

Нахавандипур Вандад

Шрифт:

Latitude = 38.4 10373

См. также

Раздел 9.8.

9.8. Преобразование данных широты и долготы в обычные адреса

Постановка задачи

Имеются значения широты и долготы определенной точки в пространстве. Необходимо получить ее адрес.

Решение

Получение обычного адреса на основании известных пространственных координат (x и y) называется обратным геокодированием. Для выполнения такой операции нужно создать

и использовать экземпляр класса CLGeocoder, а также предоставить блоковый объект завершения. При этом необходимо гарантировать, что блоковый объект не имеет возвращаемого значения и принимает два параметра:

• массив меток (типа NSArray). Метками будут обозначены те точки на карте, которые соответствуют критериям поискового запроса;

• ошибку (типа NSError), которая будет преобразована в код ошибки, если обратное геокодирование не удастся.

Инстанцировав объект типа CLGeocoder, мы используем его метод reverseGeocodeLocation: completionHandler: для выполнения обратного геокодирования.

Верхняя часть. m-файла простого контроллера вида, применяемого для этой цели, определяется следующим образом:

#import «ViewController.h»

#import <CoreLocation/CoreLocation.h>

@interface ViewController 

@property (nonatomic, strong) CLGeocoder *myGeocoder;

@end

@implementation ViewController

В ходе загрузки вида можно выполнить обратное геокодирование:

— (void)viewDidLoad{

[super viewDidLoad];

CLLocation *location = [[CLLocation alloc]

initWithLatitude:+38.41 12810

longitude:-122.8409780f];

self.myGeocoder = [[CLGeocoder alloc] init];

[self.myGeocoder

reverseGeocodeLocation: location

completionHandler: ^(NSArray *placemarks, NSError *error) {

if (error == nil && placemarks.count > 0){

CLPlacemark *placemark = placemarks[0];

/* Результаты получены. */

NSLog(@"Country = %@", placemark.country);

NSLog(@"Postal Code = %@", placemark.postalCode);

NSLog(@"Locality = %@", placemark.locality);

}

else if (error == nil &&

[placemarks count] == 0){

NSLog(@"No results were returned.");

}

else if (error!= nil){

NSLog(@"An error occurred = %@", error);

}

}];

}

— (void)viewDidUnload{

[super viewDidUnload];

self.myGeocoder = nil;

}

Если операция завершится успешно, то в массиве placemarks будут содержаться объекты типа CLPlacemark. Эти объекты будут отмечать адреса, удовлетворяющие значениям широты и долготы, которые мы сообщили методу reverseGeocodeLocation: completionHandler:. Итак, все, что от нас требуется, — убедиться в отсутствии ошибок и в том, что в массиве меток есть как минимум одна метка.

Методы NSLog из приведенного ранее кода выводят в окне консоли адрес, прошедший процедуру обратного геокодирования:

Country = United States

Postal Code = 95472

Locality = Sebastopol

Обсуждение

В

каждом приложении имеется лимит объема запросов на обратное геокодирование, которые могут быть выполнены в данном приложении за один день. Этот объем определяется провайдером серверного приложения, обеспечивающего поддержку геолокационных служб в iOS. Существуют различные платные онлайновые сервисы, которые предоставляют разработчикам сторонние API. Я не могу сейчас рекламировать какие-либо из подобных сервисов, но можете сами поискать их в Интернете, если захотите преодолеть ограничения, связанные с обратным геокодированием пространственных координат, существующие в настоящее время в iOS SDK. Чтобы выполнить запрос на обратное геокодирование, нужно создать экземпляр класса CLGeocoder. Этот класс требует активного сетевого соединения — оно необходимо для успешной обработки запросов. Значения, прошедшие обратное геокодирование, сообщаются блоку обработки завершения, который передается методу reverseGeocodeLocation: completionHandler:.

См. также

Раздел 9.7.

9.9. Поиск в картографическом виде

Постановка задачи

Требуется предоставить пользователям, просматривающим картографический вид, поисковую функцию. Например, можно помочь им найти все рестораны или тренажерные залы в конкретном регионе, отображенном на карте. Если пользователь находится в центре города и видит свое местоположение на карте, он может просто ввести в строку поиска слово «рестораны» — и приложение выполнит поиск по такому запросу.

Решение

Картографические виды, без преувеличения, просто великолепны. Но иногда такой вид ничем не может помочь пользователю, который видит на экране просто одну большую карту. В таком случае вполне сгодится и обычная бумажная карта. Картографические возможности смартфонов интересны именно в контексте их интерактивности. Пользователь может находить на карте объекты, искать интересующие его места, получать информацию о том, как попасть в место, расположенное по тому или иному адресу. Apple включила в iOS SDK три очень удобных класса, позволяющих пользователю искать места на карте. Такой поиск совершенно прост. От вас требуется всего лишь ввести текстовый запрос о том, что вас интересует, например «рестораны» или «кафе, — и SDK выполнит за вас остальную работу. В этом разделе мы собираемся отобразить в контроллере вида картографический вид (с местоположением пользователя) и отслеживать местоположение пользователя. Таким образом, та точка, в которой он находится, всегда будет располагаться в центре карты.

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

#import «ViewController.h»

#import <MapKit/MapKit.h>

@interface ViewController <MKMapViewDelegate>

@property (nonatomic, strong) MKMapView *myMapView;

@end

@implementation ViewController

Далее необходимо создать картографический вид:

— (void)viewDidLoad {

[super viewDidLoad];

/* Создаем карту, совпадающую по размеру с нашим видом */

self.myMapView = [[MKMapView alloc]

initWithFrame: self.view.bounds];

self.myMapView.delegate = self;

Поделиться с друзьями: