MKAnnotations 和核心数据的优化
Posted
技术标签:
【中文标题】MKAnnotations 和核心数据的优化【英文标题】:Optimization for MKAnnotations and Core Data 【发布时间】:2012-09-28 09:59:55 【问题描述】:我有一些位置(在本例中为 >3000)与 Core Data 一起存储。打开地图后,我会获取位置并将它们存储在一个数组中。每次更改地图视图区域时,我都会调用一个函数,该函数将计算当前visibleMaprect
中可见的注释并按像素距离过滤它们。 (我知道会有更复杂的优化,比如四叉树,但如果不是非常必要的话,我现在不会真正实现它)。
这是我的代码:
//locations is an array of NSManagedObjects
for (int i =0 ; i < [locations count]; i++)
// managed object class for faster access, valueforkey takes ages ...
LocationEntity * thisLocation = [locations objectAtIndex:i];
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake( [thisLocation.latitude doubleValue], [thisLocation.longitude doubleValue]) ;
// mapRect is mapView.visibleMapRect
BOOL isOnScreen = MKMapRectContainsPoint(mapRect, MKMapPointForCoordinate(coord));
if (isOnScreen)
CGPoint cgp = [mapView convertCoordinate:coord toPointToView:mapView];
// compare the distance to already existing annotations
for (int idx = 0; idx < [annotations count] && hasEnoughDistance; idx++)
CGPoint cgp_prev = [mapView convertCoordinate:[[annotations objectAtIndex:idx] coordinate] toPointToView:mapView];
if ( getDist(cgp, cgp_prev) < dist ) hasEnoughDistance = FALSE;
if (hasEnoughDistance)
// if it's ok, create the annotation, add to an array and after the for add all to the map
每次缩放/移动后,地图都会冻结几秒钟。
我用时间分析器检查了坐标的简单获取有时需要整整 1 秒,有时只需 0.1,即使坐标是我模型中的索引属性......而且这些类型的线似乎需要很长时间:
CGPoint cgp = [mapView convertCoordinate:coord toPointToView:mapView];
任何建议如何在不通过此函数的情况下计算两个注释/坐标之间的像素/点距离?或者对 Core Data 有什么优化建议?
谢谢:)
【问题讨论】:
【参考方案1】:好的,我有点错过了你的解释中没有让它们太靠近的地方。坐标之间的转换很慢。缓解这种情况的方法是使用MKMapPointForCoordinate
将坐标预先计算为地图点并永久存储它们——它们只依赖于坐标。然后您可以快速计算两个注释的地图点之间的距离,根据您当前地图的缩放级别对其进行缩放,这将与屏幕上的实际距离密切相关。它应该足够准确,并且会更快。
我建议计算平方距离并将其与平方dist
进行比较。你会在sqrt()
上节省很多。
如果您仍然对 getDist()
(或 getSqDist()
)感到困惑,您可以选择 kd 树或使用 Accelerate Framework 进行计算。当我需要计算许多点之间的距离并且加速非常好时,我已经完成了后者。但这个细节是另一杯茶。如果您需要任何帮助,请告诉我。
您的坐标被索引的事实只有在您实际按坐标搜索注释时才会有所帮助,因此如果您只查看所有注释将无济于事。
从 CoreData 处理较长的加载时间的一种方法是尝试使您的注释尽可能轻量级,因此只存储坐标和地图点。然后,您可以根据需要获取其余的注释数据。这可以通过代理模式来完成。
还有一件事。快速枚举可能更快,也是更好的做法,所以
for(LocationEntity* thisLocation in locations)
而不是
for (int i =0 ; i < [locations count]; i++)
【讨论】:
是的,但我不希望它们彼此靠得太近,因此需要进行某种过滤。我知道在这里检查是多余的,但这只是一个比较。 感谢您的长回答 :) 我曾考虑以某种方式缓存这些点以用于位置,但希望这将是一种更简单的方法。太糟糕了,MKMapPoint->CGPoint 没有一个简单的近似值:)getDist
确实比较了平方和,双打在取平方根时的性能很差。我已经重新安排了我可以做的事情,并将整个执行时间减少到大约一半...编辑:我稍后使用i
,这就是我使用此表单的原因。以上是关于MKAnnotations 和核心数据的优化的主要内容,如果未能解决你的问题,请参考以下文章
ANN预测模型基于差分算法改进ANN网络预测matlab源码
MKAnnotations 未显示在地图上 iOS 9 / Swift 2.0