2014-01-19 2 views
0

У меня есть NSDictionary около 2000 местоположений с lat и long, и я выпадаю контакты на карте, если они находятся в видимой области карты.поиск NSDictionary для долготы широты с определенным расстоянием

В настоящее время каждый раз, когда кастрюлю на карте, я просто прокручиваю свой словарь и вычисляю расстояние, чтобы увидеть, видимо ли это место, если это так.

CLLocationCoordinate2D centre = [self.map centerCoordinate]; 
CLLocation *mapCenter =[[CLLocation alloc] initWithLatitude: centre.latitude longitude: centre.longitude]; 

     for (int i=0; i < [self.dealersSource count]; i++) { 

      CLLocation *d = [[CLLocation alloc] initWithLatitude: [[[self.dealersSource objectAtIndex:i] valueForKey:@"lat"] floatValue] 
                  longitude: [[[self.dealersSource objectAtIndex:i] valueForKey:@"long"] floatValue]]; 

       CLLocationDistance distance = [d distanceFromLocation:mapCenter]; 
       float dist =(distance/1609.344); 

      if (dist <= radius && dist !=0) { 
       // this will be visible on the map, add to list of annotations 
      } 
} 

Это работает, но кажется довольно неэффективным и может быть медленным на старых IPADS - особенно, если все больше и больше места добавляются в этот список. Я хотел бы иметь возможность использовать какой-то NSPredicate, чтобы отфильтровать свой первоначальный список, прежде чем я начну цикл за ними.

+0

Я предполагаю, что у вас есть и NSArray из 2000 словарей, где каждый dict имеет значения @ "lat" и @ "lon". Вы можете использовать NSPredicate для фильтрации NSArray для заданного предиката. I.e. следующим образом: NSArray * filtarray = [array filterArrayUsingPredicate: [NSPredicate predicateWithFormat: @ "(lat> =% d)", 16.0989]]; Также взгляните на эту ссылку, где подробно объясняется фильтрация NSPredicate: http://stackoverflow.com/questions/110332/filtering-nsarray-into-a-new-nsarray-in-objective-c –

+0

Я предполагаю, что мой путаница в том, что мне нужно будет делать a> = и a <= оба справа на основе видимых карт? И для лат, и для длинного – Slee

+0

Точно так же. Предикат - это как условие утверждения, поэтому вам нужно написать условие, которое в конечном итоге удовлетворит ваши потребности. Addind (a> = some_value && a <= some_value) должен решить проблему. –

ответ

0

На самом деле нет стандартной структуры Objective-C, которая хорошо подходит для нахождения значений в пределах диапазона - вам в значительной степени придется искать один за другим (хотя вы можете использовать «предикаты» для «скрытия», поиск внутри filteredArray... операций и т. д., и поэтому записывайте меньше строк кода).

Лучшая структура для эффективного нахождения значений между границами на линии - это, вероятно, массив, отсортированный по значениям, поиск которых осуществляется с помощью алгоритма бинарного поиска. Вы бы сделали один бинарный поиск нижней границы другой для верхней границы. Это сложность log (n), настолько эффективная для больших списков (если вам не нужно сортировать списки очень часто).

Точно так же, как можно было бы сделать это для 2-й поверхности, сложнее изобразить. Возможно, сначала используйте вышеупомянутую технику, чтобы найти «кандидатов» в направлении X, а затем проверить их координату Y. Однако не было log (n).

Смежные вопросы