Подтвердить что ты не робот

GMSPolyline очень большой всплеск памяти

В приложении GPS, которое позволяет пользователю отображать список сложных точек местоположения, которые мы называем дорожками на разных типах карт, каждый трек может состоять из 2k - 10k точек местоположения. Треки обширно обрезаются, обрезаются и упрощаются, когда они отображаются на картах, отличных от Google. Это необходимо для уменьшения использования памяти и повышения производительности. Обычно мы заканчиваем отправку гораздо меньше тысячи (совокупных) преобразованных точек местоположения в конвейер OpenGL, даже в худших случаях.

При интеграции SDK Google Maps для iOS мы сначала попытались использовать нашу собственную систему рендеринга дорожек OpenGL, но столкнулись с проблемами с конфликтующим использованием контекста OpenGL (рендеринг работал, но мы не могли получить GMSMapView и наши собственные внутренние ресурсы OpenGL для обоих выпусков без обращения к удаленной памяти).

Итак, мы пытаемся использовать конструкции GMSPolyline и просто даем SDK Google сделать рендеринг дорожки, но мы столкнулись с серьезными проблемами использования памяти и ищем рекомендации по их работе.

Используя Xcode Instruments, мы отслеживали использование памяти при создании около 25 полилиний с общей суммой местоположений около 23 тыс. (не каждая). В ходе создания полилинии использование памяти приложения увеличивается с 14 МБ до 172 МБ, а максимальный пик - около 158 МБ. Вскоре после того, как все полилинии созданы, использование памяти, наконец, опускается примерно до 19 МБ и кажется стабильным, для совокупной сети около 5 МБ, поэтому кажется, что для каждой точки местоположения требуется около 220 байт (5 МБ /23 тыс. Точек) для магазин.

Что вредит нам, это пиковое использование памяти. В то время как в нашем лабораторном тесте использовались только локальные точки 23k, в реальном мире их часто бывает много, и iOS, похоже, сбрасывает наше приложение после того, как Google Maps потребляет около 450 МБ на iPhone 5 (тогда как наша внутренняя система визуализации линий Poly 12 МБ для одного и того же теста).

Ясно, что конструкция GMSPolyLine не предназначена для использования большого веса, который нам нужен.

Мы попробовали обернуть некоторые петли создания полилинии с отдельными пулами автозапуска, а затем вылили их в соответствующие точки, но это не влияет на использование памяти. Использование пиковой памяти после создания полилиний и возврата в основной цикл запуска не изменилось вообще. Позже стало ясно, почему; система Google Map не освобождает ресурсы до первого обратного вызова DisplayLink после создания полилиний.

Следующее усилие будет заключаться в том, чтобы вручную уменьшить объем данных, которые мы нажимаем на GMSPolyline, возможно, используя наши собственные тесты границ, отсечения, обрезки и минимизации, вместо того, чтобы полагаться на Карты Google, чтобы сделать это эффективно.

Недостатком здесь является то, что это будет означать, что многие объекты GMSPolyline будут распределены и освобождены, потенциально, пока пользователь будет панорамировать/масштабировать вокруг карты. Каждый из этих объектов будет иметь гораздо меньше точек местоположения, но все же мы обеспокоены непредвиденными последствиями этого подхода, скрытыми накладными расходами многих GMSPolyline-ассигнований и освобождением.

Итак, вопрос в том, какой наилучший подход для решения этой ситуации, и может ли кто-то из Google пролить свет на любые лучшие методы t21, верхние границы, узкие места и т.д.?

4b9b3361

Ответ 1

почему вы не пытаетесь использовать API Google для направления, основываясь на базовых HTTP-запросах. https://developers.google.com/maps/documentation/directions/. (проверьте условия лицензирования и количество запросов).

И затем постройте данные с помощью IOS MKPolyline. Я уверен, что у вас будет более высокая производительность. И вы будете зависеть только от Google для данных позиционирования.

чтобы преобразовать ответ из API Google в координаты, используйте известный метод (взятый из другого сообщения) ниже:

- (NSMutableArray *)parseResponse:(NSDictionary *)response
{
    NSArray *routes = [response objectForKey:@"routes"];
    NSDictionary *route = [routes lastObject];
    if (route) {
        NSString *overviewPolyline = [[route objectForKey: @"overview_polyline"] objectForKey:@"points"];
        return  [self decodePolyLine:overviewPolyline];
    }
    return nil;
}


-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {

    NSMutableString *encoded = [[NSMutableString alloc]initWithCapacity:[encodedStr length]];
    [encoded appendString:encodedStr];
    [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                options:NSLiteralSearch range:NSMakeRange(0,
                                                                          [encoded length])];
    NSInteger len = [encoded 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 = [encoded 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 = [encoded 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];
        CLLocation *location = [[CLLocation alloc] initWithLatitude: [latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:location]; }
    return array;
}

У меня была аналогичная проблема с производительностью на google sdk, и она работает для меня.