【问题标题】:MKAnnotation only within regionMKAnnotation 仅在区域内
【发布时间】:2011-09-07 18:41:29
【问题描述】:

如何只加载显示区域内的注释?目前我使用此方法加载所有注释

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

当我直接使用 sqllite db 时,它实际上找到了它

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

这是为什么呢?

【问题讨论】:

    标签: iphone mkannotation region


    【解决方案1】:

    我实际上找到了所有这些的解决方案。我跟踪地区是否发生了变化

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

    【讨论】:

      【解决方案2】:

      默认 MapView 仅加载显示中的注释(即屏幕上)。如果您只是移动屏幕,您可以重用带有 Reuse identifier 的 Annotations 用于注解。所以从技术上讲,您不需要删除显示之外的注释。

      来自 Apple 文档的信息

      因为注释视图只有在屏幕上才需要,所以 MKMapView 类提供了一种对注解视图进行排队的机制 未使用的。具有重用标识符的注释视图可以是 当他们离开时被地图视图内部分离和排队 屏幕。此功能通过仅保留一小部分来提高内存使用率 一次在内存中的注释视图数量,并通过回收 你有的看法。它还通过以下方式提高了滚动性能 减少在地图滚动时创建新视图的需要。

      【讨论】:

      • 我同意这一点。但我仍然一开始就从 CoreData 加载所有内容。如果可能的话,我也想限制它
      • 我可以建议您必须检查从 Coredata 返回的坐标在当前地图视图区域中是否可见,如果将坐标添加到注释中。如果我的假设是正确的,请访问此链接stackoverflow.com/questions/1197398/…
      • 其实我找到了解决办法。我编辑了我以前的帖子。唯一的问题是它不能完美地工作。有什么想法吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多