МКАнотация только внутри региона - PullRequest
2 голосов
/ 06 сентября 2011

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

- (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]];
}

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

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

EDIT:

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

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

Затем я получаю максимальный / минимальный лат / длинный и вытаскиваю его из 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>)",

На самом деле он находит его, когда я запускаю sqlite db напрямую с

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

Почему это?

Ответы [ 2 ]

3 голосов
/ 07 сентября 2011

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

- (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]];
}
1 голос
/ 06 сентября 2011

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

Информация от Apple Doc

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

...