从给定坐标(不是当前位置,而是手动提供)进行反向地理编码 [英] Reverse geocoding from given coordinates (not current location, but manually provided)

查看:83
本文介绍了从给定坐标(不是当前位置,而是手动提供)进行反向地理编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在获取所有图像的GPS信息,并将它们存储在字典中。我会过去从此字典到 reverseGeocodeLocation 函数调用的长值&将结果存储在我的数据库中。

I am fetching GPS information of all my images and they are stored in a Dictionary. I would pass on the lat & long values from this dictionary to the reverseGeocodeLocation function call & store the results in my database.

这里的问题是此函数是异步调用&我需要同步整个过程,以便将记录插入表中。

The problem here is that this function is an asynchronous call & I need to synchronize the whole process for my record to get inserted into the table.

例如:我的数组读取的坐标为:32.77003,96.87532。现在,它调用 reverseGeocodeLocation 函数,并将这些坐标作为 CLLocation 对象传递。现在,在此异步函数将我返回给地理编码的位置名称之前,带有新坐标集的下一个请求将发送到 reverseGeocodeLocation 函数。这导致将记录插入数据库不一致。

Eg: My array read following coordinates: 32.77003,96.87532. It now calls the reverseGeocodeLocation function, passing on these coordinates as CLLocation object. Now before this async function returns me back the geo-coded location name, next request with new set of coordinates is sent to reverseGeocodeLocation function. This causes inconsistency to insert the record into database.

有没有办法使整个任务同步?

即让我的for-loop等待,直到 reverseGeocodeLocation 返回一个值,然后移至下一条要进行地理编码的记录?

Is there any way to have this whole task turn synchronous?
i.e Make my for-loop wait until reverseGeocodeLocation returns a value and then move on to next record to be geo-coded?

我的部分代码在这里:

for (int imgIdx=0; imgIdx<[imageMetaMutArray count]; imgIdx++)
{
    NSDictionary *localGpsDict = [[NSDictionary alloc]initWithDictionary: [imageMetaMutArray objectAtIndex:imgIdx]];
    imgLatLoc=[localGpsDict valueForKey:@"Latitude"];
    imgLongLoc=[localGpsDict valueForKey:@"Longitude"];
    dateStamp=[localGpsDict valueForKey:@"DateStamp"];
    timeStamp=[localGpsDict valueForKey:@"TimeStamp"];

    if(imgLatLoc && imgLongLoc && dateStamp && timeStamp)
    {
        CLGeocoder *geoCoder=[[CLGeocoder alloc]init];
        CLLocation *currentLocation=[[CLLocation alloc]initWithLatitude:[imgLatLoc doubleValue] longitude:[imgLongLoc doubleValue]];

        [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placeMarks, NSError *err){
        if(err)
        {
            NSLog(@"Reverse geo-coding failed because: %@",err);
            return;
        }


        if(placeMarks && placeMarks.count>0)
        {
            CLPlacemark *placeMarkers=placeMarks[0];
            NSDictionary *locationDictionary=placeMarkers.addressDictionary;

            NSString *country=[locationDictionary objectForKey:(NSString *)kABPersonAddressCountryKey];
            NSString *city=[locationDictionary objectForKey:(NSString *)kABPersonAddressCityKey];
            NSString *state=[locationDictionary objectForKey:(NSString *)kABPersonAddressStateKey];

            NSLog(@"logged in from:");

                if(city)
                {
                    NSLog(@"city: %@",city);
                    locName = [[NSString alloc]initWithString:city];
                    if(state)
                    {
                        NSLog(@"state: %@",state);
                        locName=[locName stringByAppendingString:@","];
                        locName=[locName stringByAppendingString:state];
                    }
                    if(country)
                    {
                        NSLog(@"country: %@",country);
                        locName=[locName stringByAppendingString:@","];
                        locName=[locName stringByAppendingString:country];
                    }
                }
                else
                {
                        if(state)
                        {
                            NSLog(@"state: %@",state);
                            locName = [[NSString alloc]initWithString:state];
                            if(country)
                            {
                                NSLog(@"country: %@",country);
                                locName=[locName stringByAppendingString:@","];
                                locName=[locName stringByAppendingString:country];
                            }
                        }
                        else
                        {
                            NSLog(@"country: %@",country);
                            locName = [[NSString alloc]initWithString:country];
                        }
                    }
                }
                else
                {
                    NSLog(@"Placemark Error code:: %lu\n%@",(unsigned long)placeMarks.count,placeMarks);
                }

                [locName retain];
                NSLog(@"location decoded is: %@",locName);
                /*Call for Insert into Images table*/
               [self insertDataImgTbl:locName];
          });
      }
   }
}


推荐答案

简短的答案是您无法使其同步。

The short answer is that you can't make it synchronous.

您要做的就是将继续下一个对象的代码移到由于您可以尽快提交另一个reverseGeocodeLocation请求,所以请完成reverseGeocodeLocation的完成块。让我看看我是否可以在这里做一些伪代码...(就是说,我还没有编译它,所以它可能并不完全正确...)

What you want to do is move the code that goes on to the next object into the completion block of the reverseGeocodeLocation because that is the soonest that you can submit another reverseGeocodeLocation request. Let me see if I can make some pseudocode here... (that is, I haven't compiled this so it might not be exactly right...)

    // in place of the original for loop:
    [self reverseGeocodeForIndex:0];


// Doing the reverse geocode is in a method so you can easily call it from within the completion block.
// Maybe your parameter is not the imgIdx value but is instead some object -- I'm just hacking your posted code
// The point is that your completion block has to be able to tell when
// it is done and how to go on to the next object when it is not done.
(void) reverseGeocodeForIndex:(int) imgIdx {
    NSDictionary *localGpsDict = [[NSDictionary alloc]initWithDictionary: [imageMetaMutArray objectAtIndex:imgIdx]];
    imgLatLoc=[localGpsDict valueForKey:@"Latitude"];
    imgLongLoc=[localGpsDict valueForKey:@"Longitude"];
    dateStamp=[localGpsDict valueForKey:@"DateStamp"];
    timeStamp=[localGpsDict valueForKey:@"TimeStamp"];

    if(imgLatLoc && imgLongLoc && dateStamp && timeStamp)
    {
        CLGeocoder *geoCoder=[[CLGeocoder alloc]init];
        CLLocation *currentLocation=[[CLLocation alloc]initWithLatitude:[imgLatLoc doubleValue] longitude:[imgLongLoc doubleValue]];

        [geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placeMarks, NSError *err){
        // completion block
            if(err)
            {
                 // error stuff
            }

            if(placeMarks && placeMarks.count>0)
            {
                 // what happens when you get some data
            }

            // now see if we are done and if not do the next object
            if (imgIdx<[imageMetaMutArray count])
            {
                [self reverseGeocodeForIndex:imgIdx+1];
            } else {
                // Everything is done maybe you want to start something else
            }
        }];
    } else {
        // Since you might not reverseGeocode an object you need an else case
        // here to move on to the next object.
        // Maybe you could be more clever and not duplicate this code.
        if (imgIdx<[imageMetaMutArray count])
        {
            [self reverseGeocodeForIndex:imgIdx+1];
        } else {
            // Everything is done maybe you want to start something else
        }
    }
}

当然,您不能依靠此操作来做其他任何事情,除了在对最后一个对象进行反向地理编码后可能会开始一些事情。

And, of course, you can't depend on this being done to do anything else except that you might kick something off when you have reverseGeocoded the last object.

这种异步编程可以使您发疯。

This asynchronous programming can drive you nuts.

这篇关于从给定坐标(不是当前位置,而是手动提供)进行反向地理编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆