#ios #objective-c #google-maps #google-maps-sdk-ios #polyline
#iOS #цель-c #google-карты #google-maps-sdk-ios #полилиния #objective-c
Вопрос:
Я пытаюсь нарисовать маршрут на своей карте с помощью Google Maps SDK. Это URL-адрес, который я вызываю, и я анализирую ответ JSON на массив координат:
id jsonResponse = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
int points_count = 0;
points_count = [[[[[[jsonResponse objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"] count];
NSArray *steps = nil;
if (points_count amp;amp; [[[[jsonResponse objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] count])
{
steps = [[[[[jsonResponse objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"];
}
NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:points_count];
for (int i = 0; i < points_count; i )
{
NSDictionary *start;
NSDictionary *finish;
double st_lat = [[[[steps objectAtIndex:i] objectForKey:@"start_location"] valueForKey:@"lat"] doubleValue];
double st_lon = [[[[steps objectAtIndex:i] objectForKey:@"start_location"] valueForKey:@"lng"] doubleValue];
if (st_lat > 0.0f amp;amp; st_lon > 0.0f)
{
start = @{ @"latitude" : [NSNumber numberWithDouble:st_lat], @"longitude" : [NSNumber numberWithDouble:st_lon] };
}
double end_lat = [[[[steps objectAtIndex:i] objectForKey:@"end_location"] valueForKey:@"lat"] doubleValue];
double end_lon = [[[[steps objectAtIndex:i] objectForKey:@"end_location"] valueForKey:@"lng"] doubleValue];
if (end_lat > 0.0f amp;amp; end_lon > 0.0f)
{
finish = @{ @"latitude" : [NSNumber numberWithDouble:end_lat], @"longitude" : [NSNumber numberWithDouble:end_lon] };
}
[coordinates addObject:@{ @"start" : start, @"finish" : finish }];
}
И чем рисовать на виде карты с помощью этого метода:
GMSMutablePath *path = [GMSMutablePath path];
for (NSDictionary *d in directions)
{
NSDictionary *start = d[@"start"];
NSDictionary *finish = d[@"finish"];
CLLocationCoordinate2D c_start = CLLocationCoordinate2DMake([start[@"latitude"] doubleValue], [start[@"longitude"] doubleValue]);
CLLocationCoordinate2D c_finish = CLLocationCoordinate2DMake([finish[@"latitude"] doubleValue], [finish[@"longitude"] doubleValue]);
[path addCoordinate:c_start];
[path addCoordinate:c_finish];
}
GMSPolyline *line = [GMSPolyline polylineWithPath:path];
line.strokeColor = [UIColor redColor];
line.strokeWidth = 2.0f;
line.map = self.mapView;
Почему он так рисует, а сам не выходит на улицу?
Что я здесь делаю не так?
Ответ №1:
Попробуйте это, он рисует точный путь, как в режиме вождения — StreetMode, вот мой код :
Комментарии:
1. @adijazz91 я получаю сбой, если я остаюсь в том же положении, и у вас есть образец, пожалуйста, отправьте
Ответ №2:
Итак, проблема заключалась в том, что я использовал start_location
и end_location
вместо polyline
-> points
. Исправлен мой код в этом:
Например, URL-адрес запроса: https://maps.googleapis.com/maps/api/directions/json?origin=40.716072,-74.008836amp;destination=40.697545,-73.983892amp;sensor=falseamp;waypoints=optimize:trueamp;mode=driving
id jsonResponse = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
int points_count = 0;
points_count = [[[[[[jsonResponse objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"] count];
NSArray *steps = nil;
if (points_count amp;amp; [[[[jsonResponse objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] count])
{
steps = [[[[[jsonResponse objectForKey:@"routes"] objectAtIndex:0] objectForKey:@"legs"] objectAtIndex:0] objectForKey:@"steps"];
}
NSMutableArray *coordinates = [[NSMutableArray alloc] initWithCapacity:points_count];
for (int i = 0; i < points_count; i )
{
NSString *toDecode = [[[steps objectAtIndex:i] objectForKey:@"polyline"] valueForKey:@"points"];
NSArray *locations = [AppUtils decodePolylineWithString:toDecode];
for (int i = 0 ; i < locations.count ; i )
{
if (i != locations.count - 1) {
CLLocation *start = [locations objectAtIndex:i];
CLLocation *finish = [locations objectAtIndex:i 1];
[coordinates addObject:@{ @"start" : start, @"finish" : finish }];
}
}
}
GMSMutablePath *path = [GMSMutablePath path];
for (NSDictionary *d in directions)
{
CLLocation *start = d[@"start"];
CLLocation *finish = d[@"finish"];
[path addCoordinate:start.coordinate];
[path addCoordinate:finish.coordinate];
}
GMSPolyline *line = [GMSPolyline polylineWithPath:path];
line.strokeColor = [UIColor redColor];
line.strokeWidth = 2.0f;
line.map = self.mapView;
(NSArray*)decodePolylineWithString:(NSString *)encodedString
{
NSMutableArray *coordinates = [NSMutableArray array];
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx ] - 63;
res |= (byte amp; 0x1F) << shift;
shift = 5;
} while (byte >= 0x20);
float deltaLat = ((res amp; 1) ? ~(res >> 1) : (res >> 1));
latitude = deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx ] - 0x3F;
res |= (byte amp; 0x1F) << shift;
shift = 5;
} while (byte >= 0x20);
float deltaLon = ((res amp; 1) ? ~(res >> 1) : (res >> 1));
longitude = deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx ] = coord;
CLLocation *location = [[CLLocation alloc] initWithLatitude:finalLat longitude:finalLon];
[coordinates addObject:location];
if (coordIdx == count) {
NSUInteger newCount = count 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
free(coords);
return coordinates;
}
Я знаю, что это немного грязно, но это работа, и она отлично работает.
Наслаждайтесь.