0

我有一些位置(在本例中为 >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 有什么优化建议?

谢谢 :)

4

1 回答 1

0

好的,我有点错过了你的解释中没有让它们太近的地方。坐标之间的转换很慢。您可以缓解它的方法是将坐标预先计算为地图点MKMapPointForCoordinate并永久存储它们 - 它们仅取决于坐标。然后您可以快速计算两个注释的地图点之间的距离,根据您当前的地图缩放级别对其进行缩放,这将与屏幕上的实际距离密切相关。它应该足够准确,并且会更快。

我建议计算平方距离并将其与 squared 进行比较dist。您将在sqrt().

如果您仍然对getDist()(或getSqDist()) 感到困惑,您可以选择 kd 树或使用 Accelerate Framework 进行计算。当我需要计算许多点之间的距离并且加速非常好时,我已经完成了后者。但这个细节是另一杯茶。如果您需要任何帮助,请告诉我。

仅当您实际按坐标搜索注释时,您的坐标被索引的事实才会有所帮助,因此如果您只查看所有这些注释将无济于事。

处理来自 CoreData 的长加载时间的一种方法是尝试使您的注释尽可能轻量级,因此只存储坐标和地图点。然后,您可以根据需要获取其余的注释数据。这可以通过代理模式来完成。

还有一件事。快速枚举可能更快,也是更好的做法,所以

for(LocationEntity* thisLocation in locations)

代替

for (int i =0 ; i < [locations count]; i++)
于 2012-09-28T10:02:31.480 回答