0

Core Dataとともに保存されている場所(この場合は> 3000)がいくつかあります。マップを開いたら、場所を取得して配列に保存します。マップビュー領域が変更されるたびに、現在表示されている注釈を計算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];

この関数を使用せずに、2つの注釈/座標間のピクセル/ポイント距離を計算するにはどうすればよいですか?または、Core Dataの最適化の提案はありますか?

ありがとう :)

4

1 に答える 1

0

わかりました、私はあなたの説明からそれらがあまりにも近くないことをちょっと逃しました。座標間の変換は非常に遅いです。これを軽減する方法は、座標をマップポイントに事前計算し、MKMapPointForCoordinateそれらを永続的に保存することです。これらは座標にのみ依存します。次に、2つの注釈のマップポイント間の距離をすばやく計算し、マップの現在のズームレベルに応じてスケーリングできます。これは、画面上の実際の距離と非常に密接に関連しています。それは十分に正確でなければならず、はるかに高速になります。

二乗距離を計算し、それを二乗と比較することをお勧めしますdist。で多くの節約になりsqrt()ます。

それでもgetDist()(またはgetSqDist())行き詰まる場合は、kdツリーを使用するか、AccelerateFrameworkを使用して計算を行うことができます。多くのポイント間の距離を計算する必要があり、スピードアップが非常に良かったときに、後者を実行しました。しかし、これの詳細はもう一杯のお茶です。それについて何か助けが必要な場合は私に知らせてください。

座標にインデックスが付けられているという事実は、実際に座標で注釈を検索した場合にのみ役立つため、すべての座標を調べただけでは役に立ちません。

CoreDataからの長い読み込み時間に対処する方法は、注釈をできるだけ軽量にして、座標とマップポイントのみを保存することです。次に、必要に応じて残りの注釈データを取得する方法があります。これは、プロキシパターンを使用して実行できます。

もう一つ。高速列挙はより高速である可能性があり、同様に優れたプラクティスです。

for(LocationEntity* thisLocation in locations)

それ以外の

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