MKAnnotation только в пределах региона

Как я могу загрузить только те аннотации, которые находятся в пределах отображаемой области? На данный момент я загружаю все аннотации этим методом

- (void)reloadAnnotatons
{
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = [NSEntityDescription entityForName:@"Cave" inManagedObjectContext:self.context];
    request.predicate = [NSPredicate predicateWithFormat:@"(latitude > 0) AND (longitude > 0)"];

    [self.mapView addAnnotations:[self.context executeFetchRequest:request error:NULL]];
}

Любые идеи или хорошие документы о том, как я могу удалить все аннотации, которые находятся за пределами дисплея, и загрузить другие?

Большое спасибо

РЕДАКТИРОВАТЬ:

Я на самом деле нашел решение, но оно почему-то не работает идеально. Я проверяю, изменился ли регион

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    [self reloadAnnotatons];
}

Затем я получаю max/min lat/long и вытаскиваю его из coredata.

- (void)reloadAnnotatons
{
    double minLat = self.mapView.region.center.latitude - (self.mapView.region.span.latitudeDelta / 2);
    double maxLat = self.mapView.region.center.latitude + (self.mapView.region.span.latitudeDelta / 2);
    double minLon = self.mapView.region.center.longitude - (self.mapView.region.span.longitudeDelta / 2);
    double maxLon = self.mapView.region.center.longitude + (self.mapView.region.span.longitudeDelta / 2);

    NSLog(@"%f %f %f %f",minLat,maxLat,minLon,maxLon);

    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = [NSEntityDescription entityForName:@"Cave" inManagedObjectContext:self.context];
    request.predicate = [NSPredicate predicateWithFormat:@"(latitude > %f AND latitude < %f) AND (longitude > %f AND longitude < %f)",minLat,maxLat,minLon,maxLon];

    //NSLog(@"%@",[self.context executeFetchRequest:request error:NULL]);

    [self.mapView addAnnotations:[self.context executeFetchRequest:request error:NULL]];
}

Единственная проблема в том, что он находит аннотации только в том случае, если вы увеличиваете масштаб определенного уровня, что странно. Например

Когда я уменьшил масштаб довольно далеко, он имеет широкий диапазон от минимума до максимума. Порядок minLat, maxLat, minLong, MaxLong

2011-09-07 08:48:15.907 CaveConditions[9028:707] 43.930069 50.169209 3.078351 10.207223
2011-09-07 08:48:15.914 CaveConditions[9028:707] (
)

Как только я увеличиваю масштаб, он получает объекты. Хотя он должен уже найти его раньше.

2011-09-07 08:48:35.363 CaveConditions[9028:707] 46.277977 48.327505 5.453421 7.806564
2011-09-07 08:48:35.376 CaveConditions[9028:707] (
    "<Cave: 0x1d8710> (entity: Cave; id: 0x1cdd10 <x-coredata://738720B4-DCF4-40BA-BD83-A459CECE5F29/Cave/p2> ; data: <fault>)",
    "<Cave: 0x1941c0> (entity: Cave; id: 0x1d1e70 <x-coredata://738720B4-DCF4-40BA-BD83-A459CECE5F29/Cave/p47> ; data: <fault>)",
    "<Cave: 0x190200> (entity: Cave; id: 0x1e62b0 <x-coredata://738720B4-DCF4-40BA-BD83-A459CECE5F29/Cave/p57> ; data: <fault>)",
    "<Cave: 0x1e4960> (entity: Cave; id: 0x1a1560 <x-coredata://738720B4-DCF4-40BA-BD83-A459CECE5F29/Cave/p67> ; data: <fault>)",

Он на самом деле находит его, когда я sql непосредственно sqllite db с

SELECT * 
FROM caves
WHERE (
latitude > 43.930069
AND latitude < 50.169209
)
AND (
longitude > 3.078351
AND longitude < 10.207223
)

Это почему?


person Chris    schedule 06.09.2011    source источник


Ответы (2)


Я действительно нахожу решение для всего этого. Я отслеживаю, изменился ли регион

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    [self reloadAnnotatons];
}

Затем я получаю max/min lat/long и вытаскиваю его из coredata.

- (void)reloadAnnotatons
{
    double minLat = self.mapView.region.center.latitude - (self.mapView.region.span.latitudeDelta / 2);
    double maxLat = self.mapView.region.center.latitude + (self.mapView.region.span.latitudeDelta / 2);
    double minLon = self.mapView.region.center.longitude - (self.mapView.region.span.longitudeDelta / 2);
    double maxLon = self.mapView.region.center.longitude + (self.mapView.region.span.longitudeDelta / 2);


    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.entity = [NSEntityDescription entityForName:@"Cave" inManagedObjectContext:self.context];
    request.predicate = [NSPredicate predicateWithFormat:@"(latitude > %lf AND latitude < %lf) AND (longitude > %lf AND longitude < %lf)",minLat,maxLat,minLon,maxLon];


    [self.mapView addAnnotations:[self.context executeFetchRequest:request error:NULL]];
}
person Chris    schedule 07.09.2011

По умолчанию MapView загружает только аннотации, которые находятся на вашем дисплее (например, на экране). Если вы просто переместите экран, вы можете повторно использовать аннотации с идентификатором повторного использования для аннотаций. Так что технически вам не нужно удалять аннотации, которые не отображаются на вашем дисплее.

Информация из документа Apple

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

person ipraba    schedule 06.09.2011
comment
Я согласен с этим. Но я все равно сначала загружаю все из CoreData. Я хотел бы ограничить это, если это возможно - person Chris; 06.09.2011
comment
Что я могу предложить, так это то, что вы должны проверить, что координата, возвращаемая из Coredata, видна в текущей области просмотра карты, если вы добавляете координату в аннотации. Если мое предположение верно, перейдите по этой ссылке stackoverflow.com/questions/1197398/ - person ipraba; 06.09.2011
comment
Я действительно нашел решение. Я отредактировал свой предыдущий пост. Единственная проблема в том, что он не работает идеально. Любая идея? - person Chris; 07.09.2011