2012-02-28 46 views
1

我从数据库中提取地址列表。列表的大小可以是0-n。但是,n通常是50-60。将注释添加到MKMapView的最佳方法

我试图发现最佳方式将所有这些位置添加到地图视图。

,我目前使用的方法去如下。

  1. 我创建了一个mutableArray(注释)持有我所有的注释(我删除和添加他们经常回来,所以最好让他们所有手头上快速添加/删除)。

  2. 我通过我传递地址到反向地理编码,以获得lat和长地址(从DB)的加载列表运行。看到

  3. 检查lat和长是0,0(意思是我率谷歌限制)。

  4. Y -如果是这样,我标记已经有一个速率禁止,并将@“”添加到注释数组中。添加和删​​除时,必须保留注释以便正确参考。

  5. N -如果不是那么我将该注释添加到地图和注释数组。

  6. 如果已经存在一个速度的禁令,我通过注释阵列运行寻找@“”时,如果发现一个,用步骤2-5继续。

我递归地调用这个函数(第5步),直到添加了所有的注解为止。但它似乎效率低下。

有没有人发现了一种方法,这将是更多的时间和内存使用效率?


这是最初的呼叫开球注释加载:

- (void)addLocations { 

    /* 
    Setup an array to hold all annotations, this is done for fast removal/addition when filtering which happens often. So far, through testings, has shown to be the optimal way. 
    */ 
    annotations = [[NSMutableArray alloc] init]; 

    bool needsReload = NO; 

    //Loop through all locations parsed from the DB 
    for (int i = 0; i < [[[[self appDelegate] rssParser]rssItems] count]; i++) { 

     NSString *temp = [NSString stringWithFormat:@"%@, %@, %@", [[[[[self appDelegate]rssParser]rssItems] objectAtIndex:i] Address], [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i]City], [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i]State]]; 

     CLLocationCoordinate2D tempLocation = [self addressLocation:temp]; 


     if (tempLocation.latitude == 0.0) { 

      //We have been rate banned and flag for a re-run through locations. 
      [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i] setLocation:nil]; 

      needsReload = YES; 

      [annotations addObject:@""]; 

     } else { 

      /* 
      Set location of property. Done for property use in other locations of app. 
      */ 
      CLLocation *tempLoc = [[CLLocation alloc] initWithLatitude:tempLocation.latitude longitude:tempLocation.longitude]; 
      [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i] setLocation:tempLoc]; 

      //Create new annotation with proper coordinates 
      MapAnnotation *addAnnotation = [[MapAnnotation alloc] initWithCoordinate:tempLocation]; 
      addAnnotation.name = [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i]Address]; 

      // Check to see if location has an image associated with it. 
      if ([[[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i] imageURLs] count] > 0) 
       addAnnotation.thumbURL = [[[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i] imageURLs] objectAtIndex:0]; 
      else 
       addAnnotation.thumbURL = nil; 

      addAnnotation.tag = i; 

      addAnnotation.description = [NSString stringWithFormat:@"%@, %@ | $%@",[[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i]City] , [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i]State] ,[[[[[[self appDelegate]rssParser]rssItems] objectAtIndex:i] Deposit] stringByReplacingOccurrencesOfString:@".00" withString:@""]]; 

      //Add annotation to "annotations" array for fast addition/removal when filtering. 
      [annotations addObject:addAnnotation]; 

      [self._mapView addAnnotation:addAnnotation]; 

      //Doesn't seem necessary in ARC but somehow helps with memory on iPhone 3GS 
      temp = nil; 
      addAnnotation = nil; 
     } 
    } 

    //Attempt to force a refresh so annotations show up. 
    [self._mapView setCenterCoordinate:self._mapView.centerCoordinate zoomLevel:ZOOM_LEVEL animated:NO]; 

    /* 
     If there was a rate ban we need to run through the locations again to get proper coordinates 
    */ 
    if (needsReload == YES) { 
     //Sleep the thread to shake off rate ban from google. 
     [NSThread sleepForTimeInterval:2.0f]; 
     //Move to the background so user can begin interacting with app 
     [self performSelectorInBackground:@selector(rateLimited) withObject:nil]; 

    } else { 
     //All locations were property loaded so we can stop here. 
     [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
     self.radiusControl.hidden = NO; 
    } 
} 

,如果有一个速度禁止我们进入这递归调用方法正确地获得所有坐标。

- (void)rateLimited { 

    /* 
    Create an array to hold the newly loaded annotations. For some reason the map will only load annoations if I add this this way. Instead of adding them one at a time as done before. I suppose it has to do with some refresh issue. 
    */ 
    NSMutableArray *tempReload = [[NSMutableArray alloc] init]; 

    bool needsReload = NO; 

    /* 
    Run through the parsed list of property objects again looking for @"" 
    */ 
    for (int i = 0; i < [annotations count]; i++) { 

     if ([[annotations objectAtIndex:i] isEqualToString:@""]) { 

      Property *tempProp = (Property*) [[[self.appDelegate rssParser] rssItems] objectAtIndex:i]; 

      NSString *temp = [NSString stringWithFormat:@"%@, %@, %@", [tempProp Address], [tempProp City], [tempProp State]]; 

      CLLocationCoordinate2D tempLocation = [self addressLocation:temp]; 

      //There was another rate ban so we need to run through list again. 
      if (tempLocation.latitude == 0.0) { 
       needsReload = YES; 

      } else { 

       CLLocation *tempLoc = [[CLLocation alloc] initWithLatitude:tempLocation.latitude longitude:tempLocation.longitude]; 

       [[[[[self appDelegate] rssParser]rssItems]objectAtIndex:i] setLocation:tempLoc]; 

       MapAnnotation *addAnnotation = [[MapAnnotation alloc] initWithCoordinate:tempLocation]; 
       addAnnotation.name = [tempProp Address]; 
       if ([[tempProp imageURLs] count] > 0) 
        addAnnotation.thumbURL = [[tempProp imageURLs] objectAtIndex:0]; 
       else 
        addAnnotation.thumbURL = nil; 

       //Have to keep tags corresponding to the inital listLocation assigned when DB is parsed from server. Done so when properties are added/removed they can be referenced correctly. 
       addAnnotation.tag = [tempProp listLocation]; 

       //Set description 
       addAnnotation.description = [NSString stringWithFormat:@"%@, %@ | $%@",[tempProp City] , [tempProp State] ,[[tempProp Deposit] stringByReplacingOccurrencesOfString:@".00" withString:@""]]; 

       //Repace the @"" with the proper annotation. 
       [annotations replaceObjectAtIndex:i withObject:addAnnotation]; 

       //Add annotation for bulk addition after loop as finished. 
       [tempReload addObject:addAnnotation]; 
       temp = nil; 
       addAnnotation = nil; 
      } 
     } 
    } 

    //Bulk add new annoations 
    [self._mapView addAnnotations:tempReload]; 

    //If we need to reload, we recusivly call this method until all locations have proper coordinates. 
    if (needsReload == YES){ 
     needsReload = NO; 
     tempReload = nil; 
     //The recusive call 
     [self rateLimited]; 

    } else { 
     //All locations have property loaded now we can finish. *wew* 
     [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
     self.radiusControl.hidden = NO; 
    } 

} 

这里是我的反向地理编码方法,也许有人可以有绕了一个更好的办法。

-(CLLocationCoordinate2D)addressLocation:(NSString*)_address { 

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

    NSError* error = nil; 
    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 { 
     NSLog(@"error"); 
    } 
    CLLocationCoordinate2D location; 
    location.latitude = latitude; 
    location.longitude = longitude; 

    return location; 
} 

回答

0

我会设置每个位置作为自己的对象,然后只是让该对象本身负责找出并设置自己的位置。 (和一个小的延迟之后重试,如果有一个问题)

然后,你可以创建他们根据需要,让他们做他们的事 - 只有你的地图上显示,一旦他们让你知道他们准备好了。

相关问题