annotation - Dibujando una ruta en MapKit en iPhone SDK
google maps xcode (9)
Andiih lo hizo bien. MapKit no te permitirá hacer eso. Lamentablemente, Google no le permitirá hacer lo que quiera hacer tampoco.
Cuando Apple anunció MapKit y todo, también declaró explícitamente que cualquier aplicación de navegación sería BYOM: Traiga sus propios mapas, por lo que cualquier aplicación de navegación utiliza su propio conjunto de herramientas de asignación.
Los Términos de Servicio de Google le impiden incluso mostrar rutas en la parte superior de sus mapas:
http://code.google.com/intl/de/apis/maps/iphone/terms.html
Restricciones de licencia:
10.9 utilizar el Servicio o el Contenido con cualquier producto, sistema o aplicación para o en conexión con:
(a) navegación en tiempo real o guía de ruta, que incluye, pero no se limita a, guía de ruta paso a paso que se sincroniza con la posición del dispositivo habilitado por sensor del usuario;
(b) cualquier sistema o función para el control automático o autónomo del comportamiento del vehículo; o
(c) despacho, gestión de flotas, seguimiento de activos comerciales o aplicaciones empresariales similares (la API de Google Maps se puede utilizar para rastrear activos (como automóviles, autobuses u otros vehículos) siempre que la aplicación de seguimiento esté disponible para el público sin carga. Por ejemplo, puede ofrecer una implementación de API de Maps pública y gratuita que muestre el tránsito público en tiempo real u otra información de estado de transporte.
Tristemente, esto incluye lo que le gustaría hacer. Esperemos que algún día MapKit se amplíe para permitir tales características ... aunque es poco probable.
Buena suerte.
Quiero dibujar una ruta entre dos ubicaciones en el mapa. Algo así como un guía turístico. Cuando el turista haga clic en otra ubicación, quiero poder dibujar una ruta; así como, informar sobre la distancia desde la ubicación actual.
Conozco sitios en Internet que dicen cómo dibujar polilíneas en el mapa. Pero, la mayoría de los ejemplos tenían un archivo .csv precargado con varias coordenadas.
¿Hay alguna forma alternativa de obtener las coordenadas de Google o de cualquier otro proveedor, ya que la ubicación se selecciona dinámicamente?
Si NO, ¿cómo obtengo la información para las coordenadas intermedias?
¿IOS 6 proporciona alguna forma directa para este problema?
Es posible que desee echar un vistazo a https://github.com/leviathan/nvpolyline Esta solución está especialmente dirigida a las versiones de iPhone OS anteriores a v.4.0
Aunque también se puede usar en v.4.0 Espero que esto ayude.
Esto es complicado. No hay forma de hacerlo con MapKit: es fácil dibujar líneas cuando conoces las coordenadas, pero MapKit no te dará acceso a las carreteras u otra información de enrutamiento. Diría que necesitas llamar a una API externa para obtener tus datos.
He estado jugando con la API de cloudmade.com. El servidor de transmisión vectorial debe devolver lo que necesita y luego puede dibujarlo sobre su mapa. Sin embargo, las discrepancias entre los mapas de Google y los mapas de OSM utilizados por cloudmade pueden hacer que quieras usar mapas en la nube hasta el final: tienen un equivalente a MapKit.
PD: Otros proveedores de mapas: Google, Bing, etc. también pueden proporcionar feeds de datos equivalentes. Acabo de ver OSM / Cloudmade recientemente.
PPS: ¡Nada de esto es una novedad trivial! ¡La mejor de las suertes!
MapQuest tiene un SDK que reemplaza a MapKit. Actualmente está en beta, pero en desarrollo activo.
Permite superposiciones, enrutamiento y geocodificación.
Obtener y dibujar una ruta en el mapa es muy fácil con iOS 7 API:
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];
}
}];
Para actualizar esta pregunta, no hay necesidad de apk externo desde iOS7.
Aquí una solución muy simple y efectiva:
http://technet.weblineindia.com/mobile/draw-route-between-2-points-on-map-with-ios7-mapkit-api/2/
Sé que la pregunta era sobre iOS 6, pero creo que esta solución será útil para muchas personas.
Lo único que falta en esta solución es implementar el siguiente método delegado para mostrar el pin inicial y final
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
Pruebe MapKit-Route-Directions ( GitHub ).
Solo para aclarar, parece que hay un par de cosas que se discuten. Una es una forma de obtener los vértices de una ruta y la otra es dibujar una superposición en el mapa utilizando esos vértices. Conozco las API de MapQuest, así que tengo algunos enlaces para los que aparecen a continuación: Google y Bing tienen equivalentes, creo.
1) Obtener vértices de una ruta
Si está buscando las nuevas coordenadas de una ruta para dibujar una superposición de ruta, puede usar una llamada de servicio web a un servicio web de enrutamiento: supongo que está usando JavaScript aquí para mostrar el mapa. Si está utilizando un código nativo, aún puede acceder a un servicio web o puede usar una llamada nativa (es decir, MapQuest iPhone SDK tiene una llamada de ruta nativa).
La mayoría de los servicios de indicaciones deben devolver los "puntos de forma" de la ruta para que pueda dibujar.
Aquí hay algunos ejemplos que usan MapQuest-Directions Web Service para obtener puntos de forma (vea el objeto de devolución Shape) - http://www.mapquestapi.com/directions/
2) Dibujando una superposición
Una vez que tienes tus vértices, necesitas dibujarlos. Creo que la mayoría de las API de mapas de JavaScript tendrán una clase de superposición de algún tipo. Aquí está el de MapQuest: http://developer.mapquest.com/web/documentation/sdk/javascript/v7.0/overlays#line
3) Hacerlo con una llamada
MapQuest también tiene algunas funciones de conveniencia para hacer la llamada de la ruta y trazar la línea por usted - ¡No puedo publicar más de dos enlaces! Vaya al enlace de arriba y busque "enrutamiento" en la barra de navegación a la izquierda.
El siguiente viewDidLoad
(1) establecerá dos ubicaciones, (2) eliminará todas las anotaciones anteriores y (3) funciones de ayuda definidas por el usuario (para obtener puntos de ruta y dibujar la ruta).
-(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];
}
El siguiente es el método MKMapViewDelegate
, que dibuja la superposición (iOS 4.0 y posterior).
/* MKMapViewDelegate Meth0d -- for viewForOverlay*/
- (MKOverlayView*)mapView:(MKMapView*)theMapView viewForOverlay:(id <MKOverlay>)overlay
{
MKPolylineView *view = [[MKPolylineView alloc] initWithPolyline:objPolyline];
view.fillColor = [UIColor blackColor];
view.strokeColor = [UIColor blackColor];
view.lineWidth = 4;
return view;
}
La siguiente función obtendrá las ubicaciones y preparará la URL para obtener todos los puntos de ruta. Y, por supuesto, llamará a 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]];
}
El siguiente código es la magia real (decodificador de la respuesta que obtuvimos de la API). No modificaría ese código a menos que sepa lo que estoy haciendo :)
- (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;
}
Esta función dibujará una ruta y agregará una superposición.
- (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];
}
}
El siguiente código alineará el mapa al centro.
- (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];
}
Espero que esto ayude a alguien.