1

現在のビューの境界ボックスに基づいて地図上にトレイルを表示する iOS 用に取り組んでいるアプリケーションがあります。そのため、ユーザーがマップ内を移動すると、適切な一連のトレイルが読み込まれます。

SQLite テーブルは 260,000 行の大規模で、各行はトレイル上のポイントです。テーブルには、主キー (int)、緯度 (float)、経度 (float)、および名前 (varchar) があります。緯度と経度の列にはインデックスが付けられています。クエリを実行すると、緯度が右下と左上の緯度の間にあり、経度が左上と右下の経度の間にある場所を探しています。クエリは、期待される結果を返すため、デスクトップでも電話でも問題なく動作します。問題は、私の Mac ではクエリが即座に返されることですが、電話では何かを返す前にわずか 4 秒しかかからないことがあります。ボトルネックはデータベース クエリにあるようで、ハードウェアの制限であると考え始めています。

最初に問題に気付いた CoreData を使用してみました。その後、FMDB を使用してデータベースにアクセスするようになりましたが、まだ問題が発生しています。

データベースや接続を微調整していません。

queryForTrails メソッドの中身

    if( ![db open] ) {
        [db release];
        NSLog(@"Error opening DB: %@", dbPath);
    }

    FMResultSet *trails = [db executeQueryWithFormat:@"SELECT zname, zlatitude, zlongitude FROM ztrail WHERE ztype = 1 and zlatitude BETWEEN %@ and %@ AND zlongitude BETWEEN %@ and %@ order by zname", lrLat, ulLat, ulLon,lrLon];

    //Start to load the map with data
    NSString *lastTrailName=@"";
    int idx = 0;
    CLLocationCoordinate2D *trailCoords = nil;
    NSUInteger coordSize = 20;

    trailCoords = malloc(sizeof(CLLocationCoordinate2D)*coordSize);
    while( [trails next] ) {
        NSString *trailName = [trails stringForColumnIndex:0];
        NSString *lat = [trails stringForColumnIndex:1];
        NSString *lon = [trails stringForColumnIndex:2];

        if( [lastTrailName compare:trailName] != NSOrderedSame ) {
            if(idx > 0) {
                [trailLines addObject:[MKPolyline polylineWithCoordinates:trailCoords count:idx]];
                free(trailCoords);
                idx = 0;
                coordSize = 20;
            }
            lastTrailName = trailName;
            trailCoords = malloc(sizeof(CLLocationCoordinate2D)*coordSize);
        }

        if(idx == coordSize) {
            coordSize *= 2;
            trailCoords = realloc(trailCoords, sizeof(CLLocationCoordinate2D) * coordSize);
        }

        trailCoords[idx++] = CLLocationCoordinate2DMake([lat doubleValue], [lon doubleValue]);
    }

    //Build the new polyline
    [trailLines addObject:[MKPolyline polylineWithCoordinates:trailCoords count:idx]];
    //NSLog(@"Num Trails: %d", [trailLines count]);
    free(trailCoords);
    //NSLog(@"Num of Points %d for %@",idx, lastTrailName);

    if( [trailLines count] > 0 ) {
        dispatch_async(dispatch_get_main_queue(),^{
            [mapView addOverlays:trailLines];
        });
    }

必要に応じて、NSLog データを提供できます。Android 用にも同じアプリケーションを実行する予定なので、パフォーマンスの問題を解決したいと思います。

4

0 に答える 0