Search code examples
iphonemkannotationregion

MKAnnotation only within region


How can I only load the annotations that are within the displayed region? At the moment I load all Annotation with this method

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

Any ideas or good documents on how I could remove all annotations that are outside the display and load the others?

Thanks a lot

EDIT:

I have actually found a solution but it does not perfectly work somehow. I check if region has changed

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

Then I get max/min lat/long and pull it out of 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]];
}

Only problem is that it only finds the annotations if you zoom in a certain level which is strange. For example

When I zoomed out quite far it has a wide range from min to max. Order is 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] (
)

As soon as I zooom in it does get the objects. Allthough it should already find it before.

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>)",

It actually finds it when I sql directly the sqllite db with

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

Why is that?


Solution

  • I actually find the solution to all of that. I track if the region has changed

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

    Then I get max/min lat/long and pull it out of 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]];
    }