В iOS был существенно переработан MapKit. Разработчики Apple отказались от Google maps, и создали свой картографический сервис. Карты стали dynamic(© apple), это позволило: красиво переворачивать ярлыки, избежать размытия при масштабировании и пр. API работы с MapKit не изменились, но появились дополнения.
Встречайте MKMapItem (описание здесь).
У MKMapItem есть свойства name, phoneNumber, url дают дополнительную информацию о месте на которое указывает экземпляр класса.
Свойство placemark хранит координаты. Свойство isCurrentLocation указывает на текущее положение девайса (Важно: как только isCurrentLocation устанавливается в YES, placemark устанавливается в nil).
MKPlacemark *myPlacemark = [[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(53.90, 27.56) addressDictionary:nil]; MKMapItem *myPoint = [[MKMapItem alloc] initWithPlacemark:myPlacemark];
Чтобы открыть приложение карты с выбранной точкой, вызываем instance-метод openInMapsWithLaunchOptions:
[myPoint openInMapsWithLaunchOptions:nil];
Если необходимо запустить приложение карты с несколькими «булавками», собираем все MKMapItem в NSArray и вызываем class-метод openInMapsItems: launchOptions:
NSArray *mapItems = @[point1, point2, point3]; [MKMapItem openMapsWithItems:mapItems launchOptions:nil];
В вышеописанные методы передается параметр NSDictionary *launchOptions. В этом параметре можно описать: тип отображаемой карты (схема, спутник, гибрид), центр отображаемого участка карты, отображаемый район, отображать ли траффик.
NSDictionary *options = @{ MKLaunchOptionsMapTypeKey :[NSNumber numberWithInteger:MKMapTypeHybrid], MKLaunchOptionsMapCenterKey :[NSValue valueWithMKCoordinate:CLLocationCoordinate2DMake(53.90, 27.56)], MKLaunchOptionsMapSpanKey :[NSValue valueWithMKCoordinateSpan:MKCoordinateSpanMake(1, 1)]};
Еще одна опция которую стоит рассмотреть отдельно – MKLaunchOptionsDirectionsModeKey. Передав этот ключ приложению карты, оно создает маршрут (доступно 2 режима: walking/driving). В качестве начальной точки будет взят первый объект из массива, а конечная – последний объект, вне зависимости от количества объектов в массиве.
MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeDriving
Отобразить текущее положение девайса на карте не сложно:
MKMapItem *currentPoint = [MKMapItem mapItemForCurrentLocation]; [currentPoint openInMapsWithLaunchOptions:nil];
Работать с этим экземпляром так же, как и с обычными MKMapItem, за исключением свойства placemark — оно имеет значение nil, свойство isCurrentLocation будет иметь значение YES.
Самое интересное: теперь приложения можно запускать прямо из стандартного приложения карты.
Нажимаем кнопку «навигации», вводим начальную и конечную точку маршрута.
Выбираем тип транспорта и, по нажатию на кнопку «Route», переходим к выбору приложения.
В верхней части таблицы отображены установленные приложения, ниже – приложения из App Store, которые ассоциированы с выбранным районом и транспортом.
По нажатию на «Route» открываем приложение.
Для создания «routing app» необходимо: задекларировать приложение как routing, указать для какого района ваше приложение, и «ловить» запуск из стандартного приложения карт.
Открываем в xCode (версия 4.5 и выше) файл проекта, выбираем target, настраиваем checkboxes: “accept transit routing request” – разрешаем приложению запускаться из стандартных карт; выбираем те виды транспорта, для которых написано приложение:
Приложение задекларировано как routing app. Займемся определением района для нашего приложения.
Требования к файлу, описывающему район:
• GeoJSON формат (.geojson подробнее);
• Описывайте один мультиполигон (может содержать несколько полигонов как на третьем рисунке);
• Сделайте ваши полигоны максимально простыми (до 20 полигонов по 20 точек на каждый);
• Файл не является частью проекта и загружается отдельно через iTunesConnect.
И последний шаг, перехватываем запуск приложения. Для этого в AppDelegate реализовываем метод application: openURL: sourceApplication: annotation:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { if ([MKDirectionsRequest isDirectionsRequestURL:url]) { MKDirectionsRequest *request = [[MKDirectionsRequest alloc] initWithContentsOfURL:url]; MKMapItem *startItem = [request source]; MKMapItem *endItem = [request destination]; // YOUR CODE HERE } return YES; }
Что делать далее с полученными MKMapItem? Это зависит от вас, но не забывайте проверить свойство isCurrentLocation == YES (placemark в этом случае будет nil).
Ну и на закуску пример.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: