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];
}
然后我获取最大/最小纬度/经度并将其从 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 数据库进行 sql 查询时,它实际上找到了它,
SELECT *
FROM caves
WHERE (
latitude > 43.930069
AND latitude < 50.169209
)
AND (
longitude > 3.078351
AND longitude < 10.207223
)
为什么是这样?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我实际上找到了所有这些问题的解决方案。我跟踪该区域是否已更改
然后我获取最大/最小纬度/经度并将其从 coredata 中取出
I actually find the solution to all of that. I track if the region has changed
Then I get max/min lat/long and pull it out of coredata
默认情况下,MapView 仅加载显示内容(即屏幕上)的注释。如果您只是移动屏幕,则可以通过注释的重用标识符来重用注释。因此从技术上讲,您不需要删除显示之外的注释。
来自苹果文档的信息
As default MapView loads only the annotations that are within your display(i.e, Onscreen). If you just move the screen you can reuse the Annotations with Reuse identifier for annotations. So technically you dont need remove annotations that are out of your display.
Info from Apple doc