处理大量 MKMapView 注解
我有一个带有大量注释(3000+)的地图视图,当用户缩放到合理的级别时,一切都很好而且很快。
尽管当用户缩小并看到大量注释时,由于一次显示的注释数量巨大,速度会显着减慢。处理这个问题的最佳方法是什么?
我当前使用的解决方案:
- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated {
NSArray *annotations = [_mapView annotations];
MapAnnotation *annotation = nil;
for (int i=0; i<[annotations count]; i++)
{
annotation = (MapAnnotation*)[annotations objectAtIndex:i];
if (_mapView.region.span.latitudeDelta > .010)
{
[[_mapView viewForAnnotation:annotation] setHidden:YES];
warningLabel.hidden = NO;
}
else {
[[_mapView viewForAnnotation:annotation] setHidden:NO];
warningLabel.hidden = YES;
}
}
}
效果很好,尽管由于循环的巨大尺寸,这会导致放大、缩小和滚动时速度减慢很多。我似乎想不出更好的方法来处理这个问题,有没有办法只循环当前显示的注释或类似的东西来减少循环的大小?
I have a map view with a large quantity of annotations (3000+), when the user is zoomed to a reasonable level all is well and fast.
Although when the user zooms out and a large quanitiy of annotations come into view there is a lot of slow down due to the sheer amount of annotations being shown at once. What is the best way to handle this?
The current solution i am using:
- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated {
NSArray *annotations = [_mapView annotations];
MapAnnotation *annotation = nil;
for (int i=0; i<[annotations count]; i++)
{
annotation = (MapAnnotation*)[annotations objectAtIndex:i];
if (_mapView.region.span.latitudeDelta > .010)
{
[[_mapView viewForAnnotation:annotation] setHidden:YES];
warningLabel.hidden = NO;
}
else {
[[_mapView viewForAnnotation:annotation] setHidden:NO];
warningLabel.hidden = YES;
}
}
}
Works great although due to the sheer size of the loop this causes a lot of slow down when zooming in and out and scrolling around. I can't seem to think of a better way to handle this, is there a way to only loop through the annotations currently being displayed or something along those lines to reduce the size of the loop?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
据我了解您的代码,如果地图视图缩小超过某个指定值,您将隐藏所有注释的视图。
在我看来,像下面这样的东西会更好:
有了上面的内容,在大多数情况下,这段代码所做的唯一事情就是进行一些 if 检查。
另一种解决方案是在注释不应显示在地图上时删除注释。就我个人而言,我认为这会更好,这样代码就不必为尚未在地图上显示的注释创建视图。
As I understand your code, you are hiding all the annotations' views if the mapView is zoomed out more than a certain specified value.
It seems to me that something more like the following would be better:
With the above, in most cases the only thing this code does is a couple of if checks.
Another solution would be to remove the annotations when they shouldn't show on the map. Personally, I think this would be better, that way the code doesn't have to create views for annotations that haven't been shown on the map yet.
我会建议几件事。一、查看
annotationsInMapRect:
方法。根据文档,它说:二、查看dequeueReusableAnnotationViewWithIdentifier:。再次根据文档,它说:
最后,有几点想法。与其每次调用
- (void)mapView:(MKMapView *)_mapView RegionDidChangeAnimated:(BOOL)animated
方法时都进行这些更改,不如根据其他规则(例如在计时器被触发[确保每次调用时重置计时器])?另一件需要考虑的事情是:如何将彼此非常接近的注释分组在一起?假设您缩小到罗德岛看起来非常小,可能只有十几个像素宽,并且您在罗德岛有 100 个点 - 您应该只显示一个图钉。希望这有帮助!
I would suggest a couple of things. One, look at the method
annotationsInMapRect:
. According to the docs, it says:Two, look at
dequeueReusableAnnotationViewWithIdentifier:
. According to the docs again, it says:Finally, a couple of thoughts. Instead of doing these changes every time the
- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated
method is called, how about doing it according to some other rule (such as after a timer gets fired [make sure to reset the timer every time this gets called])? Another thing to consider: how about grouping annotations together that are super close to each other? Let's say you're zoomed out to where Rhode Island looks super small, maybe just a dozen pixels wide, and you have 100 points in Rhode Island -- you should just display one pin.Hope this helps!
我最终使用 OCMapView 将注释分组到集群中。它是免费的,并且很容易实现到现有代码中。
当缩小时,它会自动对您的注释进行分组;当您放大时,它们会按应有的方式显示为分散的。
我知道这是一个老问题,但对于其他尝试做同样事情的人来说,这是一个很好的选择。
I ended up grouping my annotations in clusters using OCMapView. Its free, and very easy to implement into existing code.
It automatically groups your annotations when zoomed out and as you zoom in they appear unclustered as they should.
I know this is an old question but its a great option for anyone else trying to do the same thing.