加快 Google 地理编码的 addAnnotations 速度?

发布于 2024-11-04 06:25:31 字数 1415 浏览 1 评论 0原文

我的应用程序中有以下代码,它通过 Google 地理编码向地图视图添加了许多注释:

for (PlaceObject *info in mapLocations) {

    NSString * addressOne = info.addressOne;
    NSString * name = info.name;

    NSString * address = [addressOne stringByAppendingString:@",London"];

    NSError * error;

    NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString ] encoding:NSASCIIStringEncoding error:&error];
    NSArray *listItems = [locationString componentsSeparatedByString:@","];

    double latitude = 0.0;
    double longitude = 0.0;

    if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) {
        latitude = [[listItems objectAtIndex:2] doubleValue];
        longitude = [[listItems objectAtIndex:3] doubleValue];

    } else {
        //Error handling

    }        

    CLLocationCoordinate2D coordinate;
    coordinate.latitude = latitude;
    coordinate.longitude = longitude;
    MyLocation *annotation = [[[MyLocation alloc] initWithName:name address:address coordinate:coordinate] autorelease];
    [mapViewLink addAnnotation:annotation];

}

这可行,但是视图需要很长时间才能显示,因为它似乎要等到数组中的所有对象都已循环通过(大约有80个)。

有没有什么方法可以加载视图,然后在创建引脚时添加它们?

I have the following code in my app which adds a number of Annotations to a mapview via Google geocoding:

for (PlaceObject *info in mapLocations) {

    NSString * addressOne = info.addressOne;
    NSString * name = info.name;

    NSString * address = [addressOne stringByAppendingString:@",London"];

    NSError * error;

    NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString ] encoding:NSASCIIStringEncoding error:&error];
    NSArray *listItems = [locationString componentsSeparatedByString:@","];

    double latitude = 0.0;
    double longitude = 0.0;

    if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) {
        latitude = [[listItems objectAtIndex:2] doubleValue];
        longitude = [[listItems objectAtIndex:3] doubleValue];

    } else {
        //Error handling

    }        

    CLLocationCoordinate2D coordinate;
    coordinate.latitude = latitude;
    coordinate.longitude = longitude;
    MyLocation *annotation = [[[MyLocation alloc] initWithName:name address:address coordinate:coordinate] autorelease];
    [mapViewLink addAnnotation:annotation];

}

This works, however it takes a long time for the view to appear as it seems to wait until all objects in the array have been looped through (there are about 80).

Is there any way to make the view load and then for the pins to be added as they are created ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

绝情姑娘 2024-11-11 06:25:32

怎么样:

for (PlaceObject *info in mapLocations) {

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{

        // GET ANNOTATION INFOS
        NSString * addressOne = info.addressOne;
        NSString * name = info.name;

        NSString * address = [addressOne stringByAppendingString:@",London"];

        NSError * error;

        NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

        NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString ] encoding:NSASCIIStringEncoding error:&error];
        NSArray *listItems = [locationString componentsSeparatedByString:@","];

        double latitude = 0.0;
        double longitude = 0.0;

        if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) {
            latitude = [[listItems objectAtIndex:2] doubleValue];
            longitude = [[listItems objectAtIndex:3] doubleValue];

        } else {
            //Error handling

        }        

        CLLocationCoordinate2D coordinate;
        coordinate.latitude = latitude;
        coordinate.longitude = longitude;
        MyLocation *annotation = [[[MyLocation alloc] initWithName:name address:address coordinate:coordinate] autorelease]; 

        dispatch_sync(dispatch_get_main_queue(), ^{

            // ADD ANNOTATION
            [mapViewLink addAnnotation:annotation];

        });

    });
}

但请考虑仔细检查此代码。您绝对应该采取一些措施来保持线程安全并避免 EXC_BAD_ACCESS

How about this:

for (PlaceObject *info in mapLocations) {

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{

        // GET ANNOTATION INFOS
        NSString * addressOne = info.addressOne;
        NSString * name = info.name;

        NSString * address = [addressOne stringByAppendingString:@",London"];

        NSError * error;

        NSString *urlString = [NSString stringWithFormat:@"http://maps.google.com/maps/geo?q=%@&output=csv", [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

        NSString *locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString ] encoding:NSASCIIStringEncoding error:&error];
        NSArray *listItems = [locationString componentsSeparatedByString:@","];

        double latitude = 0.0;
        double longitude = 0.0;

        if([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:@"200"]) {
            latitude = [[listItems objectAtIndex:2] doubleValue];
            longitude = [[listItems objectAtIndex:3] doubleValue];

        } else {
            //Error handling

        }        

        CLLocationCoordinate2D coordinate;
        coordinate.latitude = latitude;
        coordinate.longitude = longitude;
        MyLocation *annotation = [[[MyLocation alloc] initWithName:name address:address coordinate:coordinate] autorelease]; 

        dispatch_sync(dispatch_get_main_queue(), ^{

            // ADD ANNOTATION
            [mapViewLink addAnnotation:annotation];

        });

    });
}

But please consider to double-check this code. There are definitily things you should do about keeping the threads safe and avoid EXC_BAD_ACCESS.

长伴 2024-11-11 06:25:32

此代码在您的应用程序中的何处执行?

我建议使用 NSURLConnection 并在接收和解析数据后添加注释。如果您不熟悉 NSURLConnection,请在此处查看更多信息: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html

Where is this code executed in your app?

I'd recommend using NSURLConnection and adding the annotations after the data has been received and parsed. Look here for more info, if you're not familiar with NSURLConnection: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/Tasks/UsingNSURLConnection.html

厌味 2024-11-11 06:25:32

是的,您犯了在主 (UI) 线程中进行长时间工作(从 URL 进行网络加载)的经典错误。将此工作移至后台线程,然后让主线程添加引脚。这可以通过多种方式实现,例如创建另一个显式线程、带有块的 GCD,或者只是在后台线程中执行 Selector。最简单的方法可能是在后台执行Selector,然后当它有东西要添加到地图时,在主线程上执行Selector。

Yea, you are making the classic error of doing long work (net loading from a URL) in the main (UI) thread. Move this work into a background thread and then have the main thread add the pins. This can be in several ways, by creating another explicit thread, GCD with blocks, or just performSelector in background thread. Easiest way is to probably performSelector in background and then when it has something to add to map, performSelector on main thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文