Рисование маршрута в MapKit в iPhone SDK

Я хочу нарисовать маршрут между двумя местоположениями на карте. Что-то вроде гида. Когда турист нажимает на другое место, я хочу, чтобы можно было провести маршрут; а также проинформировать о расстоянии от текущего местоположения.

Я знаю сайты в Интернете, которые рассказывают, как рисовать полилинии на карте. Но в большинстве примеров был предварительно загруженный CSV-файл с различными координатами.

Есть ли альтернативный способ получить координаты от Google или любого другого провайдера, так как местоположение выбрано динамически.

Если НЕТ, как мне получить информацию для промежуточных координат?

Является ли iOS 6 прямым способом для этой проблемы?

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

Я играл с API cloudmade.com. Сервер векторного streamа должен возвращать то, что вам нужно, и затем вы можете нарисовать его по карте. Однако расхождения между картами Google и картами OSM, используемыми cloudmade, могут заставить вас использовать карты облачных карт на всем пути: они имеют эквивалент MapKit.

PS: Другие поставщики картографирования – Google, Bing и т. Д. Также могут предоставлять эквивалентные каналы данных. Недавно я смотрел OSM / Cloudmade.

PPS: Ничто из этого не является тривиальным новичком! Удачи!

Следующий viewDidLoad будет (1) установить два местоположения, (2) удалить все предыдущие annotations и (3) вызвать пользовательские вспомогательные функции (чтобы получить точки маршрута и нарисовать маршрут).

 -(void)viewDidLoad { [super viewDidLoad]; // Origin Location. CLLocationCoordinate2D loc1; loc1.latitude = 29.0167; loc1.longitude = 77.3833; Annotation *origin = [[Annotation alloc] initWithTitle:@"loc1" subTitle:@"Home1" andCoordinate:loc1]; [objMapView addAnnotation:origin]; // Destination Location. CLLocationCoordinate2D loc2; loc2.latitude = 19.076000; loc2.longitude = 72.877670; Annotation *destination = [[Annotation alloc] initWithTitle:@"loc2" subTitle:@"Home2" andCoordinate:loc2]; [objMapView addAnnotation:destination]; if(arrRoutePoints) // Remove all annotations [objMapView removeAnnotations:[objMapView annotations]]; arrRoutePoints = [self getRoutePointFrom:origin to:destination]; [self drawRoute]; [self centerMap]; } 

Ниже MKMapViewDelegate метод MKMapViewDelegate , который накладывает наложение (iOS 4.0 и более поздние MKMapViewDelegate ).

 /* MKMapViewDelegate Meth0d -- for viewForOverlay*/ - (MKOverlayView*)mapView:(MKMapView*)theMapView viewForOverlay:(id )overlay { MKPolylineView *view = [[MKPolylineView alloc] initWithPolyline:objPolyline]; view.fillColor = [UIColor blackColor]; view.strokeColor = [UIColor blackColor]; view.lineWidth = 4; return view; } 

Следующая функция получит оба места и подготовит URL-адрес, чтобы получить все точки маршрута. И, конечно, вызовет stringWithURL.

 /* This will get the route coordinates from the Google API. */ - (NSArray*)getRoutePointFrom:(Annotation *)origin to:(Annotation *)destination { NSString* saddr = [NSString stringWithFormat:@"%f,%f", origin.coordinate.latitude, origin.coordinate.longitude]; NSString* daddr = [NSString stringWithFormat:@"%f,%f", destination.coordinate.latitude, destination.coordinate.longitude]; NSString* apiUrlStr = [NSString stringWithFormat:@"http://maps.google.com/maps?output=dragdir&saddr=%@&daddr=%@", saddr, daddr]; NSURL* apiUrl = [NSURL URLWithString:apiUrlStr]; NSError *error; NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSUTF8StringEncoding error:&error]; NSString* encodedPoints = [apiResponse stringByMatching:@"points:\\\"([^\\\"]*)\\\"" capture:1L]; return [self decodePolyLine:[encodedPoints mutableCopy]]; } 

Следующий код – настоящая магия (декодер для ответа, который мы получили от API). Я бы не стал изменять этот код, если я не знаю, что делаю 🙂

 - (NSMutableArray *)decodePolyLine:(NSMutableString *)encodedString { [encodedString replaceOccurrencesOfString:@"\\\\" withString:@"\\" options:NSLiteralSearch range:NSMakeRange(0, [encodedString length])]; NSInteger len = [encodedString length]; NSInteger index = 0; NSMutableArray *array = [[NSMutableArray alloc] init]; NSInteger lat=0; NSInteger lng=0; while (index < len) { NSInteger b; NSInteger shift = 0; NSInteger result = 0; do { b = [encodedString characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); NSInteger dlat = ((result & 1) ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = [encodedString characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); NSInteger dlng = ((result & 1) ? ~(result >> 1) : (result >> 1)); lng += dlng; NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5]; NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5]; printf("\n[%f,", [latitude doubleValue]); printf("%f]", [longitude doubleValue]); CLLocation *loc = [[CLLocation alloc] initWithLatitude:[latitude floatValue] longitude:[longitude floatValue]]; [array addObject:loc]; } return array; } 

Эта функция будет рисовать маршрут и добавит оверлей.

 - (void)drawRoute { int numPoints = [arrRoutePoints count]; if (numPoints > 1) { CLLocationCoordinate2D* coords = malloc(numPoints * sizeof(CLLocationCoordinate2D)); for (int i = 0; i < numPoints; i++) { CLLocation* current = [arrRoutePoints objectAtIndex:i]; coords[i] = current.coordinate; } self.objPolyline = [MKPolyline polylineWithCoordinates:coords count:numPoints]; free(coords); [objMapView addOverlay:objPolyline]; [objMapView setNeedsDisplay]; } } 

Следующий код будет центрировать выравнивание карты.

 - (void)centerMap { MKCoordinateRegion region; CLLocationDegrees maxLat = -90; CLLocationDegrees maxLon = -180; CLLocationDegrees minLat = 90; CLLocationDegrees minLon = 180; for(int idx = 0; idx < arrRoutePoints.count; idx++) { CLLocation* currentLocation = [arrRoutePoints objectAtIndex:idx]; if(currentLocation.coordinate.latitude > maxLat) maxLat = currentLocation.coordinate.latitude; if(currentLocation.coordinate.latitude < minLat) minLat = currentLocation.coordinate.latitude; if(currentLocation.coordinate.longitude > maxLon) maxLon = currentLocation.coordinate.longitude; if(currentLocation.coordinate.longitude < minLon) minLon = currentLocation.coordinate.longitude; } region.center.latitude = (maxLat + minLat) / 2; region.center.longitude = (maxLon + minLon) / 2; region.span.latitudeDelta = maxLat - minLat; region.span.longitudeDelta = maxLon - minLon; [objMapView setRegion:region animated:YES]; } 

Надеюсь, это поможет кому-то.

Andiih получил это правильно. MapKit не позволит вам это сделать. К сожалению, Google не позволит вам делать то, что вы хотите сделать.

Когда Apple объявила MapKit и все, они также прямо заявили, что любые навигационные приложения будут BYOM: Принесите свои собственные карты, поэтому любое навигационное приложение использует свой собственный набор инструментов для сопоставления.

Условия обслуживания Google ограничивают вас даже отображением маршрутов поверх их карт:

http://code.google.com/intl/de/apis/maps/iphone/terms.html

Ограничения лицензии:

10.9 используйте Службу или Контент с любыми продуктами, системами или приложениями для или в связи с:

(a) навигацию в режиме реального времени или руководство по маршруту, включая, но не ограничиваясь, пошаговое руководство по маршруту, которое синхронизируется с положением устройства с сенсорным управлением пользователя;

(b) любые системы или функции для автоматического или автономного управления поведением транспортных средств; или

(c) диспетчеризация, управление флотом, отслеживание бизнес-активов или аналогичные корпоративные приложения (API Карт Google можно использовать для отслеживания активов (например, автомобилей, автобусов или других транспортных средств), если приложение отслеживания становится доступным для общественности без Например, вы можете предлагать бесплатную, открытую API API Карт, которая отображает информацию о государственном транзите в реальном времени или другую информацию о состоянии транспорта.

К сожалению, это включает в себя то, что вы хотели бы сделать. Надеюсь, в один прекрасный день MapKit будет расширен, чтобы позволить такие возможности … хотя и маловероятно.

Удачи.

Возможно, вам стоит взглянуть на https://github.com/leviathan/nvpolyline. Это решение особенно ориентировано на версии iPhone OS до версии 4.0.

Хотя это также можно использовать в v.4.0. Надеюсь, это поможет.

Попробуйте MapKit-Route-Directions ( GitHub ).

MapQuest имеет SDK, который является заменой MapKit. В настоящее время он находится в стадии бета-тестирования, но находится в активной разработке.

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

API карт MapQuest для iOS

Просто для уточнения, похоже, есть пара вопросов, обсуждаемых. Один из них – способ получить вершины маршрута, а другой – нарисовать оверлей на карте, используя эти вершины. Я знаю API MapQuest, поэтому у меня есть некоторые ссылки для ниже: Google и Bing имеют эквиваленты, которые я думаю.

1) Получение вершин маршрута
Если вы ищете новые координаты маршрута для наложения маршрута, вы можете либо использовать вызов веб-службы для веб-службы маршрутизации – я предполагаю, что вы используете JavaScript здесь для отображения карты. Если вы используете собственный код, вы все равно можете попасть в веб-службу или использовать собственный вызов (то есть, в SDK MapQuest iPhone есть собственный вызов маршрута).

Большинство служб маршрутов должны возвращать «точки поворота» маршрута, чтобы вы могли рисовать.

Ниже приведены некоторые примеры использования MapQuest-Directions Web Service для получения шаблонов (см. Объект возврата формы) – http://www.mapquestapi.com/directions/

2) Наложение наложения
Когда у вас есть ваши вершины, вам нужно их нарисовать. Я думаю, что большинство API-интерфейсов API-карт будут иметь class оверлея. Вот пример MapQuest: http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line

3) Выполнение этого с помощью одного вызова
MapQuest также имеет некоторые удобные функции, чтобы позвонить по маршруту и ​​провести линию для вас – я не могу разместить более двух ссылок! Поэтому перейдите по ссылке выше и найдите «маршрутизацию» в навигационной панели слева.

Получение и рисование маршрута на карте очень просто с помощью API iOS 7:

 MKDirectionsRequest *directionsRequest = [[MKDirectionsRequest alloc] init]; // Set the origin of the route to be current user location [directionsRequest setSource:[MKMapItem mapItemForCurrentLocation]]; // Set the destination point of the route CLLocationCoordinate2D destinationCoordinate = CLLocationCoordinate2DMake(34.0872, 76.235); MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoordinate addressDictionary:nil]; [directionsRequest setDestination:[[MKMapItem alloc] initWithPlacemark:destinationPlacemark]]; MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest]; // Requesting route information from Apple Map services [directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) { if (error) { NSLog(@"Cannot calculate directions: %@",[error localizedDescription]); } else { // Displaying the route on the map MKRoute *route = [response.routes firstObject]; [mapView addOverlay:route.polyline]; } }]; 

Чтобы обновить этот вопрос, нет необходимости в внешнем apk с iOS7.

Здесь очень простое и эффективное решение:

http://technet.weblineindia.com/mobile/draw-route-between-2-points-on-map-with-ios7-mapkit-api/2/

Я знаю, что вопрос касался iOS 6, но я считаю, что это решение будет полезно для многих людей.

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

 -(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation 
  • Вычислите новую координату x метров и y gradleус от одной координаты
  • Подclass MKAnnotationView и переопределение setDragState
  • Interesting Posts

    Есть ли способ использовать два оператора «…» в функции из R?

    Подзапросы с EXISTS против IN – MySQL

    Обновление Windows 10 имеет 100% -ное использование процессора при запуске

    Опубликованный Android apk дает ошибку «Файл пакета не был подписан правильно»

    Программное обеспечение блок-схемы для Linux?

    Невозможно создать AVD или протестировать любое приложение с помощью AVD после создания инструментов сборки до 22.6

    Вызов методов classа C ++ с помощью указателя функции

    Бесплатное программное обеспечение для просмотра / конвертации AVCHD

    Найдите, какой URL-адрес EXE-файл отправляет данные в

    Когда мне следует реализовать std :: convert :: From vs std :: convert :: Into?

    Windows 8.1 – Не выгружаемый пул – ATI 6950 Memory Leak

    Regex для проверки формата даты dd / mm / yyyy

    Стабилизация видео с помощью OpenCV

    Почему OS X Lion запрашивает мой пароль всякий раз, когда я удаляю файл в своем домашнем каталоге?

    Создание собственного внутреннего classа с reflectionм java

    Давайте будем гением компьютера.